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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

----
Also see AdvancedOptions
<<importTiddlers>>
With a little scripting you can use the ForEachTiddlerPlugin to display the result "by pages". I.e. you don't display the full result list, but (e.g.) 10 at a time.

Using a "pagewise" display may be useful when the result may get very large. This way you avoid scrolling the window to see the result. It also speeds up things since less items need to be display at a time.

''Example:''

<<forEachTiddler
    script '
        window.fetItemsPerPage = 10;

        function getHeader(context,count) {
            if (!window.fetStartIndex || window.fetStartIndex < 0)
                window.fetStartIndex = 0;

            // ensure not to page behind the last page
            if (window.fetStartIndex >= count)
                window.fetStartIndex = Math.min(Math.max(window.fetStartIndex-window.fetItemsPerPage,0),count-1);

            createTiddlyButton(context.place,"<",null,
                    function(e) {
                        window.fetStartIndex -= window.fetItemsPerPage;
                        story.refreshTiddler(context.viewerTiddler.title,null,true);
                    });
            createTiddlyButton(context.place,">",null,
                    function(e) {
                        window.fetStartIndex += window.fetItemsPerPage;
                        story.refreshTiddler(context.viewerTiddler.title,null,true);
                    });

            var startNo = window.fetStartIndex+1;
            var endNo = Math.min(count,window.fetStartIndex+window.fetItemsPerPage);

            return "("+startNo+" - "+endNo+ " of "+ count + " items)\n";
        }
    '

    write
            '(index >= window.fetStartIndex) && (index < window.fetStartIndex + 10) ? "* [["+tiddler.title+"]]\n" : ""'

        begin
            'getHeader(context,count)'
>>
''Code''
{{{
<<forEachTiddler
    script '
        window.fetItemsPerPage = 10;

        function getHeader(context,count) {
            if (!window.fetStartIndex || window.fetStartIndex < 0)
                window.fetStartIndex = 0;

            // ensure not to page behind the last page
            if (window.fetStartIndex >= count)
                window.fetStartIndex = Math.min(Math.max(window.fetStartIndex-window.fetItemsPerPage,0),count-1);

            createTiddlyButton(context.place,"<",null,
                    function(e) {
                        window.fetStartIndex -= window.fetItemsPerPage;
                        story.refreshTiddler(context.viewerTiddler.title,null,true);
                    });
            createTiddlyButton(context.place,">",null,
                    function(e) {
                        window.fetStartIndex += window.fetItemsPerPage;
                        story.refreshTiddler(context.viewerTiddler.title,null,true);
                    });

            var startNo = window.fetStartIndex+1;
            var endNo = Math.min(count,window.fetStartIndex+window.fetItemsPerPage);

            return "("+startNo+" - "+endNo+ " of "+ count + " items)\n";
        }
    '

    write
            '(index >= window.fetStartIndex) && (index < window.fetStartIndex + 10) ? "* [["+tiddler.title+"]]\n" : ""'

        begin
            'getHeader(context,count)'
>>
}}}
Mother's Day
Midsummer eve
Birthday TiddlyWiki (*2004)
Christmas
New Year's Eve
<<tiddler DailyStatusReport>>
<<tiddler CurrentTasks>>This page serves as a platform to share TiddlyWiki macros, plugins and other extensions, written by UdoBorkowski from {{abegoLink{[[abego Software|http://www.abego-software.de]]}}}.

If you enjoy the plugins, or find them useful then please consider a [[donation|Donations]].
<<tiddler [[Plugins]]>>
''Syntax:''
|[//action// [//actionParameters//]]|

The Action Specification in the [[ForEachTiddlerMacro]] specifies what should happen with the tiddlers. The specified action is applied to all tiddlers that are selected through the [[whereClause]], in the order specified by the [[sortClause]].

The following actions are supported:

<<tiddler AddToListAction>>
<<tiddler WriteAction>>
''//The {{{addToList}}} action//''

The {{{addToList}}} action of the ForEachTiddlerMacro adds every selected tiddler to a list and displays it at the location of the macro.

It is the default action, i.e when no action is given the addToList action is used.
Here are some examples that show the usage of the addToList action (the default action) in the ForEachTiddlerMacro.
<<forEachTiddler
 where
 'tiddler.tags.contains("addToListActionExample")'
>>
See also ForEachTiddlerExamples.
[ ... Here goes the detailed documentation for the tiddler ... ]
[ ... Here goes the detailed documentation for the tiddler ... ]
<<options>>
<<option chkUseInclude>> Include ~TiddlyWikis (IncludeList | IncludeState | [[help|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]])
^^(Reload this ~TiddlyWiki to make changes become effective)^^
''Private Settings: ''<<option chkUsePrivateSettings>> Use private settings.  <<option chkMakeSettingPrivateWhenChanged>> Make setting private when changed.&#160;&#160;&#160;[[Show Settings]].
^^(Private settings are stored in this ~TiddlyWiki, shared settings are stored as cookies. For more information see the [[Settings documentation|SettingsPlugin Documentation]].)^^
<<option chkUseYourSearch>> Use 'Your Search' //([[more options|YourSearch Options]]) ([[help|YourSearch Help]])//
<<option chkYourSearchSortByDate>> Sort 'Your Search' result by Date 
/***
|''Name:''|AutoRefreshPlugin|
|''Version:''|1.0.1 (2007-01-20)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#AutoRefreshPlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[AutoRefreshPlugin Documentation|http://tiddlywiki.abego-software.de/#%5B%5BAutoRefreshPlugin%20Documentation%5D%5D]]|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''~CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.5.0.9 or better; Internet Explorer 6.0|
A tiddler containing the {{{<<autoRefresh...>>}}} macro is automatically refreshed (re-painted) whenever a tiddler changes.
!Syntax
{{{
<<autoRefresh [observeTiddler: tiddler ...]>>
}}}
|{{{observeTiddler}}}|(optional) when specified the refresh will only happen when one of the tiddlers specified is changed.|
!Source Code
***/
//{{{

if (!window.abego) window.abego = {};

// autoRefresh Macro =============================================================
//
(function() {


var REFRESHER_NAME = "abego_onEveryChange";

var tiddlersToRefresh = {}; // A set holding the names of tiddlers to be refreshed

var onEveryChangeRefresher = function(e,changeList) {

	var tiddlerElem = story.findContainingTiddler(e);
	if (!tiddlerElem) return false;

	var title = tiddlerElem.getAttribute("tiddler");
	if (!title) return false;

	// if "observeTiddler" are specified we only refresh if one of the given
	// tiddlers has changed.
	var observedTiddlers = e.getAttribute("observedTiddlers");
	if (observedTiddlers) {
		var a = observedTiddlers.readBracketedList();
		if (!changeList || !a.containsAny(changeList))
			return;
	}

	// Refresh the tiddler asynchronously.
	// This way we can avoid repeated refreshes (e.g. when a tiddler is renamed)
	tiddlersToRefresh[title] = true;
	setTimeout(function() {
		// Refresh all tiddlers in tiddlersToRefresh
		for(var title in tiddlersToRefresh)
			story.refreshTiddler(title,null,true);

		// We have refreshed all pending tiddlers. Clear the set.
		tiddlersToRefresh = {};
	}, 0);

	return true;
}

config.refreshers[REFRESHER_NAME] = onEveryChangeRefresher;


config.macros.autoRefresh = {};

config.macros.autoRefresh.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    params = paramString.parseParams("observeTiddler",null,true,false,true); // allowEval, cascadeDefaults, names allowed

	var e = createTiddlyElement(place,"span");
	e.setAttribute("refresh",REFRESHER_NAME);
	var observedTiddlers = params[0]["observeTiddler"];
	if (observedTiddlers && observedTiddlers.length) {
		var s = "[["+observedTiddlers.join("]] [[")+"]]";
		e.setAttribute("observedTiddlers",s);
	}
};


})();

//}}}
A tiddler containing the {{{<<autoRefresh...>>}}} macro is automatically refreshed (re-painted) whenever a tiddler changes.

!Syntax
{{{
<<autoRefresh [observeTiddler: tiddler ...]>>
}}}
|{{{observeTiddler}}}|(optional) <<br>>when specified the refresh will only happen when one of the tiddlers specified is changed.<<br>>When no "observerTiddler" is specified every tiddler change triggers a repaint/refresh|

!Usage
You may add this macro to a tiddler T when the content displayed by T depends on other tiddlers, e.g. when using the ForEachTiddlerPlugin or the PartTiddlerPlugin.

!!Example 1: Keep forEachTiddler List up-to-date'
{{{
<<forEachTiddler where 'tiddler.title.startsWith("function")'>>
<<autoRefresh>>
}}}
I.e. the tiddler lists all tiddlers that start with "function" using the ForEachTiddlerPlugin.

By adding the {{{<<autoRefresh>>}}} the list is automatically updated whenever a tiddler is changed (e.g. when a new "function..." tiddler is added or an existing one is deleted).

!!Example 2: Always display most recent part content
The tiddler "Example 2" has this content:
{{{
!Topics
<<tiddler Summary/Topics>>
!Authors
<<tiddler Summary/Authors>>
<<autoRefresh observeTiddler: Summary>>
}}}
I.e. "Example 2" displays the text of the two parts "Topics" and "Authors" of the tiddler "Summary" (see PartTiddlerPlugin).

To ensure always the latest content of these parts are displayed (even when the tiddler "Summary" is changed after tiddler "Example 2" is displayed) add {{{<<autoRefresh observeTiddler: Summary>>}}} to the tiddler. Now the tiddler "Example 2" is automatically repainted whenever the (observed) tiddler "Summary" changes.
Create a tabbed view with one tab for every tiddler containing the tag "glossar" (using the {{{<<tabs...>>}}} macro).
{{{
<<forEachTiddler
    where
       'tiddler.tags.contains("glossar")'

    sortBy
       'tiddler.title.toUpperCase()'

    write '" [["+tiddler.title+" ]] \"view ["+tiddler.title+"]\" [["+tiddler.title+"]] "'

        begin '"<<tabs txtMyAutoTab "'

        end '">"+">"'

        none '"//No tiddler tagged with \"glossar\"//"'
>>
}}}
<<forEachTiddler
    where
       'tiddler.tags.contains("glossar")'

    sortBy
       'tiddler.title.toUpperCase()'

    write '" [["+tiddler.title+" ]] \"view ["+tiddler.title+"]\" [["+tiddler.title+"]] "'

        begin '"<<tabs txtMyAutoTab "'

        end '">"+">"'

        none '"//No tiddler tagged with \"glossar\"//"'
>>

//If you wonder about the trailing space in the tab titles read [[this article|http://twhelp.tiddlyspot.com/#tabs]] (Thanks to Morris Gray for this hint).//
Copyright (c) abego Software ~GmbH, 2005-2006 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

<<tiddler [[BSD open source license]]>>
<<formTiddler BiggerFormTemplate>><data>{"userName":"Jerry Wall","isVIP":true,"password":"1234","level":"Guru","browser":"Firefox","music":["New Age"],"notes":"You can enter Text\nacross multiple\nlines...","attachment":"E:\\_Library_\\MiscUB-Vol2005-06 (open)\\Opera 8.51\\ow32enen851.exe"}</data>
<<formTiddler BiggerFormTemplate>><data>{"userName":"Will Snyder","password":"ggggggg","level":"Expert","music":["Jazz","Blues"],"notes":"Having Fun with TiddlyWiki and the FormTiddlerPlugin.\n\n(BTW: notice the multi selection in the 'Music Prefernces' list box)"}</data>
<<formTiddler BiggerFormTemplate>><data>{"userName":"Jack Brown","password":"asdasd","level":"Beginner","browser":"Internet Explorer","notes":"New here..."}</data>
!An Example Form, showing many features of the FormTiddlerPlugin
<html>
<sub><b>Name:</b></sub><br/>
<input name=userName type=text/><input name=isVIP type=checkbox />is VIP<br/>
<sub><b>Password:</b></sub><br/>
<input name=password type=password /><br/>
<sub><b>Attachment:</b></sub><br/>
<input name=attachment type=file /><br/>

<sub><b>Level:</b></sub><br/><input name=level type=radio value="Beginner" />Beginner
<input name=level type=radio value="Expert" />Expert
<input name=level type=radio value="Guru" />Guru<br/>

<sub><b>Browser:</b></sub><br/>
<select name=browser >
 <option>Firefox
 <option>Internet Explorer
 <option>Opera
 <option>Other
</select >
<br/>
<sub><b>Music Preferences:</b></sub><br/>
<select name=music MULTIPLE >
 <option> R&B
 <option> Jazz
 <option> Blues
 <option> New Age
</select >
<br/>

<sub><b>Notes:</b></sub><br/>
<TEXTAREA name=notes rows=4 cols=80 ></TEXTAREA>
<p/>
<input name=hiddenValue type=hidden value="This is a hidden value" />

<input name=btn type=button value="Just a button" />
<input name=btnSubmit type=submit />
<input name=btnReset type=reset />
<br/>
</div>
</html>
[[Card 1|BiggerForm (Card 1)]] - [[Card 2|BiggerForm (Card 2)]] - [[Card 3|BiggerForm (Card 3)]]

~~(This is an example form, using the form template BiggerFormTemplate and the FormTiddlerPlugin.)~~
<html>
<style>
.rolodex table {
border: 0px solid;
background-color:#FFFF99;
}

.rolodex tr, .rolodex td {
border: 0px solid;
}
</style>
<span class="rolodex">
 <table>
 <tr>
 <td colspan="6"><sub><b>Content:</b></sub><br>
 <textarea name=contentrows="8" cols="40" style="width:100%" ></textarea></td></tr>
 <tr>
 <td colspan="6"><sub><b>Comments:</b></sub><br>
 <textarea name=comments rows="6" cols="40" style="width:100%" ></textarea></td></tr>
</table>
</span>
</html>
<<formTiddler BugReportTemplate>>
<data>{"project":"DataTiddlerProject","reportedBy":" GeoffS","reportDate":"2005-12-13","description":"Add a tiddler \"theData\" with the following text:\n==========\n<data >{\"isVIP\":true,\"user\":\"John Brown\",\"age\":\"90\"}</data >\n<script>\nDataTiddler.setData(\"theData\",\"age\",\"50\");\n</script>\n==========\nWhen reopening the tiddler the age is changed (to \"50\"), but the script is gone.","cause":"The regular expression matching the data section was buggy.","state":"closed","fixedIn":"DataTiddlerPlugin 1.0.1"}</data>
<<formTiddler BugReportTemplate>>
<data>{"description":"ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51","project":"ForEachTiddlerProject","reportedBy":"BrunoSabin","reportDate":"2005-12-09","cause":"A trailing \",\" in the field initialization of object instantiations is not allowed in Opera (Firefox accepts/ignores this extra comma)\n\n(see function createContext.)","fixedIn":"ForEachTiddlerPlugin 1.0.2","state":"closed"}</data>
<html>
<style>
.rolodex table {
border: 0px solid;
background-color:#FFFF99;
}

.rolodex tr, .rolodex td {
border: 0px solid;
}
</style>
<span class="rolodex">
 <table>
 <tr>
 <td align="right"><b>Project:</b></td>
 <td ><select name=project ><option><option>DataTiddlerProject<option>ForEachTiddlerProject<option>FormTiddlerProject</select ></td>
 <td align="right"><b>Reported By:</b></td>
 <td ><input name=reportedBy type=text style="width:100%" /></td>
 <td align="right"><b>Date:</b></td>
 <td ><input name=reportDate type=text style="width:100%" /></td>
 </tr>
 <tr>
 <td colspan="6"><sub><b>Description:</b></sub><br>
 <textarea name=description rows="8" cols="40" style="width:100%" ></textarea></td></tr>
 <tr>
 <td colspan="6"><sub><b>Cause:</b></sub><br>
 <textarea name=cause rows="6" cols="40" style="width:100%" ></textarea></td></tr>
 <tr>
 <td align="right"><b>State:</b></td>
 <td ><select name=state ><option>new<option>in progress<option>info pending<option>fixed<option>closed</select ></td>
 <td align="right"><b>Fixed in:</b></td>
 <td colspan = "4"><input name=fixedIn type=text style="width:100%" /></td></tr>
</table>
</span>
</html>
<<forEachTiddler
 where
 'tiddler.tags.contains("BugReport")'
 sortBy
 'tiddler.data("project")+tiddler.data("state")'
 script
 'function writeBugReportLine(tiddler, index) {var result =""; if (index ==0) {result +="|!Project|!Title|!State|\n";} result +="|"+tiddler.data("project")+"|[["+tiddler.title+"]]|"+tiddler.data("state")+"|\n"; return result;}'
 write
 'writeBugReportLine(tiddler,index)'
>>
[[PageTemplate]]
|>|>|[[SiteTitle]] - [[SiteSubtitle]]|
|[[MainMenu]]|[[DefaultTiddlers]] <html><br><br><br><br></html>[[ViewTemplate]] <html><br><br></html> [[EditTemplate]]|[[SideBarOptions]]|
|~|~|[[OptionsPanel]]|
|~|~|[[AdvancedOptions]]|
|~|~|<<tiddler Configuration.SideBarTabs>>|

''StyleSheet:'' [[StyleSheetColors]] - [[StyleSheetLayout]] - [[StyleSheetPrint]]

[[SiteUrl]]
[[SideBarTabs]]
|[[TabTimeline]]|[[TabAll]]|[[TabTags]]|<<tiddler Configuration.TabMore>>|
|>|[[TabMore]]|
|TabMoreMissing|TabMoreOrphans|
''//Discussion Groups//''
The TiddlyWiki community actively discusses in the following Google groups:
* A TiddlyWiki group for general discussion, bug reports and announcements at http://groups-beta.google.com/group/TiddlyWiki
* A TiddlyWikiDev group for discussion about TiddlyWiki development at http://groups-beta.google.com/group/TiddlyWikiDev

Please also use these discussion groups for technical questions regarding plugins provided by this site.


Email: contact@abego-software.de
Contacts:
[[JoeBlock]]
<html>
<style>
.rolodex table {
border: 0px solid;
background-color:#FFFF99;
}

.rolodex tr, .rolodex td {
border: 0px solid;
}
</style>
<span class="rolodex">
 <table>
 <tr>
 <td align="right"><b>Firstname:</b></td>
 <td colspan="3"><input name=firstname type=text style="width:100%" /></td></tr>
 <tr>
 <td align="right"><b>Lastname:</b></td>
 <td colspan="3"><input name=lastname type=text style="width:100%" /></td></tr>
 <tr>
 <td align="right"><b>Email:</b></td>
 <td colspan="3"><input name=email type=text style="width:100%" /></td></tr>
 <tr>
 <td align="right"><b>Phone:</b></td>
 <td colspan="3"><input name=phone type=text style="width:100%" /></td></tr>
 <tr>
 <td align="right" valign="top"><b>Address:</b></td>
 <td colspan="3"><textarea name=address rows="2" cols="40" style="width:100%" ></textarea></td></tr>
 <tr>
 <td align="right"><b>City:</b></td>
 <td colspan="3"><input name=city type=text style="width:100%" /></td></tr>
 <tr>
 <td align="right"><b>State/Province:</b></td>
 <td><input name=state type=text size="5" /></td>
 <td align="right"><b style="width:100%" >ZIP/Postal Code:</b></td>
 <td><input name=zip type=text size="5" style="width:100%" /></td></tr>
 <tr>
 <td align="right"><b>Country:</b></td>
 <td colspan="3"><input name=country type=text style="width:100%" /></td></tr>
 <tr>
 <td align="right"><b>Webpage:</b></td>
 <td colspan="3"><input name=webpage type=text style="width:100%" /></td></tr>
 <tr>
 <td colspan="4"><sub><b>Notes</b></sub><br>
 <textarea name=notes rows="4" cols="40" style="width:100%" ></textarea></td></tr>
</span>
</html>
© [[abego Software GmbH|http://www.abego-software.de]] 2005-2006

''Open Source Licence''

This page (and the TiddlyWiki it is building on) is published under a [[BSD open source license]]. This gives you the freedom to use it pretty much however you want, including for commercial purposes, as long as you keep the copyright notice. If you do use stuff from this page a link back to http://tiddlywiki.abego-software/ and to http://www.tiddlywiki.com/ is appreciated.
{{{
<<forEachTiddler
 write
 'tiddler.title+"\n"'

 toFile 'file:///c:/MyTiddlerList.txt' withLineSeparator '\r\n'
>>
}}}
<<forEachTiddler
 write
 'tiddler.title+"\n"'

 toFile 'file:///c:/MyTiddlerList.txt' withLineSeparator '\r\n'
>>

<<forEachTiddler
    where
        'tiddler.tags.contains("ReportItem")'
    sortBy
        'tiddler.title'
    script
        '
        function initColumns() {
            context["lines"] = [];

            // Add one array to context.lines per row/line you will generate
            // If you want to have an initial "header" column add its items here
            // TODO: Modify this according to your need
            context.lines.push(["!Tiddler"]);
            context.lines.push(["!~SectionA"]);
            context.lines.push(["!~SectionB"]);

            // No output yet. Postponed to the end.
            return "";
        }

        function addColumn(tiddler) {
            // TODO: Modify this according to your need
            context.lines[0].push(tiddler.title);
            context.lines[1].push(store.getTiddlerSlice(tiddler.title,"SectionA"));
            context.lines[2].push(store.getTiddlerSlice(tiddler.title,"SectionB"));

            // No output yet. Postponed to the end.
            return "";
        }

        function getTransposedTable() {
            var s = "";
            for (var y = 0; y < context.lines.length; y++) {
                var line = context.lines[y]
                for (var x = 0; x < line.length; x++) {
                      s += "|"+line[x];
                }
                s += "|\n";
            }
            return s;
        }'

    write
        'addColumn(tiddler)'
        begin
            'initColumns()'
        end
            'getTransposedTable()'
 >>

See also: [[Create a table with one row per tiddler ("Horizontal Report")]]
<<forEachTiddler
    where
        'tiddler.tags.contains("ReportItem")'
    sortBy
        'tiddler.title'
    write
        '"|"+tiddler.title+
                "|"+store.getTiddlerSlice(tiddler.title,"SectionA")+
                "|"+store.getTiddlerSlice(tiddler.title,"SectionB")+
                "|\n" '
        begin
            '"|!Tiddler|!~SectionA|!~SectionB|\n"'
 >>

See also: [[Create a table with one column per tiddler ("Vertical Report")]]
!Daily Status Report
<<forEachTiddler
 where
 'tiddler.title.contains(context.viewerTiddler.title) && tiddler.title != context.viewerTiddler.title'
 sortBy
 'tiddler.title'
write '"!![["+tiddler.title+"]]\n//"+tiddler.tags+"//\n"+tiddler.text+"\n"'
>>
Here are some examples that show the usage of tiddler data, as provided by the DataTiddlerPlugin.
<<forEachTiddler
 where
 'tiddler.tags.contains("DataTiddlerExample")'
>>
/***
|''Name:''|DataTiddlerPlugin|
|''Version:''|1.0.7 (2012-04-19)|
|''Summary:''|Enhance your tiddlers with structured data (such as strings, booleans, numbers, or even arrays and compound objects) that can be easily accessed and modified through named fields (in JavaScript code).|
|''Source:''|http://tiddlywiki.abego-software.de/#DataTiddlerPlugin|
|''Twitter:''|[[@abego|https://twitter.com/#!/abego]]|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''License:''|[[BSD open source license|http://www.abego-software.de/legal/apl-v10.html]]|
!Description
Enhance your tiddlers with structured data (such as strings, booleans, numbers, or even arrays and compound objects) that can be easily accessed and modified through named fields (in JavaScript code).

Such tiddler data can be used in various applications. E.g. you may create tables that collect data from various tiddlers.

''//Example: "Table with all December Expenses"//''
{{{
<<forEachTiddler
    where
        'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
    write
        '"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
}}}
//(This assumes that expenses are stored in tiddlers tagged with "expense".)//
<<forEachTiddler
    where
        'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
    write
        '"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
For other examples see DataTiddlerExamples.




''Access and Modify Tiddler Data''

You can "attach" data to every tiddler by assigning a JavaScript value (such as a string, boolean, number, or even arrays and compound objects) to named fields.

These values can be accessed and modified through the following Tiddler methods:
|!Method|!Example|!Description|
|{{{data(field)}}}|{{{t.data("age")}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{data(field,defaultValue)}}}|{{{t.data("isVIP",false)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{data()}}}|{{{t.data()}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{setData(field,value)}}}|{{{t.setData("age",42)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{setData(field,value,defaultValue)}}}|{{{t.setData("isVIP",flag,false)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|

Alternatively you may use the following functions to access and modify the data. In this case the tiddler argument is either a tiddler or the name of a tiddler.
|!Method|!Description|
|{{{DataTiddler.getData(tiddler,field)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{DataTiddler.getData(tiddler,field,defaultValue)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{DataTiddler.getDataObject(tiddler)}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{DataTiddler.setData(tiddler,field,value)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{DataTiddler.setData(tiddler,field,value,defaultValue)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|
//(For details on the various functions see the detailed comments in the source code.)//


''Data Representation in a Tiddler''

The data of a tiddler is stored as plain text in the tiddler's content/text, inside a "data" section that is framed by a {{{<data>...</data>}}} block. Inside the data section the information is stored in the [[JSON format|http://www.crockford.com/JSON/index.html]].

//''Data Section Example:''//
{{{
<data>{"isVIP":true,"user":"John Brown","age":34}</data>
}}}

The data section is not displayed when viewing the tiddler (see also "The showData Macro").

Beside the data section a tiddler may have all kind of other content.

Typically you will not access the data section text directly but use the methods given above. Nevertheless you may retrieve the text of the data section's content through the {{{DataTiddler.getDataText(tiddler)}}} function.


''Saving Changes''

The "setData" methods respect the "ForceMinorUpdate" and "AutoSave" configuration values. I.e. when "ForceMinorUpdate" is true changing a value using setData will not affect the "modifier" and "modified" attributes. With "AutoSave" set to true every setData will directly save the changes after a setData.


''Notifications''

No notifications are sent when a tiddler's data value is changed through the "setData" methods.

''Escape Data Section''
In case that you want to use the text {{{<data>}}} or {{{</data>}}} in a tiddler text you must prefix the text with a tilde ('~'). Otherwise it may be wrongly considered as the data section. The tiddler text {{{~<data>}}} is displayed as {{{<data>}}}.


''The showData Macro''

By default the data of a tiddler (that is stored in the {{{<data>...</data>}}} section of the tiddler) is not displayed. If you want to display this data you may used the {{{<<showData ...>>}}} macro:

''Syntax:''
|>|{{{<<}}}''showData '' [''JSON''] [//tiddlerName//] {{{>>}}}|
|''JSON''|By default the data is rendered as a table with a "Name" and "Value" column. When defining ''JSON'' the data is rendered in JSON format|
|//tiddlerName//|Defines the tiddler holding the data to be displayed. When no tiddler is given the tiddler containing the showData macro is used. When the tiddler name contains spaces you must quote the name (or use the {{{[[...]]}}} syntax.)|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
!Source Code
***/
/***
This plugin's source code is compressed (and hidden).
Use this [[link|http://tiddlywiki.abego-software.de/archive/DataTiddlerPlugin/1.0.7/DataTiddlerPlugin-1.0.7-src.js]] to get the readable source code.
***/
///%
if(!version.extensions.DataTiddlerPlugin){version.extensions.DataTiddlerPlugin={major:1,minor:0,revision:7,date:new Date(2012,3,19),type:"plugin",source:"http://tiddlywiki.abego-software.de/#DataTiddlerPlugin"};if(!window.story){window.story=window}if(!TiddlyWiki.prototype.getTiddler){TiddlyWiki.prototype.getTiddler=function(b){var a=this.tiddlers[b];return(a!==undefined&&a instanceof Tiddler)?a:null}}function DataTiddler(){}DataTiddler={stringify:null,parse:null};window.DataTiddler=DataTiddler;DataTiddler.getData=function(c,d,a){var b=(typeof c=="string")?store.getTiddler(c):c;if(!(b instanceof Tiddler)){throw"Tiddler expected. Got "+c}return DataTiddler.getTiddlerDataValue(b,d,a)};DataTiddler.setData=function(c,e,d,a){var b=(typeof c=="string")?store.getTiddler(c):c;if(!(b instanceof Tiddler)){throw"Tiddler expected. Got "+c+"("+b+")"}DataTiddler.setTiddlerDataValue(b,e,d,a)};DataTiddler.getDataObject=function(b){var a=(typeof b=="string")?store.getTiddler(b):b;if(!(a instanceof Tiddler)){throw"Tiddler expected. Got "+b}return DataTiddler.getTiddlerDataObject(a)};DataTiddler.getDataText=function(b){var a=(typeof b=="string")?store.getTiddler(b):b;if(!(a instanceof Tiddler)){throw"Tiddler expected. Got "+b}return DataTiddler.readDataSectionText(a)};DataTiddler.extendJSONError=function(a){if(a.name=="JSONError"){a.toString=function(){return a.name+": "+a.message+" ("+a.text+")"}}return a};DataTiddler.getTiddlerDataObject=function(a){if(a.dataObject===undefined){var b=DataTiddler.readData(a);a.dataObject=(b)?b:{}}return a.dataObject};DataTiddler.getTiddlerDataValue=function(b,d,a){var c=DataTiddler.getTiddlerDataObject(b)[d];return(c===undefined)?a:c};DataTiddler.setTiddlerDataValue=function(c,f,e,a){var d=DataTiddler.getTiddlerDataObject(c);var b=d[f];if(e==a){if(b!==undefined){delete d[f];DataTiddler.save(c)}return}d[f]=e;DataTiddler.save(c)};DataTiddler.readDataSectionText=function(a){var b=DataTiddler.getDataTiddlerMatches(a);if(b===null||!b[2]){return null}return b[2]};DataTiddler.readData=function(b){var c=DataTiddler.readDataSectionText(b);try{return c?DataTiddler.parse(c):null}catch(a){throw DataTiddler.extendJSONError(a)}};DataTiddler.getDataTextOfTiddler=function(a){var b=DataTiddler.getTiddlerDataObject(a);return DataTiddler.stringify(b)};DataTiddler.indexOfNonEscapedText=function(c,a,d){var b=c.indexOf(a,d);while((b>0)&&(c[b-1]=="~")){b=c.indexOf(a,b+1)}return b};DataTiddler.getDataSectionInfo=function(e){var a="<data>{";var f="}</data>";var d=DataTiddler.indexOfNonEscapedText(e,a,0);if(d<0){return null}var c=e.indexOf(f,d);if(c<0){return null}var b;while((b=e.indexOf(f,c+1))>=0){c=b}return{prefixEnd:d,dataStart:d+(a.length)-1,dataEnd:c,suffixStart:c+(f.length)}};DataTiddler.getDataTiddlerMatches=function(a){var f=a.text;var e=DataTiddler.getDataSectionInfo(f);if(!e){return null}var c=f.substr(0,e.prefixEnd);var b=f.substr(e.dataStart,e.dataEnd-e.dataStart+1);var d=f.substr(e.suffixStart);return[f,c,b,d]};DataTiddler.save=function(a){var e=DataTiddler.getDataTiddlerMatches(a);var d;var f;if(e===null){d=a.text;f=""}else{d=e[1];f=e[3]}var b=DataTiddler.getDataTextOfTiddler(a);var c=(b!==null)?d+"<data>"+b+"</data>"+f:d+f;if(c!=a.text){a.isDataTiddlerChange=true;a.set(a.title,c,config.options.txtUserName,config.options.chkForceMinorUpdate?undefined:new Date(),a.tags);delete a.isDataTiddlerChange;store.dirty=true;if(config.options.chkAutoSave){saveChanges()}}};DataTiddler.MyTiddlerChangedFunction=function(){if(this.dataObject&&!this.isDataTiddlerChange){delete this.dataObject}DataTiddler.originalTiddlerChangedFunction.apply(this,arguments)};config.formatters.push({name:"data-escape",match:"~<\\/?data>",handler:function(a){a.outputText(a.output,a.matchStart+1,a.nextMatch)}});config.formatters.push({name:"data",match:"<data>",handler:function(a){var b=DataTiddler.getDataSectionInfo(a.source);if(b&&b.prefixEnd==a.matchStart){a.nextMatch=b.suffixStart}else{a.outputText(a.output,a.matchStart,a.nextMatch)}}});DataTiddler.originalTiddlerChangedFunction=Tiddler.prototype.changed;Tiddler.prototype.changed=DataTiddler.MyTiddlerChangedFunction;Tiddler.prototype.data=function(b,a){return(b)?DataTiddler.getTiddlerDataValue(this,b,a):DataTiddler.getTiddlerDataObject(this)};Tiddler.prototype.setData=function(c,b,a){DataTiddler.setTiddlerDataValue(this,c,b,a)};config.macros.showData={label:"showData",prompt:"Display the values stored in the data section of the tiddler"};config.macros.showData.handler=function(a,g,h){var c=0;var d=false;if((c<h.length)&&h[c]=="JSON"){c++;d=true}var b=story.findContainingTiddler(a).getAttribute("tiddler");if(c<h.length){b=h[c];c++}try{if(d){this.renderDataInJSONFormat(a,b)}else{this.renderDataAsTable(a,b)}}catch(f){this.createErrorElement(a,f)}};config.macros.showData.renderDataInJSONFormat=function(a,b){var c=DataTiddler.getDataText(b);if(c){createTiddlyElement(a,"pre",null,null,c)}};config.macros.showData.renderDataAsTable=function(a,b){var f="|!Name|!Value|\n";var e=DataTiddler.getDataObject(b);if(e){for(var c in e){var d=e[c];f+="|"+c+"|"+DataTiddler.stringify(d)+"|\n"}}wikify(f,a)};config.macros.showData.createErrorElement=function(a,b){var c=(b.description)?b.description:b.toString();return createTiddlyElement(a,"span",null,"showDataError","<<showData ...>>: "+c)};setStylesheet(".showDataError{color: #ffffff;background-color: #880000;}","showData")}var JSON={copyright:"(c)2005 JSON.org",license:"http://www.crockford.com/JSON/license.html",stringify:function(c){var b=[];function f(a){b[b.length]=a}function d(a){var j,h=undefined,e,g;switch(typeof a){case"object":if(a){if(a instanceof Array){f("[");e=b.length;for(h=0;h<a.length;h+=1){g=a[h];if(typeof g!="undefined"&&typeof g!="function"){if(e<b.length){f(",")}d(g)}}f("]");return}else{if(typeof a.toString!="undefined"){f("{");e=b.length;for(h in a){g=a[h];if(a.hasOwnProperty(h)&&typeof g!="undefined"&&typeof g!="function"){if(e<b.length){f(",")}d(h);f(":");d(g)}}return f("}")}}}f("null");return;case"number":f(isFinite(a)?+a:"null");return;case"string":e=a.length;f('"');for(h=0;h<e;h+=1){j=a.charAt(h);if(j>=" "){if(j=="\\"||j=='"'){f("\\")}f(j)}else{switch(j){case"\b":f("\\b");break;case"\f":f("\\f");break;case"\n":f("\\n");break;case"\r":f("\\r");break;case"\t":f("\\t");break;default:j=j.charCodeAt();f("\\u00"+Math.floor(j/16).toString(16)+(j%16).toString(16))}}}f('"');return;case"boolean":f(String(a));return;default:f("null");return}}d(c);return b.join("")},parse:function(text){var p=/^\s*(([,:{}\[\]])|"(\\.|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|false|null)\s*/,token=undefined,operator=undefined;function error(m,t){throw {name:"JSONError",message:m,text:t||operator||token}}function next(b){if(b&&b!=operator){error("Expected '"+b+"'")}if(text){var t=p.exec(text);if(t){if(t[2]){token=null;operator=t[2]}else{operator=null;try{token=eval(t[1])}catch(e){error("Bad token",t[1])}}text=text.substring(t[0].length)}else{error("Unrecognized token",text)}}else{token=operator=undefined}}function val(){var k,o;switch(operator){case"{":next("{");o={};if(operator!="}"){for(;;){if(operator||typeof token!="string"){error("Missing key")}k=token;next();next(":");o[k]=val();if(operator!=","){break}next(",")}}next("}");return o;case"[":next("[");o=[];if(operator!="]"){for(;;){o.push(val());if(operator!=","){break}next(",")}}next("]");return o;default:if(operator!==null){error("Missing value")}k=token;next();return k}}next();return val()}};DataTiddler.format="JSON";DataTiddler.stringify=JSON.stringify;DataTiddler.parse=JSON.parse;
//%/
This example shows how one can create a "summary" table from data stored in multiple tiddlers.

For this "Expense Report" we access tiddlers tagged with "expense" that contain data with the fields "descr", "month" and "amount" and put all "December" items into our table. The example also shows how the "context" object of the ForEachTiddlerMacro can be used to store temporary data between different tiddler writes.

Here the resulting table:
<<forEachTiddler
 where
 'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
 script
 'function writeExpenseRow(index, tiddler, context) { var result = ""; if (index == 0) {context.sum = 0; result = "|!Description|!Amount|!Sum|!Receipt|\n";} context.sum=context.sum+tiddler.data("amount"); result += "|" + tiddler.data("descr") + "|" + tiddler.data("amount") + "|" + context.sum + "|[["+tiddler.title+"]]|\n"; return result;}'
 write
 'writeExpenseRow(index, tiddler, context)'
>>

The following ForEachTiddlerMacro call constructed the table:
{{{
<<forEachTiddler
 where
 'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
 script
 'function writeExpenseRow(index, tiddler, context) { var result = ""; if (index == 0) {context.sum = 0; result = "|!Description|!Amount|!Sum|!Receipt|\n";} context.sum=context.sum+tiddler.data("amount"); result += "|" + tiddler.data("descr") + "|" + tiddler.data("amount") + "|" + context.sum + "|[["+tiddler.title+"]]|\n"; return result;}'
 write
 'writeExpenseRow(index, tiddler, context)'
>>
}}}
Notice the function {{{writeExpenseRow}}} in the script section is implemented in a single line to fit a string constant. In a more readable form the function looks like this:
{{{
function writeExpenseRow(index, tiddler, context) {
 var result = "";
 if (index == 0) {
 context.sum = 0;
 result = "|!Description|!Amount|!Sum|!Receipt|\n";
 }
 context.sum=context.sum+tiddler.data("amount");
 result += "|" + tiddler.data("descr") + "|" + tiddler.data("amount") +
 "|" + context.sum + "|[["+tiddler.title+"]]|\n";
 return result;
}
}}}

[[About]]
/***
|''Name:''|DeprecatedFunctionsPlugin|
|''Description:''|Support for deprecated functions removed from core|
***/
//{{{
if(!version.extensions.DeprecatedFunctionsPlugin) {
version.extensions.DeprecatedFunctionsPlugin = {installed:true};

//--
//-- Deprecated code
//--

// @Deprecated: Use createElementAndWikify and this.termRegExp instead
config.formatterHelpers.charFormatHelper = function(w)
{
	w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
};

// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
config.formatterHelpers.monospacedByLineHelper = 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 text = lookaheadMatch[1];
		if(config.browser.isIE)
			text = text.replace(/\n/g,"\r");
		createTiddlyElement(w.output,"pre",null,null,text);
		w.nextMatch = lookaheadRegExp.lastIndex;
	}
};

// @Deprecated: Use <br> or <br /> instead of <<br>>
config.macros.br = {};
config.macros.br.handler = function(place)
{
	createTiddlyElement(place,"br");
};

// Find an entry in an array. Returns the array index or null
// @Deprecated: Use indexOf instead
Array.prototype.find = function(item)
{
	var i = this.indexOf(item);
	return i == -1 ? null : i;
};

// Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
// @Deprecated: Use store.getLoader().internalizeTiddler instead
Tiddler.prototype.loadFromDiv = function(divRef,title)
{
	return store.getLoader().internalizeTiddler(store,this,title,divRef);
};

// Format the text for storage in an HTML DIV
// @Deprecated Use store.getSaver().externalizeTiddler instead.
Tiddler.prototype.saveToDiv = function()
{
	return store.getSaver().externalizeTiddler(store,this);
};

// @Deprecated: Use store.allTiddlersAsHtml() instead
function allTiddlersAsHtml()
{
	return store.allTiddlersAsHtml();
}

// @Deprecated: Use refreshPageTemplate instead
function applyPageTemplate(title)
{
	refreshPageTemplate(title);
}

// @Deprecated: Use story.displayTiddlers instead
function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
{
	story.displayTiddlers(srcElement,titles,template,animate);
}

// @Deprecated: Use story.displayTiddler instead
function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
{
	story.displayTiddler(srcElement,title,template,animate);
}

// @Deprecated: Use functions on right hand side directly instead
var createTiddlerPopup = Popup.create;
var scrollToTiddlerPopup = Popup.show;
var hideTiddlerPopup = Popup.remove;

// @Deprecated: Use right hand side directly instead
var regexpBackSlashEn = new RegExp("\\\\n","mg");
var regexpBackSlash = new RegExp("\\\\","mg");
var regexpBackSlashEss = new RegExp("\\\\s","mg");
var regexpNewLine = new RegExp("\n","mg");
var regexpCarriageReturn = new RegExp("\r","mg");

}
//}}}
{{{
<<forEachTiddler
    where
        'tiddler.tags.contains("basic")'
    write
        '""'
        end 'count+" Tiddlers found\n"'
        none '"No Tiddlers found\n"'
>>
}}}
The macro writes an empty string for every tiddler tagged "basic", i.e. it writes nothing.

Just at the end it writes the number of found tiddlers (using the ''end'' feature of the ForEachTiddler macro) or "No Tiddler found" if no tiddler is tagged with "basic"  (using the ''none'' parameter) .

''//Result://''
<<forEachTiddler
    where
        'tiddler.tags.contains("basic")'
    write
        '""'
        end 'count+" Tiddlers found\n"'
        none '"No Tiddlers found\n"'
>>
If you find the [[Plugins]] useful then please consider a donation. A donation will encourage me to continue developing new features, plugins and improvements for TiddlyWiki. Click the below to donate using PayPal.

<html>
<style>
.donate {
	border-spacing:2em;
}

.donate td {
	text-align:center;
	font-size:90%;
	padding:1em;
	background:#f8f8f8;
	margin: 5em;
	font-size:105%;
	-moz-border-radius: 0.8em;
	border:2px solid #eee;

}
</style>
<table class="donate">
<tr>
<td>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="udo.borkowski@gmx.de">
<input type="hidden" name="item_name" value="Donation">
<input type="hidden" name="no_shipping" value="1">
<input type="hidden" name="return" value="http://www.abego-software.de">
<input type="hidden" name="cn" value="Your Note">
<input type="hidden" name="currency_code" value="EUR">
<input type="hidden" name="tax" value="0">
<input type="hidden" name="bn" value="PP-DonationsBF">
      <b>Currency:</b><select name="currency_code">
      	<option value="AUD">Australian Dollars</option>
      	<option value="CAD">Canadian Dollars</option>
      	<option value="EUR">Euros</option>
      	<option value="GBP">Pounds Sterling</option>
      	<option selected="selected" value="USD">US Dollars</option>
      	<option value="JPY">Yen</option>
      </select>
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but21.gif" border="0" name="submit" alt="Donate using PayPal - it's fast, free and secure!">
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
</html>
Thank you — your support is much appreciated,

Udo Borkowski
* [[Plugins]]
* [[Installing Plugins]]
* [[Download TiddlyWiki]]
Because a TiddlyWiki is a single HTML file, you've actually already downloaded the entire software just by viewing this site. If you want to be able to save your changes, you can save this TiddlyWiki to your local drive by right clicking on [[this link|index.html]] and selecting 'Save link as...' or 'Save target as...'. You can choose where to save the file, and what to call it (but keep the .HTML extension).

Do ''not'' use the File/Save command in your browser to save this page.

See also [[Installing Plugins]].
The following macro call exports all tiddlers to a text file "c:/MyTiddlyWikiExport.txt", using a customized format.
{{{
<<forEachTiddler
 script 'function getSortedTagsText(tiddler) {var tags = tiddler.tags; if (!tags) return ""; tags.sort(); var result = ""; for (var i = 0; i < tags.length;i++) {result += tags[i]+ " ";} return result;} function writeTiddler(tiddler) {return "==== "+tiddler.title+"=========================\nTags: "+ getSortedTagsText(tiddler)+"\nModified: "+tiddler.modified.convertToYYYYMMDDHHMM()+"\nModifier: "+tiddler.modifier+"\n--------------------------------------------------\n"+tiddler.text+"\n--------------------------------------------------\n(End of "+tiddler.title+")\n\n\n\n"}'
 write
 'writeTiddler(tiddler)'
 toFile 'file:///c:/MyTiddlyWikiExport.txt' withLineSeparator '\r\n'
>>
}}}
For better readablility here the script text in a nicer layout:
{{{
function getSortedTagsText(tiddler) {
 var tags = tiddler.tags;
 if (!tags)
 return "";
 tags.sort();
 var result = "";
 for (var i = 0; i < tags.length;i++) {
 result += tags[i]+ " ";
 }
 return result;
}

function writeTiddler(tiddler) {
 return "==== "+tiddler.title+"=========================\n"+
 "Tags: "+ getSortedTagsText(tiddler)+"\n"+
 "Modified: "+tiddler.modified.convertToYYYYMMDDHHMM()+"\n"+
 "Modifier: "+tiddler.modifier+"\n"+
 "--------------------------------------------------\n"+
 tiddler.text+"\n"+
 "--------------------------------------------------\n"
 "(End of "+tiddler.title+")\n\n\n\n"
}
}}}

<<forEachTiddler
 script 'function getSortedTagsText(tiddler) {var tags = tiddler.tags; if (!tags) return ""; tags.sort(); var result = ""; for (var i = 0; i < tags.length;i++) {result += tags[i]+ " ";} return result;} function writeTiddler(tiddler) {return "==== "+tiddler.title+"=========================\nTags: "+ getSortedTagsText(tiddler)+"\nModified: "+tiddler.modified.convertToYYYYMMDDHHMM()+"\nModifier: "+tiddler.modifier+"\n--------------------------------------------------\n"+tiddler.text+"\n--------------------------------------------------\n(End of "+tiddler.title+")\n\n\n\n"}'
 write
 'writeTiddler(tiddler)'
 toFile 'file:///c:/MyTiddlyWikiExport.txt' withLineSeparator '\r\n'
>>

Here are some examples that show the usage of the write action in the ForEachTiddlerMacro.

//''Select and Sort Examples''//
* InClauseExamples
* WhereClauseExamples
* SortClauseExamples
* ScriptClauseExamples
//''Action Examples''//
* AddToListActionExamples
* WriteActionExamples


Of cause you may also combine the examples, e.g. taking the whereClause of one example, the sortClause of a second and the action of a third.
//~~(Part of the [[ForEachTiddlerPlugin]])~~//

Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.

''Syntax:''
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]] is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|


''Using JavaScript''

To give you a lot of flexibility the [[ForEachTiddlerMacro]] uses JavaScript in its arguments. Even if you are not that familiar with JavaScript you may find forEachTiddler useful. Just have a look at the various ready-to-use [[ForEachTiddlerExamples]] and adapt them to your needs.

''The Elements of the Macro''

The arguments of the ForEachTiddlerMacro consist of multiple parts, each of them being optional.

<<slider chkFETInClause [[inClause]] "inClause" "inClause">>
<<slider chkFETWhereClause [[whereClause]] "whereClause" "whereClause">>
<<slider chkFETSortClause [[sortClause]] "sortClause" "sortClause">>
<<slider chkFETScriptClause [[scriptClause]] "scriptClause" "scriptClause">>
<<slider chkFETActions [[Action Specification]] "Action Specification" "Action Specification">>

''Using Macros and ">" inside the forEachTiddler Macro''

You may use other macro calls into the expression, especially in the actionParameters. To avoid that the {{{>>}}} of such a macro call is misinterpreted as the end of the {{{<<forEachTiddler...>>}}} macro you must escape the {{{>>}}} of the inner macro with {{{$))}}} E.g. if you want to use {{{<<tiddler ...>>}}} inside the {{{forEachTiddler}}} macro you have to write {{{<<tiddler ...$))}}}.

In addition it is necessary to escape single {{{>}}} with the text {{{$)}}}.

''Using {{{<<tiddler ... with: ...>>}}} to re-use ForEachTiddler definitions''

Sometimes you may want to use a certain ForEachTiddler definition in slight variations. E.g. you may want to list either the tiddlers tagged with "ToDo" and in the other case with "Done". To do so you may use "Tiddler parameters". Here an example:

Replace the variable part of the ForEachTiddler definition with $1 ($2,... $9 are supported). E.g. you may create the tiddler "ListTaggedTiddlers" like this
{{{
<<forEachTiddler
 where
 'tiddler.tags.contains("$1")'
>>
}}}

Now you can use the ListTaggedTiddlers for various specific tags, using the {{{<<tiddler ...>>}}} macro:
{{{
<<tiddler ListTaggedTiddlers with: "systemConfig">>
}}}
{{{
<<tiddler ListTaggedTiddlers with: "Plugin">>
}}}


See also [[ForEachTiddlerExamples]].
/***
|''Name:''|ForEachTiddlerPlugin|
|''Version:''|1.0.8 (2007-04-12)|
|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2005-2007 [[abego Software|http://www.abego-software.de]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
!Description

Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.

''Syntax:''
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and  {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and  {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]]  is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

See details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].

!Revision history
* v1.0.8 (2007-04-12)
** Adapted to latest TiddlyWiki 2.2 Beta importTiddlyWiki API (introduced with changeset 2004). TiddlyWiki 2.2 Beta builds prior to changeset 2004 are no longer supported (but TiddlyWiki 2.1 and earlier, of cause)
* v1.0.7 (2007-03-28)
** Also support "pre" formatted TiddlyWikis (introduced with TW 2.2) (when using "in" clause to work on external tiddlers)
* v1.0.6 (2006-09-16)
** Context provides "viewerTiddler", i.e. the tiddler used to view the macro. Most times this is equal to the "inTiddler", but when using the "tiddler" macro both may be different.
** Support "begin", "end" and "none" expressions in "write" action
* v1.0.5 (2006-02-05)
** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.
** Support Firefox 1.5.0.1
** Internal
*** Make "JSLint" conform
*** "Only install once"
* v1.0.4 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.3 (2005-12-22)
** Features:
*** Write output to a file supports multi-byte environments (Thanks to Bram Chen)
*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)
** Enhancements:
*** Improved error messages on InternetExplorer.
* v1.0.2 (2005-12-10)
** Features:
*** context object also holds reference to store (TiddlyWiki)
** Fixed Bugs:
*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)
* v1.0.1 (2005-12-08)
** Features:
*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".
*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.
*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).
*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .
*** Improved script evaluation (for where/sort clause and write scripts).
* v1.0.0 (2005-11-20)
** initial version

!Code
***/
//{{{


//============================================================================
//============================================================================
//		   ForEachTiddlerPlugin
//============================================================================
//============================================================================

// Only install once
if (!version.extensions.ForEachTiddlerPlugin) {

if (!window.abego) window.abego = {};

version.extensions.ForEachTiddlerPlugin = {
	major: 1, minor: 0, revision: 8,
	date: new Date(2007,3,12),
	source: "http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin",
	licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
	copyright: "Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"
};

// For backward compatibility with TW 1.2.x
//
if (!TiddlyWiki.prototype.forEachTiddler) {
	TiddlyWiki.prototype.forEachTiddler = function(callback) {
		for(var t in this.tiddlers) {
			callback.call(this,t,this.tiddlers[t]);
		}
	};
}

//============================================================================
// forEachTiddler Macro
//============================================================================

version.extensions.forEachTiddler = {
	major: 1, minor: 0, revision: 8, date: new Date(2007,3,12), provider: "http://tiddlywiki.abego-software.de"};

// ---------------------------------------------------------------------------
// Configurations and constants
// ---------------------------------------------------------------------------

config.macros.forEachTiddler = {
	 // Standard Properties
	 label: "forEachTiddler",
	 prompt: "Perform actions on a (sorted) selection of tiddlers",

	 // actions
	 actions: {
		 addToList: {},
		 write: {}
	 }
};

// ---------------------------------------------------------------------------
//  The forEachTiddler Macro Handler
// ---------------------------------------------------------------------------

config.macros.forEachTiddler.getContainingTiddler = function(e) {
	while(e && !hasClass(e,"tiddler"))
		e = e.parentNode;
	var title = e ? e.getAttribute("tiddler") : null;
	return title ? store.getTiddler(title) : null;
};

config.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	// config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);

	if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);
	// --- Parsing ------------------------------------------

	var i = 0; // index running over the params
	// Parse the "in" clause
	var tiddlyWikiPath = undefined;
	if ((i < params.length) && params[i] == "in") {
		i++;
		if (i >= params.length) {
			this.handleError(place, "TiddlyWiki path expected behind 'in'.");
			return;
		}
		tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the where clause
	var whereClause ="true";
	if ((i < params.length) && params[i] == "where") {
		i++;
		whereClause = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the sort stuff
	var sortClause = null;
	var sortAscending = true;
	if ((i < params.length) && params[i] == "sortBy") {
		i++;
		if (i >= params.length) {
			this.handleError(place, "sortClause missing behind 'sortBy'.");
			return;
		}
		sortClause = this.paramEncode(params[i]);
		i++;

		if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {
			 sortAscending = params[i] == "ascending";
			 i++;
		}
	}

	// Parse the script
	var scriptText = null;
	if ((i < params.length) && params[i] == "script") {
		i++;
		scriptText = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the action.
	// When we are already at the end use the default action
	var actionName = "addToList";
	if (i < params.length) {
	   if (!config.macros.forEachTiddler.actions[params[i]]) {
			this.handleError(place, "Unknown action '"+params[i]+"'.");
			return;
		} else {
			actionName = params[i];
			i++;
		}
	}

	// Get the action parameter
	// (the parsing is done inside the individual action implementation.)
	var actionParameter = params.slice(i);


	// --- Processing ------------------------------------------
	try {
		this.performMacro({
				place: place,
				inTiddler: tiddler,
				whereClause: whereClause,
				sortClause: sortClause,
				sortAscending: sortAscending,
				actionName: actionName,
				actionParameter: actionParameter,
				scriptText: scriptText,
				tiddlyWikiPath: tiddlyWikiPath});

	} catch (e) {
		this.handleError(place, e);
	}
};

// Returns an object with properties "tiddlers" and "context".
// tiddlers holds the (sorted) tiddlers selected by the parameter,
// context the context of the execution of the macro.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {

	var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);

	var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;
	context["tiddlyWiki"] = tiddlyWiki;

	// Get the tiddlers, as defined by the whereClause
	var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);
	context["tiddlers"] = tiddlers;

	// Sort the tiddlers, when sorting is required.
	if (parameter.sortClause) {
		this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);
	}

	return {tiddlers: tiddlers, context: context};
};

// Returns the (sorted) tiddlers selected by the parameter.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlers = function(parameter) {
	return this.getTiddlersAndContext(parameter).tiddlers;
};

// Performs the macros with the given parameter.
//
// @param parameter holds the parameter of the macro as separate properties.
//				  The following properties are supported:
//
//						place
//						whereClause
//						sortClause
//						sortAscending
//						actionName
//						actionParameter
//						scriptText
//						tiddlyWikiPath
//
//					All properties are optional.
//					For most actions the place property must be defined.
//
config.macros.forEachTiddler.performMacro = function(parameter) {
	var tiddlersAndContext = this.getTiddlersAndContext(parameter);

	// Perform the action
	var actionName = parameter.actionName ? parameter.actionName : "addToList";
	var action = config.macros.forEachTiddler.actions[actionName];
	if (!action) {
		this.handleError(parameter.place, "Unknown action '"+actionName+"'.");
		return;
	}

	var actionHandler = action.handler;
	actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);
};

// ---------------------------------------------------------------------------
//  The actions
// ---------------------------------------------------------------------------

// Internal.
//
// --- The addToList Action -----------------------------------------------
//
config.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {
	// Parse the parameter
	var p = 0;

	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);
		return;
	}

	// Perform the action.
	var list = document.createElement("ul");
	place.appendChild(list);
	for (var i = 0; i < tiddlers.length; i++) {
		var tiddler = tiddlers[i];
		var listItem = document.createElement("li");
		list.appendChild(listItem);
		createTiddlyLink(listItem, tiddler.title, true);
	}
};

abego.parseNamedParameter = function(name, parameter, i) {
	var beginExpression = null;
	if ((i < parameter.length) && parameter[i] == name) {
		i++;
		if (i >= parameter.length) {
			throw "Missing text behind '%0'".format([name]);
		}

		return config.macros.forEachTiddler.paramEncode(parameter[i]);
	}
	return null;
}

// Internal.
//
// --- The write Action ---------------------------------------------------
//
config.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {
	// Parse the parameter
	var p = 0;
	if (p >= parameter.length) {
		this.handleError(place, "Missing expression behind 'write'.");
		return;
	}

	var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);
	p++;

	// Parse the "begin" option
	var beginExpression = abego.parseNamedParameter("begin", parameter, p);
	if (beginExpression !== null)
		p += 2;
	var endExpression = abego.parseNamedParameter("end", parameter, p);
	if (endExpression !== null)
		p += 2;
	var noneExpression = abego.parseNamedParameter("none", parameter, p);
	if (noneExpression !== null)
		p += 2;

	// Parse the "toFile" option
	var filename = null;
	var lineSeparator = undefined;
	if ((p < parameter.length) && parameter[p] == "toFile") {
		p++;
		if (p >= parameter.length) {
			this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");
			return;
		}

		filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));
		p++;
		if ((p < parameter.length) && parameter[p] == "withLineSeparator") {
			p++;
			if (p >= parameter.length) {
				this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");
				return;
			}
			lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);
			p++;
		}
	}

	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);
		return;
	}

	// Perform the action.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);
	var count = tiddlers.length;
	var text = "";
	if (count > 0 && beginExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);

	for (var i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		text += func(tiddler, context, count, i);
	}

	if (count > 0 && endExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);

	if (count == 0 && noneExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(noneExpression, context)(undefined, context, count, undefined);


	if (filename) {
		if (lineSeparator !== undefined) {
			lineSeparator = lineSeparator.replace(/\\n/mg, "\n").replace(/\\r/mg, "\r");
			text = text.replace(/\n/mg,lineSeparator);
		}
		saveFile(filename, convertUnicodeToUTF8(text));
	} else {
		var wrapper = createTiddlyElement(place, "span");
		wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);
	}
};


// ---------------------------------------------------------------------------
//  Helpers
// ---------------------------------------------------------------------------

// Internal.
//
config.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {
	return {
		place : placeParam,
		whereClause : whereClauseParam,
		sortClause : sortClauseParam,
		sortAscending : sortAscendingParam,
		script : scriptText,
		actionName : actionNameParam,
		actionParameter : actionParameterParam,
		tiddlyWikiPath : tiddlyWikiPathParam,
		inTiddler : inTiddlerParam, // the tiddler containing the <<forEachTiddler ...>> macro call.
		viewerTiddler : config.macros.forEachTiddler.getContainingTiddler(placeParam) // the tiddler showing the forEachTiddler result
	};
};

// Internal.
//
// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of
// the given path.
//
config.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {
	if (!idPrefix) {
		idPrefix = "store";
	}
	var lenPrefix = idPrefix.length;

	// Read the content of the given file
	var content = loadFile(this.getLocalPath(path));
	if(content === null) {
		throw "TiddlyWiki '"+path+"' not found.";
	}

	var tiddlyWiki = new TiddlyWiki();

	// Starting with TW 2.2 there is a helper function to import the tiddlers
	if (tiddlyWiki.importTiddlyWiki) {
		if (!tiddlyWiki.importTiddlyWiki(content))
			throw "File '"+path+"' is not a TiddlyWiki.";
		tiddlyWiki.dirty = false;
		return tiddlyWiki;
	}

	// The legacy code, for TW < 2.2

	// Locate the storeArea div's
	var posOpeningDiv = content.indexOf(startSaveArea);
	var posClosingDiv = content.lastIndexOf(endSaveArea);
	if((posOpeningDiv == -1) || (posClosingDiv == -1)) {
		throw "File '"+path+"' is not a TiddlyWiki.";
	}
	var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);

	// Create a "div" element that contains the storage text
	var myStorageDiv = document.createElement("div");
	myStorageDiv.innerHTML = storageText;
	myStorageDiv.normalize();

	// Create all tiddlers in a new TiddlyWiki
	// (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)
	var store = myStorageDiv.childNodes;
	for(var t = 0; t < store.length; t++) {
		var e = store[t];
		var title = null;
		if(e.getAttribute)
			title = e.getAttribute("tiddler");
		if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
			title = e.id.substr(lenPrefix);
		if(title && title !== "") {
			var tiddler = tiddlyWiki.createTiddler(title);
			tiddler.loadFromDiv(e,title);
		}
	}
	tiddlyWiki.dirty = false;

	return tiddlyWiki;
};



// Internal.
//
// Returns a function that has a function body returning the given javaScriptExpression.
// The function has the parameters:
//
//	 (tiddler, context, count, index)
//
config.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {
	var script = context["script"];
	var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";
	var fullText = (script ? script+";" : "")+functionText+";theFunction;";
	return eval(fullText);
};

// Internal.
//
config.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {
	var result = [];
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);
	tiddlyWiki.forEachTiddler(function(title,tiddler) {
		if (func(tiddler, context, undefined, undefined)) {
			result.push(tiddler);
		}
	});
	return result;
};

// Internal.
//
config.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {
	var message = "Extra parameter behind '"+actionName+"':";
	for (var i = firstUnusedIndex; i < parameter.length; i++) {
		message += " "+parameter[i];
	}
	this.handleError(place, message);
};

// Internal.
//
config.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {
	var result =
		(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue)
			? 0
			: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
			   ? -1
			   : +1;
	return result;
};

// Internal.
//
config.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {
	var result =
		(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue)
			? 0
			: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
			   ? +1
			   : -1;
	return result;
};

// Internal.
//
config.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {
	// To avoid evaluating the sortClause whenever two items are compared
	// we pre-calculate the sortValue for every item in the array and store it in a
	// temporary property ("forEachTiddlerSortValue") of the tiddlers.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);
	var count = tiddlers.length;
	var i;
	for (i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);
	}

	// Do the sorting
	tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);

	// Delete the temporary property that holds the sortValue.
	for (i = 0; i < tiddlers.length; i++) {
		delete tiddlers[i].forEachTiddlerSortValue;
	}
};


// Internal.
//
config.macros.forEachTiddler.trace = function(message) {
	displayMessage(message);
};

// Internal.
//
config.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {
	var message ="<<"+macroName;
	for (var i = 0; i < params.length; i++) {
		message += " "+params[i];
	}
	message += ">>";
	displayMessage(message);
};


// Internal.
//
// Creates an element that holds an error message
//
config.macros.forEachTiddler.createErrorElement = function(place, exception) {
	var message = (exception.description) ? exception.description : exception.toString();
	return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);
};

// Internal.
//
// @param place [may be null]
//
config.macros.forEachTiddler.handleError = function(place, exception) {
	if (place) {
		this.createErrorElement(place, exception);
	} else {
		throw exception;
	}
};

// Internal.
//
// Encodes the given string.
//
// Replaces
//	 "$))" to ">>"
//	 "$)" to ">"
//
config.macros.forEachTiddler.paramEncode = function(s) {
	var reGTGT = new RegExp("\\$\\)\\)","mg");
	var reGT = new RegExp("\\$\\)","mg");
	return s.replace(reGTGT, ">>").replace(reGT, ">");
};

// Internal.
//
// Returns the given original path (that is a file path, starting with "file:")
// as a path to a local file, in the systems native file format.
//
// Location information in the originalPath (i.e. the "#" and stuff following)
// is stripped.
//
config.macros.forEachTiddler.getLocalPath = function(originalPath) {
	// Remove any location part of the URL
	var hashPos = originalPath.indexOf("#");
	if(hashPos != -1)
		originalPath = originalPath.substr(0,hashPos);
	// Convert to a native file format assuming
	// "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
	// "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
	// "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
	// "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
	var localPath;
	if(originalPath.charAt(9) == ":") // pc local file
		localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file
		localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file:///") === 0) // mac/unix local file
		localPath = unescape(originalPath.substr(7));
	else if(originalPath.indexOf("file:/") === 0) // mac/unix local file
		localPath = unescape(originalPath.substr(5));
	else // pc network file
		localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");
	return localPath;
};

// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
	".forEachTiddlerError{color: #ffffff;background-color: #880000;}",
	"forEachTiddler");

//============================================================================
// End of forEachTiddler Macro
//============================================================================


//============================================================================
// String.startsWith Function
//============================================================================
//
// Returns true if the string starts with the given prefix, false otherwise.
//
version.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.startsWith = function(prefix) {
	var n =  prefix.length;
	return (this.length >= n) && (this.slice(0, n) == prefix);
};



//============================================================================
// String.endsWith Function
//============================================================================
//
// Returns true if the string ends with the given suffix, false otherwise.
//
version.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.endsWith = function(suffix) {
	var n = suffix.length;
	return (this.length >= n) && (this.right(n) == suffix);
};


//============================================================================
// String.contains Function
//============================================================================
//
// Returns true when the string contains the given substring, false otherwise.
//
version.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.contains = function(substring) {
	return this.indexOf(substring) >= 0;
};

//============================================================================
// Array.indexOf Function
//============================================================================
//
// Returns the index of the first occurance of the given item in the array or
// -1 when no such item exists.
//
// @param item [may be null]
//
version.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.indexOf = function(item) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == item) {
			return i;
		}
	}
	return -1;
};

//============================================================================
// Array.contains Function
//============================================================================
//
// Returns true when the array contains the given item, otherwise false.
//
// @param item [may be null]
//
version.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.contains = function(item) {
	return (this.indexOf(item) >= 0);
};

//============================================================================
// Array.containsAny Function
//============================================================================
//
// Returns true when the array contains at least one of the elements
// of the item. Otherwise (or when items contains no elements) false is returned.
//
version.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAny = function(items) {
	for(var i = 0; i < items.length; i++) {
		if (this.contains(items[i])) {
			return true;
		}
	}
	return false;
};


//============================================================================
// Array.containsAll Function
//============================================================================
//
// Returns true when the array contains all the items, otherwise false.
//
// When items is null false is returned (even if the array contains a null).
//
// @param items [may be null]
//
version.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAll = function(items) {
	for(var i = 0; i < items.length; i++) {
		if (!this.contains(items[i])) {
			return false;
		}
	}
	return true;
};


} // of "install only once"

// Used Globals (for JSLint) ==============
// ... DOM
/*global 	document */
// ... TiddlyWiki Core
/*global 	convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink,
			displayMessage, endSaveArea, hasClass, loadFile, saveFile,
			startSaveArea, store, wikify */
//}}}


/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/

A FormTemplate is used with the [[FormTiddlerPlugin]]. It is a tiddler that contains one or more HTML INPUT elements and defines the layout of a form.

Other tiddlers can reference a FormTemplate through the [[FormTiddlerMacro]].

(See [[FormTiddler Introduction]])
|!Example|!Comment|
|[[SimpleForm|SimpleForm (Card 1)]]|Three forms, using a simple template with "username" and "password" fields|
|[[BiggerForm|BiggerForm (Card 1)]]|Three forms, using a template with all supported Form input elements|
|[[Bugreports]]|Use forms and filtered lists to maintain bug reports|
|[[Contacts|JoeBlock]]|Manage your contacts in forms|
The [[FormTiddlerPlugin]] allows you to enter your data in a form and store the form's data in your tiddlers.

(For more information on tiddler data see the [[DataTiddlerPlugin]].)

//''Define ~FormTemplate''//

When you want to enter data in a form you first have to define a [[FormTemplate]] tiddler. A FormTemplate tiddler is a tiddler that contains named HTML INPUT elements (such as textfields, password fields, lists etc.) that define the stuff that should be edited in the form. E.g. you may have a FormTemplate that looks like this:

<html>
 <b>Name:</b><br/>
 <input name=userName type=text /><br/>
 <b>Password:</b><br/>
 <input name=pwd type=password /><br/>
</html>

The correspond HTML text looks like this
{{{
<html>
 <b>Name:</b><br/>
 <input name=userName type=text /><br/>
 <b>Password:</b><br/>
 <input name=pwd type=password /><br/>
</html>
}}}

The name of the INPUT element is also the name of the data field it is editing. E.g. a text field defined like this:
{{{
<input name=userName type=text />
}}}
will edit the data field "userName" of the tiddler.


You are free to layout the INPUT elements as you like, but don't add a "form" element around them and don't define 'onchange' handlers, since this will be done automatically by the {{{<<formTiddler ...>>}}} macro.


//''Use ~FormTemplates (through the {{{<<formTiddler ...>>}}} macro)''//

In a second step you add the {{{<<formTiddler ...>>}}} macro to tiddlers that should be edited. In the macro you are referencing the [[FormTemplate]] that should be used to edit the tiddler's data. You may refer to the same FormTemplate tiddler in as many tiddlers as you like. Every such tiddler displays the same INPUT elements as the FormTemplate, but with the "data" of each individual tiddler.

In addition you may have more than one {{{<<formTiddler...>>}}} macro call in one tiddler. Just make sure that the names of the elements in the referenced FormTemplate tiddlers do not collide. This feature may be useful if you want to construct a larger input form from a set of smaller FormTemplates.

You can easily create tiddlers with an embedded {{{<<formTiddler...>>}}} macro call using the [[<<newTiddlerWithForm...>>|NewTiddlerWithFormMacro]] macro. The macro shows a button similar to the "new tiddler" button and creates the requested tiddler, ready to enter data. For details see NewTiddlerWithFormMacro.


//''"Structured" and "Free" Data''//

Typically you will edit a tiddler that uses the {{{<<formTiddler...>>}}} macro through the form. But you are free to also edit the tiddler "as usual", through the build-in edit feature. I.e. you may mix "structured data" (as entered through the form) with "free data". I.e. on a "Contact" tiddler you may add an image to the tiddler, or add extra links to related persons. Or you add more tags. Just make sure that you don't modify the {{{<data>...</data>}}} section of the tiddler, since this contains the data maintained by the form.

Also notice that since the data entered in the forms is stored in the tiddler's text (in the {{{<data>...</data>}}} section) using the "search" feature will also find the texts you entered in the forms (even though it will not hilite the texts in the fields).


//''Applications''//

Using the [[FormTiddlerPlugin]] it is easy to manage things like:
* [[Contacts]]
* [[Bugreports]]
* ~ToDo Lists
* and many more.

Since a FormTemplate is typically used for many tiddlers of the same kind you may also consider using the ForEachTiddlerMacro to collect data across multiple tiddlers (e.g. to get a list of all contacts, a summary page for the bug reports etc.)

(See also [[FormTiddler Examples]])


//''HTML Elements''//

For those not that familiar with the HTML INPUT elements here a short overview with HTML snippets.
|!Type|!HTML Example|!Comment|
|button|{{{<input name=btn type=button value="Just a button" />}}}|no data|
|checkbox|{{{<input name=isVIP type=checkbox />is VIP}}}||
|file|{{{<input name=attachment type=file />}}}|The "file" input element typically does not restore the path of the previously selected file. Nevertheless the path of the file is stored in the tiddler.|
|hidden|{{{<input name=hiddenValue type=hidden value="This is a hidden value" />}}}||
|password|{{{<input name=pwd type=password />}}}|The data entered in a "password" field is stored as clear text in the tiddler.|
|radio|{{{<input name=level type=radio value="Beginner" />Beginner<input name=level type=radio value="Expert" />Expert<input name=level type=radio value="Guru" />Guru}}}||
|reset|{{{<input name=btnReset type=reset />}}}|no data|
|select-one|{{{<select name=browser ><option>Firefox<option>Internet Explorer<option>Opera<option>Other</select >}}}||
|select-multiple|{{{<select name=music MULTIPLE ><option> R&B <option> Jazz <option> Blues <option> New Age</select >}}}||
|submit|{{{<input name=btnSubmit type=submit />}}}|no data|
|text|{{{<input name=userName type=text/>}}}||
|textarea|{{{<TEXTAREA name=notes rows=4 cols=80 ></TEXTAREA>}}}||

For details consult the Web or a textbook on HTML editing.
The {{{<<formTiddler ...>>}}} macro defined by the FormTiddlerPlugin.

When a tiddler T1 references the (FormTemplate) tiddler T2 in the FormTiddlerMacro, the data of T1 can be edited through the INPUT elements defined by T2.
/***
<<checkForDataTiddlerPlugin>>
|''Name:''|FormTiddlerPlugin|
|''Version:''|1.0.7 (2012-04-19)|
|''Summary:''|Use form-based tiddlers to enter your tiddler data using text fields, listboxes, checkboxes etc. (All standard HTML Form input elements supported).|
|''Documentation:''|[[Introduction|FormTiddler Introduction]], [[Examples|FormTiddler Examples]]|
|''Source:''|http://tiddlywiki.abego-software.de/#FormTiddlerPlugin|
|''Twitter:''|[[@abego|https://twitter.com/#!/abego]]|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''License:''|[[BSD open source license|http://www.abego-software.de/legal/apl-v10.html]]|
|''Requires:''|DataTiddlerPlugin|
!Description
Use form-based tiddlers to enter your tiddler data using text fields, listboxes, checkboxes etc. (All standard HTML Form input elements supported).

''Syntax:''
|>|{{{<<}}}''formTiddler'' //tiddlerName//{{{>>}}}|
|//tiddlerName//|The name of the FormTemplate tiddler to be used to edit the data of the tiddler containing the macro.|

|>|{{{<<}}}''newTiddlerWithForm'' //formTemplateName// //buttonLabel// [//titleExpression// [''askUser'']] {{{>>}}}|
|//formTemplateName//|The name of the tiddler that defines the form the new tiddler should use.|
|//buttonLabel//|The label of the button|
|//titleExpression//|A (quoted) JavaScript String expression that defines the title (/name) of the new tiddler.|
|''askUser''|Typically the user is not asked for the title when a title is specified (and not yet used). When ''askUser'' is given the user will be asked in any case. This may be used when the calculated title is just a suggestion that must be confirmed by the user|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

For details and how to use the macros see the [[introduction|FormTiddler Introduction]] and the [[examples|FormTiddler Examples]].

!Source Code
***/
/***
This plugin's source code is compressed (and hidden).
Use this [[link|http://tiddlywiki.abego-software.de/archive/FormTiddlerPlugin/1.0.7/FormTiddlerPlugin-1.0.7-src.js]] to get the readable source code.
***/
///%
if(!window.abego){window.abego={}}abego.getOptionsValue=function(c,b){var a=c.options[b].value;if(!a&&c.options[b].text){a=c.options[b].text}return a};version.extensions.FormTiddlerPlugin={major:1,minor:0,revision:7,date:new Date(2012,3,19),type:"plugin",source:"http://tiddlywiki.abego-software.de/#FormTiddlerPlugin"};if(!window.story){window.story=window}if(!TiddlyWiki.prototype.getTiddler){TiddlyWiki.prototype.getTiddler=function(a){return t=this.tiddlers[a];return(t!=undefined&&t instanceof Tiddler)?t:null}}config.macros.formTiddler={label:"formTiddler",prompt:"Edit tiddler data using forms",setter:{button:function(b,a){},checkbox:function(b,a){b.checked=a},file:function(b,a){try{b.value=a}catch(b){}},hidden:function(b,a){b.value=a},password:function(b,a){b.value=a},radio:function(b,a){b.checked=(b.value==a)},reset:function(b,a){},"select-one":function(b,a){config.macros.formTiddler.setSelectOneValue(b,a)},"select-multiple":function(b,a){config.macros.formTiddler.setSelectMultipleValue(b,a)},submit:function(b,a){},text:function(b,a){b.value=a},textarea:function(b,a){b.value=a}},getter:{button:function(b,a){return undefined},checkbox:function(b,a){return b.checked},file:function(b,a){return b.value},hidden:function(b,a){return b.value},password:function(b,a){return b.value},radio:function(b,a){return b.checked?b.value:undefined},reset:function(b,a){return undefined},"select-one":function(b,a){return config.macros.formTiddler.getSelectOneValue(b)},"select-multiple":function(b,a){return config.macros.formTiddler.getSelectMultipleValue(b)},submit:function(b,a){return undefined},text:function(b,a){return b.value},textarea:function(b,a){return b.value}}};config.macros.formTiddler.handler=function(g,c,f,h,d,n){if(!config.macros.formTiddler.checkForExtensions(g,c)){return}var j=0;var l=undefined;if(j<f.length){l=f[j];j++}if(!l){config.macros.formTiddler.createErrorElement(g,"No form template specified in <<"+c+">>.");return}var a=store.getTiddler(l);if(!a){config.macros.formTiddler.createErrorElement(g,"Form template '"+l+"' not found.");return}var m=a.text;if(!m){return}var b=config.macros.formTiddler.getContainingTiddlerName(g);var o="form"+l+"__"+b;var k=document.createElement("form");k.setAttribute("name",o);g.appendChild(k);wikify(m,k);config.macros.formTiddler.initValuesAndHandlersInFormElements(o,DataTiddler.getDataObject(b))};config.macros.formTiddler.initValuesAndHandlersInFormElements=function(l,f){var b=config.macros.formTiddler.findForm(l);if(!b){return}try{var a=b.elements;for(var g=0;g<a.length;g++){var j=a[g];var d=config.macros.formTiddler.setter[j.type];if(d){var k=f[j.name];if(k!=null){d(j,k)}j.onchange=onFormTiddlerChange}else{config.macros.formTiddler.displayFormTiddlerError("No setter defined for INPUT element of type '"+j.type+"'. (Element '"+j.name+"' in form '"+l+"')")}}}catch(h){config.macros.formTiddler.displayFormTiddlerError("Error when updating elements with new formData. "+h)}};config.macros.formTiddler.findForm=function(c){var a=window.document.forms;for(var b=0;b<a.length;b++){var d=a[b];if(d.name==c){return d}}return null};config.macros.formTiddler.setSelectOneValue=function(b,c){var d=b.options.length;for(var a=0;a<d;a++){b.options[a].selected=abego.getOptionsValue(b,a)==c}};config.macros.formTiddler.setSelectMultipleValue=function(c,d){var a={};for(var b=0;b<d.length;b++){a[d[b]]=true}var e=c.length;for(var b=0;b<e;b++){c.options[b].selected=!(!a[abego.getOptionsValue(c,b)])}};config.macros.formTiddler.getSelectOneValue=function(b){var a=b.selectedIndex;return(a>=0)?abego.getOptionsValue(b,a):null};config.macros.formTiddler.getSelectMultipleValue=function(c){var a=[];var d=c.length;for(var b=0;b<d;b++){if(c.options[b].selected){a.push(abego.getOptionsValue(c,b))}}return a};config.macros.formTiddler.checkForExtensions=function(a,b){if(!version.extensions.DataTiddlerPlugin){config.macros.formTiddler.createErrorElement(a,"<<"+b+">> requires the DataTiddlerPlugin. (You can get it from http://tiddlywiki.abego-software.de/#DataTiddlerPlugin)");return false}return true};config.macros.formTiddler.trace=function(a){displayMessage("Trace: "+a)};config.macros.formTiddler.displayFormTiddlerError=function(a){alert("FormTiddlerPlugin Error: "+a)};config.macros.formTiddler.createErrorElement=function(a,b){return createTiddlyElement(a,"span",null,"formTiddlerError",b)};config.macros.formTiddler.getContainingTiddlerName=function(a){return story.findContainingTiddler(a).getAttribute("tiddler")};function onFormTiddlerChange(f){if(!f){f=window.event}var d=resolveTarget(f);var b=config.macros.formTiddler.getContainingTiddlerName(d);var a=config.macros.formTiddler.getter[d.type];if(a){var c=a(d);DataTiddler.setData(b,d.name,c)}else{config.macros.formTiddler.displayFormTiddlerError("No getter defined for INPUT element of type '"+d.type+"'. (Element '"+d.name+"' used in tiddler '"+b+"')")}}window.onFormTiddlerChange=onFormTiddlerChange;setStylesheet(".formTiddlerError{color: #ffffff;background-color: #880000;}","formTiddler");config.macros.checkForDataTiddlerPlugin={label:"checkForDataTiddlerPlugin",version:{major:1,minor:0,revision:0,date:new Date(2005,12,14)},prompt:"Check if the DataTiddlerPlugin exists"};config.macros.checkForDataTiddlerPlugin.handler=function(a,b,c){config.macros.formTiddler.checkForExtensions(a,config.macros.formTiddler.label)};config.macros.newTiddlerWithForm={label:"newTiddlerWithForm",version:{major:1,minor:0,revision:1,date:new Date(2006,1,6)},prompt:"Creates a new Tiddler with a <<formTiddler ...>> macro"};config.macros.newTiddlerWithForm.handler=function(place,macroName,params){var i=0;var formTemplateName=undefined;if(i<params.length){formTemplateName=params[i];i++}if(!formTemplateName){config.macros.formTiddler.createErrorElement(place,"No form template specified in <<"+macroName+">>.");return}var buttonLabel=undefined;if(i<params.length){buttonLabel=params[i];i++}if(!buttonLabel){config.macros.formTiddler.createErrorElement(place,"No button label specified in <<"+macroName+">>.");return}var tiddlerNameScript=undefined;var askUser=false;if(i<params.length){tiddlerNameScript=params[i];i++;if(i<params.length&&params[i]=="askUser"){askUser=true;i++}}if(!readOnly){var onClick=function(){var tiddlerName=undefined;if(tiddlerNameScript){try{tiddlerName=eval(tiddlerNameScript)}catch(ex){}}if(!tiddlerName||askUser){tiddlerName=prompt("Please specify a tiddler name.",askUser?tiddlerName:"")}while(tiddlerName&&store.getTiddler(tiddlerName)){tiddlerName=prompt("A tiddler named '"+tiddlerName+"' already exists.\n\nPlease specify a tiddler name.",tiddlerName)}if(tiddlerName){var body="<<formTiddler [["+formTemplateName+"]]>>";var tags=[];store.saveTiddler(tiddlerName,tiddlerName,body,config.options.txtUserName,new Date(),tags);story.displayTiddler(null,tiddlerName,1)}};createTiddlyButton(place,buttonLabel,buttonLabel,onClick)}};
//%/
This release fixes incompatibilities of the FormTiddlerPlugin and DataTiddlerPlugin with newer TiddlyWiki versions.

''Details:''
* FormTiddlerPlugin v1.0.7
** Bugfix: FormTiddlerPlugin fails to handle tiddlers with certain names in TW 2.6.5. Thanks to Terence Jacyno, Thomas Manley, Sebastjan Hribar, and Eric Shulman for reporting or suggesting a solution.
* DataTiddlerPlugin v1.0.7
** Bugfix: showData macro fails in TW 2.6.5 when tiddler title contains spaces. Thanks to Matt Shanks and Terence Jacyno for reporting.
{{{
<<forEachTiddler
 where
 'tiddler.tags.contains("systemConfig")'
 write
 '((index == 0) ? "" : ", ")+"[["+tiddler.title+"]]"'
>>
}}}
''//Explaination//''
The initial idea to accomplish the task is use a write parameter list this: {{{"[["+tiddler.name+"]], "}. But to avoid that a comma is appended after the final tiddler the write parameter is a little bit more complex and refers to the build-in variable {{index}}.

''//Result://''
<<forEachTiddler
 where
 'tiddler.tags.contains("systemConfig")'
 write
 '((index == 0) ? "" : ", ")+"[["+tiddler.title+"]]"'
>>


See Also ForEachTiddlerExamples.
When you specify a link to a tiddler a tiddler with that title is searched at the following locations:
* In the "normal" tiddlers of the main TiddlyWiki
* In the "shadow" tiddlers of the main TiddlyWiki
* In the "normal" tiddlers of all included TiddlyWikis, in the order of the include macros.<<br>>//(You may use [[The "includeState" Macro]] to check the order)//
The first tiddler found this way is used.

''Note:'' If two tiddlers in two TiddlyWikis have the same name, the one from the first TiddlyWiki is used, i.e. the other is "hidden". The script "[[List all hidden tiddlers of included TiddlyWikis]]" can be used to detect hidden tiddlers.
!Step 1: Get the Plugin
Import the IncludePlugin (from http://tiddlywiki.abego-software.de), e.g. using the ImportTiddlers, and make sure the "systemConfig" tag is defined.
!Step 2: Include ~TiddlyWikis
To include TiddlyWikis add an „include“ macro into the tiddler „IncludeList“:
{{{
<<include "shared/TiddlyWikiHelp.html">>
<<include "journals/2007-01.html">>
}}}
For details see [[The "include" Macro]].

''Notes''
* You need to reload your TiddlyWiki after you added or changed any "include" macro in the "IncludeList" tiddler.
!Step 3: Access included Tiddlers
To access an included tiddler you just need to create a link to that tiddler (with the tiddler's title). If you click that link the included tiddler will be displayed. To "find" an included tiddler, just search for it with the standard search feature.

You only can edit included tiddlers in their "original" TiddlyWiki. Hence included Tiddlers are readonly in a "main" TiddlyWiki.


See also [[How Tiddlers are found]].

!Using the "include" macro without the "IncludeList" Tiddler
The {{{<<include ...>>}}} macro is typically used in the "IncludeList" (as described above). The TiddlyWikis listed in the "IncludeList" are included at TiddlyWiki startup.

But you may put the {{{<<include ...>>}}} macro in any tiddler. The include process starts when the tiddler containing the {{{<<include ...>>}}} macro is displayed (or after delayDuration milliseconds). This way you may include TiddlyWikis/Tiddlers "on demand", i.e. the TiddlyWiki is only loaded when a certain tiddler is displayed.

When using the include macro in a tiddler different than the "IncludeList" you may want to use the "hide: true" parameter to avoid the include macro is displayed to the user.
''abego Software ~GmbH''
Noppiusstr. 3
52062 Aachen
Germany

Phone: +49 241 966 14 96
Fax: +49 12120 259 077

Email: contact@abego-software.de
Web: http://www.abego-software.de

''Value added tax identification number:'' DE 238 253 950
''Trade Register:'' HRB Nr. 12672
''Registergericht:'' Amtsgericht Aachen

"abego" is a registered trademark of abego Software ~GmbH. The product names are used only to identify the products and may be registered brands of the relevant manufacturers.

''Copyright''
Copyright © 2004-2006 by abego Software ~GmbH
All rights reserved.

TiddlyWiki is Copyright © Osmosoft Limited 2004-2006
Here are some examples that show the usage of the inClause in the ForEachTiddlerMacro.

<<forEachTiddler
 where
 'tiddler.tags.contains("inClauseExample")'
>>

See also ForEachTiddlerExamples.
<<include "Beta.html">>
/***
|''Name:''|abego.IncludePlugin|
|''Version:''|1.0.1 (2007-04-30)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#IncludePlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[IncludePlugin Documentation|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]]|
|''Community:''|([[del.icio.us|http://del.icio.us/post?url=http://tiddlywiki.abego-software.de/index.html%23IncludePlugin]]) ([[Support|http://groups.google.com/group/TiddlyWiki]])|
|''Copyright:''|&copy; 2007 [[abego Software|http://www.abego-software.de]]|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''~CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.5.0.9 or better; Internet Explorer 6.0|
!Revision history
//The IncludePlugin is no longer in active development. If you are experiencing problems or looking for some additional features you may want have a look at the  [[SharedTiddlersPlugin|http://yakovl.bplaced.net/TW/STP/STP.html]].//
* 1.0.1 (2007-04-30)
** Make ForEachTiddler "Include-aware"
* 1.0.0 (2007-02-08)
** initial version
!Source Code
***/
/***
This plugin's source code is compressed (and hidden). Use this [[link|http://tiddlywiki.abego-software.de/archive/IncludePlugin/1.0.1/IncludePlugin-1.0.1-src.js]] to get the readable source code.
***/
///%
if(!window.abego){window.abego={};}var invokeLater=function(_1,_2,_3){return abego.invokeLater?abego.invokeLater(_1,_2,_3):setTimeout(_1,_2);};abego.loadFile=function(_4,_5,_6){var _7=function(_8,_9,_a,_b,_c){return _8?_5(_a,_b,_9):_5(undefined,_b,_9,"Error loading %0".format([_b]));};if(_4.search(/^((http(s)?)|(file)):/)!=0){if(_4.search(/^((.\:\\)|(\\\\)|(\/))/)==0){_4="file://"+_4;}else{var _d=document.location.toString();var i=_d.lastIndexOf("/");_4=_d.substr(0,i+1)+_4;}_4=_4.replace(/\\/mg,"/");}loadRemoteFile(_4,_7,_6);};abego.loadTiddlyWikiStore=function(_f,_10,_11,_12){var _13=function(_14,_15){if(_12){_12(_14,"abego.loadTiddlyWikiStore",_15,_f,_11);}};var _16=function(_17,_18){var _19=_18.indexOf(startSaveArea);var _1a=_18.indexOf("<!--POST-BODY-END--"+">");var _1b=_18.lastIndexOf(endSaveArea,_1a==-1?_18.length:_1a);if((_19==-1)||(_1b==-1)){return config.messages.invalidFileError.format([_f]);}var _1c="<html><body>"+_18.substring(_19,_1b+endSaveArea.length)+"</body></html>";var _1d=document.createElement("iframe");_1d.style.display="none";document.body.appendChild(_1d);var doc=_1d.document;if(_1d.contentDocument){doc=_1d.contentDocument;}else{if(_1d.contentWindow){doc=_1d.contentWindow.document;}}doc.open();doc.writeln(_1c);doc.close();var _1f=doc.getElementById("storeArea");_17.loadFromDiv(_1f,"store");_1d.parentNode.removeChild(_1d);return null;};var _20=function(_21){_13("Error when loading %0".format([_f]),"Failed");_10(undefined,_f,_11,_21);return _21;};var _22=function(_23){_13("Loaded %0".format([_f]),"Done");_10(_23,_f,_11);return null;};var _24=function(_25,_26,_27,_28){if(_25===undefined){_20(_28);return;}_13("Processing %0".format([_f]),"Processing");var _29=config.messages.invalidFileError;config.messages.invalidFileError="The file '%0' does not appear to be a valid TiddlyWiki file";try{var _2a=new TiddlyWiki();var _2b=_16(_2a,_25);if(_2b){_20(_2b);}else{_22(_2a);}}catch(ex){_20(exceptionText(ex));}finally{config.messages.invalidFileError=_29;}};_13("Start loading %0".format([_f]),"Started");abego.loadFile(_f,_24,_11);};(function(){if(abego.TiddlyWikiIncluder){return;}var _2c="waiting";var _2d="loading";var _2e=1000;var _2f=-200;var _30=-100;var _31=-300;var _32;var _33=[];var _34={};var _35=[];var _36;var _37=[];var _38;var _39=function(){if(_32===undefined){_32=config.options.chkUseInclude===undefined||config.options.chkUseInclude;}return _32;};var _3a=function(url){return "No include specified for %0".format([url]);};var _3c=function(){var _3d=_35;_35=[];if(_3d.length){for(var i=0;i<_37.length;i++){_37[i](_3d);}}};var _3f;var _40=function(){if(_36!==undefined){clearInterval(_36);}_3f=0;var _41=function(){abego.TiddlyWikiIncluder.sendProgress("","","Done");};_36=setInterval(function(){_3f++;if(_3f<=10){return;}clearInterval(_36);_36=undefined;abego.TiddlyWikiIncluder.sendProgress("Refreshing...","","");refreshDisplay();invokeLater(_41,0,_2f);},1);};var _42=function(_43){var _44;for(var i=0;i<_33.length;i++){var _46=abego.TiddlyWikiIncluder.getStore(_33[i]);if(_46&&(_44=_43(_46,_33[i]))){return _44;}}};var _47=function(){if(!window.store){return invokeLater(_47,100);}var _48=store.fetchTiddler;store.fetchTiddler=function(_49){var t=_48.apply(this,arguments);if(t){return t;}if(config.shadowTiddlers[_49]!==undefined){return undefined;}if(_49==config.macros.newTiddler.title){return undefined;}return _42(function(_4b,url){var t=_4b.fetchTiddler(_49);if(t){t.includeURL=url;}return t;});};if(_33.length){_40();}};var _4e=function(){if(!window.store){return invokeLater(_4e,100);}var _4f=store.getTiddlerText("IncludeList");if(_4f){wikify(_4f,document.createElement("div"));}};var _50=function(_51){var _52=function(){var _53=store.forEachTiddler;var _54=function(_55){var _56={};var _57;var _58=function(_59,_5a){if(_56[_59]){return;}_56[_59]=1;if(_57){_5a.includeURL=_57;}_55.apply(this,arguments);};_53.call(store,_58);for(var n in config.shadowTiddlers){_56[n]=1;}_56[config.macros.newTiddler.title]=1;_42(function(_5c,url){_57=url;_5c.forEachTiddler(_58);});};store.forEachTiddler=_54;try{return _51.apply(this,arguments);}finally{store.forEachTiddler=_53;}};return _52;};var _5e=function(_5f,_60){return _5f[_60]=_50(_5f[_60]);};abego.TiddlyWikiIncluder={};abego.TiddlyWikiIncluder.setProgressFunction=function(_61){_38=_61;};abego.TiddlyWikiIncluder.getProgressFunction=function(_62){return _38;};abego.TiddlyWikiIncluder.sendProgress=function(_63,_64,_65){if(_38){_38.apply(this,arguments);}};abego.TiddlyWikiIncluder.onError=function(url,_67){displayMessage("Error when including '%0':\n%1".format([url,_67]));};abego.TiddlyWikiIncluder.hasPendingIncludes=function(){for(var i=0;i<_33.length;i++){var _69=abego.TiddlyWikiIncluder.getState(_33[i]);if(_69==_2c||_69==_2d){return true;}}return false;};abego.TiddlyWikiIncluder.getIncludes=function(){return _33.slice();};abego.TiddlyWikiIncluder.getState=function(url){var s=_34[url];if(!s){return _3a(url);}return typeof s=="string"?s:null;};abego.TiddlyWikiIncluder.getStore=function(url){var s=_34[url];if(!s){return _3a(url);}return s instanceof TiddlyWiki?s:null;};abego.TiddlyWikiIncluder.include=function(url,_6f){if(!_39()||_34[url]){return;}var _70=this;_33.push(url);_34[url]=_2c;var _71=function(_72,_73,_74,_75){if(_72===undefined){_34[url]=_75;_70.onError(url,_75);return;}_34[url]=_72;_35.push(url);invokeLater(_3c);};var _76=function(){_34[url]=_2d;abego.loadTiddlyWikiStore(url,_71,null,_38);};if(_6f){invokeLater(_76,_6f);}else{_76();}};abego.TiddlyWikiIncluder.forReallyEachTiddler=function(_77){var _78=function(){store.forEachTiddler(_77);};_50(_78).call(store);};abego.TiddlyWikiIncluder.getFunctionUsingForReallyEachTiddler=_50;abego.TiddlyWikiIncluder.useForReallyEachTiddler=_5e;abego.TiddlyWikiIncluder.addListener=function(_79){_37.push(_79);};abego.TiddlyWikiIncluder.addListener(_40);if(config.options.chkUseInclude===undefined){config.options.chkUseInclude=true;}config.shadowTiddlers.AdvancedOptions+="\n<<option chkUseInclude>> Include ~TiddlyWikis (IncludeList | IncludeState | [[help|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]])\n^^(Reload this ~TiddlyWiki to make changes become effective)^^";config.shadowTiddlers.IncludeState="<<includeState>>";var _7a=function(e,_7c,_7d){if(!anim||!abego.ShowAnimation){e.style.display=_7c?"block":"none";return;}anim.startAnimating(new abego.ShowAnimation(e,_7c,_7d));};abego.TiddlyWikiIncluder.getDefaultProgressFunction=function(){setStylesheet(".includeProgressState{\n"+"background-color:#FFCC00;\n"+"position:absolute;\n"+"right:0.2em;\n"+"top:0.2em;\n"+"width:7em;\n"+"padding-left:0.2em;\n"+"padding-right:0.2em\n"+"}\n","abegoInclude");var _7e=function(){var e=document.createElement("div");e.className="includeProgressState";e.style.display="none";document.body.appendChild(e);return e;};var _80=_7e();var _81=function(_82){removeChildren(_80);createTiddlyText(_80,_82);_7a(_80,true,0);};var _83=function(){invokeLater(function(){_7a(_80,false,_2e);},100,_30);};var _84=function(_85,_86,_87,url,_89){if(_87=="Done"||_87=="Failed"){_83();return;}if(_86=="abego.loadTiddlyWikiStore"){_3f=0;if(_87=="Processing"){_81("Including...");}}else{_81(_85);}};return _84;};abego.TiddlyWikiIncluder.setProgressFunction(abego.TiddlyWikiIncluder.getDefaultProgressFunction());config.macros.include={};config.macros.include.handler=function(_8a,_8b,_8c,_8d,_8e,_8f){_8c=_8e.parseParams("url",null,true,false,true);var _90=parseInt(getParam(_8c,"delay","0"));var _91=_8c[0]["url"];var _92=getFlag(_8c,"hide",false);if(!_92){createTiddlyText(createTiddlyElement(_8a,"code"),_8d.source.substring(_8d.matchStart,_8d.nextMatch));}for(var i=0;_91&&i<_91.length;i++){abego.TiddlyWikiIncluder.include(_91[i],_90);}};config.macros.includeState={};config.macros.includeState.handler=function(_94,_95,_96,_97,_98,_99){var _9a=function(){var s="";var _9c=abego.TiddlyWikiIncluder.getIncludes();if(!_9c.length){return "{{noIncludes{\nNo includes or 'include' is disabled (see AdvancedOptions)\n}}}\n";}s+="|!Address|!State|\n";for(var i=0;i<_9c.length;i++){var inc=_9c[i];s+="|{{{"+inc+"}}}|";var t=abego.TiddlyWikiIncluder.getState(inc);s+=t?"{{{"+t+"}}}":"included";s+="|\n";}s+="|includeState|k\n";return s;};var _a0=function(){removeChildren(div);wikify(_9a(),div);if(abego.TiddlyWikiIncluder.hasPendingIncludes()){invokeLater(_a0,500,_31);}};var div=createTiddlyElement(_94,"div");invokeLater(_a0,0,_31);};var _a2=Tiddler.prototype.isReadOnly;Tiddler.prototype.isReadOnly=function(){return _a2.apply(this,arguments)||this.isIncluded();};Tiddler.prototype.isIncluded=function(){return this.includeURL!=undefined;};Tiddler.prototype.getIncludeURL=function(){return this.includeURL;};var _a3={getMissingLinks:1,getOrphans:1,getTags:1,reverseLookup:1,updateTiddlers:1};for(var n in _a3){_5e(TiddlyWiki.prototype,n);}var _a5=function(){if(abego.IntelliTagger){_5e(abego.IntelliTagger,"assistTagging");}};var _a6=function(){if(config.macros.forEachTiddler){_5e(config.macros.forEachTiddler,"findTiddlers");}};_47();invokeLater(_4e,100);invokeLater(_a5,100);invokeLater(_a6,100);})();
//%/
!About the ~IncludePlugin
Include other ~TiddlyWikis in your (main) TiddlyWiki, link to included tiddlers, view them in your (main) TiddlyWiki, without opening another TiddlyWiki. Even „search“ looks for included tiddlers.

A great way to share tiddlers, to speed up "save changes" and to keep your ~TiddlyWikis small.
!Smaller ~TiddlyWikis
Other than „imported“ tiddlers, included tiddlers are not copied into your main ~TiddlyWiki. This keeps your individual ~TiddlyWikis small.

Since your TiddlyWikis will become smaller (if you reorganize your TiddlyWikis using the IncludePlugin) also "save changes" becomes faster. You may even consider switching on "AutoSave" or "SaveBackups" again.

See also: [[Including even smaller TiddlyWiki Files]]

!Sharing ~TiddlyWikis
You may include one ~TiddlyWiki in several other ~TiddlyWikis. Changes you make to this shared ~TiddlyWiki are automatically reflected the next time you open the other ~TiddlyWikis, without any extra „import“ step or so.

''Examples''
* you may want to have a single „~TiddlyWikiHelp“ ~TiddlyWiki that you include in all your ~TiddlyWikis. So you can quickly find help information without looking into other files, and without blowing up your ~TiddlyWikis.
* You "archive" your old journal tiddlers into an extra TiddlyWiki (e.g. one per month) and just include the archived journals in you "current month diary/blog". This way you still have access to the old information (e.g. to reference historic information) but you avoid your diary/blog will get to large.
* ...

See also:
* [[How to use the IncludePlugin]]
* [[How Tiddlers are found]]
* [[IncludePlugin Options]]
* [[The "include" Macro]]
* [[The "includeState" Macro]]
* [[Programming with the IncludePlugin]]
* [[Troubleshooting the IncludePlugin]]
Using the AdvancedOptions page you have an easy way to configure the IncludePlugin options.

You will find a section like this:
{{optionsBlock{
<<option chkUseInclude>> Include ~TiddlyWikis (IncludeList | IncludeState | [[help|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]])
^^(Reload this ~TiddlyWiki to make changes become effective)^^
}}}
* By default the IncludePlugin is enabled. If you uncheck the checkbox external TiddlyWikis are not included.
* The IncludeList is the preferred place for your {{{<<include ...>>}}} lines.
* The IncludeState page gives you can an overview what TiddlyWikis are included etc.
* The help directs you to the online documentation of the Include Plugin.
''Note for the advanced user:''

The IncludePlugin expects the file to be included to be in the "TiddlyWiki format", so including every valid TiddlyWiki file is fine.

In addition you may "strip down" your TiddlyWiki file significantly, e.g. by removing the JavaScript code etc., and the IncludePlugin will still be able to include it. This "minimal" file format is called the "TiddlyWiki Pure Store Format".

See http://www.abego-software.de/references/TiddlyWikiPureStoreFormat.html for more details.
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Version|1.6.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Insert 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.
!!!!!Usage
<<<
When installed, this plugin adds new wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be treated as embedded javascript and executed each time the tiddler is rendered.

''Deferred execution from an 'onClick' link''
By including a {{{label="..."}}} parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered.  You may also include a {{{title="..."}}} parameter to specify the 'tooltip' text that will appear whenever the mouse is moved over the onClick link text

''External script source files:''
You can also load javascript from an external source URL, by including a src="..." parameter in the initial {{{<script>}}} marker (e.g., {{{<script src="demo.js"></script>}}}).  This is particularly useful when incorporating third-party javascript libraries for use in custom extensions and plugins.  The 'foreign' javascript code remains isolated in a separate file that can be easily replaced whenever an updated library file becomes available.

''Display script source in tiddler output''
By including the keyword parameter "show", in the initial {{{<script>}}} marker, the plugin will include the script source code in the output that it displays in the tiddler.

''Defining javascript functions and libraries:''
Although the external javascript file is loaded while the tiddler content is being rendered, any functions it defines will not be available for use until //after// the rendering has been completed.  Thus, you cannot load a library and //immediately// use it's functions within the same tiddler.  However, once that tiddler has been loaded, the library functions can be freely used in any tiddler (even the one in which it was initially loaded).

To ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that will be rendered as soon as your TiddlyWiki document is opened.  For example, you could put your {{{<script src="..."></script>}}} syntax into a tiddler called LoadScripts, and then add {{{<<tiddler LoadScripts>>}}} in your MainMenu tiddler.

Since the MainMenu is always rendered immediately upon opening your document, the library will always be loaded before any other tiddlers that rely upon the functions it defines.  Loading an external javascript library does not produce any direct output in the tiddler, so these definitions should have no impact on the appearance of your MainMenu.

''Creating dynamic tiddler content''
An important difference between this implementation of embedded scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document:
* In a typical web document, you use the document.write() function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.
* However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and completely replaces the entire ~TiddlyWiki document in your browser window.
* To allow these scripts to work unmodified, the plugin automatically converts all occurences of document.write() so that the output is inserted into the tiddler content instead of replacing the entire ~TiddlyWiki document.

If your script does not use document.write() to create dynamically embedded content within a tiddler, your javascript can, as an alternative, explicitly return a text value that the plugin can then pass through the wikify() rendering engine to insert into the tiddler display.  For example, using {{{return "thistext"}}} will produce the same output as {{{document.write("thistext")}}}.

//Note: your script code is automatically 'wrapped' inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler.  To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.//

''Accessing the ~TiddlyWiki DOM''
The plugin provides one pre-defined variable, 'place', that is passed in to your javascript code so that it can have direct access to the containing DOM element into which the tiddler output is currently being rendered.

Access to this DOM element allows you to create scripts that can:
* vary their actions based upon the specific location in which they are embedded
* access 'tiddler-relative' information (use findContainingTiddler(place))
* perform direct DOM manipulations (when returning wikified text is not enough)
<<<
!!!!!Examples
<<<
an "alert" message box:
><script show>
	// uncomment this: alert('InlineJavascriptPlugin: this is a demonstration message');
</script>
dynamic output:
><script show>
	return (new Date()).toString();
</script>
wikified dynamic output:
><script show>
	return "link to current user: [["+config.options.txtUserName+"]]";
</script>
dynamic output using 'place' to get size information for current tiddler:
><script show>
   if (!window.story) window.story=window;
   var title=story.findContainingTiddler(place).id.substr(7);
   return title+" is using "+store.getTiddlerText(title).length+" bytes";
</script>
creating an 'onclick' button/link that runs a script:
><script label="click here" title="clicking this link will show an 'alert' box" show>
   if (!window.story) window.story=window;
   alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
</script>
loading a script from a source url:
>http://www.TiddlyTools.com/demo.js contains:
>>{{{function demo() { alert('this output is from demo(), defined in demo.js') } }}}
>>{{{alert('InlineJavascriptPlugin: demo.js has been loaded'); }}}
><script src="demo.js" show>
	return "loading demo.js..."
</script>
><script label="click to execute demo() function" show>
	demo()
</script>
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''InlineJavascriptPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2007.02.19 [1.6.0]'' added support for title="..." to specify mouseover tooltip when using an onclick (label="...") script
''2006.10.16 [1.5.2]'' add newline before closing '}' in 'function out_' wrapper.  Fixes error caused when last line of script is a comment.
''2006.06.01 [1.5.1]'' when calling wikify() on script return value, pass hightlightRegExp and tiddler params so macros that rely on these values can render properly
''2006.04.19 [1.5.0]'' added 'show' parameter to force display of javascript source code in tiddler output
''2006.01.05 [1.4.0]'' added support 'onclick' scripts.  When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked.  'place' value is set to match the clicked button/link element.
''2005.12.13 [1.3.1]'' when catching eval error in IE, e.description contains the error text, instead of e.toString().  Fixed error reporting so IE shows the correct response text.  Based on a suggestion by UdoBorkowski
''2005.11.09 [1.3.0]'' for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content.  Based on a suggestion by BradleyMeck
''2005.11.08 [1.2.0]'' handle loading of javascript from an external URL via src="..." syntax
''2005.11.08 [1.1.0]'' pass 'place' param into scripts to provide direct DOM access
''2005.11.08 [1.0.0]'' initial release
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/
//{{{
version.extensions.inlineJavascript= {major: 1, minor: 6, revision: 0, date: new Date(2007,2,19)};

config.formatters.push( {
	name: "inlineJavascript",
	match: "\\<script",
	lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?( 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) {
			if (lookaheadMatch[1]) { // load a script library
				// make script tag, set src, add to body to execute, then remove for cleanup
				var script = document.createElement("script"); script.src = lookaheadMatch[1];
				document.body.appendChild(script); document.body.removeChild(script);
			}
			if (lookaheadMatch[5]) { // there is script code
				if (lookaheadMatch[4]) // show inline script code in tiddler output
					wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
				if (lookaheadMatch[2]) { // create a link to an 'onclick' script
					// add a link, define click handler, save code in link (pass 'place'), set link attributes
					var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",lookaheadMatch[2]);
					link.onclick=function(){try{return(eval(this.code))}catch(e){alert(e.description?e.description:e.toString())}}
					link.code="function _out(place){"+lookaheadMatch[5]+"\n};_out(this);"
					link.setAttribute("title",lookaheadMatch[3]?lookaheadMatch[3]:"");
					link.setAttribute("href","javascript:;");
					link.style.cursor="pointer";
				}
				else { // run inline script code
					var code="function _out(place){"+lookaheadMatch[5]+"\n};_out(w.output);"
					code=code.replace(/document.write\(/gi,'place.innerHTML+=(');
					try { var out = eval(code); } 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;
		}
	}
} )
//}}}
[[Plugins|http://tiddlywiki.com/#Plugins]] are tiddlers that extend the standard functionality of TiddlyWiki, e.g. they may add new macros or formattings etc. A plugin tiddler contains JavaScript code and must be tagged with <<tag systemConfig>> to be activated .

''How to install a plugin''
* If you haven't already done so, follow the instructions in [[Download TiddlyWiki]] to get your own local copy of TiddlyWiki.
* Open the ImportTiddlers tiddler
* Enter the URL of the site containing the plugin (typically the plugin author's site) and press the "fetch" button.
** E.g. you may enter {{{http://danielbaird.com/tiddlywinks/}}} if you would like to get ~DanielBaird's Minesweeper plugin
* A table will appear with all tiddlers of the given site. In that table check the plugin tiddler you want to retrieve (e.g. the "Minesweeper" tiddler) and select "Import these tiddlers" from the field below the table.
* //(The plugin tiddler is now loaded into your TiddlyWiki.)//
* If the imported tiddler has not yet the "systemConfig" tag you should add it now. (Take care to use the exact spelling, with the capital "C")
* Save your TiddyWiki by pressing the "SaveChanges" button.
* Reload your TiddlyWiki in the browser.
The plugin is now installed and available for use.

''Finding Plugins''

See [[Plugins|http://tiddlywiki.com/#Plugins]] for a list of some site providing plugins for TiddlyWiki, or have a look at the plugins listed at http://del.icio.us/TiddlyWikiPlugin.

BTW:  If you would like to writing your own plugins see [[TiddlyWiki/Dev|http://www.tiddlywiki.com/dev/]] for more information.

/***
|''Name:''|IntelliTaggerPlugin|
|''Version:''|1.0.2 (2007-07-25)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[IntelliTaggerPlugin Documentation]]|
|''~SourceCode:''|[[IntelliTaggerPlugin SourceCode]]|
|''Licence:''|[[BSD open source license (abego Software)]]|
|''~CoreVersion:''|2.0.8|
|''Browser:''|Firefox 1.5.0.2 or better|
***/
/***
!Version History
* 1.0.2 (2007-07-25):
** Feature: "Return" key may be used to accept first tag suggestion (beside "Alt-1")
** Bugfix: Keyboard shortcuts (Alt+3 etc.) shifted
* 1.0.1 (2007-05-18):
** Improvement: Speedup when using TiddlyWikis with many tags
* 1.0.0 (2006-04-26):
** Initial release
!Source Code
***/
// /%
if(!version.extensions.IntelliTaggerPlugin){if(!window.abego){window.abego={};}if(!abego.internal){abego.internal={};}abego.alertAndThrow=function(s){alert(s);throw s;};if(version.major<2){abego.alertAndThrow("Use TiddlyWiki 2.0.8 or better to run the IntelliTagger Plugin.");}version.extensions.IntelliTaggerPlugin={major:1,minor:0,revision:2,date:new Date(2007,6,25),type:"plugin",source:"http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin",documentation:"[[IntelliTaggerPlugin Documentation]]",sourcecode:"[[IntelliTaggerPlugin SourceCode]]",author:"Udo Borkowski (ub [at] abego-software [dot] de)",licence:"[[BSD open source license (abego Software)]]",tiddlywiki:"Version 2.0.8 or better",browser:"Firefox 1.5.0.2 or better"};abego.createEllipsis=function(_2){var e=createTiddlyElement(_2,"span");e.innerHTML="&hellip;";};abego.isPopupOpen=function(_4){return _4&&_4.parentNode==document.body;};abego.openAsPopup=function(_5){if(_5.parentNode!=document.body){document.body.appendChild(_5);}};abego.closePopup=function(_6){if(abego.isPopupOpen(_6)){document.body.removeChild(_6);}};abego.getWindowRect=function(){return {left:findScrollX(),top:findScrollY(),height:findWindowHeight(),width:findWindowWidth()};};abego.moveElement=function(_7,_8,_9){_7.style.left=_8+"px";_7.style.top=_9+"px";};abego.centerOnWindow=function(_a){if(_a.style.position!="absolute"){throw "abego.centerOnWindow: element must have absolute position";}var _b=abego.getWindowRect();abego.moveElement(_a,_b.left+(_b.width-_a.offsetWidth)/2,_b.top+(_b.height-_a.offsetHeight)/2);};abego.isDescendantOrSelf=function(_c,e){while(e){if(_c==e){return true;}e=e.parentNode;}return false;};abego.toSet=function(_e){var _f={};for(var i=0;i<_e.length;i++){_f[_e[i]]=true;}return _f;};abego.filterStrings=function(_11,_12,_13){var _14=[];for(var i=0;i<_11.length&&(_13===undefined||_14.length<_13);i++){var s=_11[i];if(s.match(_12)){_14.push(s);}}return _14;};abego.arraysAreEqual=function(a,b){if(!a){return !b;}if(!b){return false;}var n=a.length;if(n!=b.length){return false;}for(var i=0;i<n;i++){if(a[i]!=b[i]){return false;}}return true;};abego.moveBelowAndClip=function(_1b,_1c){if(!_1c){return;}var _1d=findPosX(_1c);var _1e=findPosY(_1c);var _1f=_1c.offsetHeight;var _20=_1d;var _21=_1e+_1f;var _22=findWindowWidth();if(_22<_1b.offsetWidth){_1b.style.width=(_22-100)+"px";}var _23=_1b.offsetWidth;if(_20+_23>_22){_20=_22-_23-30;}if(_20<0){_20=0;}_1b.style.left=_20+"px";_1b.style.top=_21+"px";_1b.style.display="block";};abego.compareStrings=function(a,b){return (a==b)?0:(a<b)?-1:1;};abego.sortIgnoreCase=function(arr){var _27=[];var n=arr.length;for(var i=0;i<n;i++){var s=arr[i];_27.push([s.toString().toLowerCase(),s]);}_27.sort(function(a,b){return (a[0]==b[0])?0:(a[0]<b[0])?-1:1;});for(i=0;i<n;i++){arr[i]=_27[i][1];}};abego.getTiddlerField=function(_2d,_2e,_2f){var _30=document.getElementById(_2d.idPrefix+_2e);var e=null;if(_30!=null){var _32=_30.getElementsByTagName("*");for(var t=0;t<_32.length;t++){var c=_32[t];if(c.tagName.toLowerCase()=="input"||c.tagName.toLowerCase()=="textarea"){if(!e){e=c;}if(c.getAttribute("edit")==_2f){e=c;}}}}return e;};abego.setRange=function(_35,_36,end){if(_35.setSelectionRange){_35.setSelectionRange(_36,end);var max=0+_35.scrollHeight;var len=_35.textLength;var top=max*_36/len,bot=max*end/len;_35.scrollTop=Math.min(top,(bot+top-_35.clientHeight)/2);}else{if(_35.createTextRange!=undefined){var _3b=_35.createTextRange();_3b.collapse();_3b.moveEnd("character",end);_3b.moveStart("character",_36);_3b.select();}else{_35.select();}}};abego.internal.TagManager=function(){var _3c=null;var _3d=function(){if(_3c){return;}_3c={};store.forEachTiddler(function(_3e,_3f){for(var i=0;i<_3f.tags.length;i++){var tag=_3f.tags[i];var _42=_3c[tag];if(!_42){_42=_3c[tag]={count:0,tiddlers:{}};}_42.tiddlers[_3f.title]=true;_42.count+=1;}});};var _43=TiddlyWiki.prototype.saveTiddler;TiddlyWiki.prototype.saveTiddler=function(_44,_45,_46,_47,_48,_49){var _4a=this.fetchTiddler(_44);var _4b=_4a?_4a.tags:[];var _4c=(typeof _49=="string")?_49.readBracketedList():_49;_43.apply(this,arguments);if(!abego.arraysAreEqual(_4b,_4c)){abego.internal.getTagManager().reset();}};var _4d=TiddlyWiki.prototype.removeTiddler;TiddlyWiki.prototype.removeTiddler=function(_4e){var _4f=this.fetchTiddler(_4e);var _50=_4f&&_4f.tags.length>0;_4d.apply(this,arguments);if(_50){abego.internal.getTagManager().reset();}};this.reset=function(){_3c=null;};this.getTiddlersWithTag=function(tag){_3d();var _52=_3c[tag];return _52?_52.tiddlers:null;};this.getAllTags=function(_53){_3d();var _54=[];for(var i in _3c){_54.push(i);}for(i=0;_53&&i<_53.length;i++){_54.pushUnique(_53[i],true);}abego.sortIgnoreCase(_54);return _54;};this.getTagInfos=function(){_3d();var _56=[];for(var _57 in _3c){_56.push([_57,_3c[_57]]);}return _56;};var _58=function(a,b){var a1=a[1];var b1=b[1];var d=b[1].count-a[1].count;return d!=0?d:abego.compareStrings(a[0].toLowerCase(),b[0].toLowerCase());};this.getSortedTagInfos=function(){_3d();var _5e=this.getTagInfos();_5e.sort(_58);return _5e;};this.getPartnerRankedTags=function(_5f){var _60={};for(var i=0;i<_5f.length;i++){var _62=this.getTiddlersWithTag(_5f[i]);for(var _63 in _62){var _64=store.getTiddler(_63);if(!(_64 instanceof Tiddler)){continue;}for(var j=0;j<_64.tags.length;j++){var tag=_64.tags[j];var c=_60[tag];_60[tag]=c?c+1:1;}}}var _68=abego.toSet(_5f);var _69=[];for(var n in _60){if(!_68[n]){_69.push(n);}}_69.sort(function(a,b){var d=_60[b]-_60[a];return d!=0?d:abego.compareStrings(a.toLowerCase(),b.toLowerCase());});return _69;};};abego.internal.getTagManager=function(){if(!abego.internal.gTagManager){abego.internal.gTagManager=new abego.internal.TagManager();}return abego.internal.gTagManager;};(function(){var _6e=2;var _6f=1;var _70=30;var _71;var _72;var _73;var _74;var _75;var _76;if(!abego.IntelliTagger){abego.IntelliTagger={};}var _77=function(){return _72;};var _78=function(tag){return _75[tag];};var _7a=function(s){var i=s.lastIndexOf(" ");return (i>=0)?s.substr(0,i):"";};var _7d=function(_7e){var s=_7e.value;var len=s.length;return (len>0&&s[len-1]!=" ");};var _81=function(_82){var s=_82.value;var len=s.length;if(len>0&&s[len-1]!=" "){_82.value+=" ";}};var _85=function(tag,_87,_88){if(_7d(_87)){_87.value=_7a(_87.value);}story.setTiddlerTag(_88.title,tag,0);_81(_87);abego.IntelliTagger.assistTagging(_87,_88);};var _89=function(n){if(_76&&_76.length>n){return _76[n];}return (_74&&_74.length>n)?_74[n]:null;};var _8b=function(n,_8d,_8e){var _8f=_89(n);if(_8f){_85(_8f,_8d,_8e);}};var _90=function(_91){var pos=_91.value.lastIndexOf(" ");var _93=(pos>=0)?_91.value.substr(++pos,_91.value.length):_91.value;return new RegExp(_93.escapeRegExp(),"i");};var _94=function(_95,_96){var _97=0;for(var i=0;i<_95.length;i++){if(_96[_95[i]]){_97++;}}return _97;};var _99=function(_9a,_9b,_9c){var _9d=1;var c=_9a[_9b];for(var i=_9b+1;i<_9a.length;i++){if(_9a[i][1].count==c){if(_9a[i][0].match(_9c)){_9d++;}}else{break;}}return _9d;};var _a0=function(_a1,_a2){var _a3=abego.internal.getTagManager().getSortedTagInfos();var _a4=[];var _a5=0;for(var i=0;i<_a3.length;i++){var c=_a3[i][1].count;if(c!=_a5){if(_a2&&(_a4.length+_99(_a3,i,_a1)>_a2)){break;}_a5=c;}if(c==1){break;}var s=_a3[i][0];if(s.match(_a1)){_a4.push(s);}}return _a4;};var _a9=function(_aa,_ab){return abego.filterStrings(abego.internal.getTagManager().getAllTags(_ab),_aa);};var _ac=function(){if(!_71){return;}var _ad=store.getTiddlerText("IntelliTaggerMainTemplate");if(!_ad){_ad="<b>Tiddler IntelliTaggerMainTemplate not found</b>";}_71.innerHTML=_ad;applyHtmlMacros(_71,null);refreshElements(_71,null);};var _ae=function(e){if(!e){var e=window.event;}var tag=this.getAttribute("tag");if(_73){_73.call(this,tag,e);}return false;};var _b2=function(_b3){createTiddlyElement(_b3,"span",null,"tagSeparator"," | ");};var _b4=function(_b5,_b6,_b7,_b8,_b9){if(!_b6){return;}var _ba=_b8?abego.toSet(_b8):{};var n=_b6.length;var c=0;for(var i=0;i<n;i++){var tag=_b6[i];if(_ba[tag]){continue;}if(c>0){_b2(_b5);}if(_b9&&c>=_b9){abego.createEllipsis(_b5);break;}c++;var _bf="";var _c0=_b5;if(_b7<10){_c0=createTiddlyElement(_b5,"span",null,"numberedSuggestion");_b7++;var key=_b7<10?""+(_b7):"0";createTiddlyElement(_c0,"span",null,"suggestionNumber",key+") ");var _c2=_b7==1?"Return or ":"";_bf=" (Shortcut: %1Alt-%0)".format([key,_c2]);}var _c3=config.views.wikified.tag.tooltip.format([tag]);var _c4=(_78(tag)?"Remove tag '%0'%1":"Add tag '%0'%1").format([tag,_bf]);var _c5="%0; Shift-Click: %1".format([_c4,_c3]);var btn=createTiddlyButton(_c0,tag,_c5,_ae,_78(tag)?"currentTag":null);btn.setAttribute("tag",tag);}};var _c7=function(){if(_71){window.scrollTo(0,ensureVisible(_71));}if(_77()){window.scrollTo(0,ensureVisible(_77()));}};var _c8=function(e){if(!e){var e=window.event;}if(!_71){return;}var _cb=resolveTarget(e);if(_cb==_77()){return;}if(abego.isDescendantOrSelf(_71,_cb)){return;}abego.IntelliTagger.close();};addEvent(document,"click",_c8);var _cc=Story.prototype.gatherSaveFields;Story.prototype.gatherSaveFields=function(e,_ce){_cc.apply(this,arguments);var _cf=_ce.tags;if(_cf){_ce.tags=_cf.trim();}};var _d0=function(_d1){story.focusTiddler(_d1,"tags");var _d2=abego.getTiddlerField(story,_d1,"tags");if(_d2){var len=_d2.value.length;abego.setRange(_d2,len,len);window.scrollTo(0,ensureVisible(_d2));}};var _d4=config.macros.edit.handler;config.macros.edit.handler=function(_d5,_d6,_d7,_d8,_d9,_da){_d4.apply(this,arguments);var _db=_d7[0];if((_da instanceof Tiddler)&&_db=="tags"){var _dc=_d5.lastChild;_dc.onfocus=function(e){abego.IntelliTagger.assistTagging(_dc,_da);setTimeout(function(){_d0(_da.title);},100);};_dc.onkeyup=function(e){if(!e){var e=window.event;}if(e.altKey&&!e.ctrlKey&&!e.metaKey&&(e.keyCode>=48&&e.keyCode<=57)){_8b(e.keyCode==48?9:e.keyCode-49,_dc,_da);}else{if(e.ctrlKey&&e.keyCode==32){_8b(0,_dc,_da);}}if(!e.ctrlKey&&(e.keyCode==13||e.keyCode==10)){_8b(0,_dc,_da);}setTimeout(function(){abego.IntelliTagger.assistTagging(_dc,_da);},100);return false;};_81(_dc);}};var _e0=function(e){if(!e){var e=window.event;}var _e3=resolveTarget(e);var _e4=_e3.getAttribute("tiddler");if(_e4){story.displayTiddler(_e3,_e4,"IntelliTaggerEditTagsTemplate",false);_d0(_e4);}return false;};var _e5=config.macros.tags.handler;config.macros.tags.handler=function(_e6,_e7,_e8,_e9,_ea,_eb){_e5.apply(this,arguments);abego.IntelliTagger.createEditTagsButton(_eb,createTiddlyElement(_e6.lastChild,"li"));};var _ec=function(){if(_71&&_72&&!abego.isDescendantOrSelf(document,_72)){abego.IntelliTagger.close();}};setInterval(_ec,100);abego.IntelliTagger.displayTagSuggestions=function(_ed,_ee,_ef,_f0,_f1){_74=_ed;_75=abego.toSet(_ee);_76=_ef;_72=_f0;_73=_f1;if(!_71){_71=createTiddlyElement(document.body,"div",null,"intelliTaggerSuggestions");_71.style.position="absolute";}_ac();abego.openAsPopup(_71);if(_77()){var w=_77().offsetWidth;if(_71.offsetWidth<w){_71.style.width=(w-2*(_6e+_6f))+"px";}abego.moveBelowAndClip(_71,_77());}else{abego.centerOnWindow(_71);}_c7();};abego.IntelliTagger.assistTagging=function(_f3,_f4){var _f5=_90(_f3);var s=_f3.value;if(_7d(_f3)){s=_7a(s);}var _f7=s.readBracketedList();var _f8=_f7.length>0?abego.filterStrings(abego.internal.getTagManager().getPartnerRankedTags(_f7),_f5,_70):_a0(_f5,_70);abego.IntelliTagger.displayTagSuggestions(_a9(_f5,_f7),_f7,_f8,_f3,function(tag,e){if(e.shiftKey){onClickTag.call(this,e);}else{_85(tag,_f3,_f4);}});};abego.IntelliTagger.close=function(){abego.closePopup(_71);_71=null;return false;};abego.IntelliTagger.createEditTagsButton=function(_fb,_fc,_fd,_fe,_ff,id,_101){if(!_fd){_fd="[edit]";}if(!_fe){_fe="Edit the tags";}if(!_ff){_ff="editTags";}var _102=createTiddlyButton(_fc,_fd,_fe,_e0,_ff,id,_101);_102.setAttribute("tiddler",(_fb instanceof Tiddler)?_fb.title:String(_fb));return _102;};abego.IntelliTagger.getSuggestionTagsMaxCount=function(){return 100;};config.macros.intelliTagger={label:"intelliTagger",handler:function(_103,_104,_105,_106,_107,_108){var _109=_107.parseParams("list",null,true);var _10a=_109[0]["action"];for(var i=0;_10a&&i<_10a.length;i++){var _10c=_10a[i];var _10d=config.macros.intelliTagger.subhandlers[_10c];if(!_10d){abego.alertAndThrow("Unsupported action '%0'".format([_10c]));}_10d(_103,_104,_105,_106,_107,_108);}},subhandlers:{showTags:function(_10e,_10f,_110,_111,_112,_113){_b4(_10e,_74,_76?_76.length:0,_76,abego.IntelliTagger.getSuggestionTagsMaxCount());},showFavorites:function(_114,_115,_116,_117,_118,_119){_b4(_114,_76,0);},closeButton:function(_11a,_11b,_11c,_11d,_11e,_11f){var _120=createTiddlyButton(_11a,"close","Close the suggestions",abego.IntelliTagger.close);},version:function(_121){var t="IntelliTagger %0.%1.%2".format([version.extensions.IntelliTaggerPlugin.major,version.extensions.IntelliTaggerPlugin.minor,version.extensions.IntelliTaggerPlugin.revision]);var e=createTiddlyElement(_121,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">"+t+"<font>";},copyright:function(_124){var e=createTiddlyElement(_124,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de");e.innerHTML="<font color=\"black\" face=\"Arial, Helvetica, sans-serif\">&copy; 2006-2007 <b><font color=\"red\">abego</font></b> Software<font>";}}};})();config.shadowTiddlers["IntelliTaggerStyleSheet"]="/***\n"+"!~IntelliTagger Stylesheet\n"+"***/\n"+"/*{{{*/\n"+".intelliTaggerSuggestions {\n"+"\tposition: absolute;\n"+"\twidth: 600px;\n"+"\n"+"\tpadding: 2px;\n"+"\tlist-style: none;\n"+"\tmargin: 0;\n"+"\n"+"\tbackground: #eeeeee;\n"+"\tborder: 1px solid DarkGray;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .currentTag   {\n"+"\tfont-weight: bold;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .suggestionNumber {\n"+"\tcolor: #808080;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .numberedSuggestion{\n"+"\twhite-space: nowrap;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .intelliTaggerFooter {\n"+"\tmargin-top: 4px;\n"+"\tborder-top-width: thin;\n"+"\tborder-top-style: solid;\n"+"\tborder-top-color: #999999;\n"+"}\n"+".intelliTaggerSuggestions .favorites {\n"+"\tborder-bottom-width: thin;\n"+"\tborder-bottom-style: solid;\n"+"\tborder-bottom-color: #999999;\n"+"\tpadding-bottom: 2px;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .normalTags {\n"+"\tpadding-top: 2px;\n"+"}\n"+"\n"+".intelliTaggerSuggestions .intelliTaggerFooter .button {\n"+"\tfont-size: 10px;\n"+"\n"+"\tpadding-left: 0.3em;\n"+"\tpadding-right: 0.3em;\n"+"}\n"+"\n"+"/*}}}*/\n";config.shadowTiddlers["IntelliTaggerMainTemplate"]="<!--\n"+"{{{\n"+"-->\n"+"<div class=\"favorites\" macro=\"intelliTagger action: showFavorites\"></div>\n"+"<div class=\"normalTags\" macro=\"intelliTagger action: showTags\"></div>\n"+"<!-- The Footer (with the Navigation) ============================================ -->\n"+"<table class=\"intelliTaggerFooter\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody>\n"+"  <tr>\n"+"\t<td align=\"left\">\n"+"\t\t<span macro=\"intelliTagger action: closeButton\"></span>\n"+"\t</td>\n"+"\t<td align=\"right\">\n"+"\t\t<span macro=\"intelliTagger action: version\"></span>, <span macro=\"intelliTagger action: copyright \"></span>\n"+"\t</td>\n"+"  </tr>\n"+"</tbody></table>\n"+"<!--\n"+"}}}\n"+"-->\n";config.shadowTiddlers["IntelliTaggerEditTagsTemplate"]="<!--\n"+"{{{\n"+"-->\n"+"<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler'></div>\n"+"<div class='title' macro='view title'></div>\n"+"<div class='tagged' macro='tags'></div>\n"+"<div class='viewer' macro='view text wikified'></div>\n"+"<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler'></div>\n"+"<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>\n"+"<!--\n"+"}}}\n"+"-->\n";config.shadowTiddlers["BSD open source license (abego Software)"]="See [[Licence|http://tiddlywiki.abego-software.de/#%5B%5BBSD%20open%20source%20license%5D%5D]].";config.shadowTiddlers["IntelliTaggerPlugin Documentation"]="[[Documentation on abego Software website|http://tiddlywiki.abego-software.de/doc/IntelliTagger.pdf]].";config.shadowTiddlers["IntelliTaggerPlugin SourceCode"]="[[Plugin source code on abego Software website|http://tiddlywiki.abego-software.de/archive/IntelliTaggerPlugin/Plugin-IntelliTagger-src.1.0.2.js]]\n";(function(){var _126=restart;restart=function(){setStylesheet(store.getTiddlerText("IntelliTaggerStyleSheet"),"IntelliTaggerStyleSheet");_126.apply(this,arguments);};})();}
// %/
/***
|''Name:''|IntelliTagsEditCommandPlugin|
|''Version:''|1.0.0 (2007-10-03)|
|''Type:''|plugin|
|''Description:''|A command for your tiddler's toolbar to directly edit the tiddler's tags using the IntelliTaggerPlugin, without switching to "edit mode".|
|''Source:''|http://tiddlywiki.abego-software.de/#IntelliTagsEditCommandPlugin|
|''Requires:''|IntelliTaggerPlugin http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)]]|
|''~CoreVersion:''|2.0.8|
|''Browser:''|Firefox 1.5.0.2 or better|
***/
/***
!Using the "IntelliTagsEditCommandPlugin"
Add the command {{{intelliTagsEdit}}} into the 'macro' attribute of the 'toolbar' {{{<div...>}}} in your ViewTemplate.

''Example:''
{{{
<div class='toolbar'
        macro='toolbar -closeTiddler closeOthers +editTiddler intelliTagsEdit permalink references jump'>
</div>
}}}

This adds a "tags" button to the toolbar of the tiddlers (next to the ''edit'' button). Pressing the "tags" button will open the input field for the tiddler's tags and let you edit the tags with all the [[IntelliTaggerPlugin|http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin]] features.
***/
/***
!Source Code
***/
//{{{
(function(){

if (!version.extensions.IntelliTaggerPlugin)
    throw Error("IntelliTagsEditCommandPlugin requires the IntelliTaggerPlugin (http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin)");

if (config.commands.intelliTagsEdit)
    return;

config.commands.intelliTagsEdit = {
	text: "tags",
	tooltip: "edit the tags"
};

config.commands.intelliTagsEdit.handler = function(event,src,title) {
	var button = abego.IntelliTagger.createEditTagsButton(title, null, "tags", "edit the tags");
	button.onclick(event);
	return false;
};

})();
//}}}
<<showData>>
<data>{"month":"Dec","descr":"Restaurant","amount":35}</data>
<<showData>>
<data>{"month":"Nov", "descr" : "Ring", "amount" : 2999}</data>
<<showData>>
<data>{"month":"Dec","descr":"Flight","amount":688}</data>
The programming language TiddlyWiki is written in.
JavaScript in actionParameters may refer to the build-in variables {{{tiddler}}}, {{{count}}}, {{{index}}} and {{{context}}}.
<<formTiddler ContactsFormTemplate>>
<data>{"firstname":"Joe","lastname":"Block","email":"jb@example.org","phone":"555-1234567","city":"Boston","state":"MA","notes":"works as a designer, \nmay help with logo.","webpage":"www.example.org","country":"US"}</data>
/***
|''Name:''|LegacyStrikeThroughPlugin|
|''Description:''|Support for legacy (pre 2.1) strike through formatting|
|''Version:''|1.0.2|
|''Date:''|Jul 21, 2006|
|''Source:''|http://www.tiddlywiki.com/#LegacyStrikeThroughPlugin|
|''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.0|
***/

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

config.formatters.push(
{
	name: "legacyStrikeByChar",
	match: "==",
	termRegExp: /(==)/mg,
	element: "strike",
	handler: config.formatterHelpers.createElementAndWikify
});

} //# end of "install only once"
//}}}
When using the IncludePlugin the ForEachTiddlerMacro loops over all tiddlers, the ones from the "master" TiddlyWiki and all included TiddlyWiki.

If you want to restrict the result to tiddlers of a certain included TiddlyWiki you may refer to the tiddler variable "includedURL" that holds the URL of the TiddlyWiki this tiddler was included from. For the "master" TiddlyWiki the "includeURL" is empty.

''Example''

Assume you have included "http://www.tiddlywiki.com/index.html". You want to list the tiddlers of that TiddlyWiki that have changed after July 1st, 2007. The result should be sorted by the modified date, with the last changes listed first.

This is the ForEachTiddlerMacro call you may use for this purpose:
{{{
<<forEachTiddler
    where
        'tiddler.modified > new Date("July 1, 2007") && tiddler.includeURL == "http://www.tiddlywiki.com/index.html"'

    sortBy
        ' tiddler.modified'
    descending

    write
        '"* "+tiddler.modified.formatString("YYYY-0MM-0DD")+" [[" +tiddler.title+"]]\n"'
>>
}}}

See also:
* [[List Tiddlers of the "Master" TiddlyWiki (when using the IncludePlugin)]]
* [[Programming with the IncludePlugin]])
When using the IncludePlugin the ForEachTiddlerMacro loops over all tiddlers, the ones from the "master" TiddlyWiki and all included TiddlyWiki.

If you want to restrict the result to tiddlers of the "master" TiddlyWiki you may refer to the tiddler variable "includedURL" that holds the URL of the TiddlyWiki this tiddler was included from.  For the "master" TiddlyWiki the "includeURL" is empty.

''Example''

You want to list the tiddlers of the "master" TiddlyWiki that have changed after July 1st, 2007. The result should be sorted by the modified date, with the last changes listed first.

This is the ForEachTiddlerMacro call you may use for this purpose:
{{{
<<forEachTiddler
    where
        'tiddler.modified > new Date("July 1, 2007") && ! tiddler.includeURL'

    sortBy
        ' tiddler.modified'
    descending

    write
        '"* "+tiddler.modified.formatString("YYYY-0MM-0DD")+" [[" +tiddler.title+"]]\n"'
>>
}}}

See also:
* [[List Tiddlers of an included TiddlyWiki (using the ForEachTiddlerMacro)]]
* [[Programming with the IncludePlugin]]
{{{
<<forEachTiddler
 where
 'tiddler.title.contains("it")'
 sortBy
 'tiddler.title.length'
 descending
>>
}}}
//''Result:''//
<<forEachTiddler
 where
 'tiddler.title.contains("it")'
 sortBy
 'tiddler.title.length'
 descending
>>

See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler
 where
 'tiddler.title.contains("it")'
 sortBy
 'tiddler.title.length'
 descending
>>
}}}
//''Result:''//
<<forEachTiddler
 where
 'tiddler.title.contains("it")'
 sortBy
 'tiddler.title.length'
 descending
>>
{{{
<<forEachTiddler
 where
 'tiddler.title.contains("it")'
 sortBy
 'tiddler.title'
 descending
>>
}}}
//''Result:''//
<<forEachTiddler
 where
 'tiddler.title.contains("it")'
 sortBy
 'tiddler.title'
 descending
>>
See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler
    script '
        function lastDays(tiddler) {
            var compareDate = new Date();
            compareDate.setDate(compareDate.getDate() - 30);
            if (tiddler.modified > compareDate)
                return "* [[" + tiddler.title + "]]\n";
            else
                return "";
        }
    '

    write 'lastDays(tiddler)'
>>
}}}
//(Based on source code provided by Edmund Rodgers)//

''//Result://''
<<forEachTiddler
    script '
        function lastDays(tiddler) {
            var compareDate = new Date();
            compareDate.setDate(compareDate.getDate() - 30);
            if (tiddler.modified > compareDate)
                return "* [[" + tiddler.title + "]]\n";
            else
                return "";
        }
    '

    write 'lastDays(tiddler)'
>>
This code is based on the examples [[List all Tiddlers changed in the last 30 days]] and [[List the 10 most recently modified tiddlers]]. It demonstrates how to create different output depending on the outcome of a ForEachTiddlerMacro call.

The basic idea is to first collect the output of one ForEachTiddlerMacro call and not directly write it as the individual tiddlers are processed. At the end we check the result and decide what the real outcome should be and then actually write the result. To collect the output we use a "context" variable.

In our example we first collect the output of the [[List all Tiddlers changed in the last 30 days]] and check in the end if there was any output written. If yes that output is used, otherwise we generate a {{{<<tiddler ...>>}}} macro to display the content of the [[List the 10 most recently modified tiddlers]] tiddler instead.

{{{
<<forEachTiddler
    script '
        function lastDays(tiddler) {
            var compareDate = new Date();
            compareDate.setDate(compareDate.getDate() - 30);
            if (tiddler.modified > compareDate)
                return "* [[" + tiddler.title + "]]\n";
            else
                return "";
        }
    '

    write 'context.output+= lastDays(tiddler) , ""'

        begin 'context.output = ""'

        end 'context.output
                ? context.output
                : "<<tiddler [[List the 10 most recently modified tiddlers]]\>\>"
        '
>>
}}}

''//Result://''
<<forEachTiddler
    script '
        function lastDays(tiddler) {
            var compareDate = new Date();
            compareDate.setDate(compareDate.getDate() - 30);
            if (tiddler.modified > compareDate)
                return "* [[" + tiddler.title + "]]\n";
            else
                return "";
        }
    '

    write 'context.output+= lastDays(tiddler) , ""'

        begin 'context.output = ""'

        end 'context.output
                ? context.output
                : "<<tiddler [[List the 10 most recently modified tiddlers]]\>\>"
        '
>>
{{{
<<forEachTiddler
    sortBy
        'tiddler.title.toUpperCase()'

    script
        '
        function getGroupCaption(tiddler) {
            return tiddler.title.substr(0,1).toUpperCase();
        }

        function getGroupTitle(tiddler, context) {
            if (!context.lastGroup || context.lastGroup != getGroupCaption(tiddler)) {
                context.lastGroup = getGroupCaption(tiddler);
                return "* {{{"+(context.lastGroup?context.lastGroup:"no tags")+"}}}\n";
            } else
                return "";
        }
        '

    write
         'getGroupTitle(tiddler, context)+"** [[" + tiddler.title+"]]\n"'
>>
}}}
<<forEachTiddler
    sortBy
        'tiddler.title.toUpperCase()'

    script
        '
        function getGroupCaption(tiddler) {
            return tiddler.title.substr(0,1).toUpperCase();
        }

        function getGroupTitle(tiddler, context) {
            if (!context.lastGroup || context.lastGroup != getGroupCaption(tiddler)) {
                context.lastGroup = getGroupCaption(tiddler);
                return "* {{{"+(context.lastGroup?context.lastGroup:"no tags")+"}}}\n";
            } else
                return "";
        }
        '

    write
         'getGroupTitle(tiddler, context)+"** [[" + tiddler.title+"]]\n"'
>>
{{{
<<forEachTiddler
 where
 'tiddler.tags.containsAny(["TaskToDo","TaskOpen","TaskDone"])'
>>
}}}
//''Result:''//
<<forEachTiddler
 where
 'tiddler.tags.containsAny(["TaskToDo","TaskOpen","TaskDone"])'
>>

See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler
 where
 'tiddler.tags.contains("systemConfig")'
>>
}}}
//''Result:''//
<<forEachTiddler
 where
 'tiddler.tags.contains("systemConfig")'
>>
See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler
     where 'tiddler != context.inTiddler &&
            tiddler.tags.sort().join("]]") ==  context.inTiddler.tags.sort().join("]]")'
>>
}}}
!Notes
* The {{{tiddler != context.inTiddler}}} ensure the tiddler containing the macro call is not listed.
* {{{tiddler.tags.sort().join("]]")}}} creates a string with all tags of the tiddler, with the tags sorted alphabetically and separated by "]]". The "]]" string is used because it cannot be part of any tag name so it is fine to use it as a separator between tags.
* A "sorted tags string" is created both for the current tiddler and the tiddler containing the macro. If both strings are equal both tiddlers have the same tags.
* Instead of {{{context.inTiddler}}} you may also use {{{context.viewTiddler}}}, especially when you are working with the {{{<<tiddler...>>}}} macro. See  [[whereClause]] for details.
{{{
<<forEachTiddler
 where
 'tiddler.title.startsWith("Site")'
>>
}}}
//''Result:''//
<<forEachTiddler
 where
 'tiddler.title.startsWith("Site")'
>>
See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler
 where
 'tiddler.tags && tiddler.tags.length'
 sortBy
 'getSortedTagsText(tiddler)+"###"+tiddler.title'
 script
 'function getSortedTagsText(tiddler) {var tags = tiddler.tags; if (!tags) return ""; tags.sort(); var result = ""; for (var i = 0; i < tags.length;i++) {result += tags[i]+ " ";} return result;} function getGroupTitle(tiddler, context) {if (!context.lastGroup || context.lastGroup != getSortedTagsText(tiddler)) { context.lastGroup = getSortedTagsText(tiddler); return "* {{{"+(context.lastGroup?context.lastGroup:"no tags")+"}}}\n";} else return "";} '
 write
 'getGroupTitle(tiddler, context)+"** [[" + tiddler.title+"]]\n"'
>>
}}}
<<forEachTiddler
 where
 'tiddler.tags && tiddler.tags.length'
 sortBy
 'getSortedTagsText(tiddler)+"###"+tiddler.title'
 script
 'function getSortedTagsText(tiddler) {var tags = tiddler.tags; if (!tags) return ""; tags.sort(); var result = ""; for (var i = 0; i < tags.length;i++) {result += tags[i]+ " ";} return result;} function getGroupTitle(tiddler, context) {if (!context.lastGroup || context.lastGroup != getSortedTagsText(tiddler)) { context.lastGroup = getSortedTagsText(tiddler); return "* {{{"+(context.lastGroup?context.lastGroup:"no tags")+"}}}\n";} else return "";} '
 write
 'getGroupTitle(tiddler, context)+"** [[" + tiddler.title+"]]\n"'
>>
//(Tiddlers without tags are not included)//
{{{
<<forEachTiddler
	sortBy
		'getSortedTagsText(tiddler)+"###"+tiddler.title'

	script
		'
		function getSortedTagsText(tiddler) {
			var tags = tiddler.tags;
			if (!tags || !tags.length)
				return "{no tags}";
			tags.sort();
			var result = "";
			for (var i = 0; i < tags.length;i++) {
				result += tags[i]+ " ";
			}
			return result;
		}

		function getGroupTitle(tiddler, context) {
			if (!context.lastGroup || context.lastGroup != getSortedTagsText(tiddler)) {
				context.lastGroup = getSortedTagsText(tiddler);
				return "* {{{"+(context.lastGroup?context.lastGroup:"no tags")+"}}}\n";
			} else
				return "";
		}
		'

	write
		 'getGroupTitle(tiddler, context)+"** [[" + tiddler.title+"]]\n"'
>>
}}}
<<forEachTiddler
	sortBy
		'getSortedTagsText(tiddler)+"###"+tiddler.title'

	script
		'
		function getSortedTagsText(tiddler) {
			var tags = tiddler.tags;
			if (!tags || !tags.length)
				return "{no tags}";
			tags.sort();
			var result = "";
			for (var i = 0; i < tags.length;i++) {
				result += tags[i]+ " ";
			}
			return result;
		}

		function getGroupTitle(tiddler, context) {
			if (!context.lastGroup || context.lastGroup != getSortedTagsText(tiddler)) {
				context.lastGroup = getSortedTagsText(tiddler);
				return "* {{{"+(context.lastGroup?context.lastGroup:"no tags")+"}}}\n";
			} else
				return "";
		}
		'

	write
		 'getGroupTitle(tiddler, context)+"** [[" + tiddler.title+"]]\n"'
>>
If a tiddler name is used in more than one TiddlyWiki (e.g. in the main TiddlyWiki and some included TiddlyWiki) only one of these tiddlers is visible, the others are hidden. For details see [[How Tiddlers are found]].

The following script reports all "hidden" tiddlers, also reporting the TiddlyWiki containing them.
{{{
<script>
// List all hidden tiddlers of included TiddlyWikis
// see http://tiddlywiki.abego-software.de/#[[How%20Tiddlers%20are%20found]]

// By default hidden tiddlers with names of shadow tiddlers in the main TiddlyWiki
// are not reported. Set the following variable to false if these should also be reported.
var ignoreShadowTiddlers = true;


// returns the url (if defined) or the text "main ~TiddlyWiki"
var twLabel = function(url) {
    return url ? url : "main ~TiddlyWiki";
}

var hiddenTiddlers = [];
var incls = abego.TiddlyWikiIncluder.getIncludes();
var n = incls.length;
for (var i = 0; i < n; i++) {
    var url = incls[i]
    var twStore = abego.TiddlyWikiIncluder.getStore(url);
    if (twStore == null) {
        displayMessage("not found "+url);
        continue;
    }

    twStore.forEachTiddler(function(title,tiddler) {
        var foundTiddler = store.getTiddler(tiddler.title);
        if (foundTiddler == null) {
            // no tiddler with this title found (using getTiddler),
            // so this must be a shadow tiddler in the main TiddlyWiki.
            if (!ignoreShadowTiddlers) {
                hiddenTiddlers.push("[["+title+"]] in "+url+" (using shadow tiddler from "+twLabel(null)+")");
            }
        } else if (tiddler != foundTiddler) {
            if (!ignoreShadowTiddlers || config.shadowTiddlers[[title]] == undefined) {
                hiddenTiddlers.push("[["+title+"]] in "+url+" (using tiddler from "+twLabel(foundTiddler.includeURL)+")");
            }
        }
    });
}

return hiddenTiddlers.length
        ? "!Hidden Tiddlers\n# "+hiddenTiddlers.join("\n# ")+"]]\n"
        : "No tiddlers are hidden.";
</script>
}}}
<script>
// List all hidden tiddlers of included TiddlyWikis
// see http://tiddlywiki.abego-software.de/#[[How%20Tiddlers%20are%20found]]

// By default hidden tiddlers with names of shadow tiddlers in the main TiddlyWiki
// are not reported. Set the following variable to false if these should also be reported.
var ignoreShadowTiddlers = true;


// returns the url (if defined) or the text "main ~TiddlyWiki"
var twLabel = function(url) {
    return url ? url : "main ~TiddlyWiki";
}

var hiddenTiddlers = [];
var incls = abego.TiddlyWikiIncluder.getIncludes();
var n = incls.length;
for (var i = 0; i < n; i++) {
    var url = incls[i]
    var twStore = abego.TiddlyWikiIncluder.getStore(url);
    if (twStore == null) {
        displayMessage("not found "+url);
        continue;
    }

    twStore.forEachTiddler(function(title,tiddler) {
        var foundTiddler = store.getTiddler(tiddler.title);
        if (foundTiddler == null) {
            // no tiddler with this title found (using getTiddler),
            // so this must be a shadow tiddler in the main TiddlyWiki.
            if (!ignoreShadowTiddlers) {
                hiddenTiddlers.push("[["+title+"]] in "+url+" (using shadow tiddler from "+twLabel(null)+")");
            }
        } else if (tiddler != foundTiddler) {
            if (!ignoreShadowTiddlers || config.shadowTiddlers[[title]] == undefined) {
                hiddenTiddlers.push("[["+title+"]] in "+url+" (using tiddler from "+twLabel(foundTiddler.includeURL)+")");
            }
        }
    });
}

return hiddenTiddlers.length
        ? "!Hidden Tiddlers\n# "+hiddenTiddlers.join("\n# ")+"]]\n"
        : "No tiddlers are hidden.";
</script>
{{{
<<forEachTiddler
 where
 'tiddler.tags.contains("TaskOpen") && ! tiddler.tags.contains("UdoBorkowski")'
>>
}}}
//''Result:''//
<<forEachTiddler
 where
 'tiddler.tags.contains("TaskOpen") && ! tiddler.tags.contains("UdoBorkowski")'
>>
See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler
 where
 'tiddler.tags.containsAll(["TaskOpen","UdoBorkowski"])'
>>
}}}
//''Result:''//
<<forEachTiddler
 where
 'tiddler.tags.containsAll(["TaskOpen","UdoBorkowski"])'
>>
See also [[ForEachTiddlerExamples]].
Assume in a "journal" tiddler you want to see all tasks you completed that day. For every task you have tiddler with its details. When it is completed you add the date to the title (make sure to spell the date exactly as in the journal tiddler title).

Then you can add the following forEachTiddler macro to the journal tiddler to list all these tasks:
{{{
<<forEachTiddler
 where
 'tiddler.title.contains(context.viewerTiddler.title) && tiddler.title != context.viewerTiddler.title'
 sortBy
 'tiddler.title'
write '"!![["+tiddler.title+"]]\n"+tiddler.tags+"\n"+tiddler.text+"\n"'
>>
}}}

Instead of copying this long statement to each journal tiddler you better create a helper tiddler with just the forEachTiddler macro call. Later you can "include" the helper tiddler in each journal tiddler.

E.g. have a look at the tiddler DailyStatusReport. You can now add a line like:
{{{
<<tiddler DailyStatusReport>>
}}}
into the journal tiddlers (e.g. as in journal tiddler "[[29 December 2009]]") to get the daily status report for that day.


(Based on code suggested by cmari and Alan Cohen. Thanks)
{{{
<<forEachTiddler
 where
 'tiddler.tags.length == 0'
>>
}}}
//''Result:''//
<<forEachTiddler
 where
 'tiddler.tags.length == 0'
>>
See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler
    sortBy
        'tiddler.text.length'
        descending
    write
        '"* [["+tiddler.title+"]] ("+tiddler.text.length+")\n"'
>>
}}}
//''Result:''//
<<forEachTiddler
    sortBy
        'tiddler.text.length'
        descending
    write
        '"* [["+tiddler.title+"]] ("+tiddler.text.length+")\n"'
>>
{{{
<<forEachTiddler
 sortBy
 '(tiddler.title.toLowerCase())'
>>
}}}
//''Result:''//
<<forEachTiddler
 sortBy
 '(tiddler.title.toLowerCase())'
>>
See also [[ForEachTiddlerExamples]].
{{{
<<forEachTiddler
    sortBy
        tiddler.modified
    descending

    write
        '(index < 10) ? "* [["+tiddler.title+"]]\n" : ""'
>>
}}}

''//Result://''
<<forEachTiddler
    sortBy
        tiddler.modified
    descending

    write
        '(index < 10) ? "* [["+tiddler.title+"]]\n" : ""'
>>
See also: [[List the first 10 tiddlers that have the tag 'basic']].
For this "List" task we don't use the default action "addToList" (that simply adds all selected items to the list) but create the list using the "write" action and refer to the build-in variable "index" that is incremented for every tiddler being processed.
{{{
<<forEachTiddler
    where
        'tiddler.tags.contains("basic")'
    write
        '(index < 10) ? "* [["+tiddler.title+"]]\n" : ""'
>>
}}}
In the write parameter there is a conditional output: when we are processing the tiddlers 0 to 9 it will write a line with:

 {{{* [[theTiddlerName]]}}}

Tiddler 10 and the following ones will generate no output (as the empty string is specified).

''//Result://''
<<forEachTiddler
    where
        'tiddler.tags.contains("basic")'
    write
        '(index < 10) ? "* [["+tiddler.title+"]]\n" : ""'
>>
This example shows how the ''begin'',  ''end'' and ''none'' options for the write action can be used.
{{{
<<forEachTiddler
    where
        'tiddler.tags.contains("basics")'
    write
        '(index < 10) ? "|"+(index+1)+"|[["+tiddler.title+"]]|\n" : ""'
        begin '"|!#|!Tiddler|\n"'
        end 'count+" Tiddlers found\n"'
        none '"No Tiddlers found\n"'
>>
}}}
In the write parameter there is a conditional output: when we are processing the tiddlers 0 to 9 it will write a table line like this:

 {{{|}}}//n//{{{|[[theTiddlerName]]|}}}

with n running from 1 to 10. All following tiddlers don't generate any output (as the empty string is specified).

The ''begin'' and ''end'' expression are used to create a table header and a "summary line" after the table.

''//Result://''
<<forEachTiddler
    where
        'tiddler.tags.contains("basic")'
    write
        '(index < 10) ? "|"+(index+1)+"|[["+tiddler.title+"]]|\n" : ""'
        begin '"|!#|!Tiddler|\n"'
        end 'count+" Tiddlers found\n"'
        none '"No Tiddlers found\n"'
>>


If no tiddler would have been found the ''none'' expression would be written

''//Result://''
<<forEachTiddler
    where
        'tiddler.tags.contains("basics")'
    write
        '(index < 10) ? "|"+(index+1)+"|[["+tiddler.title+"]]|\n" : ""'
        begin '"|!#|!Tiddler|\n"'
        end 'count+" Tiddlers found\n"'
        none '"No Tiddlers found\n"'
>>


{{{
<<forEachTiddler
 where
 'tiddler.tags.contains("basic")'
 script
 '
 function getFirstLine(s) {
 var m = s.match(/\s*(.*)/);
 return m != null && m.length >= 1 ? m[1] : "";
 }
 '
 write
 '"*[["+tiddler.title+"]] &rarr; "+getFirstLine(tiddler.text)+"\n"'
>>
}}}
<<forEachTiddler
 where
 'tiddler.tags.contains("basic")'
 script
 '
 function getFirstLine(s) {
 var m = s.match(/\s*(.*)/);
 return m != null && m.length >= 1 ? m[1] : "";
 }
 '
 write
 '"*[["+tiddler.title+"]] &rarr; "+getFirstLine(tiddler.text)+"\n"'
>>
{{{
<<forEachTiddler
 in
 'file:///c:/SampleTiddlyWiki.html'
 write
 'tiddler.title+"\n"'
>>
}}}
<<forEachTiddler
 in
 'file:///c:/SampleTiddlyWiki.html'
 write
 'tiddler.title+"\n"'
>>

{{{
<<forEachTiddler
where
	'tiddler.tags.contains("schedule")'

sortBy
	'(tiddler.title)'

script '

	// Returns the first line of the string
	//
	function getFirstLine(s) {
		var m = s.match(/\s*(.*)/);
		return m != null && m.length >= 1 ? m[1] : "";
	}

	// Returns the number of days between two dates.
	//
	// Only the year,month and day of the dates are considered.
	//
	// if date2 < date1 the result will be negative.
	//
	function getDaysBetween(date1, date2) {
		date1 = new Date(date1.getFullYear(),date1.getMonth(),date1.getDate());
		date2 = new Date(date2.getFullYear(),date2.getMonth(),date2.getDate());
		return ((date2.getTime()-date1)/86400000).toFixed();
	}

	// Returns the date given by the string s
	//
	// @param s 			String of format YYYY-MM-DD ("-" may be any char)
	// @param defaultValue 	returned when s is not a valid date.
	//
	// @return a Date object representing the given date.
	//
	function parseDate(s, defaultValue) {
		try {
			return new Date(parseInt(s.substr(0,4),10),
					parseInt(s.substr(5,2),10)-1,
					parseInt(s.substr(8,2),10));
		} catch(e) {
			return defaultValue;
		}
	}

	function getDaysLeftText(tiddler) {
		return getDaysBetween(new Date(),parseDate(tiddler.title, new Date()))+" days left: ";
	}
'

write
	'"* "+getDaysLeftText(tiddler)+"[["+tiddler.title+"]] &rarr; "+getFirstLine(tiddler.text)+"\n"'
>>
}}}
//''Result:''//
<<forEachTiddler
where
	'tiddler.tags.contains("schedule")'

sortBy
	'(tiddler.title)'

script '

	// Returns the first line of the string
	//
	function getFirstLine(s) {
		var m = s.match(/\s*(.*)/);
		return m != null && m.length >= 1 ? m[1] : "";
	}

	// Returns the number of days between two dates.
	//
	// Only the year,month and day of the dates are considered.
	//
	// if date2 < date1 the result will be negative.
	//
	function getDaysBetween(date1, date2) {
		date1 = new Date(date1.getFullYear(),date1.getMonth(),date1.getDate());
		date2 = new Date(date2.getFullYear(),date2.getMonth(),date2.getDate());
		return ((date2.getTime()-date1)/86400000).toFixed();
	}

	// Returns the date given by the string s
	//
	// @param s 			String of format YYYY-MM-DD ("-" may be any char)
	// @param defaultValue 	returned when s is not a valid date.
	//
	// @return a Date object representing the given date.
	//
	function parseDate(s, defaultValue) {
		try {
			return new Date(parseInt(s.substr(0,4),10),
					parseInt(s.substr(5,2),10)-1,
					parseInt(s.substr(8,2),10));
		} catch(e) {
			return defaultValue;
		}
	}

	function getDaysLeftText(tiddler) {
		return getDaysBetween(new Date(),parseDate(tiddler.title, new Date()))+" days left: ";
	}
'

write
	'"* "+getDaysLeftText(tiddler)+"[["+tiddler.title+"]] &rarr; "+getFirstLine(tiddler.text)+"\n"'
>>
<<forEachTiddler
 where
 'tiddler.text.contains("title")'
>>
See also ForEachTiddlerExamples.
[[About]]
[[TiddlyWiki]]
{{abegoLink{[[abego Software|http://www.abego-software.de]]}}}
[[News|abegoExtensions News]]
----
[[Plugins]]
[[Installing Plugins]]
----
[[Download]]
{{abegoLink{[[Archive|http://tiddlywiki.abego-software.de/archive]]}}}
[[Donations]]
----
[[Copyright]]
[[Contact]]
[[Imprint]]
----
^^© 2005-2012<<br>>[[abego Software|http://www.abego-software.de]]^^
/***
|''Name:''|Minesweeper|
|''Version:''|0.72 (12 Oct 2005)|
|''Source:''|Tiddly W;nks (http://www.bur.st/~blazeoz/tiddlywinks/)|
|''Author:''|[[Daniel Baird]]|
|''Type:''|Macro|
!Description
It's minesweeper!

!Syntax/Example usage
{{{<<minesweeper>>}}} or {{{<<minesweeper [width] [height] [bombs]>>}}}
<<minesweeper>>

!Notes
* Let me know if you want graphics, or that MSWindows Minesweeper thing where you can click with both buttons on a numbered square, and it does the thinking for you..

!Revision History
* 0.5.0 (2-Oct-05)
** original version (Daniel)
* 0.5.1 (3-Oct-05)
** added the css styles via set~StyleSheet (Simon)
* 0.5.2 (3-Oct-05)
** added parameters to macro and fixed bug preventing detection of win (Simon)
* 0.6 (5-Oct-05)
** Fixed the problem with multiple games on screen at once.
** Cleaned up the JavaScript warning generated when you clicked anywhere but on a square.
* 0.7 (6-Oct-05)
** Integrated sweet additions from Genesis_mage (genisis329 at gmail dot com) that:
*** allows winning by having all non-mines clicked (without having to mark every mine)
*** added a mark button to mark and unmark mines without the keyboard
** Win time now shows tenths of a second.
* 0.71 (10-Oct-05)
** tweaked a style to make the mark button work better in IE
* 0.72 (12-Oct-05)
** worked out how to use a closure as a event handler, which means that the code added in 0.6 could be made a lot simpler.

***/
/*{{{*/

version.extensions.minesweeper = {major: 0, minor: 7, revision: 2};

config.macros.minesweeper = {};

config.macros.minesweeper.handler = function(place,macroName,params) {
    var width = params[0];
    var height = params[1];
    var bombs = params[2];

    if (width == undefined) width = 9;
    if (height == undefined) height = width;
    if (bombs == undefined) bombs = Math.round(width * height /  8)
    if (bombs > width * height) bombs = width * height;

    var aGame = new MinesweeperGame();

    createTiddlyElement(place,'div',aGame.id,null,'If you see this, Minesweeper is broken.  Let Daniel know (DanielBaird at gmail dot com).');
    aGame.newGame(width, height, bombs);
}
// =======================================================================
function MinesweeperGame() {
    this.idprefix = 'mines';
    this.version = '0.72 beta';
    this.id = this.idprefix + MinesweeperGame.prototype.nextid;
    MinesweeperGame.prototype.nextid++;
    return this;
}
// -----------------------------------------------------------------------
MinesweeperGame.prototype.nextid = 0;
// -----------------------------------------------------------------------
MinesweeperGame.prototype.newGame = function(height, width, mines) {
    this.height = height;
    this.width = width;
    this.mines = mines;
    this.total = height * width;
    this.markMode = false;

    this.startGame();
}
// -----------------------------------------------------------------------
MinesweeperGame.prototype.startGame = function() {

    this.gamestate = 'ready';
    this.clicks = 0;
    this.marks = 0;
    this.message = 'click on the board to begin';

    this.starttime = null;
    this.wintime = null;
    this.board = new Array();

    // create the squares
    for (var x = 0; x < this.height; x++) {
        var row = new Array();
        for (var y = 0; y < this.width; y++) {
            row.push( {count: 0, mine: false, clicked: false, marked: false} );
        }
        this.board.push(row);
    }

    // add mines
    for (var m = 0; m < this.mines; m++) {
        var mx = Math.round((this.height-1)*Math.random());
        var my = Math.round((this.width-1)*Math.random());
        if (this.board[mx][my].mine) {
            m--;
        } else {
            this.board[mx][my].mine = true;
        }
    }

    // work out counts
    for (var cx = 0; cx < this.height; cx++) {
        for (var cy = 0; cy < this.width; cy++) {
            var count = 0;
            for (var dx = -1; dx < 2; dx++) {
                for (var dy = -1; dy < 2; dy++) {
                    var nx = cx + dx;
                    var ny = cy + dy;
                    if ( (!(dx==0 && dy==0))
                            && (nx >= 0) && (nx < this.height)
                            && (ny >= 0) && (ny < this.width)
                            && this.board[nx][ny].mine) {
                        count++;
                    }
                }
            }
            this.board[cx][cy].count = count;
        }
    }
    this.showBoard();
}
// -----------------------------------------------------------------------
MinesweeperGame.prototype.showBoard = function() {
    var node = document.getElementById(this.id);
    var html = new Array();
    html.push('<table class="minefield" cellspacing="2">');
    html.push('<tr><td class="info" colspan="'+this.width+'">');
    html.push('Minesweeper '+this.version+'<br /><b>'+this.gamestate+'</b>');
    if (this.gamestate == 'playing') {
        this.message = (this.mines - this.marks)+' mines unmarked';
    }
    html.push('</td></tr>');
    for (var x = 0; x < this.height; x++) {
        html.push('<tr>');
        for (var y = 0; y < this.width; y++) {
            html.push( this.makeSquare(x,y) );
        }
        html.push('</tr>');
    }
    var cls = 'un';
    if (this.markMode) cls = '';
    html.push('<tr><td id="'+this.id+'_markbtn" class="'+cls+'clicked widebtn" colspan="'+this.width+'">mark / unmark mines</td></tr>');
    html.push('<tr><td class="info" colspan="'+this.width+'">'+this.message);
    html.push('<small>');
    html.push('<br /><span class="minesweeper' + cls + 'show">ctrl- shift- or alt-</span>click to reveal a square');
    html.push('<br /><span class="minesweeper' + cls + 'hide">ctrl- shift- or alt-</span>click to mark a mine');
    html.push('</small>');
    html.push('</td></tr>');
    html.push('</table>');
    node.innerHTML = html.join('');
    node.onclick = this.getClickHandler();
}
// -----------------------------------------------------------------------
MinesweeperGame.prototype.makeSquare = function(x,y) {
    var sq = this.board[x][y];
    var reveal = (this.gamestate != 'playing' && this.gamestate != 'ready');
    var html = new Array();
    if (sq.clicked) {
        html.push('<td class="clicked" id="'+this.id+'_x-'+x+'_y-'+y+'">');
        if (!sq.marked && reveal && sq.mine) {
            html.push('B!');
        } else if (!sq.marked && reveal && sq.mine) {
            html.push('B!');
        } else if (sq.count > 0){
            html.push(sq.count);
        } else {
            html.push('&nbsp;');
        }
    } else {
        html.push('<td class="unclicked" id="'+this.id+'_x-'+x+'_y-'+y+'">');
        if (sq.marked && !reveal) {
            html.push('B?');
        } else if (sq.marked && sq.mine && reveal) {
            html.push('B');
        } else if (sq.marked && !sq.mine && reveal) {
            html.push('X');
        } else if (sq.mine && reveal) {
            html.push('B!');
        } else {
            html.push('&nbsp;');
        }
    }
    html.push('</td>');
    return html.join('');
}
// -------------------------------------------------------------------
MinesweeperGame.prototype.clickSquare = function(cx,cy,modifier) {
    if (this.gamestate == 'ready') {
        this.starttime = new Date();
        this.gamestate = 'playing';
    }
    if (this.gamestate == 'playing') {
        if (!this.board[cx][cy].clicked) {
            if ( (modifier && !this.markMode) || (!modifier && this.markMode) ) {
                if (this.board[cx][cy].marked) {
                    this.marks--;
                    this.board[cx][cy].marked = false;
                } else {
                    this.marks++;
                    this.board[cx][cy].marked = true;
                }
            } else if (!this.board[cx][cy].clicked && !this.board[cx][cy].marked) {
                this.revealSquare(cx,cy);
            }
            this.markMode = false;
        }
        this.checkWin();
        this.showBoard();
    } else {
        // clicked when we're not playing..
        this.startGame();
    }
}
// -------------------------------------------------------------------
MinesweeperGame.prototype.revealSquare = function(x,y) {
    if (this.board[x][y].clicked == false && this.board[x][y].marked == false) {
        this.board[x][y].clicked = true;
        this.clicks++;
        if (this.board[x][y].mine) {
            this.gamestate = 'boom!';
            this.message = 'click board to play again';
        } else if (this.board[x][y].count == 0) {
            // if it's a zero, we might have to reveal some other squares..
            for (var dx = -1; dx < 2; dx++) {
                for (var dy = -1; dy < 2; dy++) {
                    var nx = x + dx;
                    var ny = y + dy;
                    if ( (!(dx==0 && dy==0)) && (nx >= 0) && (nx < this.height) && (ny >= 0) && (ny < this.width) ) {
                        this.revealSquare(nx,ny);
                    }
                }
            }
        }
    }
}
// -------------------------------------------------------------------
MinesweeperGame.prototype.handleClick = function(e) {
    // work out which cell was clicked
    if (!e) var e = window.event;
    var str = resolveTarget(e).id;
    if (str && str != undefined) {
        if (str == this.id + '_markbtn') {
            this.markMode = !this.markMode;
            this.showBoard();
        } else {
            var cx = parseInt(str.substr( str.indexOf('x-')+2 ));
            var cy = parseInt(str.substr( str.indexOf('y-')+2 ));
            if ( !isNaN(cx) && !isNaN(cy) ) {
                this.clickSquare(cx,cy,(e.altKey || e.shiftKey || e.ctrlKey));
            }
        }
    }
}
// -------------------------------------------------------------------
MinesweeperGame.prototype.getClickHandler = function() {
    var thisGame = this;
    return function(e) {
        thisGame.handleClick(e);
    }
}
// -------------------------------------------------------------------
MinesweeperGame.prototype.checkWin = function() {
    if (this.clicks == this.total - this.mines && this.gamestate !='boom!') {
        this.gamestate = 'win';
        this.wintime = new Date();
        this.message = 'You won in '+Math.round(((this.wintime - this.starttime)/100))/10+' seconds';
        this.message = this.message + '<br />click board to play again';
    }
}
// -----------------------------------------------------------------------

setStylesheet(
	".viewer .minefield { "+
		"background: #ddd; "+
		"border: double 3px black; "+
		"border-collapse: separate; "+
		"border-spacing: 2px; "+
	"} \n"+

	".viewer .minefield td { "+
		"cursor: default; "+
		"width: 1.3em; "+
		"height: 1.1em; "+
		"text-align: center; "+
		"vertical-align: center; "+
		"background: #ddd; "+
		"border: 1px solid #ccc; "+
	"} \n"+

	".viewer .minefield td.info, .viewer .minefield td.widebtn { "+
		"width: auto; "+
	"} \n"+

	".minesweeperhide, .minesweeperunshow { "+
		"display: none; "+
	"} \n"+

	".viewer .minefield td.unclicked { "+
		"cursor: pointer; "+
		"border-color: #fff; "+
		"border-right-color: #999; "+
		"border-bottom-color: #999; "+
	"} \n"+
	"",
	"MinesweeperGame");

/*}}}*/
''The newTiddlerWithForm Macro''

To create tiddlers that are referencing [[FormTemplate]]s you may use the {{{<<newTiddlerWithForm...>>}}} macro.

The {{{<<newTiddlerWithForm...>>}}} macro displays a button. When pressed the button creates the requested tiddler and displays it.

If no title is given in the macro (or a tiddler with the given name already exists) the user can enter the tiddlers name in a dialog.

''Syntax:''
|>|{{{<<}}}''newTiddlerWithForm'' //formTemplateName// //buttonLabel// [//titleExpression// [''askUser'']] {{{>>}}}|
|//formTemplateName//|The name of the tiddler that defines the form the new tiddler should use.|
|//buttonLabel//|The label of the button|
|//titleExpression//|A (quoted) JavaScript String expression that defines the title (/name) of the new tiddler.|
|''askUser''|Typically the user is not asked for the title when a title is specified (and not yet used). When ''askUser'' is given the user will be asked in any case. This may be used when the calculated title is just a suggestion that must be confirmed by the user|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

''Examples''
* Ask the user for a bug report name and create a bugreport.
{{{
<<newTiddlerWithForm BugReportTemplate "New Bugreport">>
}}}
<<newTiddlerWithForm BugReportTemplate "New Bugreport">>

* Create a blog entry tiddler. Let the user confirm the automatically generated title (that contains the current date) or change it.
{{{
<<newTiddlerWithForm
 BlogTemplate
 "New Blog"
 '"Blog: "+(new Date()).formatString("YYYY-MM-DD")' askUser
>>
}}}
<<newTiddlerWithForm
 BlogTemplate
 "New Blog"
 '"Blog: "+(new Date()).formatString("YYYY-MM-DD")' askUser
>>
!Using the build-in newTiddler macro
Instead of the {{{<<newTiddlerWithForm>>}}} macro you may also use the build-in {{{<<newTiddler>>}}} macro to create tiddlers referencing [[FormTemplate]]s. E.g. you may use the {{{<<newTiddler>>}}} macro to create a tiddler with tags .

In the "text" you need to call the formTiddler macro and in the tagparameters you specify your tags. E.g.:
{{{
<<newTiddler
        label:"Button Label"
        text:{{"<<formTiddler [[MyTemplateTiddler]]>"+">"}}
        tag:"MyTag1"
        tag:"Three Word Tag"
>>
}}}
For details on newTiddler see http://tiddlywiki.org/wiki/NewTiddler_%28macro%29 
<div class='header' macro='gradient vert #ff8000 #ffb200'>
<div class='headerForeground'>
<span class='siteTitle'><b>abego</b>Extensions<br/></span>
<table width="99%"><tr><td>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span></td><td align="right"><span macro='search "" buttonAtRight:1'></span></td></tr></table>
</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>
/***
|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
|''Version:''|1.0.10 (2011-05-23)|
|''Source:''|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Table of Content<html><a name="TOC"/></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Description',null, event)">Description, Syntax</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Applications',null, event)">Applications</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('LongTiddler',null, event)">Refering to Paragraphs of a Longer Tiddler</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Citation',null, event)">Citation Index</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('TableCells',null, event)">Creating "multi-line" Table Cells</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Tabs',null, event)">Creating Tabs</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Sliders',null, event)">Using Sliders</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Revisions',null, event)">Revision History</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Code',null, event)">Code</a></html>
!Description<html><a name="Description"/></html>
With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate (named) parts.
Each part can be referenced as a "normal" tiddler, using the "//tiddlerName//''/''//partName//" syntax (e.g. "About/Features").  E.g. you may create links to the parts (e.g. {{{[[Quotes/BAX95]]}}} or {{{[[Hobbies|AboutMe/Hobbies]]}}}), use it in {{{<<tiddler...>>}}} or {{{<<tabs...>>}}} macros etc.


''Syntax:''
|>|''<part'' //partName// [''hidden''] ''>'' //any tiddler content// ''</part>''|
|//partName//|The name of the part. You may reference a part tiddler with the combined tiddler name "//nameOfContainerTidder//''/''//partName//. <<br>>If you use a partName containing spaces you need to quote it (e.g. {{{"Major Overview"}}} or {{{[[Shortcut List]]}}}).|
|''hidden''|When defined the content of the part is not displayed in the container tiddler. But when the part is explicitly referenced (e.g. in a {{{<<tiddler...>>}}} macro or in a link) the part's content is displayed.|
|<html><i>any&nbsp;tiddler&nbsp;content</i></html>|<html>The content of the part.<br>A part can have any content that a "normal" tiddler may have, e.g. you may use all the formattings and macros defined.</html>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Applications<html><a name="Applications"/></html>
!!Refering to Paragraphs of a Longer Tiddler<html><a name="LongTiddler"/></html>
Assume you have written a long description in a tiddler and now you want to refer to the content of a certain paragraph in that tiddler (e.g. some definition.) Just wrap the text with a ''part'' block, give it a nice name, create a "pretty link" (like {{{[[Discussion Groups|Introduction/DiscussionGroups]]}}}) and you are done.

Notice this complements the approach to first writing a lot of small tiddlers and combine these tiddlers to one larger tiddler in a second step (e.g. using the {{{<<tiddler...>>}}} macro). Using the ''part'' feature you can first write a "classic" (longer) text that can be read "from top to bottom" and later "reuse" parts of this text for some more "non-linear" reading.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Citation Index<html><a name="Citation"/></html>
Create a tiddler "Citations" that contains your "citations".
Wrap every citation with a part and a proper name.

''Example''
{{{
<part BAX98>Baxter, Ira D. et al: //Clone Detection Using Abstract Syntax Trees.//
in //Proc. ICSM//, 1998.</part>

<part BEL02>Bellon, Stefan: //Vergleich von Techniken zur Erkennung duplizierten Quellcodes.//
Thesis, Uni Stuttgart, 2002.</part>

<part DUC99>Ducasse, St�fane et al: //A Language Independent Approach for Detecting Duplicated Code.//
in //Proc. ICSM//, 1999.</part>
}}}

You may now "cite" them just by using a pretty link like {{{[[Citations/BAX98]]}}} or even more pretty, like this {{{[[BAX98|Citations/BAX98]]}}}.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Creating "multi-line" Table Cells<html><a name="TableCells"/></html>
You may have noticed that it is hard to create table cells with "multi-line" content. E.g. if you want to create a bullet list inside a table cell you cannot just write the bullet list
{{{
* Item 1
* Item 2
* Item 3
}}}
into a table cell (i.e. between the | ... | bars) because every bullet item must start in a new line but all cells of a table row must be in one line.

Using the ''part'' feature this problem can be solved. Just create a hidden part that contains the cells content and use a {{{<<tiddler >>}}} macro to include its content in the table's cell.

''Example''
{{{
|!Subject|!Items|
|subject1|<<tiddler ./Cell1>>|
|subject2|<<tiddler ./Cell2>>|

<part Cell1 hidden>
* Item 1
* Item 2
* Item 3
</part>
...
}}}

Notice that inside the {{{<<tiddler ...>>}}} macro you may refer to the "current tiddler" using the ".".

BTW: The same approach can be used to create bullet lists with items that contain more than one line.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Creating Tabs<html><a name="Tabs"/></html>
The build-in {{{<<tabs ...>>}}} macro requires that you defined an additional tiddler for every tab it displays. When you want to have "nested" tabs you need to define a tiddler for the "main tab" and one for every tab it contains. I.e. the definition of a set of tabs that is visually displayed at one place is distributed across multiple tiddlers.

With the ''part'' feature you can put the complete definition in one tiddler, making it easier to keep an overview and maintain the tab sets.

''Example''
The standard tabs at the sidebar are defined by the following eight tiddlers:
* SideBarTabs
* TabAll
* TabMore
* TabMoreMissing
* TabMoreOrphans
* TabMoreShadowed
* TabTags
* TabTimeline

Instead of these eight tiddlers one could define the following SideBarTabs tiddler that uses the ''part'' feature:
{{{
<<tabs txtMainTab
    Timeline Timeline SideBarTabs/Timeline
    All 'All tiddlers' SideBarTabs/All
    Tags 'All tags' SideBarTabs/Tags
    More 'More lists' SideBarTabs/More>>
<part Timeline hidden><<timeline>></part>
<part All hidden><<list all>></part>
<part Tags hidden><<allTags>></part>
<part More hidden><<tabs txtMoreTab
    Missing 'Missing tiddlers' SideBarTabs/Missing
    Orphans 'Orphaned tiddlers' SideBarTabs/Orphans
    Shadowed 'Shadowed tiddlers' SideBarTabs/Shadowed>></part>
<part Missing hidden><<list missing>></part>
<part Orphans hidden><<list orphans>></part>
<part Shadowed hidden><<list shadowed>></part>
}}}

Notice that you can easily "overwrite" individual parts in separate tiddlers that have the full name of the part.

E.g. if you don't like the classic timeline tab but only want to see the 100 most recent tiddlers you could create a tiddler "~SideBarTabs/Timeline" with the following content:
{{{
<<forEachTiddler
		sortBy 'tiddler.modified' descending
		write '(index < 100) ? "* [["+tiddler.title+"]]\n":""'>>
}}}
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!!Using Sliders<html><a name="Sliders"/></html>
Very similar to the build-in {{{<<tabs ...>>}}} macro (see above) the {{{<<slider ...>>}}} macro requires that you defined an additional tiddler that holds the content "to be slid". You can avoid creating this extra tiddler by using the ''part'' feature

''Example''
In a tiddler "About" we may use the slider to show some details that are documented in the tiddler's "Details" part.
{{{
...
<<slider chkAboutDetails About/Details details "Click here to see more details">>
<part Details hidden>
To give you a better overview ...
</part>
...
}}}

Notice that putting the content of the slider into the slider's tiddler also has an extra benefit: When you decide you need to edit the content of the slider you can just doubleclick the content, the tiddler opens for editing and you can directly start editing the content (in the part section). In the "old" approach you would doubleclick the tiddler, see that the slider is using tiddler X, have to look for the tiddler X and can finally open it for editing. So using the ''part'' approach results in a much short workflow.

<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Revision history<html><a name="Revisions"/></html>
* v1.0.10 (2011-05-23)
** Adapt to TW 2.6.2 default behaviour when existing tiddlers are opened (don't select text) and fixed Firefox 4 issue. Thanks to dave for reporting the issue.
* v1.0.9 (2007-07-14)
** Bugfix: Error when using the SideBarTabs example and switching between "More" and "Shadow". Thanks to cmari for reporting the issue.
* v1.0.8 (2007-06-16)
** Speeding up display of tiddlers containing multiple pard definitions. Thanks to Paco Rivi�re for reporting the issue.
** Support "./partName" syntax inside {{{<<tabs ...>>}}} macro
* v1.0.7 (2007-03-07)
** Bugfix: <<tiddler "./partName">> does not always render correctly after a refresh (e.g. like it happens when using the "Include" plugin). Thanks to Morris Gray for reporting the bug.
* v1.0.6 (2006-11-07)
** Bugfix: cannot edit tiddler when UploadPlugin by Bidix is installed. Thanks to Jos� Luis Gonz�lez Castro for reporting the bug.
* v1.0.5 (2006-03-02)
** Bugfix: Example with multi-line table cells does not work in IE6. Thanks to Paulo Soares for reporting the bug.
* v1.0.4 (2006-02-28)
** Bugfix: Shadow tiddlers cannot be edited (in TW 2.0.6). Thanks to Torsten Vanek for reporting the bug.
* v1.0.3 (2006-02-26)
** Adapt code to newly introduced Tiddler.prototype.isReadOnly() function (in TW 2.0.6). Thanks to Paulo Soares for reporting the problem.
* v1.0.2 (2006-02-05)
** Also allow other macros than the "tiddler" macro use the "." in the part reference (to refer to "this" tiddler)
* v1.0.1 (2006-01-27)
** Added Table of Content for plugin documentation. Thanks to RichCarrillo for suggesting.
** Bugfix: newReminder plugin does not work when PartTiddler is installed. Thanks to PauloSoares for reporting.
* v1.0.0 (2006-01-25)
** initial version
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Code<html><a name="Code"/></html>
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
//{{{
//============================================================================
//                           PartTiddlerPlugin

// Ensure that the PartTiddler Plugin is only installed once.
//
if (!version.extensions.PartTiddlerPlugin) {



version.extensions.PartTiddlerPlugin = {
    major: 1, minor: 0, revision: 10,
    date: new Date(2011, 4, 23),
    type: 'plugin',
    source: "http://tiddlywiki.abego-software.de/#PartTiddlerPlugin"
};

if (!window.abego) window.abego = {};
if (version.major < 2) alertAndThrow("PartTiddlerPlugin requires TiddlyWiki 2.0 or newer.");

//============================================================================
// Common Helpers

// Looks for the next newline, starting at the index-th char of text.
//
// If there are only whitespaces between index and the newline
// the index behind the newline is returned,
// otherwise (or when no newline is found) index is returned.
//
var skipEmptyEndOfLine = function(text, index) {
	var re = /(\n|[^\s])/g;
	re.lastIndex = index;
	var result = re.exec(text);
	return (result && text.charAt(result.index) == '\n')
			? result.index+1
			: index;
}


//============================================================================
// Constants

var partEndOrStartTagRE = /(<\/part>)|(<part(?:\s+)((?:[^>])+)>)/mg;
var partEndTagREString = "<\\/part>";
var partEndTagString = "</part>";

//============================================================================
// Plugin Specific Helpers

// Parse the parameters inside a <part ...> tag and return the result.
//
// @return [may be null] {partName: ..., isHidden: ...}
//
var parseStartTagParams = function(paramText) {
	var params = paramText.readMacroParams();
	if (params.length == 0 || params[0].length == 0) return null;

	var name = params[0];
	var paramsIndex = 1;
	var hidden = false;
	if (paramsIndex < params.length) {
		hidden = params[paramsIndex] == "hidden";
		paramsIndex++;
	}

	return {
		partName: name,
		isHidden: hidden
	};
}

// Returns the match to the next (end or start) part tag in the text,
// starting the search at startIndex.
//
// When no such tag is found null is returned, otherwise a "Match" is returned:
// [0]: full match
// [1]: matched "end" tag (or null when no end tag match)
// [2]: matched "start" tag (or null when no start tag match)
// [3]: content of start tag (or null if no start tag match)
//
var findNextPartEndOrStartTagMatch = function(text, startIndex) {
	var re = new RegExp(partEndOrStartTagRE);
	re.lastIndex = startIndex;
	var match = re.exec(text);
	return match;
}

//============================================================================
// Formatter

// Process the <part ...> ... </part> starting at (w.source, w.matchStart) for formatting.
//
// @return true if a complete part section (including the end tag) could be processed, false otherwise.
//
var handlePartSection = function(w) {
	var tagMatch = findNextPartEndOrStartTagMatch(w.source, w.matchStart);
	if (!tagMatch) return false;
	if (tagMatch.index != w.matchStart || !tagMatch[2]) return false;

	// Parse the start tag parameters
	var arguments = parseStartTagParams(tagMatch[3]);
	if (!arguments) return false;

	// Continue processing
	var startTagEndIndex = skipEmptyEndOfLine(w.source, tagMatch.index + tagMatch[0].length);
	var endMatch = findNextPartEndOrStartTagMatch(w.source, startTagEndIndex);
	if (endMatch && endMatch[1]) {
		if (!arguments.isHidden) {
			w.nextMatch = startTagEndIndex;
			w.subWikify(w.output,partEndTagREString);
		}
		w.nextMatch = skipEmptyEndOfLine(w.source, endMatch.index + endMatch[0].length);

		return true;
	}
	return false;
}

config.formatters.push( {
    name: "part",
    match: "<part\\s+[^>]+>",

	handler: function(w) {
		if (!handlePartSection(w)) {
			w.outputText(w.output,w.matchStart,w.matchStart+w.matchLength);
		}
	}
} )

//============================================================================
// Extend "fetchTiddler" functionality to also recognize "part"s of tiddlers
// as tiddlers.

var currentParent = null; // used for the "." parent (e.g. in the "tiddler" macro)

// Return the match to the first <part ...> tag of the text that has the
// requrest partName.
//
// @return [may be null]
//
var findPartStartTagByName = function(text, partName) {
	var i = 0;

	while (true) {
		var tagMatch = findNextPartEndOrStartTagMatch(text, i);
		if (!tagMatch) return null;

		if (tagMatch[2]) {
			// Is start tag

			// Check the name
			var arguments = parseStartTagParams(tagMatch[3]);
			if (arguments && arguments.partName == partName) {
				return tagMatch;
			}
		}
		i = tagMatch.index+tagMatch[0].length;
	}
}

// Return the part "partName" of the given parentTiddler as a "readOnly" Tiddler
// object, using fullName as the Tiddler's title.
//
// All remaining properties of the new Tiddler (tags etc.) are inherited from
// the parentTiddler.
//
// @return [may be null]
//
var getPart = function(parentTiddler, partName, fullName) {
	var text = parentTiddler.text;
	var startTag = findPartStartTagByName(text, partName);
	if (!startTag) return null;

	var endIndexOfStartTag = skipEmptyEndOfLine(text, startTag.index+startTag[0].length);
	var indexOfEndTag = text.indexOf(partEndTagString, endIndexOfStartTag);

	if (indexOfEndTag >= 0) {
		var partTiddlerText = text.substring(endIndexOfStartTag,indexOfEndTag);
		var partTiddler = new Tiddler();
		partTiddler.set(
						fullName,
						partTiddlerText,
						parentTiddler.modifier,
						parentTiddler.modified,
						parentTiddler.tags,
						parentTiddler.created);
		partTiddler.abegoIsPartTiddler = true;
		return partTiddler;
	}

	return null;
}

// Hijack the store.fetchTiddler to recognize the "part" addresses.
//
var hijackFetchTiddler = function() {
	var oldFetchTiddler = store.fetchTiddler ;
	store.fetchTiddler = function(title) {
		var result = oldFetchTiddler.apply(this, arguments);
		if (!result && title) {
			var i = title.lastIndexOf('/');
			if (i > 0) {
				var parentName = title.substring(0, i);
				var partName = title.substring(i+1);
				var parent = (parentName == ".")
						? store.resolveTiddler(currentParent)
						: oldFetchTiddler.apply(this, [parentName]);
				if (parent) {
					return getPart(parent, partName, parent.title+"/"+partName);
				}
			}
		}
		return result;
	};
};

// for debugging the plugin is not loaded through the systemConfig mechanism but via a script tag.
// At that point in the "store" is not yet defined. In that case hijackFetchTiddler through the restart function.
// Otherwise hijack now.
if (!store) {
	var oldRestartFunc = restart;
	window.restart = function() {
		hijackFetchTiddler();
		oldRestartFunc.apply(this,arguments);
	};
} else
	hijackFetchTiddler();




// The user must not edit a readOnly/partTiddler
//

config.commands.editTiddler.oldIsReadOnlyFunction = Tiddler.prototype.isReadOnly;

Tiddler.prototype.isReadOnly = function() {
	// Tiddler.isReadOnly was introduced with TW 2.0.6.
	// For older version we explicitly check the global readOnly flag
	if (config.commands.editTiddler.oldIsReadOnlyFunction) {
		if (config.commands.editTiddler.oldIsReadOnlyFunction.apply(this, arguments)) return true;
	} else {
		if (readOnly) return true;
	}

	return this.abegoIsPartTiddler;
}

config.commands.editTiddler.handler_PartTiddlerPlugin = config.commands.editTiddler.handler;

config.commands.editTiddler.handler = function(event,src,title)
{
	var t = store.getTiddler(title);
	// Edit the tiddler if it either is not a tiddler (but a shadowTiddler)
	// or the tiddler is not readOnly
	if(!t || !t.abegoIsPartTiddler)
		{
		return config.commands.editTiddler.handler_PartTiddlerPlugin(event,src,title);
		}
	return false;
}

// To allow the "./partName" syntax in macros we need to hijack
// the invokeMacro to define the "currentParent" while it is running.
//
var oldInvokeMacro = window.invokeMacro;
function myInvokeMacro(place,macro,params,wikifier,tiddler) {
	var oldCurrentParent = currentParent;
	if (tiddler) currentParent = tiddler;
	try {
		oldInvokeMacro.apply(this, arguments);
	} finally {
		currentParent = oldCurrentParent;
	}
}
window.invokeMacro = myInvokeMacro;

// To correctly support the "./partName" syntax while refreshing we need to hijack
// the config.refreshers.tiddlers to define the "currentParent" while it is running.
//
(function() {
	var oldTiddlerRefresher= config.refreshers.tiddler;
	config.refreshers.tiddler = function(e,changeList) {
		var oldCurrentParent = currentParent;
		try {
			currentParent = e.getAttribute("tiddler");
			return oldTiddlerRefresher.apply(this,arguments);
		} finally {
			currentParent = oldCurrentParent;
		}
	};
})();

// Support "./partName" syntax inside <<tabs ...>> macro
(function() {
	var extendRelativeNames = function(e, title) {
		var nodes = e.getElementsByTagName("a");
		for(var i=0; i<nodes.length; i++) {
			var node = nodes[i];
			var s = node.getAttribute("content");
			if (s && s.indexOf("./") == 0)
				node.setAttribute("content",title+s.substr(1));
		}
	};
	var oldHandler = config.macros.tabs.handler;
	config.macros.tabs.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
		var result = oldHandler.apply(this,arguments);
		if (tiddler)
			extendRelativeNames(place, tiddler.title);
		return result;
	};
})();

// Scroll the anchor anchorName in the viewer of the given tiddler visible.
// When no tiddler is defined use the tiddler of the target given event is used.
window.scrollAnchorVisible = function(anchorName, tiddler, evt) {
	var tiddlerElem = null;
	if (tiddler) {
		tiddlerElem = document.getElementById(story.idPrefix + tiddler);
	}
	if (!tiddlerElem && evt) {
		var target = resolveTarget(evt);
		tiddlerElem = story.findContainingTiddler(target);
	}
	if (!tiddlerElem) return;

	var children = tiddlerElem.getElementsByTagName("a");
	for (var i = 0; i < children.length; i++) {
		var child = children[i];
		var name = child.getAttribute("name");
		if (name == anchorName) {
			var y = findPosY(child);
			window.scrollTo(0,y);
			return;
		}
	}
}

} // of "install only once"
//}}}

/***
<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>

!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2011 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
|!Plugin|!Description|
|AutoRefreshPlugin|A tiddler containing the {{{<<autoRefresh...>>}}} macro is automatically refreshed (re-painted) whenever a tiddler changes.|
|[[DataTiddlerPlugin]]|<<tiddler [[DataTiddlerPlugin::Summary]]>>|
|[[ForEachTiddlerPlugin]]|Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.|
|[[FormTiddlerPlugin]]|<<tiddler [[FormTiddlerPlugin::Summary]]>>|
|[[IncludePlugin]]|„Include“ other ~TiddlyWikis in your „main“ TiddlyWiki, link to included tiddlers, view them in your „main“ TiddlyWiki (without opening another TiddlyWiki). Even „search“ looks for included tiddlers. A great way to share tiddlers, to speed up "save changes" and to keep your ~TiddlyWikis small.|
|[[IntelliTaggerPlugin]]|Speed up tagging tiddlers using tag autocompletion and correction, tag suggestions and context sensitive tag guessing, "Edit Tags only" mode and many more. Especially when you are working with a lot of tags this is the plugin you are looking for.|
|[[IntelliTagsEditCommandPlugin]]|A command for your tiddler's toolbar to directly edit the tiddler's tags using the IntelliTaggerPlugin, without switching to "edit mode".|
|[[PartTiddlerPlugin]]|With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate parts. Each part can be referenced as a "normal" tiddler, using the "tiddlerName/partName" syntax.|
|[[SettingsPlugin]]|Manage your option settings' scope: keep settings private to a ~TiddlyWiki or share them with other ~TiddlyWikis.|
|[[TiddlerWithParamsPlugin]]|The plugin extends the build-in {{{<<tiddler...>>}}} macro. It replaces placeholders ($1, $2, ...) in the tiddler by values passed with the macro before it inserts the (replaced) text at the macro's location.|
|[[XHTML10Plugin]]|Make your TiddlyWiki XHTML 1.0 compliant.|
|[[YourSearchPlugin]]|Search your TiddlyWiki with advanced search features such as result lists, tiddler preview, result ranking, search filters, combined searches and many more.|

Read [[Installing Plugins]] on how to install these plugins in your TiddlyWiki.

Previous versions of these plugins (e.g. to run in older versions of TiddlyWiki) you may find in the [[archive|http://tiddlywiki.abego-software.de/archive]].
txtMainTab=Timeline; txtMoreTab=Shadowed; chkSliderOptionsPanel=true; chkFETActions=true
Every TiddlyWiki included using the IncludePlugin is loaded into memory and can be accessed through a "TiddlyWiki" object. This is a "TiddlyWiki" object just as the object stored in the global "store" object, used to access the TiddlyWiki you are running.

To get the TiddlyWiki ("store") object of an included TiddlyWiki you may use:
{{{
	var includedStore = abego.TiddlyWikiIncluder.getStore(tiddyWikiURL)
}}}
With the returned TiddlyWiki object you can do the same things you would do with the "store" object. E.g. you may iterate through the Tiddlers of the store etc.

''Example: List tiddlers from included TiddlyWiki changed after a given date''

Assume you have included "http://www.tiddlywiki.com/index.html" and want to list the tiddlers of that TiddlyWiki that have changed after July 1st, 2007.

You may then use this script:
{{{
<script>
var twStore = abego.TiddlyWikiIncluder.getStore("http://www.tiddlywiki.com/index.html");
var list = [];
twStore.forEachTiddler(function(title,tiddler) {
    if (tiddler.modified > new Date("July 1, 2007"))
        list.push(title);
});
return "* [["+list.join("]]\n* [[")+"]]\n";
</script>
}}}
//(To use the {{{<script>}}} tag you must install the InlineJavascriptPlugin (http://www.TiddlyTools.com/#InlineJavascriptPlugin))//

(See also [[List Tiddlers of an included TiddlyWiki (using the ForEachTiddlerMacro)]])

''Example: List all hidden Tiddlers of included TiddlyWikis''

For a more extended example see: [[List all hidden tiddlers of included TiddlyWikis]]


[ ... Here goes the detailed documentation for the tiddler ... ]
<<showData>>
<data>{"month":"Dec", "descr" : "Hotel", "amount" : 149}</data>
SectionA:Text 1 A
SectionB:Text 1 B
SectionA:Text 2 A
SectionB:Text 2 B
Here are some examples that show the usage of the scriptClause in the ForEachTiddlerMacro.

<<forEachTiddler
 where
 'tiddler.tags.contains("scriptClauseExample")'
>>

See also ForEachTiddlerExamples.
/***
|''Name:''|SettingsPlugin|
|''Version:''|1.1.0 (2006-07-30)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#SettingsPlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[SettingsPlugin Documentation]]|
|''~SourceCode:''|[[SettingsPlugin SourceCode]]|
|''Licence:''|[[BSD open source license (abego Software)]]|
|''~CoreVersion:''|2.0.7|
|''Browser:''|Firefox 1.5.0.2 or better; Internet Explorer 6.0|
^^This tiddler contains compressed source code. [[Full Source Code|SettingsPlugin SourceCode]].^^
***/
// /%
if(!version.extensions.SettingsPlugin){if(version.major<2){(function(){var s="Use TiddlyWiki 2.0 or better to run the Settings Plugin.";alert(s);throw s;})();}version.extensions.SettingsPlugin={major:1,minor:1,revision:0,date:new Date(2006,6,30),type:"plugin",source:"http://tiddlywiki.abego-software.de/#SettingsPlugin",documentation:"[[SettingsPlugin Documentation]]",sourcecode:"[[SettingsPlugin SourceCode]]",author:"Udo Borkowski (ub [at] abego-software [dot] de)",licence:"[[BSD open source license (abego Software)]]",coreVersion:"2.0.7",browser:"Firefox 1.5.0.2 or better; Internet Explorer 6.0"};if(!window.abego){window.abego={};}if(!abego.setTiddlerText){abego.setTiddlerText=function(_2,_3,_4,_5,_6,_7){var _8=_2.getTiddler(_3);if(_8&&(_8.text==_4)){return;}var _9=config.options.chkForceMinorUpdate;var _a=!_8?_5:_8.tags;_2.suspendNotifications();try{_2.saveTiddler(_3,_3,_4,_9?undefined:config.options.txtUserName,_9?undefined:new Date(),_a);}finally{_2.resumeNotifications();}if(_7){_2.notify(_3,true);}if(!_6&&config.options.chkAutoSave){saveChanges();}};}(function(){var _b="PrivateSettings";var _c="chkUsePrivateSettings";var _d="chkMakeSettingPrivateWhenChanged";var _e=null;var _f=false;var _10=function(_11,s){var _13=s.split(";");var _14={};for(var c=0;c<_13.length;c++){var p=_13[c].indexOf("=");if(p!=-1){var _17=_13[c].substr(0,p).trim();var _18=_13[c].substr(p+1).trim();_11[_17]=unescape(_18);_14[_17]=true;}}return _14;};var _19=function(_1a){var s=store.getTiddlerText(_b);_e=s?_10(_1a,s):{};};var _1c=function(_1d){_10(_1d,document.cookie);};var _1e=function(){var _1f={};_1c(_1f);return _1f;};var _20=function(){var _21={};_19(_21);return _21;};var _22=function(_23,_24){document.cookie=_23+"="+escape(_24)+"; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";};var _25=function(_26,s,_28){var _29=_20();if(s===null){if(!_e[_26]){return;}delete _29[_26];delete _e[_26];}else{var _2a=_29[_26];if(_2a!==undefined&&_2a==s){return;}_29[_26]=s;_e[_26]=true;}var t="";for(var i in _29){if(t){t+="; ";}t+=i+"="+escape(_29[i]);}abego.setTiddlerText(store,_b,t,["excludeLists","excludeSearch"],_28);if(!_28&&config.options.chkAutoSave){saveChanges();}};config.shadowTiddlers["BSD open source license (abego Software)"]="See [[Licence|http://tiddlywiki.abego-software.de/#%5B%5BBSD%20open%20source%20license%5D%5D]].";config.shadowTiddlers["SettingsPlugin Documentation"]="[[Documentation on abego Software website|http://tiddlywiki.abego-software.de/#%5B%5BSettingsPlugin%20Documentation%5D%5D]].\n\n^^You may copy the documentation tiddler from the website to your TiddlyWiki.\nThen you don't need to access the internet to read the documentation.^^";config.shadowTiddlers["SettingsPlugin SourceCode"]="Rightclick this [[link|http://tiddlywiki.abego-software.de/src/Plugin-Settings-src.js]] and choose 'Save target/link as...' to get the plugin source code from the abego Software website.";config.shadowTiddlers["Show Settings"]="<<showSettings>>";if(config.options[_c]===undefined){config.options[_c]=false;}if(config.options[_d]===undefined){config.options[_d]=false;}config.shadowTiddlers.AdvancedOptions+="\n''Private Settings: ''<<option "+_c+">> Use private settings.  <<option "+_d+">> Make setting private when changed.&#160;&#160;&#160;[[Show Settings]].\n^^(Private settings are stored in this ~TiddlyWiki, shared settings are stored as cookies. For more information see the [[Settings documentation|SettingsPlugin Documentation]].)^^";abego.usePrivateSettings=function(){return _f;};abego.setUsePrivateSettings=function(f){if(f!=abego.usePrivateSettings()){_f=f;loadOptionsCookie();}};abego.isUsePrivateSettingsOption=function(_2e){return _2e==_c;};abego.makeSettingPrivateWhenChanged=function(){return config.options[_d];};abego.setMakeSettingPrivateWhenChanged=function(f){config.options[_d]=f;};abego.getSettings=function(){var _30={};_1c(_30);_f=_30[_c]=="true";if(abego.usePrivateSettings()){_19(_30);}return _30;};abego.getSetting=function(_31){var s=abego.getSettings()[_31];return !s?"":s;};abego.saveSetting=function(_33,_34){if(abego.isUsePrivateSettingsOption(_33)){_22(_33,_34);abego.setUsePrivateSettings(_34=="true");loadOptionsCookie();window.alert("You changed the 'Use private settings' option.\nPlease reload your TiddlyWiki to update the settings.\n");return;}if(abego.usePrivateSettings()&&(abego.isSettingPrivate(_33)||abego.makeSettingPrivateWhenChanged())){_25(_33,_34);}else{_22(_33,_34);}};abego.isSettingPrivate=function(_35){if(abego.isUsePrivateSettingsOption(_35)){return false;}if(!_e){_20();}return !!_e[_35];};abego.isPasswordSetting=function(_36){return (_36.substr(0,3)=="pas")||(_36.substr(0,6)=="chkpas");};abego.makeSettingPrivate=function(_37,_38,_39){if(abego.isPasswordSetting(_37)){_25(_37,null,_39);return;}var _3a=_20();var _3b=_3a[_37]!==undefined;if(_38==_3b){return;}var _3c=_1e();if(_38){_25(_37,_3c[_37],_39);}else{if(_3c[_37]===undefined){_22(_37,_3a[_37]);}_25(_37,null,_39);}};abego.setAllSettingsPrivate=function(_3d,_3e){var _3f=abego.getSettings();for(var s in _3f){abego.makeSettingPrivate(s,_3d,true);}if(config.options.chkAutoSave){saveChanges();}if(_3e){story.refreshTiddler(_3e,1,true);}return false;};})();config.macros.showSettings={label:"showSettings",prompt:"Display the current TiddlyWiki settings"};config.macros.showSettings.handler=function(_41,_42,_43,_44,_45,_46){var _47=function(a){var s=a.substr(0,3);return s=="txt"||s=="chk";};var _4a=function(a,b){var s1=a.toLowerCase();var s2=b.toLowerCase();return (s1<s2)?-1:(s1==s2)?0:1;};var _4f=function(a,b){var _52=_47(a);var _53=_47(b);if(_52){if(!_53){return -1;}else{return _4a(a.substr(3),b.substr(3));}}else{if(_53){return 1;}else{return _4a(a,b);}}};var s="<html><table><tr align=\"left\"><th>Private</th><th>Name</th><th>Value</th></tr>";var c=abego.getSettings();var _56=[];for(var i in c){if(!abego.isPasswordSetting(i)){_56.push(i);}}_56.sort(_4f);for(i=0;i<_56.length;i++){var _58=_56[i];var _59=_47(_58)?_58.substr(3)+" ("+_58.substr(0,3)+"...)":_58;var _5a=abego.isUsePrivateSettingsOption(_58)?"":"<input name=\""+_58+"\" type=\"checkbox\" onclick=\"abego.onPrivateSettingClick(this)\""+(abego.isSettingPrivate(_58)?" checked":"")+"/>";s+="<tr><td align=\"right\">"+_5a+"</td><td>"+_59+"</td><td>"+c[_58]+"</td></tr>\n";}s+="</table>";s+="<a class=\"button\" title=\"Make all current settings private\" href=\"javascript:;\" onclick=\"abego.setAllSettingsPrivate(true,'"+_46.title+"',1);\">Make all private</a>";s+="<a class=\"button\" title=\"Make all current settings shared\" href=\"javascript:;\" onclick=\"abego.setAllSettingsPrivate(false,'"+_46.title+"',1);\">Make all shared</a>";s+="</html>";wikify(s,_41);};abego.onPrivateSettingClick=function(_5b){abego.makeSettingPrivate(_5b.name,_5b.checked);return false;};this.loadOptionsCookie=function(){if(safeMode){return;}var _5c=abego.getSettings();for(var _5d in _5c){var _5e=_5c[_5d];switch(_5d.substr(0,3)){case "txt":config.options[_5d]=unescape(_5e);break;case "chk":config.options[_5d]=_5e=="true";break;}}};this.saveOptionCookie=function(_5f){if(safeMode){return;}var v="";switch(_5f.substr(0,3)){case "txt":v=config.options[_5f].toString();break;case "chk":v=config.options[_5f]?"true":"false";break;}abego.saveSetting(_5f,v);};loadOptionsCookie();}
// %/

!Description
By default the settings that you can change in the [[options|OptionsPanel]] panel and the [[AdvancedOptions]] are shared by all ~TiddlyWikis of the same site.

This also means that all your local ~TiddlyWikis share the same settings. This is not always what you want, especially when you are working with multiple local ~TiddlyWikis at once.

The SettingsPlugin allows you to decide "per setting" if a setting should be shared by all ~TiddlyWikis or if a setting should be "private" to a given ~TiddlyWiki. Alternatively you may also decide that all settings should be private to a given ~TiddlyWiki.

''Using Private Settings''

By default all settings are "shared", i.e. the settings behave in their standard way. To enable the "private settings" feature check the "Use private settings" checkbox in the AdvancedOptions.

Once private settings are enabled you have two options:
* All changes to settings should be "private", i.e. don't affect other ~TiddlyWikis. Therefore check the "Make setting private when changed" checkbox in the AdvancedOptions.
* Individual settings should be private. You can specify the settings in the [[Show Settings]] tiddler. Here you can also make all settings shared or private, with one click. The [[Show Settings]] tiddler can be accessed through the AdvancedOptions.

You can decide what settings should be private or shared individually for every ~TiddlyWiki.

You may temporarily switch off "Use private settings". Then your private settings will not be used. When you switch on again "Use Private Settings", your decision what settings should be private or shared and also the private values will be remembered.

''How Settings are Stored''

As in the original ~TiddlyWiki code shared settings/options are stored as "cookies" with your browser.
Private settings are stored in a tiddler of the ~TiddlyWiki. You need to ensure that the ~TiddlyWiki can be saved when you want to keep your private settings.


!Revision history
* v1.1.0
** Support Internet Explorer
** Don't save password options ("pas..."/"chkpas...") as private settings, and don't display them in the showSettings. Thanks to BidiX for the implementation.
** Bugfix: Invalid syntax HTML stmt for the "private" settings checkboxes. Thanks to BidiX for the fix.
* v1.0.2
** Bugfix: corrected "suspendNotification" bug. Thanks to Jack, BobEverson and MorrisGray for reporting.
* v1.0.1
** Bugfix: Corrected wrong comment in compressed version of plugin.
** Internal: Simplified "saveTiddler" code. Thanks to Jeremy Ruston for the suggestion.
* v1.0.0 (2006-04-03)
** initial version


!Code
The SettingsPlugin SourceCode contains compressed source code. You will find the full source code [[here|SettingsPlugin SourceCode]].
For SettingsPlugin source code see the [[archive|http://tiddlywiki.abego-software.de/archive]].
{{{
<<forEachTiddler
 where
 'tiddler.title.contains("it")'
 write
 '"|[["+tiddler.title+"]]|"+tiddler.tags+"|\n"'
>>
}}}

//''Explaination:''//

The interesting part of this task is the creation of the table.

The idea here is to "write" the same stuff that you would write manually in a tiddler to generate such a table. For every tiddler you would write:
|{{{|[[}}}//titleOfTiddler//{{{]]|}}}//tagsOfTiddler//{{{|}}}|

Instead of typing the title and looking up the tags you can just ask the [[ForEachTiddlerMacro]] to do the job:
* instead of //titleOfTiddler// you write {{{tiddler.title}}}
* instead of //tagsOfTiddler// you write {{{tiddler.tags}}}

You now need to create a JavaScript expression to build the complete line together:
* The constant parts ({{{|[[}}}, {{{]]|}}} and {{{|}}}) must be quoted:{{{"|[["}}}, {{{"]]|"}}} and {{{"|"}}}
* The part are all concatenated to one long string.
* At the end we need a "newline" character ("\n") to start the next tiddler in a new line.

This all ends up in: {{{"|[["+tiddler.title+"]]|"+tiddler.tags+"|\n"}}}.

//''Result:''//
<<forEachTiddler
 where
 'tiddler.title.contains("it")'
 write
 '"|[["+tiddler.title+"]]|"+tiddler.tags+"|\n"'
>>

See also ForEachTiddlerExamples.
The idea is to use the {{{<<tiddler ... >>}}} macro to include the contents. I.e. we would write something like:
{{{
<<forEachTiddler ... write ..."<<tiddler ...>>" ...>>
}}}
The problem is that TiddlyWiki takes the first ">>" after a macro as the macro's end. I.e. it processes a macro that looks like this:
{{{
<<forEachTiddler ... write ..."<<tiddler ...>>
}}}
This leads to an error.

To avoid this we escape the {{{>>}}} of the inner macro with the string {{{$))}}}:
{{{
<<forEachTiddler
 where
 'tiddler.title.startsWith("Site")'
 write
 '"----\n<<tiddler [["+tiddler.title+"]]$))\n"'
>>
}}}
//(Also adds a separator line before every tiddler)//

This way the correct end of the macro is detected and we get the following

''//Result://''
<<forEachTiddler
 where
 'tiddler.title.startsWith("Site")'
 write
 '"----\n<<tiddler [["+tiddler.title+"]]$))\n"'
>>

See also [[ForEachTiddlerExamples]].
<<closeAll>><<permaview>><<newTiddler>><<newJournal 'DD MMM YYYY'>><<newTiddlerWithForm BugReportTemplate "new bugreport">><<saveChanges>><script>
var onClick = function() {
story.closeAllTiddlers();
restart();
// displayTiddler(null,'About',1,null,null,false,false);
}
createTiddlyButton(place,"reset","Reset (Shortcut: Alt-T)",onClick, null, null, "T");
</script><script>var btn = createTiddlyButton(place,"configuration","Configure this TiddlyWiki",onClickTiddlerLink,"button");btn.setAttribute("tiddlyLink","Configuration");</script><<slider chkSliderOptionsPanel OptionsPanel 'options »' 'Change TiddlyWiki advanced options'>>
<<formTiddler SimpleFormTemplate>><data>{"userName":"AliceInWonder","pwd":"abcd"}</data>
<<formTiddler SimpleFormTemplate>><data>{"userName":"Bob","pwd":"1234"}</data>
<<formTiddler SimpleFormTemplate>><data>{"userName":"Cedric","pwd":"4321"}</data>
<html>
 <sub><b>Name:</b></sub><br/>
 <input name=userName type=text /><br/>
 <sub><b>Password:</b></sub><br/>
 <input name=pwd type=password /><br/>
</html>
[[Card 1|SimpleForm (Card 1)]] - [[Card 2|SimpleForm (Card 2)]] - [[Card 3|SimpleForm (Card 3)]]

~~(This is an example form, using the form template SimpleFormTemplate and the FormTiddlerPlugin.)~~
UdoBorkowski's Extensions for [[TiddlyWiki]]
abegoExtensions
http://tiddlywiki.abego-software.de
When using TiddlyWiki 2.0+ you may refer to the date a tiddler was created through the "created" property:
* [[Sort Tiddlers by 'Create' Date (TiddlyWiki 2.0+)]]

Tiddler's prior to TiddlyWiki 2.0 don't include a "Create" date by default. But you may use plugins to add this functionality. Depending on the plugin your ForEachTiddlerMacro call will differ.
* [[Sort Tiddlers by 'Create' Date (CreationTimePlugin version)]]
* [[Sort Tiddlers by 'Create' Date (AutoTaggerPlugin version)]]
''Note:'' TiddlyWiki 2.0+ directly supports the "created" property, i.e. you don't need a separate plugin (see also [[Sort Tiddlers by 'Create' Date]]).

If you use EricShulman's plugin [[AutoTaggerPlugin|http://www.TiddlyTools.com/#AutoTaggerPlugin]] to add a create date to you tiddlers you can use the following ForEachTiddlerMacro call to get a list sorted by create date:
{{{
<<forEachTiddler
 where
 'getCreateDate(tiddler) != null'
 sortBy
 'getCreateDate(tiddler)'
>>
}}}
//(Only includes the tiddlers that really have a create date.)//

If you want to have the newest tiddlers listed first just add a 'descending' to the sortClause.

To make this work you need to add the [[getCreateDate Function]] tiddler (with a 'systemConfig' tag) to your TiddlyWiki.

//Result://
<<forEachTiddler
 where
 'getCreateDate(tiddler) != null'
 sortBy
 'getCreateDate(tiddler)'
>>

See also [[Sort Tiddlers by 'Create' Date]].
''Note:'' TiddlyWiki 2.0+ directly supports the "created" property, i.e. you don't need a separate plugin (see also [[Sort Tiddlers by 'Create' Date]]).

If you use HustonFranklin's plugin [[CreationTimePlugin|http://franklin.ro/tw/HackingTW.html#%5B%5BCreation%20Time%5D%5D]] to add a create date to you tiddlers you can use the following ForEachTiddlerMacro call to get a list sorted by create date (newest tiddlers first).

{{{
<<forEachTiddler
 where
 'tiddler.created'
 sortBy
 'tiddler.created'
 descending
>>
}}}
//(Only includes the tiddlers that really have a create date.)//

If you want to have the oldest tiddlers listed first just remove the 'descending' from the sortClause.

//Result://
<<forEachTiddler
 where
 'tiddler.created'
 sortBy
 'tiddler.created'
 descending
>>
When using TiddlyWiki 2.0+ you may refer to the date a tiddler was created through the "created" property:
{{{
<<forEachTiddler
 where
 'tiddler.created'
 sortBy
 'tiddler.created'
 descending
>>
}}}

If you want to have the oldest tiddlers listed first just remove the 'descending' from the sortClause.

//Result://
<<forEachTiddler
 where
 'tiddler.created'
 sortBy
 'tiddler.created'
 descending
>>

See also [[Sort Tiddlers by 'Create' Date]].
The items in the YourSearch result list are displayed in a "ranked" order, i.e. the best matches are listed first.

If you want any other ordering (e.g. sort by date) you need to make the function {{{abego.YourSearch.getRankFunction()}}} return a different rank function {{{function(tiddler, lastQuery)}}}. The number returned by the rankFunction defines the position of the given tiddler in the result. Higher numbers are displayed first. Tiddlers with same rank numbers are sorted by their titles (case sensitive).

! Example: Sort by title
As tiddlers with the same rank number are sorted by their title you may use the following simple script to get the YourSearch result alphabetically sorted:
{{{
<script>
var myZeroRankFunction = function(tiddler, lastQuery) {
    return 0;
};

abego.YourSearch.getRankFunction = function() {
    return myZeroRankFunction;
}
</script>
}}}

! Example: Sort by date
For a "sort by last modified date" ordering you may use this script:
{{{
<script>
var myDateRankFunction = function(tiddler, lastQuery) {
    return tiddler.modified.getTime();
};

abego.YourSearch.getRankFunction = function() {
    return myDateRankFunction;
}
</script>
}}}

! Use the Standard Ordering
To switch back to the standard ordering you may use this code use:
{{{
<script>
abego.YourSearch.getRankFunction = abego.YourSearch.getStandardRankFunction;
</script>
}}}
//(Note: there are no {{{()}}} behind the {{{abego.YourSearch.getStandardRankFunction}}})//

! Switch between "Standard" and "By Date" Ordering
With just some few lines more you can use a checkbox to switch between "standard" and "by date" sorting.

To define the checkbox add a line like the following in a tiddler (e.g. in AdvancedOptions):
{{{
<<option chkYourSearchSortByDate>> Sort 'Your Search' result by Date
}}}
<<option chkYourSearchSortByDate>> Sort 'Your Search' result by Date
(Clicking the checkbox will affect the next query you type).

And here the script that adjusts the ranking/sorting:
{{{
<script>
var myDateRankFunction = function(tiddler, lastQuery) {
    return tiddler.modified.getTime();
};

abego.YourSearch.getRankFunction = function() {
return config.options.chkYourSearchSortByDate
        ? myDateRankFunction
         : abego.YourSearch.getStandardRankFunction();
}
</script>
}}}
Here are some examples that show the usage of the sortClause in the ForEachTiddlerMacro.

<<forEachTiddler
 where
 'tiddler.tags.contains("sortClauseExample")'
>>
See also ForEachTiddlerExamples.
/***
!Colors Used
*@@bgcolor(#ffb200): #ffb200 - Primary Color@@
*@@bgcolor(#ffcc66): #ffcc66 - Primary Color Light@@
*@@bgcolor(#ff8000): #ff8000- Primary Color Bright@@
*@@bgcolor(#b75b00): #b75b00 - Primary Color Dark@@
*@@bgcolor(#666666): #666666 - Text Color Light@@
*@@bgcolor(#703):color(#fff): #703 - Title Color @@
***/
/*{{{*/
.header {
	background: #ffb200;
}
.headerForeground {
	color: #000;
}
.headerForeground a {
	color: #000;
}

a {
	color: #666666;
}

a:hover{
	color: #666666;
}

#sidebarOptions input {
	border: 1px solid #ff8000;
}

#sidebarOptions .sliderPanel {
	background: #ffcc66;
}

#sidebarOptions .sliderPanel a {
	color: #b75b00;
}

#sidebarOptions .sliderPanel a:hover {
	color: #ff8000;
}

#sidebarOptions .sliderPanel a:active {
	color: #ff8000;
	background: #fff;
}
h1,h2,h3,h4,h5 {
	margin-top: 1em;
	color: #703;
	background: #ffcc66;
}

/*}}}*/
/***
!Other Styling
***/
/*{{{*/
.headerForeground {
	position:relative;
	padding:0.3em 0em 1em 1em;
	left:-1px; top:-1px;
}

.headerForeground table {
	width: 100%;
}

a {
	font-family: Arial, Helvetica, sans-serif;
	text-decoration: none;
}

a:hover{
	text-decoration: underline;
	background: none;
}

.button:hover {
	text-decoration: none;
}

.abegoLink .externalLink {
	font-weight: bold;
	text-decoration: none;
}

.abegoLink .externalLink:hover {
	font-weight: bold;
	text-decoration: underline;
}

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

#sidebarOptions .sliderPanel a {
	color: #b75b00;
}

#sidebarOptions .sliderPanel a:hover {
	background:none;
}
.optionsBlock {
	padding: 0.5em;
	margin-left: 0.5em;
	overflow: auto;
	border: 1px solid #b75b00;
}
.txtOptionInput {width:30em;}

/*}}}*/
/***
|''Name:''|SyncFileTiddlerPlugin|
|''Summary:''|Automatically synchronizes the text of a tiddler with the content of an associated text file.|
|''Version:''|1.0.0 (2012-04-16)|
|''Source:''|http://tiddlywiki.abego-software.de/#SyncFileTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2012 [[abego Software|http://www.abego-software.de]]|
!About SyncFileTiddler
SyncFileTiddler automatically synchronizes the text of a tiddler with the content of an associated text file.

The tiddlers to be synched are specified in a table in the tiddler SyncFileTiddlers. A table entry looks like this:
{{{
|SomeTiddler|path/To/File.txt|readonly|
}}}
This will be rendered as:
|SomeTiddler|path/To/File.txt|readonly|
When the "readonly" parameter is missing the tiddler is editable. Changes to the tiddler's text will be written to the associated file.
When "readonly" is specified the tiddler is not editable in the TiddlyWiki, but changes in the associated file will also change the tiddler's text accordingly.
The file is regularily read ("polled") to verify if its text has changed.

The tags of the tiddler can only be specified in the TiddlyWiki. The file will not affect the tags.
!Revision history
* SyncFileTiddlerPlugin 1.0.0 (2012-04-16)
** initial version
!Source Code
***/
//{{{
var abego = abego || {};

(function(namespace) {
	var entries = {};

	var errorMsg = function(s) {
		throw "SyncFileTiddler: " + s;
	};

	var save = function(filepath, s) {
		var b = saveFile(filepath, s);
		if (!b) {
			throw errorMsg("file could not be saved: " + filepath);
		}
		return s;
	};

	var createTiddler = function(title, text) {
		var t = store.createTiddler(title);
		t.text = text;
		return text;
	};

	var getTiddlerText = function(title) {
		return store.getTiddlerText(title, null);
	};

	var setTiddlerText = function(title, text) {
		var t = store.fetchTiddler(title);
		store.saveTiddler(title, title, text, "SyncFileTiddler ("
				+ config.options.txtUserName + ")", new Date(), t.fields.tags);
		return text;
	};

	/**
	 * FIXME: also implement the "delete" case, i.e. delete the "Slave" when the
	 * "Master" is missing (need a deleteFile method first). (? What about
	 * losing tags when deleting the tiddler after a file delete?)
	 *
	 * @param oldFileContent
	 *            [nullable] when not null it holds the content of the file as
	 *            it was loaded "some time ago". Before the method overwrites
	 *            the file it checks if the file still has the oldFileContent.
	 *            If the file's current content differs from the oldFileContent,
	 *            the file was modified "from the outside". Then we have a sync
	 *            conflict and the method fails.
	 * @param fileIsMaster
	 *            when true the file is the Master, i.e. the tiddler should get
	 *            the file's content. When false the file should get the
	 *            tiddler's content. When undefined the function should try to
	 *            find out what is the Master.
	 * @return [nullable] the text/content of the Tiddler/File, or null if
	 *         neither Tiddler nor File exists
	 */
	var syncTiddlerAndFile = function(tiddler, filepath, oldFileContent,
			fileIsMaster) {
		var tiddlerContent = getTiddlerText(tiddler);
		var fileContent = loadFile(filepath);

		if (fileContent) {
			fileContent = fileContent.replace(/\r\n/g,'\n');

			if (tiddlerContent) {
				// both file and tiddler exist.

				if (fileContent == tiddlerContent) {
					// both file and tiddler are equal
					return fileContent;

				} else {
					// file and tiddler differ.
					if (fileIsMaster === undefined) {
						// No Master is explicitly defined.
						throw errorMsg("tiddler and file have different content (delete the 'old' one to fix this):\n"
								+ tiddler + "\n" + filepath);

					} else if (fileIsMaster) {
						// the file is the master, i.e. the tiddler gets the
						// file's content
						return setTiddlerText(tiddler, fileContent);

					} else {
						// the tiddler is the master, i.e. the file gets the
						// tiddler's text

						// But first check if the file was not modified in the
						// meantime
						if (oldFileContent && oldFileContent != fileContent) {
							throw errorMsg("The file was modified externally: "
									+ filepath);
						}
						return save(filepath, tiddlerContent);
					}
				}
			} else {
				// file exists, but no tiddler.

				// Create a new tiddler with the fileContent
				return createTiddler(tiddler, fileContent);
			}
		} else {
			if (tiddlerContent) {
				// tiddler exists, but no file.

				// create a file with the tiddler's content
				return save(filepath, tiddlerContent);
			} else {
				// Neither tiddler nor file exists.

				// do nothing
				return null;
			}
		}
	};

	var syncEntry = function(entry, fileIsMaster, ignoreOldFileContent) {
		if (entry.readonly && !fileIsMaster) {
			return false;
		}

		entry.oldFileContent = syncTiddlerAndFile(entry.tiddler,
				entry.filepath, ignoreOldFileContent ? null
						: entry.oldFileContent, fileIsMaster);
		return true;
	};

	var saveAsFile = function(tiddler) {
		var e = entries[tiddler];
		if (e) {
			var s = getTiddlerText(tiddler);
			save(e.filepath, s);
			e.oldFileContent = s;
		}
	};

	// When a tiddler is saved and it is a "SyncFileTiddler" the corresponding
	// file is updated.
	var oldSaveTiddler = TiddlyWiki.prototype.saveTiddler;
	TiddlyWiki.prototype.saveTiddler = function(title, newTitle) {
		var result = oldSaveTiddler.apply(this, arguments);

		try {
			// "Sync" the tiddler with its file, with the tiddler being the
			// Master.
			// (Will do nothing if the tiddler is not a "SyncFileTiddler")
			SyncFileTiddler.syncTiddler(newTitle, false);
		} catch (e) {
			if (confirm("The file to sync with was modified externally.\n\n"
					+ "Press OK to overwrite anyway.\n"
					+ "Press Cancel to keep file unchanged.")) {
				saveAsFile(newTitle);
			} else if (confirm("Use the file's content as the tiddler text?")) {
				syncEntry(entries[newTitle], true);
			}
		}
		return result;
	};

	// The tiddler must be readonly when its "sync" entry is readonly
	var oldIsReadOnly = Tiddler.prototype.isReadOnly;

	Tiddler.prototype.isReadOnly = function() {
		if (oldIsReadOnly.apply(this, arguments)) {
			return true;
		}
		var e = entries[this.title];
		return e && e.readonly;
	}

	var pauseBetweenFilePolls = 2000;
	var polling = false;
	var pollFileChanges = function() {
		if (polling) {
			SyncFileTiddler.syncAll(true);

			// schedule the next time to poll for file changes
			setTimeout(pollFileChanges, pauseBetweenFilePolls);
		}
	};

	var SyncFileTiddler = {

		/**
		 * The tiddler is registered to be "synched" with the file.
		 *
		 * If a tiddler is added more than once the last file specified is used.
		 *
		 * @param tiddler
		 *            title of the tiddler to register
		 * @param filepath
		 *            path to the file to associate with the tiddler.
		 */
		add : function(tiddler, filepath, readonly) {
			if (!filepath.startsWith("/")) {
				// a path relative to the document
				var docPath = document.URL;
				if (!docPath.startsWith("file://"))
					return;
				var p = docPath.substring(7, docPath.lastIndexOf("/") + 1);
				filepath = p + filepath;
			}

			entries[tiddler] = {
				tiddler : tiddler,
				filepath : filepath,
				readonly : readonly,
				oldFileContent : syncTiddlerAndFile(tiddler, filepath, null,
						true),
			};
		},

		/**
		 * "Syncs" the tiddler with its file.
		 *
		 * Will do nothing when the tiddler is not a "FileSyncTiddler" (i.e. was
		 * not registered using add)
		 */
		syncTiddler : function(tiddler, fileIsMaster) {
			var e = entries[tiddler];
			if (e) {
				syncEntry(e, fileIsMaster);
				autoSaveChanges(true);
				return true;
			} else {
				return false;
			}
		},

		syncAll : function(fileIsMaster) {
			for ( var e in entries) {
				syncEntry(entries[e], fileIsMaster);
			}
			autoSaveChanges(true);
		},

		setPolling : function(b) {
			if (b == polling)
				return;

			polling = b;
			if (polling) {
				// start polling
				pollFileChanges();
			}
		},

		isPolling : function() {
			return polling;
		},

		setPauseBetweenFilePolls : function(millis) {
			pauseBetweenFilePolls = millis;
		},

		getPauseBetweenFilePolls : function() {
			return pauseBetweenFilePolls;
		},

		addSyncFileTiddlers : function() {
			var s = store.getTiddlerText("SyncFileTiddlers");
			if (!s)
				return;

			var lines = s.split("\n");
			for ( var i = 0; i < lines.length; i++) {
				var line = lines[i];
				var a = line.split('\|');
				if (a.length >= 3) {
					var tiddler = a[1];
					var filepath = a[2];
					var readonly = a.length >= 4 && a[3]=="readonly";
					SyncFileTiddler.add(tiddler, filepath,readonly);
				}
			}
		}
	};

	namespace.SyncFileTiddler = SyncFileTiddler;

})(abego);

setTimeout(function() {
	abego.SyncFileTiddler.addSyncFileTiddlers();
	abego.SyncFileTiddler.setPolling(true);
},1);
//}}}
|DataTiddlerPlugin|archive/DataTiddlerPlugin/latest/DataTiddlerPlugin.js|readonly|
|ForEachTiddlerPlugin|archive/ForEachTiddlerPlugin/latest/ForEachTiddlerPlugin.js|readonly|
|FormTiddlerPlugin|archive/FormTiddlerPlugin/latest/FormTiddlerPlugin.js|readonly|
|IncludePlugin|archive/IncludePlugin/latest/IncludePlugin.js|readonly|
|IntelliTaggerPlugin|archive/IntelliTaggerPlugin/latest/IntelliTaggerPlugin.js|readonly|
|PartTiddlerPlugin|archive/PartTiddlerPlugin/latest/PartTiddlerPlugin.js|readonly|
|SettingsPlugin|archive/SettingsPlugin/latest/SettingsPlugin.js|readonly|
|TiddlerWithParamsPlugin|archive/TiddlerWithParamsPlugin/latest/TiddlerWithParamsPlugin.js|readonly|
|XHTML10Plugin|archive/XHTML10Plugin/latest/XHTML10Plugin.js|readonly|
|YourSearchPlugin|archive/YourSearchPlugin/latest/YourSearchPlugin.js|readonly|

Content of Tab 1
Content of Tab 2
Content of Tab 3





Type the text for 'New Tiddler'

Include the tiddlers of an external TiddlyWiki into the current TiddlyWiki.

''Syntax''
|>|{{{<<}}}''include'' [''url:''] //tiddlyWikiPath// [''delay:'' //delayDuration//] [''hide:'' //hideFlag//]{{{>>}}}|
|//tiddlyWikiPath//|The path to the TiddlyWiki to include.<<br>>This may be a relative path, an absolute local file path, or a "file:", "http:" or "https:" URL)|
|//delayDuration//|Integer. Defines the number of milliseconds (thousands of a second) to wait before actually including the TiddlyWiki. By default a TiddlyWiki is included immediately when the TiddlyWiki starts.|
|//hideFlag//|When "{{{true}}}" the "include" macro is not displayed in the tiddler.|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

''Examples''
{{{
<<include "http://tiddlywiki.abego-software.de/index.html">>
<<include "C:\TiddlyWiki\shared\TiddlyWikiHelp.html">>
<<include "file://C:/Private/journals/2006-12.html" delay: 8000 >>
<<include "test/sample33.html">>
}}}

''Notes''
* For security reasons it may not be possible to include some TiddlyWikis. Especially you cannot access a TiddlyWiki on a different website when running your TiddlyWiki on your webserver (the so-called "Cross-Site Scripting" issue). Nevertheless you can access TiddlyWikis on various websites if you are running your TiddlyWiki locally. And you may refer to other Wikis on your own site.
* The macro may be placed in any tiddler, but it is recommended to put them into the "IncludeList" tiddler. The includes listed in the "IncludeList" are processed at TiddlyWiki startup. An include defined in a different tiddler are processed the first time the tiddler is displayed. The order the include macros are processed is used when [[looking for a tiddler|How Tiddlers are found]].
Displays the list of "included" TiddlyWikis, together with their "load state". I.e. you can see if the TiddlyWiki is already loaded (include), if there was an error (e.g. the TiddlyWiki to include was not found) etc.

''Syntax:''
|>|{{{<<}}}''includeState''{{{>>}}}|

The TiddlyWikis are listed in the order they are checked for tiddlers (see [[How Tiddlers are found]])

The (shadow) tiddler "IncludeState" contains this macro, i.e. you can view that tiddler to see the current include state.

See also: [[The "include" Macro]].
/***
|''Name:''|TiddlerWithParamsPlugin|
|''Version:''|1.0.1 (2006-03-22)|
|''Source:''|http://tiddlywiki.abego-software.de/#TiddlerWithParamsPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
!Description

The TiddlerWithParamsPlugin extends the build-in {{{<<tiddler...>>}}} macro. It replaces placeholders ($1, $2, ...) in the given tiddler by values passed with the macro. Then it inserts the (replaced) text, just like the original {{{<<tiddler...>>}}} macro.

''Syntax:''
|>|{{{<<}}}''tiddler '' //tiddlerName// [//className//] [''asText''] [''with:'' //arguments// ] [''prefix:'' //prefixString//] {{{>>}}}|
|//tiddlerName//|The name of the tiddler to be included. The tiddler may contain placeholders ($1, $2, ... $9) that will be replaced with the values passed with the macro|
|//className//|The (CSS) class to be used around the embedded tiddler|
|''asText''|When defined the (replaced) content of the tiddler is inserted as pure text, i.e. it is not "wikified".|
|//arguments//|up to 9 arguments may be passed to the macro, used as the values for the placeholders $1, $2, ... $9 in the referenced template|
|//prefixString//|By default the placeholders $1, $2, $3,..., $9 are used. But you may change the "prefix" before the placeholder number ("$") to some other text through the "prefix:" option. This may be necessary when you are using the $n in the tiddler you are referencing (e.g. when you are using regular expressions).|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. ~~|

!Example

The following ''//ProjectTemplate//'' tiddler defines an "Overview" page for a project, that gives access to various "sub-tiddlers" used in the project, that follow a static naming schema (e.g. all Notes for any project are stored in a tiddler called "//projectName// Notes"). $1 holds the name of the Project (e.g. "ForEachTiddler"), $2 holds the type of the published component (e.g. "Plugin", "Macro", "Function").
{{{
![[$1Project]] Overview
* [[$1$2]]
* [[ToDo|$1 ToDos]]
* [[Notes|$1 Notes]]
* [[Examples|$1Examples]]
* [[Tests|$1 Tests]]
* [[Open Bugs/CRs|$1 Open Bugs and ChangeRequests]]
}}}

This template is now used in the ''//ForEachTiddlerProject//'' tiddler:
{{{
<<tiddler ProjectTemplate with: ForEachTiddler Plugin>>
}}}

This results in the following tiddler text for the ''//ForEachTiddlerProject//'' tiddler:
{{{
![[ForEachTiddlerProject]] Overview
* [[ForEachTiddlerPlugin]]
* [[ToDo|ForEachTiddler ToDos]]
* [[Notes|ForEachTiddler Notes]]
* [[Examples|ForEachTiddlerExamples]]
* [[Tests|ForEachTiddler Tests]]
* [[Open Bugs/CRs|ForEachTiddler Open Bugs and ChangeRequests]]
}}}

!Revision history
* v1.0.0 (2006-01-20)
** initial version
* v1.0.1 (2006-03-22)
** Added 'asText' option
** Support Safari (Thanks to Elise Springer for reporting the problem)
!Code
***/
//{{{
//============================================================================
// TiddlerWithParamsPlugin
//============================================================================

// Ensure that the Plugin is only installed once.
//
if (!version.extensions.TiddlerWithParamsPlugin) {

version.extensions.TiddlerWithParamsPlugin = {
	major: 1, minor: 0, revision: 1,
	date: new Date(2006,3,22),
	type: 'plugin',
	source: "http://tiddlywiki.abego-software.de/#TiddlerWithParamsPlugin"
};

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

var indexInArray = function(array, item) {
	for (var i = 0; i < array.length; i++) {
		if (array[i] == item) {
			return i;
		}
	}
	return -1;
}

var myEscapeRegExp = function(s)
{
	// The original escapeRegExp function does not work with Safari (2.0.3)
	// since the $& is not implemented.
var t = s.replace(/\\/g, "\\\\");
	t = t.replace(/\^/g, "\\^");
	t = t.replace(/\$/g, "\\$");
	t = t.replace(/\*/g, "\\*");
	t = t.replace(/\+/g, "\\+");
	t = t.replace(/\?/g, "\\?");
	t = t.replace(/\(/g, "\\(");
	t = t.replace(/\)/g, "\\)");
	t = t.replace(/\=/g, "\\=");
	t = t.replace(/\!/g, "\\!");
	t = t.replace(/\|/g, "\\|");
	t = t.replace(/\,/g, "\\,");
	t = t.replace(/\{/g, "\\{");
	t = t.replace(/\}/g, "\\}");
	t = t.replace(/\[/g, "\\[");
	t = t.replace(/\]/g, "\\]");
	t = t.replace(/\./g, "\\.");

    return t;
}

// ---------------------------------------------------------------------------
// The (hijacked) tiddler Macro Handler
// ---------------------------------------------------------------------------

config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {

	var className = null;
	var argsStart = -1;
	var doWikify = true;

	var iParams = 1;
	if (params[iParams] != "asText" && params[iParams] != "with:") {
		className = params[iParams++];
	}
	if (params[iParams] == "asText") {
		iParams++;
		doWikify = false;
	}
	if (params[iParams] == "with:") {
		iParams++;
		argsStart = iParams;
	}

	var wrapper = createTiddlyElement(place,"span",null,className ? className : null,null);
	var text = store.getTiddlerText(params[0]);
	if(text) {
		// Check for recursion
		var tiddlerName = params[0];
		var stack = config.macros.tiddler.tiddlerStack;
		if (stack.find(tiddlerName) !== null) return;

		if (argsStart >= 0) {
			// The params between the "with:" and the "prefix:" (or the end) are the arguments,
			// The param behind the "prefix:" is the prefix before the placeholder numbers.
			var argsEnd = params.length;
			var prefix = "$";
			var prefixIndex = indexInArray(params, "prefix:");
			if (prefixIndex >= argsStart) {
				argsEnd = prefixIndex;
				if (prefixIndex < (params.length-1)) {
					prefix = params[prefixIndex+1];
				}
			}
			// to avoid any "special RE chars" problems with the prefix string escape all chars.
			prefix = myEscapeRegExp(prefix);

			var args = params.slice(argsStart, argsEnd);
			var n = Math.min(args.length, 9);
			for (var i = 0; i < n; i++) {
				var value = args[i];

				var placeholderRE = new RegExp(prefix+(i+1),"mg");
				text = text.replace(placeholderRE, value);
			}
		}
		stack.push(tiddlerName);
		try {
			if (doWikify) {
				wikify(text,wrapper,null,store.getTiddler(params[0]));
			} else {
				wrapper.appendChild(document.createTextNode(text));
			}
		} finally {
			stack.pop();
		}
	}
}
config.macros.tiddler.tiddlerStack = [];

// End of "install only once"
}

//============================================================================
// End of TiddlerWithParamsPlugin
//============================================================================
//}}}
/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2006 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/
A standalone wiki that stores it data in a single HTML file and requires just ~JavaScript and a web browser to run.

For more information visit http://www.tiddlywiki.com/.
see TiddlyWiki
If you have problems running the IncludePlugin you may try this:
* Have a look at the PluginManager if the IncludePlugin is installed correctly.
* If the IncludePlugin is installed correctly go to the AdvancedOptions and look for the checkbox "Include TiddlyWikis". This must be checked.
* If "Include TiddlyWikis" is checked click on the IncludeState link next to the checkbox. This reports problems related to every included TiddlyWiki.
* Be aware only TiddlyWikis listed in the IncludeList of the "main" TiddlyWiki are included. Any IncludeList of included TiddlyWikis is ignored (i.e. the IncludePlugin does not work "recursively".)
* Running IncludePlugin in the Opera or Chrome browser is not officially supported, but people report it also works fine with these browsers. However you may need to "allow file access" through browser specific options, e.g. {{{opera:config#UserPrefs|AllowFileXMLHttpRequest}}} for Opera, and {{{--allow-file-access-from-files}}} for Chrome. For details see: http://groups.google.com/group/tiddlywiki/browse_thread/thread/392be3c984a1fb33
Udo Borkowski (email: ub [at] abego-software [dot] de)
<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler editIncludedTiddler intelliTagsEdit permalink references jump'></div>
<div class='title' macro='view title'></div>
<div class='subtitle' macro='view includeURL'></div>
<!-- <div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date [[DD MMM YYYY]]'></span> (created <span macro='view created date [[DD MMM YYYY]]'></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>
Here are some examples that show the usage of the whereClause in the ForEachTiddlerMacro.

<<forEachTiddler
 where
 'tiddler.tags.contains("whereClauseExample")'
>>

See also ForEachTiddlerExamples.
''//The {{{write}}} action//''

''Syntax''
|''write'' //stringExpression//<<br>><html>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</html>[''begin'' //stringExpression//]<<br>><html>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</html>[''end'' //stringExpression//]<<br>><html>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</html>[''none'' //stringExpression//] <<br>><html>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</html>[''toFile'' //filepath//<<br>><html>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</html>[''withLineSeparator'' //stringExpression// ] ] |

The {{{write}}} action of the ForEachTiddlerMacro has a parameter that is a (quoted) JavaScript String expression. <<tiddler [[JavaScript in actionParameters]]>>

The first expression is evaluated for every selected tiddler and the results are concatenated to a text (the "result text").

When a ''begin'' expression is given that text is written before the first tiddler output. When an ''end'' expression is given that text is written after the last tiddler output. When a ''none'' expression is given and no tiddler is found that text is written.

When a "toFile" is specified the result text is written to the given file. In that case one may also specify a "line separator" (through the {{{withLineSeparator}}} option) that is used instead of every "\n" that appears in the result text.

When no "toFile" is specified the result text is inserted in the tiddler at the location of the ForEachTiddlerMacro (similar to the {{{<<tiddler ...>>}}} macro. So if you write expressions resulting in "{{{| ... | ... |}}}" you will see a table, when you write "{{{[img[...]]}}} you see the image etc. .

Also see [[WriteActionExamples]], e.g. for how to create tables or "embed" the content of a list of tiddlers in another tiddler using the {{{write}}} action.
Here are some examples that show the usage of the write action in the ForEachTiddlerMacro.

<<forEachTiddler
 where
 'tiddler.tags.contains("writeActionExample")'
>>
See also ForEachTiddlerExamples.
/***
|''Name:''|XHTML10Plugin|
|''Version:''|1.0.1 (2006-09-16)|
|''Source:''|http://tiddlywiki.abego-software.de/#XHTML10Plugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2005-2006 [[abego Software|http://www.abego-software.de]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 1.5.0.2 or better; Internet Explorer 6.0|

Make your ~TiddlyWiki XHTML 1.0 compliant format.

Once the plugin is installed the existing tiddlers of that TiddlyWiki are automatically converted to the new (XHTML 1.0 compliant) format on the first save. After that all changes are stored in the XHTML format.

!Source Code
***/
//{{{
// Ensure the Plugin is only installed once.
//
if (!version.extensions.XHTML10Plugin) {

if (version.major < 2 || (version.major == 2 && version.minor < 1)) {
	(function() {
		var s = "Use TiddlyWiki 2.1 or better to run the XHTML10Plugin.";
		alert(s);
		throw s;
	})();
}

version.extensions.XHTML10Plugin = {
	major: 1, minor: 0, revision: 1,
	date: new Date(2006, 8, 16),
	source: "http://tiddlywiki.abego-software.de/#XHTML10Plugin",
	licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
	copyright: "Copyright (c) abego Software GmbH, 2005-2006 (www.abego-software.de)",
};

// Ensure the global abego namespace is set up.
if (!window.abego) window.abego = {};


//--------------------------------
// XHTML10Saver (inherits from SaverBase)

abego.XHTML10Saver = function() {};

abego.XHTML10Saver.prototype = new SaverBase();

abego.XHTML10Saver.prototype.externalizeTiddler = function(store, tiddler) {
	try {
		var s = '';
		store.forEachField(tiddler,
			function(tiddler, fieldName, value) {
				// don't store stuff from the temp namespace
				if (!fieldName.match(/^temp\./)) {
					if (value)
						value = value.htmlEncode();
					s += ['<pre title="',fieldName,'">',value,'</pre>'].join("");
				}
			});
		return ['<div title="',tiddler.title.htmlEncode(),'">',s,'</div>'].join("");

	} catch (e) {
		showException(e, config.messages.tiddlerSaveError.format([tiddler.title]));
		return '';
	}
};

abego.XHTML10Saver.prototype.externalize = function(store) {
	return ["<div class='twXHTML10'>\n",SaverBase.prototype.externalize.apply(this, arguments),"\n</div>"].join("");
};


//--------------------------------
// Overwrite TiddlyWiki.prototype.getSaver to use the XHTML10 format on save

TiddlyWiki.prototype.getSaver = function() {
	if (!this.saver)
		this.saver = new abego.XHTML10Saver();
	return this.saver;
};

//======================================
// Install the Loader into the HTML page

(function() {
	// The loader code will be inserted into the PostHead markup block,
	// so it can be executed before tiddlers are loaded. We cannot just put this
	// code into a normal plugin since this "load" code is required to load
	// tiddlers. I.e. this code must be executed before any tiddlers/plugins
	// can be loaded.

	var getXHTML10LoaderBlock = function() {
		// The loader code in a big JavaScript string.
		// You may get a non-stringified version of the XHTML10Loader source code at
		// http://tiddlywiki.abego-software.de/archive/XHTML10Plugin/1.0.1/XHTML10Plugin-1.0.1-loader.js

		XHTML10LoaderCode =
			"if (!window.abego) window.abego = {};\nif (!abego.XHTML10Loader) {\n\t//-"+
			"-------------------------------\n\t// abego.XHTML10Loader (inherits from"+
			" LoaderBase)\n\t\n\tabego.XHTML10Loader = function() {};\n\tabego.XHTML10Loa"+
			"der.prototype = new LoaderBase();\n\t\n\tabego.XHTML10Loader.prototype.lin"+
			"go = {\n\t\tunnamedValue: \"Unnamed value\",\n\t\tredefining: \"Redefining valu"+
			"e of %0\",\n\t\tnoXHTML10Format: \"Storage not in XHTML 1.0 format\"\n\t}\n\t\n\ta"+
			"bego.XHTML10Loader.prototype.getTitle = function(store, e) {\n\t\tvar tit"+
			"le = null;\n\t\tif(e.getAttribute)\n\t\t\ttitle = e.getAttribute('title');\n\t\t"+
			"if(!title && e.id) {\t\n\t\t\tvar lenPrefix = store.idPrefix.length;\n\t\t\tif "+
			"(e.id.substr(0,lenPrefix) == store.idPrefix)\n\t\t\t\ttitle = e.id.substr(l"+
			"enPrefix);\n\t\t}\n\t\treturn title;\n\t};\n\t\n\tabego.XHTML10Loader.prototype.in"+
			"ternalizeTiddler = function(store, tiddler, title, data) {\n\t\tvar field"+
			"s = {};\n\t\tvar elems = data.childNodes;\n\t\tfor(var i = 0; i < elems.leng"+
			"th; i++) {\n\t\t\tvar e = elems[i];\n\t\t\tvar name = e.getAttribute('title');"+
			"\n\t\t\tif (!name) \n\t\t\t\tthrow this.lingo.unnamedValue;\n\t\t\tif (fields[name]"+
			" !== undefined) \n\t\t\t\tthrow this.lingo.redefining.format([name]);\n\t\t\tfi"+
			"elds[name] = getNodeText(e.firstChild); \n\t\t}\n\t\n\t\t// Extract (and remov"+
			"e) the standard fields from the extended fields\n\t\tvar text = fields.te"+
			"xt;\n\t\tvar modifier = fields.modifier;\n\t\tvar modified = Date.convertFro"+
			"mYYYYMMDDHHMM(fields.modified);\n\t\tvar c = fields.created;\n\t\tvar create"+
			"d = c ? Date.convertFromYYYYMMDDHHMM(c) : modified;\n\t\tvar tags = field"+
			"s.tags;\n\t\tdelete fields.modifier;\n\t\tdelete fields.modified;\n\t\tdelete f"+
			"ields.created;\n\t\tdelete fields.tags;\n\t\tdelete fields.text;\n\t\tdelete fi"+
			"elds.title;\n\t\n\t\ttiddler.assign(title,text,modifier,modified,tags,creat"+
			"ed,fields);\n\t\t\n\t\treturn tiddler;\n\t};\n\t\n\tvar findRootNode = function(no"+
			"des) {\n\t\tif (nodes) {\n\t\t\t// skip leading text nodes\n\t\t\tfor (var i = 0;"+
			" i < nodes.length; i++)\n\t\t\t\tif (nodes[i].nodeType != 3)\n\t\t\t\t\tbreak;\n\t\t"+
			"\t\t\t\n\t\t\tif (i < nodes.length && nodes[i].className == 'twXHTML10')\n\t\t\t\t"+
			"return nodes[i];\n\t\t}\n\t};\n\t\n\tabego.XHTML10Loader.prototype.loadTiddlers"+
			" = function(store,nodes) {\n\t\t// in the twXHMTL10 format all tiddler el"+
			"ements are contained in one enclosing DIV\n\t\t// that contains the forma"+
			"t information\n\t\tvar root = findRootNode(nodes)\n\t\tif (!root) \n\t\t\tthrow "+
			"this.lingo.noXHTML10Format;\n\t\treturn LoaderBase.prototype.loadTiddlers"+
			".apply(this, [store, root.childNodes]);\n\t};\n\t\n\t\n\t//-------------------"+
			"-------------\n\t// Hijack the loadFromDiv\n\t(function() {\n\t\tvar origTidd"+
			"lyWikiLoadFromDiv = TiddlyWiki.prototype.loadFromDiv;\n\t\tTiddlyWiki.pro"+
			"totype.loadFromDiv = function(srcID,idPrefix) {\n\t\t\t// use the XHTML 1."+
			"0 loader when the storearea is in 'twXHTML10' format,\n\t\t\t// otherwise "+
			"use the default loader\n\t\t\tvar e = document.getElementById(srcID);\n\t\t\ti"+
			"f (e && findRootNode(e.childNodes))\n\t\t\t\tthis.loader = new abego.XHTML1"+
			"0Loader();\n\t\t\treturn origTiddlyWikiLoadFromDiv.apply(this, arguments);"+
			"\n\t\t};\n\t})();\n}\n\n";
		return '<'+'script type="text/javascript">\n//<![CDATA[\n'+XHTML10LoaderCode+'\n//]]>\n</script'+'>\n';
	};

	var insertLoaderBlock = function() {
		if (!store)
			throw "XHTML10LoaderInstaller must run as a plugin";

		var START = "<!--XHMTL10Loader-START-->";
		var END = "<!--XHMTL10Loader-END-->";

		var postHeadText = store.getTiddlerText("MarkupPostHead");
		if (postHeadText.getChunk(START, END))
			return; // already installed

		postHeadText += "\n"+START+getXHTML10LoaderBlock()+END+"\n";
		var tiddler = store.getTiddler("MarkupPostHead");
		var tags = tiddler ? tiddler.tags : [];
		store.saveTiddler("MarkupPostHead","MarkupPostHead",postHeadText,config.options.txtUserName,new Date(),tags);
		alert("XHTML10Loader installed.\nPlease save and reload your TiddlyWiki to complete the installation. After that your TiddlyWiki will be stored in an XHTML 1.0 compliant format.");
	};

	insertLoaderBlock();
})();

} // of single install

//}}}
<!--{{{-->
<span class='yourSearchNumber' macro='foundTiddler number'></span>
<span class='yourSearchTitle' macro='foundTiddler title'/></span>&nbsp;-&nbsp;
<span macro='foundTiddler field includeURL'/></span>&nbsp;-&nbsp;
<span class='yourSearchTags' macro='foundTiddler field tags 50'/></span>
<span macro="yourSearch if previewText"><div class='yourSearchText' macro='foundTiddler field text 250'/></div></span>
<!--}}}-->
/***
|''Name:''|YourSearchPlugin|
|''Version:''|2.2.0 (2023-05-06)|
|''Summary:''|Search your TiddlyWiki with advanced search features such as result lists, tiddler preview, result ranking, search filters, combined searches and many more.|
|''Source:''|http://tiddlywiki.abego-software.de/#YourSearchPlugin|
|''Twitter:''|[[@abego|https://twitter.com/#!/abego]]|
|''GitHub:''|https://github.com/abego/YourSearchPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''License:''|[[BSD open source license|http://www.abego-software.de/legal/apl-v10.html]]|
!About YourSearch
YourSearch gives you a bunch of new features to simplify and speed up your daily searches in TiddlyWiki. It seamlessly integrates into the standard TiddlyWiki search: just start typing into the 'search' field and explore!

For more information see [[Help|YourSearch Help]].
!Compatibility
This plugin requires TiddlyWiki 2.1.
Check the [[archive|http://tiddlywiki.abego-software.de/archive]] for ~YourSearchPlugins supporting older versions of TiddlyWiki.
!Source Code
***/
/***
This plugin's source code is compressed (and hidden).
Use this [[link|http://tiddlywiki.abego-software.de/archive/YourSearchPlugin/2.2.0/YourSearchPlugin-2.2.0-src.js]] to get the readable source code.
***/
///%
if(!version.extensions.YourSearchPlugin){version.extensions.YourSearchPlugin={major:2,minor:2,revision:0,source:"http://tiddlywiki.abego-software.de/#YourSearchPlugin",licence:"[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",copyright:"Copyright (c) abego Software GmbH, 2005-2023 (www.abego-software.de)"};if(!window.abego){window.abego={}}if(!Array.forEach&&!Array.prototype.forEach){Array.forEach=function(c,e,d){for(var b=0,a=c.length;b<a;b++){e.call(d,c[b],b,c)}};Array.prototype.forEach=function(d,c){for(var b=0,a=this.length;b<a;b++){d.call(c,this[b],b,this)}}}abego.toInt=function(b,a){if(!b){return a}var c=parseInt(b);return(c==NaN)?a:c};abego.createEllipsis=function(a){var b=createTiddlyElement(a,"span");b.innerHTML="&hellip;"};abego.shallowCopy=function(b){if(!b){return b}var a={};for(var c in b){a[c]=b[c]}return a};abego.copyOptions=function(a){return !a?{}:abego.shallowCopy(a)};abego.countStrings=function(c,b){var e=0;if(!b){return e}var d=0;while(true){var a=c.indexOf(b,d);if(a<0){return e}e++;d=a+b.length}};abego.getBracedText=function(j,e,a){if(!e){e=0}var k=/\{([^\}]*)\}/gm;k.lastIndex=e;var d=k.exec(j);if(d){var l=d[1];var b=abego.countStrings(l,"{");if(!b){if(a){a.lastIndex=k.lastIndex}return l}var g=j.length;for(var f=k.lastIndex;f<g&&b;f++){var h=j.charAt(f);if(h=="{"){b++}else{if(h=="}"){b--}}}if(!b){if(a){a.lastIndex=f-1}return j.substring(d.index+1,f-1)}}};abego.select=function(d,c,b,a){if(!a){a=[]}d.forEach(function(e){if(c.call(b,e)){a.push(e)}});return a};abego.consumeEvent=function(a){if(a.stopPropagation){a.stopPropagation()}if(a.preventDefault){a.preventDefault()}a.cancelBubble=true;a.returnValue=true};abego.TiddlerFilterTerm=function(d,b){if(!b){b={}}var c=d;if(!b.textIsRegExp){c=d.escapeRegExp();if(b.fullWordMatch){c="\\b"+c+"\\b"}}var a=new RegExp(c,"m"+(b.caseSensitive?"":"i"));this.tester=new abego.MultiFieldRegExpTester(a,b.fields,b.withExtendedFields)};abego.TiddlerFilterTerm.prototype.test=function(a){return this.tester.test(a)};abego.parseNewTiddlerCommandLine=function(c){var a=/(.*?)\.(?:\s+|$)([^#]*)(#.*)?/.exec(c);if(!a){a=/([^#]*)()(#.*)?/.exec(c)}if(a){var d;if(a[3]){var b=a[3].replace(/#/g,"");d=b.parseParams("tag")}else{d=[[]]}var e=a[2]?a[2].trim():"";d.push({name:"text",value:e});d[0].text=[e];return{title:a[1].trim(),params:d}}else{return{title:c.trim(),params:[[]]}}};abego.parseTiddlerFilterTerm=function(queryText,offset,options){var re=/\s*(?:(?:\{([^\}]*)\})|(?:(=)|([#%!])|(?:(\w+)\s*\:(?!\/\/))|(?:(?:("(?:(?:\\")|[^"])+")|(?:\/((?:(?:\\\/)|[^\/])+)\/)|(\w+\:\/\/[^\s]+)|([^\s\)\-\"]+)))))/mg;var shortCuts={"!":"title","%":"text","#":"tags"};var fieldNames={};var fullWordMatch=false;re.lastIndex=offset;while(true){var i=re.lastIndex;var m=re.exec(queryText);if(!m||m.index!=i){throw"Word or String literal expected"}if(m[1]){var lastIndexRef={};var code=abego.getBracedText(queryText,0,lastIndexRef);if(!code){throw"Invalid {...} syntax"}var f=Function("tiddler","return ("+code+");");return{func:f,lastIndex:lastIndexRef.lastIndex,markRE:null}}if(m[2]){fullWordMatch=true}else{if(m[3]){fieldNames[shortCuts[m[3]]]=1}else{if(m[4]){fieldNames[m[4]]=1}else{var textIsRegExp=m[6];var text=m[5]?window.eval(m[5]):m[6]?m[6]:m[7]?m[7]:m[8];options=abego.copyOptions(options);options.fullWordMatch=fullWordMatch;options.textIsRegExp=textIsRegExp;var fields=[];for(var n in fieldNames){fields.push(n)}if(fields.length==0){options.fields=options.defaultFields}else{options.fields=fields;options.withExtendedFields=false}var term=new abego.TiddlerFilterTerm(text,options);var markREText=textIsRegExp?text:text.escapeRegExp();if(markREText&&fullWordMatch){markREText="\\b"+markREText+"\\b"}return{func:function(tiddler){return term.test(tiddler)},lastIndex:re.lastIndex,markRE:markREText?"(?:"+markREText+")":null}}}}}};abego.BoolExp=function(i,c,j){this.s=i;var h=j&&j.defaultOperationIs_OR;var e=/\s*\)/g;var f=/\s*(?:(and|\&\&)|(or|\|\|))/gi;var b=/\s*(\-|not)?(\s*\()?/gi;var a;var d=function(p){b.lastIndex=p;var l=b.exec(i);var o=false;var k=null;if(l&&l.index==p){p+=l[0].length;o=l[1];if(l[2]){var n=a(p);e.lastIndex=n.lastIndex;if(!e.exec(i)){throw"Missing ')'"}k={func:n.func,lastIndex:e.lastIndex,markRE:n.markRE}}}if(!k){k=c(i,p,j)}if(o){k.func=(function(m){return function(q){return !m(q)}})(k.func);k.markRE=null}return k};a=function(s){var n=d(s);while(true){var p=n.lastIndex;f.lastIndex=p;var k=f.exec(i);var o;var q;if(k&&k.index==p){o=!k[1];q=d(f.lastIndex)}else{try{q=d(p)}catch(r){return n}o=h}n.func=(function(t,m,l){return l?function(u){return t(u)||m(u)}:function(u){return t(u)&&m(u)}})(n.func,q.func,o);n.lastIndex=q.lastIndex;if(!n.markRE){n.markRE=q.markRE}else{if(q.markRE){n.markRE=n.markRE+"|"+q.markRE}}}};var g=a(0);this.evalFunc=g.func;if(g.markRE){this.markRegExp=new RegExp(g.markRE,j.caseSensitive?"mg":"img")}};abego.BoolExp.prototype.exec=function(){return this.evalFunc.apply(this,arguments)};abego.BoolExp.prototype.getMarkRegExp=function(){return this.markRegExp};abego.BoolExp.prototype.toString=function(){return this.s};abego.MultiFieldRegExpTester=function(b,a,c){this.re=b;this.fields=a?a:["title","text","tags"];this.withExtendedFields=c};abego.MultiFieldRegExpTester.prototype.test=function(b){var d=this.re;for(var a=0;a<this.fields.length;a++){var c=store.getValue(b,this.fields[a]);if(typeof c=="string"&&d.test(c)){return this.fields[a]}}if(this.withExtendedFields){return store.forEachField(b,function(e,g,f){return typeof f=="string"&&d.test(f)?g:null},true)}return null};abego.TiddlerQuery=function(b,a,d,c,e){if(d){this.regExp=new RegExp(b,a?"mg":"img");this.tester=new abego.MultiFieldRegExpTester(this.regExp,c,e)}else{this.expr=new abego.BoolExp(b,abego.parseTiddlerFilterTerm,{defaultFields:c,caseSensitive:a,withExtendedFields:e})}this.getQueryText=function(){return b};this.getUseRegExp=function(){return d};this.getCaseSensitive=function(){return a};this.getDefaultFields=function(){return c};this.getWithExtendedFields=function(){return e}};abego.TiddlerQuery.prototype.test=function(a){if(!a){return false}if(this.regExp){return this.tester.test(a)}return this.expr.exec(a)};abego.TiddlerQuery.prototype.filter=function(a){return abego.select(a,this.test,this)};abego.TiddlerQuery.prototype.getMarkRegExp=function(){if(this.regExp){return"".search(this.regExp)>=0?null:this.regExp}return this.expr.getMarkRegExp()};abego.TiddlerQuery.prototype.toString=function(){return(this.regExp?this.regExp:this.expr).toString()};abego.PageWiseRenderer=function(){this.firstIndexOnPage=0};merge(abego.PageWiseRenderer.prototype,{setItems:function(a){this.items=a;this.setFirstIndexOnPage(0)},getMaxPagesInNavigation:function(){return 10},getItemsCount:function(a){return this.items?this.items.length:0},getCurrentPageIndex:function(){return Math.floor(this.firstIndexOnPage/this.getItemsPerPage())},getLastPageIndex:function(){return Math.floor((this.getItemsCount()-1)/this.getItemsPerPage())},setFirstIndexOnPage:function(a){this.firstIndexOnPage=Math.min(Math.max(0,a),this.getItemsCount()-1)},getFirstIndexOnPage:function(){this.firstIndexOnPage=Math.floor(this.firstIndexOnPage/this.getItemsPerPage())*this.getItemsPerPage();return this.firstIndexOnPage},getLastIndexOnPage:function(){return Math.min(this.getFirstIndexOnPage()+this.getItemsPerPage()-1,this.getItemsCount()-1)},onPageChanged:function(a,b){},renderPage:function(a){if(a.beginRendering){a.beginRendering(this)}try{if(this.getItemsCount()){var d=this.getLastIndexOnPage();var c=-1;for(var b=this.getFirstIndexOnPage();b<=d;b++){c++;a.render(this,this.items[b],b,c)}}}finally{if(a.endRendering){a.endRendering(this)}}},addPageNavigation:function(c){if(!this.getItemsCount()){return}var k=this;var g=function(n){if(!n){n=window.event}abego.consumeEvent(n);var i=abego.toInt(this.getAttribute("page"),0);var m=k.getCurrentPageIndex();if(i==m){return}var l=i*k.getItemsPerPage();k.setFirstIndexOnPage(l);k.onPageChanged(i,m)};var e;var h=this.getCurrentPageIndex();var f=this.getLastPageIndex();if(h>0){e=createTiddlyButton(c,"Previous","Go to previous page (Shortcut: Alt-'<')",g,"prev");e.setAttribute("page",(h-1).toString());e.setAttribute("accessKey","<")}for(var d=-this.getMaxPagesInNavigation();d<this.getMaxPagesInNavigation();d++){var b=h+d;if(b<0){continue}if(b>f){break}var a=(d+h+1).toString();var j=b==h?"currentPage":"otherPage";e=createTiddlyButton(c,a,"Go to page %0".format([a]),g,j);e.setAttribute("page",(b).toString())}if(h<f){e=createTiddlyButton(c,"Next","Go to next page (Shortcut: Alt-'>')",g,"next");e.setAttribute("page",(h+1).toString());e.setAttribute("accessKey",">")}}});abego.LimitedTextRenderer=function(){var l=40;var c=4;var k=function(p,z,v){var q=p.length;if(q==0){p.push({start:z,end:v});return}var u=0;for(;u<q;u++){var w=p[u];if(w.start<=v&&z<=w.end){var o;var s=u+1;for(;s<q;s++){o=p[s];if(o.start>v||z>w.end){break}}var x=z;var y=v;for(var t=u;t<s;t++){o=p[t];x=Math.min(x,o.start);y=Math.max(y,o.end)}p.splice(u,s-u,{start:x,end:y});return}if(w.start>v){break}}p.splice(u,0,{start:z,end:v})};var d=function(n){var q=0;for(var p=0;p<n.length;p++){var o=n[p];q+=o.end-o.start}return q};var b=function(n){return(n>="a"&&n<="z")||(n>="A"&&n<="Z")||n=="_"};var f=function(p,r){if(!b(p[r])){return null}for(var o=r-1;o>=0&&b(p[o]);o--){}var q=o+1;var t=p.length;for(o=r+1;o<t&&b(p[o]);o++){}return{start:q,end:o}};var a=function(o,q,p){var n;if(p){n=f(o,q)}else{if(q<=0){return q}n=f(o,q-1)}if(!n){return q}if(p){if(n.start>=q-c){return n.start}if(n.end<=q+c){return n.end}}else{if(n.end<=q+c){return n.end}if(n.start>=q-c){return n.start}}return q};var j=function(r,q){var n=[];if(q){var u=0;do{q.lastIndex=u;var o=q.exec(r);if(o){if(u<o.index){var p=r.substring(u,o.index);n.push({text:p})}n.push({text:o[0],isMatch:true});u=o.index+o[0].length}else{n.push({text:r.substr(u)});break}}while(true)}else{n.push({text:r})}return n};var i=function(p){var n=0;for(var o=0;o<p.length;o++){if(p[o].isMatch){n++}}return n};var h=function(v,u,q,t,o){var w=Math.max(Math.floor(o/(t+1)),l);var n=Math.max(w-(q-u),0);var r=Math.min(Math.floor(q+n/3),v.length);var p=Math.max(r-w,0);p=a(v,p,true);r=a(v,r,false);return{start:p,end:r}};var m=function(r,y,o){var n=[];var v=i(r);var u=0;for(var p=0;p<r.length;p++){var x=r[p];var w=x.text;if(x.isMatch){var q=h(y,u,u+w.length,v,o);k(n,q.start,q.end)}u+=w.length}return n};var g=function(t,p,o){var n=o-d(p);while(n>0){if(p.length==0){k(p,0,a(t,o,false));return}else{var q=p[0];var v;var r;if(q.start==0){v=q.end;if(p.length>1){r=p[1].start}else{k(p,v,a(t,v+n,false));return}}else{v=0;r=q.start}var u=Math.min(r,v+n);k(p,v,u);n-=(u-v)}}};var e=function(p,x,w,n,o){if(n.length==0){return}var u=function(z,I,D,F,C){var H;var G;var E=0;var B=0;var A=0;for(;B<D.length;B++){H=D[B];G=H.text;if(F<E+G.length){A=F-E;break}E+=G.length}var y=C-F;for(;B<D.length&&y>0;B++){H=D[B];G=H.text.substr(A);A=0;if(G.length>y){G=G.substr(0,y)}if(H.isMatch){createTiddlyElement(z,"span",null,"marked",G)}else{createTiddlyText(z,G)}y-=G.length}if(C<I.length){abego.createEllipsis(z)}};if(n[0].start>0){abego.createEllipsis(p)}var q=o;for(var r=0;r<n.length&&q>0;r++){var t=n[r];var v=Math.min(t.end-t.start,q);u(p,x,w,t.start,t.start+v);q-=v}};this.render=function(p,q,o,t){if(q.length<o){o=q.length}var r=j(q,t);var n=m(r,q,o);g(q,n,o);e(p,q,r,n,o)}};(function(){function alertAndThrow(msg){alert(msg);throw msg}if(version.major<2||(version.major==2&&version.minor<1)){alertAndThrow("YourSearchPlugin requires TiddlyWiki 2.1 or newer.\n\nCheck the archive for YourSearch plugins\nsupporting older versions of TiddlyWiki.\n\nArchive: http://tiddlywiki.abego-software.de/archive")}abego.YourSearch={};var lastResults=undefined;var lastQuery=undefined;var setLastResults=function(array){lastResults=array};var getLastResults=function(){return lastResults?lastResults:[]};var getLastResultsCount=function(){return lastResults?lastResults.length:0};var matchInTitleWeight=4;var precisionInTitleWeight=10;var matchInTagsWeight=2;var getMatchCount=function(s,re){var m=s.match(re);return m?m.length:0};var standardRankFunction=function(tiddler,query){var markRE=query.getMarkRegExp();if(!markRE){return 1}var matchesInTitle=tiddler.title.match(markRE);var nMatchesInTitle=matchesInTitle?matchesInTitle.length:0;var nMatchesInTags=getMatchCount(tiddler.getTags(),markRE);var lengthOfMatchesInTitle=matchesInTitle?matchesInTitle.join("").length:0;var precisionInTitle=tiddler.title.length>0?lengthOfMatchesInTitle/tiddler.title.length:0;var rank=nMatchesInTitle*matchInTitleWeight+nMatchesInTags*matchInTagsWeight+precisionInTitle*precisionInTitleWeight+1;return rank};var findMatches=function(store,searchText,caseSensitive,useRegExp,sortField,excludeTag){lastQuery=null;var candidates=store.reverseLookup("tags",excludeTag,false);try{var defaultFields=[];if(config.options.chkSearchInTitle){defaultFields.push("title")}if(config.options.chkSearchInText){defaultFields.push("text")}if(config.options.chkSearchInTags){defaultFields.push("tags")}lastQuery=new abego.TiddlerQuery(searchText,caseSensitive,useRegExp,defaultFields,config.options.chkSearchExtendedFields)}catch(e){return[]}var results=lastQuery.filter(candidates);var rankFunction=abego.YourSearch.getRankFunction();for(var i=0;i<results.length;i++){var tiddler=results[i];var rank=rankFunction(tiddler,lastQuery);tiddler.searchRank=rank}if(!sortField){sortField="title"}var sortFunction=function(a,b){var searchRankDiff=a.searchRank-b.searchRank;if(searchRankDiff==0){if(a[sortField]==b[sortField]){return(0)}else{return(a[sortField]<b[sortField])?-1:+1}}else{return(searchRankDiff>0)?-1:+1}};results.sort(sortFunction);return results};var maxCharsInTitle=80;var maxCharsInTags=50;var maxCharsInText=250;var maxCharsInField=50;var itemsPerPageDefault=25;var itemsPerPageWithPreviewDefault=10;var yourSearchResultID="yourSearchResult";var yourSearchResultItemsID="yourSearchResultItems";var lastSearchText=null;var resultElement=null;var searchInputField=null;var searchButton=null;var lastNewTiddlerButton=null;var initStylesheet=function(){if(version.extensions.YourSearchPlugin.styleSheetInited){return}version.extensions.YourSearchPlugin.styleSheetInited=true;setStylesheet(store.getTiddlerText("YourSearchStyleSheet"),"yourSearch")};var isResultOpen=function(){return resultElement!=null&&resultElement.parentNode==document.body};var closeResult=function(){if(isResultOpen()){document.body.removeChild(resultElement)}};var closeResultAndDisplayTiddler=function(e){closeResult();var title=this.getAttribute("tiddlyLink");if(title){var withHilite=this.getAttribute("withHilite");var oldHighlightHack=highlightHack;if(withHilite&&withHilite=="true"&&lastQuery){highlightHack=lastQuery.getMarkRegExp()}story.displayTiddler(this,title);highlightHack=oldHighlightHack}return(false)};var adjustResultPositionAndSize=function(){if(!searchInputField){return}var root=searchInputField;var rootLeft=findPosX(root);var rootTop=findPosY(root);var rootHeight=root.offsetHeight;var popupLeft=rootLeft;var popupTop=rootTop+rootHeight;var winWidth=findWindowWidth();if(winWidth<resultElement.offsetWidth){resultElement.style.width=(winWidth-100)+"px";winWidth=findWindowWidth()}var popupWidth=resultElement.offsetWidth;if(popupLeft+popupWidth>winWidth){popupLeft=winWidth-popupWidth-30}if(popupLeft<0){popupLeft=0}resultElement.style.left=popupLeft+"px";resultElement.style.top=popupTop+"px";resultElement.style.display="block"};var scrollVisible=function(){if(resultElement){window.scrollTo(0,ensureVisible(resultElement))}if(searchInputField){window.scrollTo(0,ensureVisible(searchInputField))}};var ensureResultIsDisplayedNicely=function(){adjustResultPositionAndSize();scrollVisible()};var indexInPage=undefined;var currentTiddler=undefined;var pager=new abego.PageWiseRenderer();var MyItemRenderer=function(parent){this.itemHtml=store.getTiddlerText("YourSearchItemTemplate");if(!this.itemHtml){alertAndThrow("YourSearchItemTemplate not found")}this.place=document.getElementById(yourSearchResultItemsID);if(!this.place){this.place=createTiddlyElement(parent,"div",yourSearchResultItemsID)}};merge(MyItemRenderer.prototype,{render:function(pager,object,index,indexOnPage){indexInPage=indexOnPage;currentTiddler=object;var item=createTiddlyElement(this.place,"div",null,"yourSearchItem");item.innerHTML=this.itemHtml;applyHtmlMacros(item,null);refreshElements(item,null)},endRendering:function(pager){currentTiddler=null}});var refreshResult=function(){if(!resultElement||!searchInputField){return}var html=store.getTiddlerText("YourSearchResultTemplate");if(!html){html="<b>Tiddler YourSearchResultTemplate not found</b>"}resultElement.innerHTML=html;applyHtmlMacros(resultElement,null);refreshElements(resultElement,null);var itemRenderer=new MyItemRenderer(resultElement);pager.renderPage(itemRenderer);ensureResultIsDisplayedNicely()};pager.getItemsPerPage=function(){var n=(config.options.chkPreviewText)?abego.toInt(config.options.txtItemsPerPageWithPreview,itemsPerPageWithPreviewDefault):abego.toInt(config.options.txtItemsPerPage,itemsPerPageDefault);return(n>0)?n:1};pager.onPageChanged=function(){refreshResult()};var reopenResultIfApplicable=function(){if(searchInputField==null||!config.options.chkUseYourSearch){return}if((searchInputField.value==lastSearchText)&&lastSearchText&&!isResultOpen()){if(resultElement&&(resultElement.parentNode!=document.body)){document.body.appendChild(resultElement);ensureResultIsDisplayedNicely()}else{abego.YourSearch.onShowResult(true)}}};var invalidateResult=function(){closeResult();resultElement=null;lastSearchText=null};var isDescendantOrSelf=function(self,e){while(e!=null){if(self==e){return true}e=e.parentNode}return false};var onDocumentClick=function(e){if(e.target==searchInputField){return}if(e.target==searchButton){return}if(resultElement&&isDescendantOrSelf(resultElement,e.target)){return}closeResult()};var onDocumentKeyup=function(e){if(e.keyCode==27){closeResult()}};addEvent(document,"click",onDocumentClick);addEvent(document,"keyup",onDocumentKeyup);var myStorySearch=function(text,useCaseSensitive,useRegExp){lastSearchText=text;setLastResults(findMatches(store,text,useCaseSensitive,useRegExp,"title","excludeSearch"));abego.YourSearch.onShowResult()};var myMacroSearchHandler=function(place,macroName,params,wikifier,paramString,tiddler){initStylesheet();lastSearchText="";var searchTimeout=null;var doSearch=function(txt){if(config.options.chkUseYourSearch){myStorySearch(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch)}else{story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch)}lastSearchText=txt.value};var clickHandler=function(e){doSearch(searchInputField);return false};var keyHandler=function(e){if(!e){e=window.event}searchInputField=this;switch(e.keyCode){case 13:if(e.ctrlKey&&lastNewTiddlerButton&&isResultOpen()){lastNewTiddlerButton.onclick.apply(lastNewTiddlerButton,[e])}else{doSearch(this)}break;case 27:if(isResultOpen()){closeResult()}else{this.value="";clearMessage()}break}if(String.fromCharCode(e.keyCode)==this.accessKey||e.altKey){reopenResultIfApplicable()}if(this.value.length<3&&searchTimeout){clearTimeout(searchTimeout)}if(this.value.length>2){if(this.value!=lastSearchText){if(!config.options.chkUseYourSearch||config.options.chkSearchAsYouType){if(searchTimeout){clearTimeout(searchTimeout)}var txt=this;searchTimeout=setTimeout(function(){doSearch(txt)},500)}}else{if(searchTimeout){clearTimeout(searchTimeout)}}}if(this.value.length==0){closeResult()}};var focusHandler=function(e){this.select();clearMessage();reopenResultIfApplicable()};var args=paramString.parseParams("list",null,true);var buttonAtRight=getFlag(args,"buttonAtRight");var sizeTextbox=getParam(args,"sizeTextbox",this.sizeTextbox);var txt=createTiddlyElement(null,"input",null,"txtOptionInput searchField",null);if(params[0]){txt.value=params[0]}txt.onkeyup=keyHandler;txt.onfocus=focusHandler;txt.setAttribute("size",sizeTextbox);txt.setAttribute("accessKey",this.accessKey);txt.setAttribute("autocomplete","off");if(config.browser.isSafari){txt.setAttribute("type","search");txt.setAttribute("results","5")}else{if(!config.browser.isIE){txt.setAttribute("type","text")}}var btn=createTiddlyButton(null,this.label,this.prompt,clickHandler);if(place){if(!buttonAtRight){place.appendChild(btn)}place.appendChild(txt);if(buttonAtRight){place.appendChild(btn)}}searchInputField=txt;searchButton=btn};var openAllFoundTiddlers=function(){closeResult();var results=getLastResults();var n=results.length;if(n){var titles=[];for(var i=0;i<n;i++){titles.push(results[i].title)}story.displayTiddlers(null,titles)}};var createOptionWithRefresh=function(place,optionParams,wikifier,tiddler){invokeMacro(place,"option",optionParams,wikifier,tiddler);var elem=place.lastChild;var oldOnClick=elem.onclick;elem.onclick=function(e){var result=oldOnClick.apply(this,arguments);refreshResult();return result};return elem};var removeTextDecoration=function(s){var removeThis=["''","{{{","}}}","//","<<<","/***","***/"];var reText="";for(var i=0;i<removeThis.length;i++){if(i!=0){reText+="|"}reText+="("+removeThis[i].escapeRegExp()+")"}return s.replace(new RegExp(reText,"mg"),"").trim()};var getShortCutNumber=function(){var i=indexInPage;return(i>=0&&i<=9)?(i<9?(i+1):0):-1};var limitedTextRenderer=new abego.LimitedTextRenderer();var renderLimitedText=function(place,s,maxLen){limitedTextRenderer.render(place,s,maxLen,lastQuery.getMarkRegExp())};var oldTiddlyWikiSaveTiddler=TiddlyWiki.prototype.saveTiddler;TiddlyWiki.prototype.saveTiddler=function(title,newTitle,newBody,modifier,modified,tags,fields){oldTiddlyWikiSaveTiddler.apply(this,arguments);invalidateResult()};var oldTiddlyWikiRemoveTiddler=TiddlyWiki.prototype.removeTiddler;TiddlyWiki.prototype.removeTiddler=function(title){oldTiddlyWikiRemoveTiddler.apply(this,arguments);invalidateResult()};config.macros.yourSearch={label:"yourSearch",prompt:"Gives access to the current/last YourSearch result",handler:function(place,macroName,params,wikifier,paramString,tiddler){if(params.length==0){return}var name=params[0];var func=config.macros.yourSearch.funcs[name];if(func){func(place,macroName,params,wikifier,paramString,tiddler)}},tests:{"true":function(){return true},"false":function(){return false},found:function(){return getLastResultsCount()>0},previewText:function(){return config.options.chkPreviewText}},funcs:{itemRange:function(place){if(getLastResultsCount()){var lastIndex=pager.getLastIndexOnPage();var s="%0 - %1".format([pager.getFirstIndexOnPage()+1,lastIndex+1]);createTiddlyText(place,s)}},count:function(place){createTiddlyText(place,getLastResultsCount().toString())},query:function(place){if(lastQuery){createTiddlyText(place,lastQuery.toString())}},version:function(place){var t="YourSearch %0.%1.%2".format([version.extensions.YourSearchPlugin.major,version.extensions.YourSearchPlugin.minor,version.extensions.YourSearchPlugin.revision]);var e=createTiddlyElement(place,"a");e.setAttribute("href","http://tiddlywiki.abego-software.de/#YourSearchPlugin");e.innerHTML='<font color="black" face="Arial, Helvetica, sans-serif">'+t+"<font>"},copyright:function(place){var e=createTiddlyElement(place,"a");e.setAttribute("href","http://www.abego-software.de");e.innerHTML='<font color="black" face="Arial, Helvetica, sans-serif">&copy; 2005-2008 <b><font color="red">abego</font></b> Software<font>'},newTiddlerButton:function(place){if(lastQuery){var r=abego.parseNewTiddlerCommandLine(lastQuery.getQueryText());var btn=config.macros.newTiddler.createNewTiddlerButton(place,r.title,r.params,"new tiddler","Create a new tiddler based on search text. (Shortcut: Ctrl-Enter; Separators: '.', '#')",null,"text");var oldOnClick=btn.onclick;btn.onclick=function(){closeResult();oldOnClick.apply(this,arguments)};lastNewTiddlerButton=btn}},linkButton:function(place,macroName,params,wikifier,paramString,tiddler){if(params<2){return}var tiddlyLink=params[1];var text=params<3?tiddlyLink:params[2];var tooltip=params<4?text:params[3];var accessKey=params<5?null:params[4];var btn=createTiddlyButton(place,text,tooltip,closeResultAndDisplayTiddler,null,null,accessKey);btn.setAttribute("tiddlyLink",tiddlyLink)},closeButton:function(place,macroName,params,wikifier,paramString,tiddler){createTiddlyButton(place,"close","Close the Search Results (Shortcut: ESC)",closeResult)},openAllButton:function(place,macroName,params,wikifier,paramString,tiddler){var n=getLastResultsCount();if(n==0){return}var title=n==1?"open tiddler":"open all %0 tiddlers".format([n]);var button=createTiddlyButton(place,title,"Open all found tiddlers (Shortcut: Alt-O)",openAllFoundTiddlers);button.setAttribute("accessKey","O")},naviBar:function(place,macroName,params,wikifier,paramString,tiddler){pager.addPageNavigation(place)},"if":function(place,macroName,params,wikifier,paramString,tiddler){if(params.length<2){return}var testName=params[1];var negate=(testName=="not");if(negate){if(params.length<3){return}testName=params[2]}var test=config.macros.yourSearch.tests[testName];var showIt=false;try{if(test){showIt=test(place,macroName,params,wikifier,paramString,tiddler)!=negate}else{showIt=(!eval(testName))==negate}}catch(ex){}if(!showIt){place.style.display="none"}},chkPreviewText:function(place,macroName,params,wikifier,paramString,tiddler){var elem=createOptionWithRefresh(place,"chkPreviewText",wikifier,tiddler);elem.setAttribute("accessKey","P");elem.title="Show text preview of found tiddlers (Shortcut: Alt-P)";return elem}}};config.macros.foundTiddler={label:"foundTiddler",prompt:"Provides information on the tiddler currently processed on the YourSearch result page",handler:function(place,macroName,params,wikifier,paramString,tiddler){var name=params[0];var func=config.macros.foundTiddler.funcs[name];if(func){func(place,macroName,params,wikifier,paramString,tiddler)}},funcs:{title:function(place,macroName,params,wikifier,paramString,tiddler){if(!currentTiddler){return}var shortcutNumber=getShortCutNumber();var tooltip=shortcutNumber>=0?"Open tiddler (Shortcut: Alt-%0)".format([shortcutNumber.toString()]):"Open tiddler";var btn=createTiddlyButton(place,null,tooltip,closeResultAndDisplayTiddler,null);btn.setAttribute("tiddlyLink",currentTiddler.title);btn.setAttribute("withHilite","true");renderLimitedText(btn,currentTiddler.title,maxCharsInTitle);if(shortcutNumber>=0){btn.setAttribute("accessKey",shortcutNumber.toString())}},tags:function(place,macroName,params,wikifier,paramString,tiddler){if(!currentTiddler){return}renderLimitedText(place,currentTiddler.getTags(),maxCharsInTags)},text:function(place,macroName,params,wikifier,paramString,tiddler){if(!currentTiddler){return}renderLimitedText(place,removeTextDecoration(currentTiddler.text),maxCharsInText)},field:function(place,macroName,params,wikifier,paramString,tiddler){if(!currentTiddler){return}var name=params[1];var len=params.length>2?abego.toInt(params[2],maxCharsInField):maxCharsInField;var v=store.getValue(currentTiddler,name);if(v){renderLimitedText(place,removeTextDecoration(v),len)}},number:function(place,macroName,params,wikifier,paramString,tiddler){var numberToDisplay=getShortCutNumber();if(numberToDisplay>=0){var text="%0)".format([numberToDisplay.toString()]);createTiddlyElement(place,"span",null,"shortcutNumber",text)}}}};var opts={chkUseYourSearch:true,chkPreviewText:true,chkSearchAsYouType:true,chkSearchInTitle:true,chkSearchInText:true,chkSearchInTags:true,chkSearchExtendedFields:true,txtItemsPerPage:itemsPerPageDefault,txtItemsPerPageWithPreview:itemsPerPageWithPreviewDefault};for(var n in opts){if(config.options[n]==undefined){config.options[n]=opts[n]}}config.shadowTiddlers.AdvancedOptions+="\n<<option chkUseYourSearch>> Use 'Your Search' //([[more options|YourSearch Options]]) ([[help|YourSearch Help]])// ";config.shadowTiddlers["YourSearch Help"]="!Field Search\nWith the Field Search you can restrict your search to certain fields of a tiddler, e.g only search the tags or only the titles. The general form is //fieldname//'':''//textToSearch// (e.g. {{{title:intro}}}). In addition one-character shortcuts are also supported for the standard fields {{{title}}}, {{{text}}} and {{{tags}}}:\n|!What you want|!What you type|!Example|\n|Search ''titles only''|start word with ''!''|{{{!jonny}}} (shortcut for {{{title:jonny}}})|\n|Search ''contents/text only''|start word with ''%''|{{{%football}}} (shortcut for {{{text:football}}})|\n|Search ''tags only''|start word with ''#''|{{{#Plugin}}} (shortcut for {{{tags:Plugin}}})|\n\nUsing this feature you may also search the extended fields (\"Metadata\") introduced with TiddlyWiki 2.1, e.g. use {{{priority:1}}} to find all tiddlers with the priority field set to \"1\".\n\nYou may search a word in more than one field. E.g. {{{!#Plugin}}} (or {{{title:tags:Plugin}}} in the \"long form\") finds tiddlers containing \"Plugin\" either in the title or in the tags (but does not look for \"Plugin\" in the text). \n\n!Boolean Search\nThe Boolean Search is useful when searching for multiple words.\n|!What you want|!What you type|!Example|\n|''All words'' must exist|List of words|{{{jonny jeremy}}} (or {{{jonny and jeremy}}})|\n|''At least one word'' must exist|Separate words by ''or''|{{{jonny or jeremy}}}|\n|A word ''must not exist''|Start word with ''-''|{{{-jonny}}} (or {{{not jonny}}})|\n\n''Note:'' When you specify two words, separated with a space, YourSearch finds all tiddlers that contain both words, but not necessarily next to each other. If you want to find a sequence of word, e.g. '{{{John Brown}}}', you need to put the words into quotes. I.e. you type: {{{\"john brown\"}}}.\n\nUsing parenthesis you may change the default \"left to right\" evaluation of the boolean search. E.g. {{{not (jonny or jeremy)}}} finds all tiddlers that contain neither \"jonny\" nor \"jeremy. In contrast to this {{{not jonny or jeremy}}} (i.e. without parenthesis) finds all tiddlers that either don't contain \"jonny\" or that contain \"jeremy\".\n\n!'Exact Word' Search\nBy default a search result all matches that 'contain' the searched text. E.g. if you search for {{{Task}}} you will get all tiddlers containing 'Task', but also '~CompletedTask', '~TaskForce' etc.\n\nIf you only want to get the tiddlers that contain 'exactly the word' you need to prefix it with a '='. E.g. typing '=Task' will find the tiddlers that contain the word 'Task', ignoring words that just contain 'Task' as a substring.\n\n!~CaseSensitiveSearch and ~RegExpSearch\nThe standard search options ~CaseSensitiveSearch and ~RegExpSearch are fully supported by YourSearch. However when ''~RegExpSearch'' is on Filtered and Boolean Search are disabled.\n\nIn addition you may do a \"regular expression\" search even with the ''~RegExpSearch'' set to false by directly entering the regular expression into the search field, framed with {{{/.../}}}. \n\nExample: {{{/m[ae][iy]er/}}} will find all tiddlers that contain either \"maier\", \"mayer\", \"meier\" or \"meyer\".\n\n!~JavaScript Expression Filtering\nIf you are familiar with JavaScript programming and know some TiddlyWiki internals you may also use JavaScript expression for the search. Just enter a JavaScript boolean expression into the search field, framed with {{{ { ... } }}}. In the code refer to the variable tiddler and evaluate to {{{true}}} when the given tiddler should be included in the result. \n\nExample: {{{ { tiddler.modified > new Date(\"Jul 4, 2005\")} }}} returns all tiddler modified after July 4th, 2005.\n\n!Combined Search\nYou are free to combine the various search options. \n\n''Examples''\n|!What you type|!Result|\n|{{{!jonny !jeremy -%football}}}|all tiddlers with both {{{jonny}}} and {{{jeremy}}} in its titles, but no {{{football}}} in content.|\n|{{{#=Task}}}|All tiddlers tagged with 'Task' (the exact word). Tags named '~CompletedTask', '~TaskForce' etc. are not considered.|\n\n!Access Keys\nYou are encouraged to use the access keys (also called \"shortcut\" keys) for the most frequently used operations. For quick reference these shortcuts are also mentioned in the tooltip for the various buttons etc.\n\n|!Key|!Operation|\n|{{{Alt-F}}}|''The most important keystroke'': It moves the cursor to the search input field so you can directly start typing your query. Pressing {{{Alt-F}}} will also display the previous search result. This way you can quickly display multiple tiddlers using \"Press {{{Alt-F}}}. Select tiddler.\" sequences.|\n|{{{ESC}}}|Closes the [[YourSearch Result]]. When the [[YourSearch Result]] is already closed and the cursor is in the search input field the field's content is cleared so you start a new query.|\n|{{{Alt-1}}}, {{{Alt-2}}},... |Pressing these keys opens the first, second etc. tiddler from the result list.|\n|{{{Alt-O}}}|Opens all found tiddlers.|\n|{{{Alt-P}}}|Toggles the 'Preview Text' mode.|\n|{{{Alt-'<'}}}, {{{Alt-'>'}}}|Displays the previous or next page in the [[YourSearch Result]].|\n|{{{Return}}}|When you have turned off the 'as you type' search mode pressing the {{{Return}}} key actually starts the search (as does pressing the 'search' button).|\n\n//If some of these shortcuts don't work for you check your browser if you have other extensions installed that already \"use\" these shortcuts.//";config.shadowTiddlers["YourSearch Options"]="|>|!YourSearch Options|\n|>|<<option chkUseYourSearch>> Use 'Your Search'|\n|!|<<option chkPreviewText>> Show Text Preview|\n|!|<<option chkSearchAsYouType>> 'Search As You Type' Mode (No RETURN required to start search)|\n|!|Default Search Filter:<<option chkSearchInTitle>>Title ('!')     <<option chkSearchInText>>Text ('%')     <<option chkSearchInTags>>Tags ('#')    <<option chkSearchExtendedFields>>Extended Fields<html><br><font size=\"-2\">The fields of a tiddlers that are searched when you don't explicitly specify a filter in the search text <br>(Explictly specify fields using one or more '!', '%', '#' or 'fieldname:' prefix before the word/text to find).</font></html>|\n|!|Number of items on search result page: <<option txtItemsPerPage>>|\n|!|Number of items on search result page with preview text: <<option txtItemsPerPageWithPreview>>|\n";config.shadowTiddlers.YourSearchStyleSheet="/***\n!~YourSearchResult Stylesheet\n***/\n/*{{{*/\n.yourSearchResult {\n\tz-index: 10;\n\tposition: absolute;\n\twidth: 800px;\n\n\tpadding: 0.2em;\n\tlist-style: none;\n\tmargin: 0;\n\n\tbackground: #ffd;\n\tborder: 1px solid DarkGray;\n}\n\n/*}}}*/\n/***\n!!Summary Section\n***/\n/*{{{*/\n.yourSearchResult .summary {\n\tborder-bottom-width: thin;\n\tborder-bottom-style: solid;\n\tborder-bottom-color: #999999;\n\tpadding-bottom: 4px;\n}\n\n.yourSearchRange, .yourSearchCount, .yourSearchQuery   {\n\tfont-weight: bold;\n}\n\n.yourSearchResult .summary .button {\n\tfont-size: 10px;\n\n\tpadding-left: 0.3em;\n\tpadding-right: 0.3em;\n}\n\n.yourSearchResult .summary .chkBoxLabel {\n\tfont-size: 10px;\n\n\tpadding-right: 0.3em;\n}\n\n/*}}}*/\n/***\n!!Items Area\n***/\n/*{{{*/\n.yourSearchResult .marked {\n\tbackground: none;\n\tfont-weight: bold;\n}\n\n.yourSearchItem {\n\tmargin-top: 2px;\n}\n\n.yourSearchNumber {\n\tcolor: #808080;\n}\n\n\n.yourSearchTags {\n\tcolor: #008000;\n}\n\n.yourSearchText {\n\tcolor: #808080;\n\tmargin-bottom: 6px;\n}\n\n/*}}}*/\n/***\n!!Footer\n***/\n/*{{{*/\n.yourSearchFooter {\n\tmargin-top: 8px;\n\tborder-top-width: thin;\n\tborder-top-style: solid;\n\tborder-top-color: #999999;\n}\n\n.yourSearchFooter a:hover{\n\tbackground: none;\n\tcolor: none;\n}\n/*}}}*/\n/***\n!!Navigation Bar\n***/\n/*{{{*/\n.yourSearchNaviBar a {\n\tfont-size: 16px;\n\tmargin-left: 4px;\n\tmargin-right: 4px;\n\tcolor: black;\n\ttext-decoration: underline;\n}\n\n.yourSearchNaviBar a:hover {\n\tbackground-color: none;\n}\n\n.yourSearchNaviBar .prev {\n\tfont-weight: bold;\n\tcolor: blue;\n}\n\n.yourSearchNaviBar .currentPage {\n\tcolor: #FF0000;\n\tfont-weight: bold;\n\ttext-decoration: none;\n}\n\n.yourSearchNaviBar .next {\n\tfont-weight: bold;\n\tcolor: blue;\n}\n/*}}}*/\n";config.shadowTiddlers.YourSearchResultTemplate='<!--{{{-->\n<span macro="yourSearch if found">\n<!-- The Summary Header ============================================ -->\n<table class="summary" border="0" width="100%" cellspacing="0" cellpadding="0"><tbody>\n  <tr>\n\t<td align="left">\n\t\tYourSearch Result <span class="yourSearchRange" macro="yourSearch itemRange"></span>\n\t\t&nbsp;of&nbsp;<span class="yourSearchCount" macro="yourSearch count"></span>\n\t\tfor&nbsp;<span class="yourSearchQuery" macro="yourSearch query"></span>\n\t</td>\n\t<td class="yourSearchButtons" align="right">\n\t\t<span macro="yourSearch chkPreviewText"></span><span class="chkBoxLabel">preview text</span>\n\t\t<span macro="yourSearch newTiddlerButton"></span>\n\t\t<span macro="yourSearch openAllButton"></span>\n\t\t<span macro="yourSearch linkButton \'YourSearch Options\' options \'Configure YourSearch\'"></span>\n\t\t<span macro="yourSearch linkButton \'YourSearch Help\' help \'Get help how to use YourSearch\'"></span>\n\t\t<span macro="yourSearch closeButton"></span>\n\t</td>\n  </tr>\n</tbody></table>\n\n<!-- The List of Found Tiddlers ============================================ -->\n<div id="'+yourSearchResultItemsID+'" itemsPerPage="25" itemsPerPageWithPreview="10"></div>\n\n<!-- The Footer (with the Navigation) ============================================ -->\n<table class="yourSearchFooter" border="0" width="100%" cellspacing="0" cellpadding="0"><tbody>\n  <tr>\n\t<td align="left">\n\t\tResult page: <span class="yourSearchNaviBar" macro="yourSearch naviBar"></span>\n\t</td>\n\t<td align="right"><span macro="yourSearch version"></span>, <span macro="yourSearch copyright"></span>\n\t</td>\n  </tr>\n</tbody></table>\n<!-- end of the \'tiddlers found\' case =========================================== -->\n</span>\n\n\n<!-- The "No tiddlers found" case =========================================== -->\n<span macro="yourSearch if not found">\n<table class="summary" border="0" width="100%" cellspacing="0" cellpadding="0"><tbody>\n  <tr>\n\t<td align="left">\n\t\tYourSearch Result: No tiddlers found for <span class="yourSearchQuery" macro="yourSearch query"></span>.\n\t</td>\n\t<td class="yourSearchButtons" align="right">\n\t\t<span macro="yourSearch newTiddlerButton"></span>\n\t\t<span macro="yourSearch linkButton \'YourSearch Options\' options \'Configure YourSearch\'"></span>\n\t\t<span macro="yourSearch linkButton \'YourSearch Help\' help \'Get help how to use YourSearch\'"></span>\n\t\t<span macro="yourSearch closeButton"></span>\n\t</td>\n  </tr>\n</tbody></table>\n</span>\n<!--}}}-->';config.shadowTiddlers.YourSearchItemTemplate="<!--{{{-->\n<span class='yourSearchNumber' macro='foundTiddler number'></span>\n<span class='yourSearchTitle' macro='foundTiddler title'/></span>&nbsp;-&nbsp;\n<span class='yourSearchTags' macro='foundTiddler field tags 50'/></span>\n<span macro=\"yourSearch if previewText\"><div class='yourSearchText' macro='foundTiddler field text 250'/></div></span>\n<!--}}}-->";config.shadowTiddlers.YourSearch="<<tiddler [[YourSearch Help]]>>";config.shadowTiddlers["YourSearch Result"]="The popup-like window displaying the result of a YourSearch query.";config.macros.search.handler=myMacroSearchHandler;var checkForOtherHijacker=function(){if(config.macros.search.handler!=myMacroSearchHandler){alert("Message from YourSearchPlugin:\n\n\nAnother plugin has disabled the 'Your Search' features.\n\n\nYou may disable the other plugin or change the load order of \nthe plugins (by changing the names of the tiddlers)\nto enable the 'Your Search' features.")}};setTimeout(checkForOtherHijacker,5000);abego.YourSearch.getStandardRankFunction=function(){return standardRankFunction};abego.YourSearch.getRankFunction=function(){return abego.YourSearch.getStandardRankFunction()};abego.YourSearch.getCurrentTiddler=function(){return currentTiddler};abego.YourSearch.closeResult=function(){closeResult()};abego.YourSearch.getFoundTiddlers=function(){return lastResults};abego.YourSearch.getQuery=function(){return lastQuery};abego.YourSearch.onShowResult=function(useOldResult){highlightHack=lastQuery?lastQuery.getMarkRegExp():null;if(!useOldResult){pager.setItems(getLastResults())}if(!resultElement){resultElement=createTiddlyElement(document.body,"div",yourSearchResultID,"yourSearchResult")}else{if(resultElement.parentNode!=document.body){document.body.appendChild(resultElement)}}refreshResult();highlightHack=null}})()};
//%/
Fix issue when using YourSearchPlugin with Internet Explorer 8. Thanks to Roger Gallion for reporting and providing the fix.  (For details see: https://github.com/abego/YourSearchPlugin/issues/1)
For YourSearchPlugin source code see the [[archive|http://tiddlywiki.abego-software.de/archive]].
/***
|''Name:''|abego.editIncludedTiddlerCommand|
|''Version:''|experimental|
|''SourceCode:''|http://tiddlywiki.abego-software.de/experimental/abego.editIncludedTiddlerCommand-src.js|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Copyright:''|&copy; 2007 [[abego Software|http://www.abego-software.de]]|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''~CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.5.0.9 or better; Internet Explorer 6.0|
***/
//{{{
(function(){


//================================================================================
// The "editIncludedTiddler" command
//
// allows editing tiddlers from "included TiddlyWikis"
//
// (see IncludePlugin (http://tiddlywiki.abego-software.de/#IncludePlugin))

var fixUpURL = function(url) {
	// Make sure the URL is a real URL, with protocol prefix etc.
	if (url.search(/^((http(s)?)|(file)):/) != 0) {

		// no protocol specified.
		if (url.search(/^((.\:\\)|(\\\\)|(\/))/) == 0) {
			// "url" is an "absolute" path to a local file. Prefix it with file://
			url = "file://"+url;

		} else {
			// "url" is a "relative" URL. Make it absolute

			// prefix the url with the directory containing the current document
			// (This also includes the protocol prefix)
			var documentPath = document.location.toString();
			var i = documentPath.lastIndexOf("/");
			url = documentPath.substr(0,i+1)+url;
		}
		// replace every \ by a /, to cover Windows style pathes
		url = url.replace(/\\/mg,"/");
	}
	return url;
};

// @return [may be null/undefined]
var getIncludedTiddlerURL = function(title) {
	var t = store.fetchTiddler(title);
	if (!t) return;
	var url = t["includeURL"];
	if (!url) return;
	return fixUpURL(url)+"#"+encodeURIComponent(String.encodeTiddlyLink(title));
};

config.commands.editIncludedTiddler = {
	text: "goto",
	tooltip: "Open tiddler from an included TiddlyWiki in a separate window. e.g. to edit it"
};

var editIncludedTiddlerWindow;

config.commands.editIncludedTiddler.handler = function(event,src,title) {
	var url = getIncludedTiddlerURL(title);
	if (url) {
		if (editIncludedTiddlerWindow) editIncludedTiddlerWindow.close();
		editIncludedTiddlerWindow = window.open(url,"editIncludedTiddlerWindow");
	} else {
		displayMessage("Tiddler is not from an included TiddlyWiki");
	}
};

var orig_getValue = TiddlyWiki.prototype.getValue;
// see 'Applications of "getValue"' below
TiddlyWiki.prototype.getValue = function(tiddler,fieldName) {
	var result = orig_getValue.apply(this,arguments);
	if (result === undefined) {
		var t = this.resolveTiddler(tiddler);
		if (t)
			result = t[fieldName];
	}
	return result;
};

// Applications of "getValue"
//
// Display the name of the TW containing the included tiddler in the ViewTemplate:
//
// 		in the "ViewTemplate" (shadow) tiddler add:
//
// 			<div class='subtitle' macro='view includeURL'></div>
//	 	(e.g. below the "title" div)
//
// In the YourSearch result also display the name of the TW containing the included tiddler
//
// 		in the "YourSearchItemTemplate" (shadow) tiddler add:
//
// 			<span macro='foundTiddler field includeURL'/></span>&nbsp;-&nbsp;
//
//		(e.g. behind the "title" span)


})();
//}}}
!2012-04-19
* [[FormTiddlerPlugin v1.0.7 and DataTiddlerPlugin v1.0.7 released]]
* [[YourSearchPlugin v2.1.6 released]]
!2012-04-09
* Added compatibility note in DataTiddlerPlugin on tiddlers with spaces in their titles when using TiddlyWiki > 2.6.2. Thanks to Matt Shanks for reporting this.
!2011-09-29
* Added info on using the IncludePlugin in the Opera or Chrome browser. Thanks to Yakov Litvin for this.
!2011-05-23
* Release PartTiddlerPlugin v1.0.10
** Adapt to TW 2.6.2 default behaviour when existing tiddlers are opened (don't select text) and fixed Firefox 4 issue. Thanks to dave for reporting the issue.
!2011-01-20
* Added the ForEachTiddlerPlugin example '[[Create a table with one column per tiddler ("Vertical Report")]]' and '[[Create a table with one row per tiddler ("Horizontal Report")]]'.
!2010-02-16
* YourSearchPlugin v2.1.5 released
** Fixed problems with CSS and search textfield. Thanks to Guido Glatzel for reporting.
!2009-12-29
* Added the ForEachTiddlerPlugin example '[[List all tasks completed on a journal tiddler's day, as a "Daily Status Report"]]'. Based on an idea by cmari and Alan Cohen. Thanks.
!2009-10-09
* Revised the NewTiddlerWithFormMacro documentation
!2009-09-04
* YourSearchPlugin v2.1.4 released
** Fixed "this command is not supported" error under IE 8. Thanks to rouilj for reporting. (For details see: http://groups.google.com/group/TiddlyWiki/browse_thread/thread/cffee3254381e478)
!2008-05-04
* Improved TiddlyWiki style for better appearance in Safari
!2008-04-16
* YourSearchPlugin v2.1.3 released
** Fixed problem with Firefox3. Thanks to Andreas Hoefler for reporting.
!2008-03-17
* YourSearchPlugin v2.1.2 released
** Bugfix: on IE (6.0) the first letter is dropped from the search string. Thanks to Kashgarinn and Nick Padfield for reporting.

^^For older news see the revision history of the various plugins.^^
//{{{
//============================================================================
// getCreateDate Function
//============================================================================
//
// Returns the "create date" as generated by the AutoTaggerPlugin
// (http://www.TiddlyTools.com/#AutoTaggerPlugin).
// The create date must be stored in the default format "YYYY.0MM.0DD".
//
// @return [may be null] the create date (as a String) or null if no create
// date is found.
//
version.extensions.getCreateDate = {major: 1, minor: 0, revision: 0,
 date: new Date(2005,11,21),
 provider: "http://tiddlywiki.abego-software.de"};
//
function getCreateDate(tiddler) {
 if (!tiddler || !tiddler.tags) {
 return null;
 }

 for(var i = 0; i < tiddler.tags.length; i++) {
 var matches = tiddler.tags[i].match(/^[0-9]{4}\.[0-9]{2}\.[0-9]{2}$/);
 if (matches && matches.length > 0) {
 return matches[0];
 }
 }
 return null;
}

//}}}
''Syntax''
|[''in'' //tiddlyWikiPath//]|

The //tiddlyWikiPath// in the [[ForEachTiddlerMacro]]s inClause is a path to a TiddlyWiki file. The [[ForEachTiddlerMacro]] will use the tiddlers of that TiddlyWiki.

When no inClause is specified the tiddlers of the current TiddlyWiki are used.

Example:
{{{
<<forEachTiddler in 'file:///c:/SampleTiddlyWiki.html' ...
}}}

See also [[ForEachTiddlerExamples]].
''Syntax''
|[''script'' //scriptText//]|

The //scriptText// in the [[ForEachTiddlerMacro]]s scriptClause is a JavaScript text. It typically defines JavaScript "helper" functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...). It main purpose is to make the expressions more simpler and to allow reuse of code.

See also [[ForEachTiddlerExamples]].
''Syntax''
|[''sortBy'' //sortExpression// [''ascending'' or ''descending'']]|

Using the sortClause of the [[ForEachTiddlerMacro]] you can specify the order the tiddlers are processed.

The sortClause consists of the sortExpression and the sort order directive (''ascending'' or ''descending'').

The sortExpression is a (quoted) JavaScript expression returning the value that should be used for sorting. The value is anything that can be compared using {{{<}}}, {{{>}}} and {{{==}}}. In the sortExpression you refer to the build-in variable {{{tiddler}}} to access the "current" tiddler.

A typical sortExpression is {{{'tiddler.title'}}} to sort by title or {{{'tiddler.modified'}}} to sort by modification time. But you are not limited to only access the tiddlers properties, you may to more complex stuff like {{{'tiddler.title.length'}}}: this will sort the tiddlers by the length of their titles.

With the sort order directives ''ascending'' and ''descending'' you specify if the smaller one should be processed before the larger ones (''ascending'') or vice versa (''descending''). When no sort order directive is given ''ascending'' is used.

See also [[ForEachTiddlerExamples]].
''Syntax''
|[''where'' //whereCondition//]|

The whereCondition in the [[ForEachTiddlerMacro]]s whereClause is a (quoted) JavaScript boolean expression that specifies what tiddlers should be processed. In the whereCondition you refer to the build-in variable {{{tiddler}}} to access the "current" tiddler, i.e. the one that is currently checked.

Every tiddler of the TiddlyWiki is checked against the whereCondition. Those tiddlers that make the whereCondition return {{{true}}} are selected for further processing.

When the where clause is empty all tiddlers are selected for further processing.

E.g. you may write {{{'tiddler.title.length <= 4'}}} to select all tiddlers that have a title with 4 or less characters. Or {{{'tiddler.tags.contain("TODO")'}}} to select all tiddlers that have the tag "TODO". Of cause you may use any other valid JavaScript expression.

''{{{context.inTiddler}}} and {{{context.viewerTiddler}}}''

Inside the whereCondition you may also refer to the build-in variables {{{context.inTiddler}}} and {{{context.viewerTiddler}}}. {{{context.inTiddler}}} refers the Tiddler that contains the ForEachTiddlerMacro currently executed, and  {{{context.viewerTiddler}}} the Tiddler currently rendered ("viewed").

Most times {{{context.inTiddler}}} and {{{context.viewerTiddler}}} refer the same Tiddler but when a tiddler ("A") uses the {{{<<tiddler ...>>}}} macro to "call" a tiddler "B" (containing the ForEachTiddlerMacro) the {{{context.inTiddler}}} will be the Tiddler "B" and the {{{context.viewerTiddler}}} the Tiddler "A".

The {{{context}}} variable may also be used to hold "custom" properties, e.g. to share data across the processing of the individual tiddlers.

See also [[ForEachTiddlerExamples]].