<!--{{{-->
<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]];}

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

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

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

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

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

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

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

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

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

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

.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; width:90%; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

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

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

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

----
Also see [[AdvancedOptions]]
<<importTiddlers>>
|''Type:''|file|
|''URL:''|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
Ich habe gerade eine gute Seite gefunden, die das Thema Input/Output, Streams und Probleme die mit getline() auftauchen können, ganz erfrischend nochmal darstellt. Es werden hier die Themen behandelt: was machen mit Zeichen, die auf dem Stream bleiben? Welche Zeichen können auf dem Stream bleiben?, etc.
Themen sind: 
<<<
   1. There are three header files to include when using C++ I/O
   2. How to set the width of a printing field
   3. By default, leading whitespace (carriage returns, tabs, spaces) is ignored by cin.
   4. cin.getline() can run into problems when used with cin >> var.
   5. Reading in numbers directly is problematic
   6. Using getline to input numbers is a more robust alternate to reading numbers directly
   7. Once a file is opened, it may be used exactly as cin is used.
   8. When reading an entire file, embed the file input inside of the loop condition
   9. Getline can be told to stop grabbing input at any designated character
  10. Delimited files can easily be read using a while loop and getline.
  11. Using C++-style strings
  12. How to prepare the output stream to print fixed precision numbers (3.40 instead of 3.4)
<<<

http://www.augustcouncil.com/~tgibson/tutorial/iotips.html
!22.10.2009
[[Aufgabe 9|Aufgabe 19]] ist, (lange) verspätet (sorry!) online. Hier werden einige schöne Lösungen zur Verwendung von //~STL-Alogrithmen// gezeigt und der Code ist zum Teil mit //~Doxygen-Kommentaren// ausgestattet -- viel Spass damit! 
!14.10.2009
[[Aufgabe 8|Aufgabe 18]], die verlängert und modifiziert worden ist, ist online. Sie verwendet regexes aus der boost-Bibliothek und muss entsprechend kompiliert werden (hierzu gibt es Hinweise in der main). Ausserdem verwendet sie eine auf {{{wstring}}} umgeschriebene Klasse {{{HashCisString}}} – nur sie irgendwie nicht entsprechend umbenannt worden. Zum Teil finden sich auch noch ~code-Fetzen in der main, beispielsweise für ein schnelles einlesen von Dateien, etc und es werden ein paar bequeme Arbeitserleichterungen vorgestellt, z.B. {{{BOOST_FOREACH()}}}.
PS: Passend zur Jahreszeit hat die Lösung für Aufgabe 8.5 einen "Perl ~Secret-Operator" mit an Bord: den "Eskimo Kiss Operator"...
Viel Spass damit!
!17.12.2009:
Ein Frohes Fest und einen guten Rutsch an alle! Gratulation für alle, die bis hierher „durchgehalten“ haben! Bleibt unbedingt am Ball und vergesst über die Feiertage nicht alles, was ihr euch so hart erarbeitet habt ;)

//Doch nun zum unwesentlichen://

Die {{{unordered_map}}} aus dem kommenden, neuen C++-Standard (betitelt C++0x) liess sich fast reibungslos in die Klasse {{{Cis_Text}}} ([[für die Aufgabe 7|Aufgabe 17]]) einbauen.
Damit kommen einige kleine, und notwendige Umstellungen:
* Um die {{{unordered_map}}} also den //Hash// einbinden zu können, muss mit {{{g++ -std=c++0x <dateien>}}} kompiliert werden
* Die lästigen (und gefährlichen) {{{includes}}} am Ende der {{{,hpp}}}s sind entfernt. Damit ändert sich das Kompilieren zu:
: {{{g++ -std=c++0x main.cpp cis_string.cpp Cis_Text.cpp HashCisString.cpp}}}
* oder kürzer und von der Menge an Fehlermeldungen übersichtlicher und letztendlich schneller, empfiehlt es sich, die Klassen einzeln zu entwickeln und nur diese zu kompilieren mit
: {{{g++ -std=c++0x HashCisString.cpp}}} dabei entsteht ein fertig kompiliertes ~Object-File (mit der Endung {{{.o}}}), am Schluss kann man alle diese zur {{{main.cpp}}} //hinzulinken//
: {{{g++ -std=c++0x main.cpp cis_string.o Cis_Text.o HashCisString.o}}}, was wiederum wesentlich schneller geht, da die {{{.o}}}-Dateien nicht mehr kompiliert werden.
!10.12.2009, Neues:
* [[Die aktuellen Klassen sind ab jetzt "const-save" (Aufgabe 6)|Aufgabe 16]]...
* ..und im [[Download|Downloads]]-Bereich angekommen
* es gibt in den Klassendateien Changelogs und Todos – Mithilfe wird hier jederzeit gern entgegengenommen!
!9.12.2009
[[Aufgabe 5 – "Arbeiten mit const"|Aufgabe 15]] ist online
!2.12.2009: //Kill bugs before implementing more bugs!//
Die "Musterlösung" von [[Aufgabe 4|Aufgabe 14]] ist ab nun online, trotz dessen, dass es noch //vieles// zu verbessern gäbe! Soweit aber schon okay.
!26.11.2009: //Zum Glück war hier keine Mondlandung geplant...// 
Der Fehler der zum Ausbleiben der Musterlösung geführt hat, war denkbar trivial: es hat ein {{{+1}}} an drei (!!!) richtigen Stellen gefehlt. (Diese Stellen werden im Code ''dick'' markiert sein (und dieser Code wird so bald wie möglich nachgeliefert werden)) 
!22.11.2009
Die Lösung von [[Aufgabe 3|Aufgabe 13]] ist online, die Markierung, wo die Baustellen zum Mithelfen sind, kommen noch! Viel Freude erstmal damit ;). Der bisherige Stand der Klasse {{{Cis_Text}}} findet sich wieder bei den [[Downloads]].
!13.11.2009
[[Aufgabe 2|Aufgabe 12]] ist online, als Grundlage für [[Aufgabe 3|Aufgabe 13]]
!12.11.2009
Es gibt jetzt einen [[Download-Bereich|Downloads]]. Dort finden sich ab jetzt stets die aktuellsten Zusammenfassungen von Dingen, die wir so machen oder Dingen, die wir so brauchen. Also z.B. die Klasse {{{cis_string}}} oder ähnliches. Auch gibt es dort eine nette Anleitung, [[wie man .tar.gz-Dateien entpackt|Downloads]].
!8.11.2009
Die Klasse {{{cis_string}}} ist verbessert. Folgende Funktionen haben ein Update erfahren:
* {{{operator+}}}
* {{{operator<}}}
und folgende Funktion ist neu:
* {{{operator[]}}}
Bequemerweise gibt es [[die Klasse cis_string auch zum einfachen herunteladen|http://www.cip.ifi.lmu.de/~bruder/cis_string.tar.gz]].
!29.10.2009
* Das alte aktuelle ist das neue Vergangene: [[Archiv der Rubrik "Aktuelles" vom letzten Semester|Vergangenes]]
* Die Lösung von [[Aufgabe 1|Aufgabe 11]] ist online; [[TIMTOWDI|http://en.wikipedia.org/wiki/There%27s_more_than_one_way_to_do_it]]: inklusive einer Zugabe in [[Perl|http://www.youtube.com/watch?v=JzIWdJVP-wo]]
!28.10.2009: //"Es gibt nur 10 Sorten von Menschen: die, die binär verstehen, und die, die's nicht tun "//
...in diesem Sinne definieren wir um: [[Aufgabe 11 = Aufgabe 1|Themen]] dieses Semster...
/***
|Name|AliasPlugin|
|Source|http://www.TiddlyTools.com/#AliasPlugin|
|Documentation|http://www.TiddlyTools.com/#AliasPluginInfo|
|Version|1.1.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|Create text-substitution macros|
Define macros for abbreviations and other "aliases", and then embed them in the rest of your tiddler content to quickly insert common terms, phrases and links without a lot of repetitive typing.
!!!!!Documentation
> see [[AliasPluginInfo]]
!!!!!Revisions
<<<
2008.03.11 [*.*.*] plugin size reduction - documentation moved to [[AliasPluginInfo]]
2007.03.21 [1.1.0] added support for parameter substitution into alias macros, using format() method and%0..%9 markers
| Please see [[AliasPluginInfo]] for previous revision details |
2005.08.12 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.alias= {major: 1, minor: 1, revision: 0, date: new Date(2007,3,21)};
config.macros.alias= { };
config.macros.alias.handler = function(place,macroName,params) {
	var alias=params.shift(); if (!alias) return; alias=alias.replace(/ /g,"_"); // don't allow spaces in alias
	if (config.macros[alias]==undefined) // create new macro (as needed)
		{	 
		config.macros[alias] = { };
		config.macros[alias].handler =
			function (place,macroName,params)
				{ wikify(config.macros[macroName].text.format(params),place,null,null); }
		}
	config.macros[alias].text = params[0]?params.join(' '):alias;	// set alias text
}
//}}}
! Aufgabe 0
* [[Strings einlesen etc.|Aufgabe 0]] – war keine offizielle Hausaufgabe
! Aufgabe 1
* [[Tests auf Grossbuchstaben usw.|Aufgabe 1]]
! Aufgabe 2
* [[Tests auf Grossbuchstaben, Teil 2, "translate" und anderes|Aufgabe 2]]
! Aufgabe 3
* [[Schleifen und Datei-Handling.|Aufgabe 3]]
! Aufgabe 4
* [[Einstellen der locale, Umgang mit Umlauten|Aufgabe 4]]
! Aufgabe 5
* [[Dateien, UTF8, Frequenzlisten|Aufgabe 5]]
! Aufgabe 6
* [[Module für einen Tokenizer|Aufgabe 6]]
! Aufgabe 7
* [[Klasse cis_string|Aufgabe 7]]
! Aufgabe 8
* [[Erweiterung der Klasse cis_string|Aufgabe 8]]
! Aufgabe 9
* [[Weitere Erweiterung der Klasse cis_string / Zusammenfassung der Aufgaben 7 bis 9|Aufgabe 9]]
! Aufgabe 10
* [[Der Arithmetik-Parser von Fred Béchet|Aufgabe 10]]
; 0.1 Schreiben Sie ein C++ Programm, das den Text "Hallo! Hier bin ich" auf dem Terminal ausgibt.
<code cpp>
/*
	"Hello Biber!"

*/

#include <iostream>

int main() {
	std::cout << "Biber beherrschen die Welt (seit Anbeginn der Zeit)!" << std::endl;
	return 0;
}

</code>

; 0.2 Schreiben Sie ein C++ Programm, das einen String einliest und den String umdreht.
<code cpp>
/*
	String einlesen und umdrehen
	Lösungsvariante 1
*/

#include <iostream>
#include <string>
using namespace std;

int main() {
	string str; // Das ist eine Variablendeklaration

	getline(cin, str); // Liest die ganze Zeile ein
	for(int i = str.length() - 1; i >= 0; i--) {
	    cout << str.at(i);
	}
	cout << endl;

	return 0;
}

</code>


* In dieser Lösung wird ein String eingelesen und über Verwendung der ~Header-Datei {{{algorithm}}} im Speicher umgedreht:
<code cpp>
/*
	String einlesen und umdrehen
	Lösungsvariante 2 (Fortgeschritten)
*/

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
	string str;

	cin >> str; // Liest das erste "Wort" ein
	reverse(str.begin(), str.end());
	cout << str << endl;

	return 0;
}

</code>
; 1.1 Schreiben Sie ein C++ Programm, das einen String einliest und testet, ob der erste Buchstabe des Strings ein großer Buchstabe ist.

<code cpp>
/*
    1.cpp

        Aufgabe 1
        Schreiben Sie ein C++ Programm, das einen String einliest und testet, 
        ob der erste Buchstabe des Strings ein großer Buchstabe ist.

*/


#include <iostream>
#include <string>
#include <cctype>

using namespace std;

int main() {
    
    string  str;
    
    cin >> str;     // für ganze Sätze: getline(cin, str);
    
    if (isupper(str.at(0))) {
        cout << "Ist ein Grossbuchstabe am Anfang!" << endl;
    }
    else if (isdigit(str.at(str.length()-1)) || islower(str.at(0)))             // Klammernsparen zu Nutze machen für eine "else if"-Konstruktion
        cout << "Entweder es ist eine Zahl am Ende oder ein Grossbuchstabe am Anfang!" << endl;

    return 0;
}
</code>
<code cpp>

#define SIZE_SENTENCE 1000

#include <string>
#include <iostream>

using namespace std;

// Die BNF:
// expression -> term { operator-add term }
// term -> factor { operator-mult factor }
// factor -> number | ‘ (’ expression ‘ )’
// operator-add -> ‘ +’ | ‘ -’
// operator-mult-> ‘*’ | ‘/’
// number-> digit { digit }
// digit-> ‘0’|‘1’|‘2’|‘3’|‘4’|‘5’|‘6’|‘7’|‘8’|‘9’

class Parser {
 char sentence[SIZE_SENTENCE];
 char token_read;
  int pos;

public:
 char read_next() { return sentence[pos++]; }

  int exp(int &val);
  int term(int &val);
  int fac(int &val);
  int num(int &val);
  int digit(int &val);
  int operator_add (char &val_op);
  int operator_mult(char &val_op);


int analyze(char *buffer,int &value) {
    strcpy(sentence,buffer);
    pos=0;
    token_read=read_next();
    return (exp(value) && token_read == '\0');
}
};

/*******************************************/
int Parser::exp(int &val) {
    
    int val_t2;  char val_op;

if (!term(val)) return false;
    while (operator_add(val_op)) {
        if (!term(val_t2)) return false;
        if (val_op == '+') val = val + val_t2;
        if (val_op == '-') val = val - val_t2;
    }
    return true;
}

/*******************************************/
int Parser::term(int &val) {
    int val_t;
    char val_op;
    if (!fac(val)) return false;
    while (operator_mult(val_op)) {
        if (!fac(val_t)) return false;
        if (val_op == '*') val = val * val_t;
        if (val_op == '/') val = val / val_t;
    }
    return true;
}

/*******************************************/
int Parser::operator_add(char &val_op) {
    if ((token_read == '+') || (token_read == '-')) {
        val_op=token_read;
        token_read = read_next();
        return true;
    } else
        return false;
}

/*******************************************/
int Parser::operator_mult(char &val_op) {
    if ((token_read == '*') || (token_read == '/')) {
        val_op=token_read;
        token_read = read_next();
        return true;
    } else
        return false;
}


/*******************************************/
int Parser::fac(int &val) {
    if (num(val)) return true;
    if ((token_read == '(')) {
        token_read = read_next();
        if (!exp(val)) return false;
        else {
            if (token_read == ')') {
                token_read = read_next();
                return true;
            }
        }
    }
    return false;
}


/*******************************************/
int Parser::num(int &val) {
    int val_d; 
    if (!digit(val_d)) return false; 

    val=val_d;

    while(digit(val_d)) {
        val = val * 10;
        val = val + val_d;
    }

    return true;
}



/*******************************************/
int Parser::digit(int &val) {

    if (token_read >= '0' && token_read <= '9')  {
        val = token_read - '0';
        token_read=read_next();
        return true;
    } else
        return false;
}


/*******************************************/
/*******************************************/
int main() {
    char buffer[SIZE_SENTENCE];

    do {
        int value = 0;
        int brac  = 0;
        Parser p;
        cout << "command> ";
        cin >> buffer;
        if (*buffer!='.') {
            if(p.analyze(buffer,value))
                cout << "correct expression" << endl << "its value is " << value << endl;
            else
                cout << "Not correct" << endl;
        }

        } while (*buffer!='.');
    cout << "Auf wiedersehen!!"<< endl;
}

</code>
!! Verwenden Sie einen utf-8 Text, wstrings und Internationalsierung
; Schreiben Sie ein C++ Programm, das eine Datei öffnet und die Zeilen in W�rter zerlegt und alle Wörter in einem Vector speichert.
;
;   1. Öffnen Sie die Datei
;   2. setzten Sie das richtige encondig
;   3. lesen Sie die Datei zeilenweise und implementieren Sie eine Split Funktion, die die Zeile wortweise zerlegt.
{{{
      int split (wstring line, <vector> wstring &words)

      /* Input: wstring line ... die Zeile die zerlegt werden soll
         Ausgabe: <vector> wstring words ... alle Wörter in der Zeile

         Return Value: int ... Anzahl de Wörter in der Zeile */ 
}}}

;   4. Geben Sie das erste und letzte Wort jeder Zeile aus.
;   5. Speichern Sie alle Wörter des Textes in einem <vector> wstring all_words
;   6. Wieviele Wörter sind im Text?

<code cpp>
/*
    1.cpp
    
    Datei einlesen, UTF-8 korrekt behandeln, locale setzen, 
    Zeilen auf Wörter splitten u.a.
    
    Daniel Bruder, Susanne Peters
    CIS, LMU, WS 09/10

*/


#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

using namespace std;


int split(wstring line, vector<wstring> &words, locale &loc);


int main() {

    /// Locale holen / setzen
    locale      loc("");
    locale::global(loc);

    /// Datei-Handles anlegen
    wifstream   in("sz.txt.utf8");
 
    /// Wir benutzen den Farbeimer fuer alle Kanaele, auf denen wir lesen und schreiben.
    in   .imbue(loc);
    wcin .imbue(loc);    
    wcout.imbue(loc);
    
    /// Zum guten Schluss die Variablen, die wir brauchen
    wstring         str;
    wstring           w;
    vector<wstring> vec;
    unsigned int    last = 0, num = 0;

    while (getline(in, str, L'\n')) {
       num = split(str, vec, loc);
       if (num != 0) {
            wcout << vec.at(last) << L" " << vec.at(last+num-1) << endl;
            last += num;    
        }        
    }

    wcout << L"Der Woerter im Text gibt es viele, (ungefaehr) genau genommen aber " << vec.size() << L" Stueck" << endl;
    
    return 0;
}



int split(wstring line, vector<wstring> &words, locale &loc) {
    
    /* 
        Split arbeitet mit einem Trick: 
            es "wandelt" den string &line zurück in einen Stream,
            denn damit lässt sich der operator>> aus der Klasse stream verwenden.
              
        Wieso das Rad neu erfinden?
        
    */
    
    int             count = 0;
    wstring         buff;
    wstringstream   ss;   ss.imbue(loc);   ss.str(line);

    if (line.size() >= 0)
    while (ss >> buff) {
        words.push_back(buff);
        count++;
    }
    else return 0;
    return count;
}

</code>

!! Zugabe: Äquivalent in Perl
{{{
    perl -ne 'print for (split)[0,-1]' sz.txt.utf8 
    perl -ane ' print for @F[0,-1] ' sz.txt.utf8     
}}}
{{{
    perl -C -0 -ane 'print scalar @F' sz.txt.utf8
    perl -Mutf8 -F"\p{isSpace}+" -C -0 -plane '$_=@F' sz.txt.utf8 
}}}
<code pl>
#!/usr/bin/perl

use utf8;
undef $/;

while (<>) {
    chomp;
    @F = split /\p{isSpace}+/, $_;
    $_ = scalar @F
} continue {
    print
}

</code>
! Verwenden Sie einen utf-8 Text, wstrings und Internationalsierung
//Verwenden Sie die Lösung der Aufgabe 1 und die Musterlösung der Aufgabe9 in der Sie eine Klasse cis_string ([[hier zum Runterladen, Achtung, es sind 3 Dateien|Aufgabe 9]]) geschrieben haben.
Mit Hilfe der [[Aufgabe 1|Aufgabe 11]] können Sie jetzt eine Zeile in Wörter zerlegen.
Die [[Aufgabe 9]] des letzten Semesters liefert Ihnen zahlreiche Operatoren//

''1. Lesen Sie, analog zur Aufgabe 1 eine Datei ein, zerlegen Sie jede Zeile mit Hilfe Ihrer Split Funktion in Wörter und speichern Sie alle Wörter in einem vector<cis_string> Text''
''2. Verwenden Sie jetzt die Operatoren der cis_string Klasse aus Aufgabe 9''
*Konvertieren Sie alle Wörter in Text in Kleinbuchstaben
*Testen Sie die Translatefunktion
*Durchlaufen Sie den alle Wörter in Text und konkatenieren Sie benachbarte Worte (So bekommen Sie Bigramme).. Geben Sie die Wortpaare auf dem Terminal aus.
* Verwenden Sie den < Operator der cis_string Klasse und suchen Sie das alphabetisch kleinste Wort. (Der < Operator in der cis_string Klasse verwendet die Sortierreihenfolge der Vorschrift DIN 5007-1, Variante 1) ([[siehe hier|http://de.wikipedia.org/wiki/Alphabetische_Sortierung]])
''3. Ändern Sie den < Operator der cis_string Klasse, sodass Umlaute nach der Vorschrift: DIN 5007-1, Variante 2 sortiert werden? ([[siehe hier|http://de.wikipedia.org/wiki/Alphabetische_Sortierung]]). Führen Sie dazu einen neuen sinnvollen Operator ein.''
: //Bemerkung: Schwieriger wird es, wenn Sie nach der österreichischen Vorschrift sortieren sollen. Wie könnten Sie hier vorgehen?//
''4. Übrigens ist ein Fehler in der cis_string Klasse:''
: //Probieren sie folgendes://
: //Sie addieren zwei cis_string's s1 und s2 mit dem + Operator der cis_string Klasse, dann geben Sie die Konkatenation aus. Sie stimmt! Aber ... der erste cis_string s1 ist jetzt verändert!! Wieso??//

<code cpp>
/*
    2.cpp

    Datei einlesen, UTF-8 korrekt behandeln, locale setzen, 
    Zeilen auf Wörter splitten, und verschiedne Sortierungen
    vornehmen.

    Daniel Bruder, Susanne Peters
    CIS, LMU, WS 09/10

*/

#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include "cis_string.hpp"


using namespace std;

typedef vector<cis_string>::iterator	cis_it;

int main() {

    /// Locale holen / setzen
    locale      loc("");
    locale::global(loc);

    /// Datei-Handles anlegen
    wifstream   in("sz.txt.utf8");

    /// Wir benutzen den Farbeimer fuer alle Kanaele, auf denen wir lesen und schreiben.
    in   .imbue(loc);
    wcin .imbue(loc);
    wcout.imbue(loc);

    /// Ein paar Variablen, die wir brauchen
    wstring             str;
    wstring             w;
    vector<cis_string>  vec;


    /// Ab hier Aufgabe 2                        //////////

    /// 2.1 vector fuellen
    while (in >> str)
        vec.push_back(cis_string(str));

    /// 2.2b translate aller woerter
    for (vector<cis_string>::iterator it = vec.begin(); it != vec.end(); ++it)
        it->translate();
		
    /// 2.2a kleinschreiben aller woerter
    for (int i = 0; i < vec.size(); i++) {
        vec.at(i).cis_string_to_lower();
    }

    //transform(vec.begin(), vec.end(), cis_string::translate);		/// waere schoen

    wcout << endl << L"Bigramme BEGIN" << endl;
    /// 2.2c Ausgabe der Bigramme
    for (int i = 0; i < vec.size(); i++) {
        wcout << vec.at(i);
        if (i < vec.size()-1) 
            wcout << L" " << vec.at(i+1) << endl;
        else
            break;
    }
    wcout << endl << L"Bigramme END" << endl;
    wcout << endl;




    /// 2.3.1 Kleinstes Wort finden und ausgeben (Sortier-Variante 1)
    cis_string smallest = *(vec.begin());                       // bzw. vec.at(0);
    //wcout << smallest << endl;
    for (cis_it it = vec.begin(); it != vec.end(); ++it) {		/// s.o: cis_it ist ein typedef!
        cis_string compare = *it;

        if (compare < smallest)
            smallest = compare;
    }
    wcout << L"Kleinstes Wort, Variante 1: " << smallest << endl;




    /// 2.3.2 Kleinstes Wort finden und ausgeben (Sortier-Variante 2)
    smallest = vec.at(0);
    for (int i = 1; i < vec.size(); i++) {
        cis_string comparison = vec.at(i);

        //if (comparison.variant2_compare(smallest)) {
        if (comparison ^ smallest) {
            smallest = comparison;
        }
    }
    wcout << L"Kleinstes Wort, Variante 2: " << smallest << endl;




    /// 2.3.3 Kleinstes Wort finden und ausgeben (österreichische Sortier-Variante)
    smallest = vec.at(0);
    for (int i = 1; i < vec.size(); i++) {
        cis_string comparison = vec.at(i);

        if (comparison > smallest) {
            smallest = comparison;
        }
    }
    wcout << L"Kleinstes Wort, Variante 3: " << smallest << endl;

    wcout << L"Der Woerter im Text gibt es viele, (ungefaehr) genau genommen aber " << vec.size() << L" Stueck" << endl;

    return 0;
}
</code>
! Verwenden Sie einen utf-8 Text, wstrings und Internationalsierung
//Verwenden Sie die Lösung der [[Aufgabe 2|Aufgabe 12]].
Mit Hilfe der [[Aufgabe 2|Aufgabe 12]] können Sie jetzt eine Datei zerlegen und alle Wörter in einem {{{cis_string Vector}}} speichern.//

; 1. Schreiben Sie eine Klasse [[Cis_Text|Downloads]], die als private Member mindestens folgene Einträge hat:
{{{
vector<cis_string> Text
int anz_woerter
}}}

; 2. Schreiben Sie eine globale Memberfunktion {{{void print}}} für die Klasse {{{Cis_Text}}}, die mit Hilfe eines Iterators die Textelemente der {{{Cis_Text}}} Klasse durchläuft und auf dem Terminal ausgibt.

; 3. Schreiben Sie eine globale Memberfunktion {{{bool find(cis_string &wort)}}} für die Klasse {{{Cis_Text}}}, die {{{true}}} ausgibt, wenn es {{{cis_string wort}}} in den Text Elemente der {{{Cis_Text}}} Klasse findet.

; 4. Schreiben Sie eine globale Memberfunktion {{{void unique()}}} für die Klasse {{{Cis_Text}}}, die alle Dupletten von Wörtern in den Text Elementen der {{{Cis_Text}}} Klasse löscht.

; 5. Jetzt sollen die Elemente sortiert werden: Eine triviale Lösung ist: Die Wörter der {{{Cis_Text}}} Klasse werden in einen STL-Container {{{set <wstring>}}} kopiert und sind dann per definitionem innerhalb des set sortiert und können über einen Iterator der Reihe nach sortiert ausgegeben werden. Doch nun die geistige Herausforderung: Wie können Sie den set dazu "überreden" ihre Vergleichsfunktion der [[Aufgabe 2|Aufgabe 12]], DIN 5007-1, Variante 2) zu verwenden? (Es ist ganz einfach, sie müssen nur ganz wenig ändern!)

!!3.cpp 
+++[Loesung ausklappen]
<code cpp>
/*
    3.cpp

    Benutzt neue Klasse Cis_Text:
        Diese ausgeben, Wörter darin finden, Dubletten entfernen und sortieren

    Daniel Bruder, Susanne Peters
    CIS, LMU, WS 09/10

*/


#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include "cis_string.hpp"
#include "Cis_Text.hpp"

//##define foreach( i, c ) typedef __typeof__( c ) STL_CONTAINERTYPE; for( STL_CONTAINERTYPE::iterator i = c.begin(); i != c.end(); ++i )

using namespace std;

typedef vector<cis_string>::iterator	cis_it;


int main() {

    /// Locale holen / setzen
    locale      loc("");
    locale::global(loc);

    /// Datei-Handles anlegen
    wifstream   in("sz.txt.utf8");

    /// Wir benutzen den Farbeimer fuer alle Kanaele,
    ///   auf denen wir lesen und schreiben.
    in   .imbue(loc);
    wcin .imbue(loc);
    wcout.imbue(loc);

    /// Ein paar Variablen, die wir brauchen
    wstring             str;
    wstring             w;
    vector<cis_string>  vec;


    /// 2.1 vector fuellen
    while (in >> str)
        vec.push_back(cis_string(str));

    ///////////////////////////////////////////////////////
    /// Ab hier Aufgabe 3                        //////////
	Cis_Text	T(vec);
	wstring		dummy;
    /// 3.2 print-Methode
    T.print();
	wcout << L"--- END Cis_Text::print() --- weiter? " << endl; getline(wcin, dummy);


	/// 3.3 find()-Methode
    cis_string    find_this(L"Arzt");
    if (T.find(find_this)) {
        wcout << L"Word >" << find_this << L"< found!" << endl;
    }
	wcout << L"--- END Cis_Text::find() --- weiter? " << endl; getline(wcin, dummy);


    /// 3.4 Dubletten rauswerfen
    // T.uniq();
    T.unique();     // doppelt so schnell!
    T.print();
	wcout << L"---END Cis_Text::unique()\nweiter? " << endl; getline(wcin, dummy);

    set<cis_string, sort1> my_set(vec.begin(), vec.end());
    /*for (set<cis_string>::iterator it = my_set.begin(); it != my_set.end(); ++it) {
		wstring tmp = it->get_data();
        wcout << tmp << endl;
	}*/
    return 0;
}

</code>
===
!!~Cis_Text.hpp
+++[Loesung ausklappen]
<code cpp>
/*
        Cis_String.hpp

    Class definitions for
        class Cis_Text

*/

using namespace std;

#ifndef CIS_TEXT_HPP
#define CIS_TEXT_HPP


#include <functional>
#include <vector>
#include <set>

#include "cis_string.hpp"

class Cis_Text {
	vector<cis_string> 	Text;
	unsigned int		Size;

  typedef
	vector<cis_string>::iterator Text_iterator;

  public:
	Cis_Text();
   //#~Cis_Text();
	Cis_Text(vector<cis_string> v);
	Cis_Text(cis_string &c);
	Cis_Text(char* file);

	void print();
	void drucke(cis_string &c);
	bool find(cis_string &f);
	bool find(wstring &f);
    void unique();                          // ... MOD löscht Dubletten aus dem "running Text", Text ist danach sortiert!
    void uniq();                            // ... MOD löscht Dubletten aus dem "running Text", Text bleibt fortlaufend; teuer!
    void empty();
	cis_string at(unsigned int i);
	Text_iterator begin();
	Text_iterator end();
    void push_back(cis_string word);
    void operator=(Cis_Text T);
    unsigned int size();
};

#ifndef   CIS_TEXT_CPP
#include "Cis_Text.cpp"
#endif

#endif

</code>
===
!!~Cis_Text.cpp
+++[Loesung ausklappen]
<code cpp>
#ifndef CIS_TEXT_CPP
#define CIS_TEXT_CPP

#ifndef   CIS_TEXT_HPP
#include "Cis_Text.hpp"
#endif


#include <functional>
#include <vector>
#include <set>


Cis_Text::Cis_Text() {
		Size = 0;
}

//    :   Text(),
 //       Size(Text.size()) { /*# Size = 0; */ }
    //#Cis_Text::~Cis_Text() {};

Cis_Text::Cis_Text(vector<cis_string> v) : Text(v), Size(Text.size()){
    /*# Text = v;
        Size = Text.size();
    #*/
}

Cis_Text::Cis_Text(cis_string &c) {
    Text.push_back(c);
    Size = Text.size();
}

Cis_Text::Cis_Text(char* file) { /*# not implemented yet. #*/}

void Cis_Text::print() {
    wcout << endl;
    for (Text_iterator it = Text.begin(); it != Text.end(); ++it)
        wcout << *it << endl;
}

void Cis_Text::drucke(cis_string &c) { wcout << c << endl; }

bool Cis_Text::find(wstring &f) { //# find(cis_string(f)); };
    Text_iterator it = Text.begin();
    while ((it->get_data()) != f) {
        ++it;
        if ((it->get_data()) == f)
            return true;
    }
    return false;
};

/* /// Der operator== und der operator!= sind in der Klasse cis_string
   ///    noch nicht definiert, daher zunaechst mal nur find(wstring)!!
*/

bool Cis_Text::find(cis_string &f) {
    Text_iterator it = Text.begin();

	for (Text_iterator it = Text.begin(); it != Text.end(); ++it)
		if (it->get_data() == f.get_data())
			return true;
    //#while ((it->get_data()) != f.get_data()) {
        //++it;
        //if ((it->get_data()) == f.get_data())
            //return true;
    //}
    return false;
};

// bool operator<(cis_string &first, cis_string &comparison) {
//   first  = first.entferne_umlaute();
//  cis_string second = comparison.entferne_umlaute();
//
//  if (first.get_data() < second.get_data()) // string::operator<()
//      return true;
//  else
//      return false;
// }


void Cis_Text::push_back(cis_string word) { Text.push_back(word); }

unsigned int Cis_Text::size() { return Size; }

void Cis_Text::empty() { ;Text.empty(); }


void Cis_Text::unique() {
    set<wstring> mySet;

    for(vector<cis_string>::iterator it = Text.begin(); it != Text.end(); ++it)
        mySet.insert(it->get_cis_string_data());

    Text.empty();

    for (set<wstring>::iterator jt = mySet.begin(); jt != mySet.end(); ++jt)
        Text.push_back(cis_string(*jt));

}

void Cis_Text::uniq() {
    for (vector<cis_string>::iterator it = Text.begin(); it != Text.end(); ++it) {
        for (vector<cis_string>::iterator jt = Text.begin()+1; jt != Text.end(); ++jt) {
            if (it->get_cis_string_data() == jt->get_cis_string_data())
                Text.erase(jt);
        }
    }
}

cis_string Cis_Text::at(unsigned int i) { return Text.at(i); };

vector<cis_string>::iterator Cis_Text::begin() { return Text.begin(); };
vector<cis_string>::iterator Cis_Text::end() { return Text.end(); };

#endif

</code>
===


; //[[Aufgabe 3 komplett gepackt herunterladen|Downloads]]//
!Verwenden Sie einen utf-8 Text, wstrings und Internationalsierung

//Mit Hilfe der Aufgabe 3 und 2 können Sie jetzt eine Datei zerlegen und alle Wörter in einem cis_string Vector speichern. aber jetzt geht es um die Häufigkeit der Wörter im Text.//

; 1. Erweitern Sie die Klasse Cis_Text, aus der Aufgabe 3, die zu den Membern:
{{{
vector<cis_string> Text
int anz_woerter
}}}
: folgenden privaten Member zum Zählen der Frequenz hat:
{{{
map<cis_string,int> Text
}}}
; In der map sollen alle Wörter als kleingeschriebene Wörter gespeichert werden.

; 2. Schreiben Sie eine globale Memberfunktion {{{void print_stopwords(int max_freq)}}} für die Klasse {{{Cis_Text}}}, die mit Hilfe eines Iterators die Textelemente der {{{Cis_Text}}}-Klasse durchläuft und auf dem Terminal die Wörter ausgibt, die mehr als {{{max_freq}}} vorkommen.

! 4.cpp
<code cpp>
/*
    4.cpp

    Benutzt neue Klasse Cis_Text:
        Wörter einlesen, ausgeben, finden,
        Dubletten entfernen, sortieren,
        Frequenzlisten erstellen und
        häufigste Wörter ausgeben

    Daniel Bruder, Susanne Peters, 
    Max Hadersbeck

    CIS, LMU, WS 09/10

*/


#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <iomanip>      // for setw(), left, etc. in wcout <<
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>

#include "cis_string.hpp"
#include "Cis_Text.hpp"

//##define foreach( i, c ) typedef __typeof__( c ) STL_CONTAINERTYPE; for( STL_CONTAINERTYPE::iterator i = c.begin(); i != c.end(); ++i )

using namespace std;

typedef vector<cis_string>::iterator    cis_it;

void wait(wstring const &str) {wcout << str << L"\nweiter?" << endl; wstring dummy; getline(wcin, dummy); }

int main() {

    /// Locale holen / setzen
    locale      loc("");
    locale::global(loc);

    /// Datei-Handles anlegen
    wifstream   in("sz.txt.utf8");

    /// Wir benutzen den Farbeimer fuer alle Kanaele,
    ///   auf denen wir lesen und schreiben.
    in   .imbue(loc);
    wcin .imbue(loc);
    wcout.imbue(loc);

    /// Ein paar Variablen, die wir brauchen
    wstring             str;
    wstring             w;
    vector<cis_string>  vec;


    /// 2.1 vector fuellen
    while (in >> str)
        vec.push_back(cis_string(str));     // jetzt mit Copyconstructor!

    ///////////////////////////////////////////////////////
    /// Ab hier Aufgabe 3                        //////////
    Cis_Text    T(vec);
    wstring     dummy;

    /// 3.2 print-Methode
    T.print();
    wait(L" DONE WITH PRINT");


    /// 3.3 find()-Methode
    cis_string    find_this(L"Arzt");
    if (T.find(find_this))
        wcout << L"Word >" << find_this << L"< found!" << endl;
    wait(L"DONE WITH FIND()");


    /// 3.4 Dubletten rauswerfen
    Cis_Text T2(T.my_unique()); /// jetzt ueber algorithm::unique()
    //T2 = T.my_unique();      /// operator= gibt es noch nicht
    T2.print();
    wait(L"DONE WITH UNIQUE");


    /*
    vector<cis_string>::iterator it;
    map<cis_string, int, sort1> my_map;
    for (it = T.my_begin(); it != T.my_end(); ++it) {
        wcout << *it << endl;
        my_map[*it]++;
    }

    for(map<cis_string, int, sort1>::iterator it = my_map.begin(); it != my_map.end(); ++it)
        wcout << setw(25) << it->first.get_data() << left << setw(5) << it->second << endl;

    */ // entspricht:

    T.make_freq();
    T.print();
    wait(L"DONE WITH INTERNAL MAP");


    T.print_freq();
    wait(L"DONE WITH PRINTING INTERNAL MAP");

    // 4.2 print_stopwords
    T.print_stopwords(5);   /// drucke alle Woerter mit Frequenz > 5

    return 0;
}

</code>

!Klassen
&rarr; Aktualisierte Klasse [[cis_string|Downloads]]
&rarr; Aktualisierte Klasse [[Cis_Text|Downloads]]
! Teil 1
; 1. //Zu den Konstanten:// Schreiben Sie ein Programm, das einen String {{{str}}} definiert, //der nicht verändert werden darf.//
; 2. Definieren Sie //eine Referenz// auf den String {{{str}}} der respektiert, dass der String {{{str}}} nicht verändert werden darf.
; 3. Schreiben Sie ein Programm, das 5 Namen in einem String-{{{vector}}} speichert, und genau festlegt, dass die 5 Namen //nicht verändert// werden dürfen.
++++[wieder aufklappen][Diese Lösung wegfalten]
<code cpp>
/*
    5.cpp

    "Arbeiten mit const"

    Daniel Bruder, Susanne Peters, 
    Max Hadersbeck

    CIS, LMU, WS 09/10

*/



/*
   1. Zu den Konstanten: Schreiben Sie ein Programm, das einen String str definiert, der nicht verändert werden darf.
   2. Definieren Sie eine Referenz auf den String str der respektiert, dass der String str nicht verändert werden darf.
   3. Schreiben Sie ein Programm, das 5 Namen in einem String-vector speichert, und genau festlegt, dass die 5 Namen nicht verändert werden dürfen.

   1. Zum Alloziieren: Modifizieren Sie die c_s Klasse in eine c_ws Klasse, die in den Daten wstrings speichert.
   2. Schreiben Sie das Programm so um, dass es mit ihren Default-locales arbeitet und vom Terminal 5 Strings einliest und wieder ausgibt.

*/

#include <string>
#include <vector>
#include <iterator>
#include <iostream>

//using namespace std;
using std::string;       /* nicht gleich den gesamten namespace in Beschlag nehmen, sondern nur std::string */
using std::vector;      /*                                                                (und Konsorten)  */
using std::cout;

int main() {
    // Aufgabe 5.1
    const string doesnt_change  = "ein Fels in der Brandung";
    string const also_no_change = "dieser steht ebenso fest";

    #ifdef ERR1
    doesnt_change = "divide et impera";
    #endif
    
    
    #ifdef ERR2
    also_no_change = "tempus fugit!";
    #endif

    // Aufgabe 5.2
    string const &const_ref = doesnt_change;
    // string* pointer(doesnt_change);

    // Aufgabe 5.3
    // mal was neues zum kennenlernen (makriert mit *):
    string names[5] = {"Sepp", "Hans", "Max", "Franz", "Moni"}; // (obligatorisch)
    vector<string> const v(names, names+5);                     // neue Konstruktionsmethode *

    std::ostream_iterator<string> out(cout, ", ");
    copy (v.begin(), v.end(), out);                             // neue Ausgabemethode *
    cout << std::endl;

    #ifdef ERR3
    v.erase(v.front());
    #endif

    copy (v.begin(), v.end(), out);
    cout << std::endl;

    return 0;
}

</code>
===
!Teil 2
; 1. //Zum Alloziieren:// Modifizieren Sie die {{{c_s}}} Klasse in eine {{{c_ws}}} Klasse, die in den Daten {{{wstrings}}} speichert.
; 2. Schreiben Sie das Programm so um, dass es mit ihren Default-locales arbeitet und vom Terminal 5 Strings einliest und wieder ausgibt.
!!main
+++[Lösung ausklappen][wieder einfalten]
<code cpp>
//    main() zu Konstruktoren, Speicherallokation


#include "wc_s.hpp"


#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
#include <string>
#include <locale>

// using std::locale;
using std::wcout;
using std::wcin;
using std::endl;

int main() {

    std::locale loc("");
    std::locale::global(loc);
    std::wcout.imbue(loc);
    std::wcin.imbue(loc);

    wc_s s1(L"Hülle");
    std::wcout << L" s1 " << s1 << std::endl;

    // Aufgabe 5.2.2
    std::vector<wc_s>   vec;
    int i = 0;
    while (++i <= 5) {
        wcout << L"Input " << i << L" > ";
        wc_s    obj;
        wcin >> obj;
        wcout << endl;
        vec.push_back(obj);

    }

    for (std::vector<wc_s>::iterator wit = vec.begin(); wit != vec.end(); ++wit)
        wcout << *wit << endl;


    return 0;
}

</code>
===
!!wc_s.hpp
+++[Loesung ausklappen][einfalten]
<code cpp>
/*
  wc_s.hpp

  Class definitions for 
  class wc_s

*/

#ifndef WC_S_HPP
#define WC_S_HPP

#include <iostream>
#include <string>
#include <locale>

//#include <unistd>

const unsigned int MAX_SIZE =10000*1024;  // == Default Memory Groesse


class wc_s {
public:

  // Konstruktoren
  wc_s(int size=MAX_SIZE);           // ... legt ein c_s-Objekt an
  wc_s(const std::wstring &text);    // ... legt ein c_s-Objekt an und Instantiiert mit string: c_s s1(str)


  // "Methods for Convenience"
  int size();
  std::wstring get_data();
  std::wstring get_data() const;
  void set_data(const std::wstring &text);

  //Operatoren
  friend std::wostream& operator<<(std::wostream &o, wc_s::wc_s &object);
  friend std::wistream& operator>>(std::wistream &i, wc_s::wc_s &object);


private:
  wchar_t *data;                // ... Buchstaben
  int anzahl;                // ... Anzahl der  Buchstaben in data

};

wc_s to_upper(wc_s str);

#ifndef   WC_S_CPP
#include "wc_s.cpp"
#endif

#endif

</code>
===
!!wc_s.cpp
+++[Loesung ausklappen][einfalten]
<code cpp>
/*
  wc_s.cpp
  Implementation for 
  class wc_s

*/

#ifndef   WC_S_CPP
#define   WC_S_CPP

#ifndef   WC_S_HPP
#include "wc_s.hpp"
#endif

#include <string>
#include <locale>
#include <iostream>


wc_s::wc_s(int size) {
#ifndef ERROR 
   data = new wchar_t[size+1];   // ... alle Buchstaben der c_s Daten + terminierende Null
   data = L'\0';
#endif
   anzahl = 0;
}


wc_s::wc_s(const std::wstring &text) {
  anzahl = text.length();
#ifndef ERROR 
  data = new wchar_t[anzahl+1];  // ... alle Buchstaben der c_s Daten + terminierende Null
#endif
  wcsncpy(data,text.c_str(),anzahl+1);
}



int wc_s::size() { return anzahl; }
std::wstring wc_s::get_data() { return (std::wstring)data; }
std::wstring wc_s::get_data() const { return (std::wstring)data; }

void wc_s::set_data(const std::wstring &text) {
  anzahl = text.length();
#ifndef ERROR 
  data = new wchar_t[anzahl+1];   // ... alle Buchstaben der cis_string Daten  + terminierende Null
#endif
  wcsncpy(data,text.c_str(),anzahl+1);

}

std::wostream& operator<<(std::wostream &o, wc_s &object) {
  o << object.data;
  return o;
}


std::wistream& operator>>(std::wistream &i, wc_s::wc_s &object) {
    std::wstring wstr;
    i >> wstr;
    object.set_data(wstr);
    return i;
}
#endif

</code>
===
!main()
{{{
/*
    6.const_save.cpp

    Benutzt neue Klasse Cis_Text:
        Wörter einlesen, ausgeben, finden,
        Dubletten entfernen, sortieren,
        Frequenzlisten erstellen und
        häufigste Wörter ausgeben

    Daniel Bruder, Susanne Peters, 
    Max Hadersbeck

    CIS, LMU, WS 09/10

*/


#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <iomanip>      // for setw(), left, etc. in wcout <<
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>

#include "cis_string.hpp"
#include "Cis_Text.hpp"

//##define foreach( i, c ) typedef __typeof__( c ) STL_CONTAINERTYPE; for( STL_CONTAINERTYPE::iterator i = c.begin(); i != c.end(); ++i )

using namespace std;

typedef vector<cis_string>::iterator    cis_it;

void wait(wstring const &str) {wcout << str << L"\nweiter?" << endl; wstring dummy; getline(wcin, dummy); }

int main() {

    /// Locale holen / setzen
    locale      loc("");
    locale::global(loc);

    /// Datei-Handles anlegen
    wifstream   in("sz.txt.utf8");

    /// Wir benutzen den Farbeimer fuer alle Kanaele,
    ///   auf denen wir lesen und schreiben.
    in   .imbue(loc);
    wcin .imbue(loc);
    wcout.imbue(loc);

    /// Ein paar Variablen, die wir brauchen
    wstring             str;
    wstring             w;
    vector<cis_string>  vec;


    /// 2.1 vector fuellen
    while (in >> str)
        vec.push_back(cis_string(str));     // jetzt mit Copyconstructor!

    ///////////////////////////////////////////////////////
    /// Ab hier Aufgabe 3                        //////////
    Cis_Text    T(vec);
    wstring     dummy;

    /// 3.2 print-Methode
    T.print();
    wait(L" DONE WITH PRINT");


    /// 3.3 find()-Methode
    cis_string    find_this(L"Arzt");
    if (T.find(find_this))
        wcout << L"Word >" << find_this << L"< found!" << endl;
    wait(L"DONE WITH FIND()");


    /// 3.4 Dubletten rauswerfen
    Cis_Text T2(T.my_unique()); /// jetzt ueber algorithm::unique()
    //T2 = T.my_unique();      /// operator= gibt es noch nicht
    T2.print();
    wait(L"DONE WITH UNIQUE");


    /*
    vector<cis_string>::iterator it;
    map<cis_string, int, sort1> my_map;
    for (it = T.my_begin(); it != T.my_end(); ++it) {
        wcout << *it << endl;
        my_map[*it]++;
    }

    for(map<cis_string, int, sort1>::iterator it = my_map.begin(); it != my_map.end(); ++it)
        wcout << setw(25) << it->first.get_data() << left << setw(5) << it->second << endl;

    */ // entspricht:

    T.make_freq();
    T.print();
    wait(L"DONE WITH INTERNAL MAP");


    T.print_freq();
    wait(L"DONE WITH PRINTING INTERNAL MAP");

    // 4.2 print_stopwords
    T.print_stopwords(5);   /// drucke alle Woerter mit Frequenz > 5

    return 0;
}

}}}

!cis_string.hpp
{{{
/*
        cis_string.hpp

    Class definitions for
        class cis_string

*/

/* See cis_string.hpp for changelog */

#ifndef CIS_STRING_HPP
#define CIS_STRING_HPP

#include <iostream>
#include <locale>
#include <string>
#include <cwchar>                               /// entspricht wchar.h aus C
#include <string.h>                             /// und müsste hier noch angepasst werden

//using namespace std;                          // namespace std was killed.


const unsigned int MAX_SIZE = 24288;            // UP! irgendeine Hausnummer zum Dateienlesen, etc. /* Zum Glueck ab jetzt ungueltig */ //

const unsigned int Debug = 1;                   /* Set for more information while Debugging */


class cis_string {
                                                  /* Legende                                                                 */
  public:                                        /* NEU  --> Neues feature in dieser Woche                                  */
                                                /* UP!  --> Hat Update erfahren (Vorsicht noch in der Verwendung!)        */
    // Konstruktoren
    cis_string(const int &size = MAX_SIZE);     // ... legt ein cis_string–Objekt an.
    cis_string(const std::wstring &text);       // ... legt ein cis_string–Objekt an und initialisiert mit std::wstring: cis_string s1(wstr)
    cis_string(const wchar_t* text);            // ... legt ein cis_string-Objekt an und initialisiert es mit einem wide-character c-string.
    cis_string(const char* filename);           // ... (Bonus!) legt ein cis_string-Objekt an und instantiiert es mit einem (UTF8)-Dateiinhalt
    cis_string(const cis_string &str);          // ... Default Copyconstruktor

    // Destruktoren
   ~cis_string();

    // Setters
    void set_cis_string_data(const std::wstring &t);    // ... trägt den String text in die cis_string Daten ein.

    // Getters
    int  get_anzahl_chars() const;                      // ... liefert die Anzahl der Buchstaben der cis_string Daten
    void get_cis_string_data(std::wstring &text);       // ... liefert als std::wstring den Inhalt der String-Daten
    void get_cis_string_data(std::wstring &text) const; // ... liefert als std::wstring den Inhalt der String-Daten
    std::wstring get_cis_string_data();                 // ... liefert als Rückgabewert den Inhalt der String-Daten (nicht gefordert!)
    std::wstring get_cis_string_data() const;           // ... liefert als Rückgabewert den Inhalt der String-Daten (nicht gefordert!)


    // Converters
    int  cis_string_to_upper();                 // ... konvertiert die Daten des cis_string in Großbuchstaben.
    int  cis_string_to_lower();                 // ... konvertiert die Daten des cis_string in klein.
    bool first_is_upper() const;                // ... liefert wahr/falsch, ob der erste Buchstaben des cis_string ein Großbuchstabe ist
    void translate();                           // ... alle Großbuchstaben in Kleinbuchstaben und umgekehrt konvertieren und ausgeben
    //bool compare(cis_string &comparison);     // XXX Don't use


    // Operators
    void operator++(int);                       // ... wandelt in GROSS, "post-fix-non-const-in-situ-operator"!
    void operator--(int);                       // ... vice versa.
    std::wstring operator++();                  // ... Präfix-Operator, geeignet für Ausgabe: std::wcout << ++str << endl;
    std::wstring operator--();                  // ... mutatis mutandis.
    bool operator<(const cis_string &comparison) const;     // ... Lexikographischer Vergleichs-Operator
                                                            // --> there is a struct bool sort1 is in this place in .cpp
    int operator^(const cis_string &comparison) const;      // ... Lexikographischer Vergleich nach DIN 5007-Variante 2. Das ist zwar nicht schön, dient hier aber lediglich Anschauungszwecken
                                                            // --> there is a struct bool sort2 is in this place in .cpp
    bool operator>(const cis_string &comparison) const;     // ... Lexikographischer Vergleichs-Operator nach österreichischer Sortier-Variante (ä folgt auf a)
                                                            // --> likewise
    cis_string& operator+(const cis_string &object) const;  // ... Konkatenations-Operator (kann verkettet werden: s1 + s2 + s3)
    //cis_string& operator*(cis_string &object);            // XXX Komisch: Kommentar siehe cpp
    cis_string operator=(const std::wstring &str);          // ... Zuweisungsoperator für std::wstring.
    cis_string operator=(const cis_string &object);         // ... Zuweisungsoperator cis_string = cis_string
    cis_string operator+=(const std::wstring &str);         // ... Bonus! (Ermöglicht cis_string += std::wstring)

    wchar_t operator[](const int &i) const;                 // ... Zugriffs-Operator

    bool operator==(const cis_string &object) const;        // ... Gleichheit
    bool operator!=(const cis_string &object) const;        // ... Un-Gleichheit

    friend std::wostream& operator<<(std::wostream& o, const cis_string &object);   // ... Ausgabe, diesmal innerhalb der Klasse
    friend std::wostream& operator<<(std::wostream& o, cis_string &object);         // ... Ausgabe, diesmal innerhalb der Klasse
    friend std::wistream& operator>>(std::wistream& i, cis_string &object);         // ... Eingabe


    // "Methods for Convenience" (short names for long calls)
    int size() const;
    int length() const;

    void get_data(std::wstring &dest);          // ... 'gets' data into dest
    std::wstring get_data();
    std::wstring get_data() const;

    void set_data(const std::wstring &text);

    cis_string to_upper(const cis_string &str);


  private:
    wchar_t *data;
    int anzahl;                                 // ... Anzahl der Buchstaben in data
    std::wstring entferne_umlaute();            // ... selbstredend.
    std::wstring entferne_umlaute2();           // ... fuer das andere Sortierkriterium verwendet
};


#ifndef   CIS_STRING_CPP
#include "cis_string.cpp"
#endif

#endif

}}}
!cis_string.cpp
{{{
/*

        cis_string.cpp

       Implementation for
        class cis_string

    For (additional) comments on the methods
        please look inside cis_string.hpp

*/


/* Change-Log
 * 
 * 09/12/2009 DB: class made const save and is
 * (major Change) not using namespace std any more;
 *                Destructor tested
 *
 * 30/11/2009 DB: Revisions of methods get_data() etc following
 *                introduction of copyconstructor
 * 26/11/2009 MH: Last corrections on copyconstructor
 * 25/11/2009 DB: Change to copyconstructors
 * 00/10/2009 DB: First version of cis_string
 */

/* TODO
 * [ ] Look inside Cis_Text.cpp ;)
 */

#ifndef   CIS_STRING_CPP
#define   CIS_STRING_CPP

#ifndef   CIS_STRING_HPP
#include "cis_string.hpp"
#endif


#include <fstream>

// there is no more namespace

cis_string::cis_string(const int &size) {
    data = new wchar_t[size+1];         // ... alle Buchstaben der cis_string Daten + Terminierende NULL
    anzahl = 0; /// ARGH!   ^-- und genau hier war der Fehler!
}


cis_string::cis_string(const std::wstring &text) {
    anzahl = text.size();
    data = new wchar_t[anzahl+1];
    wcsncpy(data,text.c_str(),anzahl+1);            /// wide-character-c-string-n-copy(from, to, length);

}


cis_string::cis_string(const wchar_t* text) {
    anzahl = wcslen(text);
    data = new wchar_t[anzahl+1];        // ... alle Buchstaben der cis_string Daten + Terminierende NULL
    wcsncpy(data,text,anzahl+1);            /// wide-character-c-string-n-copy(from, to, length);

}


cis_string::cis_string(const char* filename) {      /*! Check functionality, implementation is a long time ago !*/
    std::wifstream in(filename, std::ios::binary);  /* but should be fast anyway */

    in.seekg(0, std::ios_base::end);
    long size = in.tellg();
    in.seekg(0, std::ios::beg);

    data =  new wchar_t[size+1];
    in.read(data,size);
    data[size+1] = L'\0';
    anzahl = size;
}


cis_string::cis_string(const cis_string &str) {        // ... Default Copyconstruktor

    if (Debug >= 2) 
        std::wcout << L"[Copyconstructor of class cis_string]" << std::endl;


      anzahl = str.anzahl;
      data = new wchar_t[anzahl+1];        // ... alle Buchstaben der cis_string Daten + Terminierende NULL
      wcsncpy(data, str.data, anzahl+1);

/*     if (Debug >= 2)  std::wcout << L"End Copyconstructor of class cis_string ...  this = ["
        << (*this).get_data() << L"]\tAnzahl = " << (*this).anzahl << std::endl;*/
}


cis_string::~cis_string() {
   //if (Debug >= 2) std::wcout << L"Delete" << std::endl;
    if (Debug >= 2) 
        std::wcout << L"[Custom Destructor of class cis_string]" << std::endl;

   delete [] data;
   anzahl = 0;
 }


void cis_string::set_cis_string_data(const std::wstring &text) {
    anzahl = text.length();
    data = new wchar_t[anzahl+1];                         // ... alle Buchstaben der cis_string Daten
    wcsncpy(data,text.c_str(),anzahl+1);
}


int cis_string::get_anzahl_chars() const { 
    return anzahl;
}


void cis_string::get_cis_string_data(std::wstring &text) {
    text.assign(data);
}


void cis_string::get_cis_string_data(std::wstring &text) const {
    text.assign(data);
}


std::wstring cis_string::get_cis_string_data() {
    return (std::wstring)data;
}

std::wstring cis_string::get_cis_string_data() const {
    const std::wstring tmp(data);
    return tmp;

}


int cis_string::cis_string_to_upper() {
    for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (!iswupper(data[i]))
            data[i] = towupper(data[i]);
}


int cis_string::cis_string_to_lower() {
    for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (!iswlower(data[i]))
            data[i] = towlower(data[i]);
}


bool cis_string::first_is_upper() const {
    if (iswupper(data[0]))
        return true;
    return false;
}


void cis_string::translate() {
    for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (iswupper(data[i]))
            data[i] = towlower(data[i]);
        else if (iswlower(data[i]))
            data[i] = towupper(data[i]);
}


void cis_string::operator++(int undef) {
    cis_string_to_upper();
}


void cis_string::operator--(int undef) {
    cis_string_to_lower();
}


std::wstring cis_string::operator++() {
    cis_string_to_upper();
    return (std::wstring)data;
}


std::wstring cis_string::operator--() {
    cis_string::cis_string_to_lower();
    return (std::wstring)data;
}

/*        dont use this for now!

bool cis_string::compare(cis_string &comparison) {
    std::wstring tmp = this->get_cis_string_data();
//     if (this->get_cis_string_data().compare(comparison) > 0)
    if (tmp.compare(comparison.get_cis_string_data()) < 0)
        return true;
    else
        return false;
}
*/

bool cis_string::operator<(const cis_string &comparison) const {
    cis_string first = *this;
    cis_string second = comparison;
    if (first.get_data() < second.get_data()) // std::string::operator<()
        return true;
    else
        return false;
}

bool austria_compare_w1_lt_w2 (std::wstring w1, std::wstring w2){ //Vergleich nach österreichischer Norm (Max)
  std::wstring alphabet(L"aäbcdefghijklmnoöpqrstuüvwxyzAÄBCDEFGHIJKLMNOÖPQRSTUÜVXYZ0123456789");
  bool comp_is_decided=false;
  bool is_lower=true;
  wchar_t letter_first,letter_second;
  size_t found_first,found_second;
  int i;
  i=0;
  while ((i<w1.size() && i<w2.size()) && !comp_is_decided) {
    letter_first = w1.at(i);
    found_first = alphabet.find(letter_first);
    letter_second = w2.at(i);
    found_second = alphabet.find(letter_second);
    if(found_first < found_second){
      comp_is_decided=true;
      is_lower=true;
    }
    else if(found_first == found_second) {
         }
         else {
           comp_is_decided=true;
           is_lower=false;
         }
    i++;
  }
  return is_lower;
}

bool austria_compare_cs1_lt_cs2 (cis_string cs1, cis_string cs2){ //Vergleich nach österreichischer Norm (Max)
    return austria_compare_w1_lt_w2(cs1.get_data(),cs2.get_data());
}

struct sort1 {      /*  to be used as a sorting-criterion, e.g. map<cis_string, int, sort1>  */
  bool operator()(cis_string s1, cis_string s2) const {
    return s1 < s2;
  }
};


int cis_string::operator^(const cis_string &comparison) const {     /// ^ sortiert nach DIN 5007, Variante 2
    cis_string first  = *this;      /// ... und benutzt im Gegensatz zur Variante 1 die methode entferne_umlaute2()
               first.entferne_umlaute2();        // wegen const umgebaut
    cis_string second = comparison;
               second.entferne_umlaute2(); // wg. const

    if (first.get_data() < second.get_data())
        return true;
    else
        return false;

    return -1;  /// never reached
}

struct sort2 {
  bool operator()(cis_string s1, cis_string s2) const {
    return s1 ^ s2;
  }
};


bool cis_string::operator>(const cis_string &comparison) const {     /// > sortiert nach österreischer Sortier-Variante
// [...] und die Idee der „Österreicher“
//
// std::wstring char_ord[]=“aäbcdefghijklmnoöpq   …“
//
// mit jedem Buchstaben sucht man die Position im String,
//
// Die Position gibt die Prioritätenordnung aus, je kleiner, desto früher im Alphabet.
//
// Viele Grüße
//
// MAX

    std::wstring ord = L"AaÄäBbCcDdEeFfGgHhIiJjKkLlMmNnOoÖöPpQqRrSsTtUuÜüVvWwXxYyZz";    // NEW
    int i = 0;
    while (i < (*this).size()) {
        if (i < comparison.size()) {
            int ord1 = ord.find((*this)[i]);
            int ord2 = ord.find(comparison[i]);
            if (ord1 == ord2) {
                i++;
            } else if (ord1 < ord2) {
                return true;
            } else if (ord2 < ord1) {
                return false;
            }
        } else if (i == ((*this).size()-1))
            return true;
          else
            return false;
    }
}


struct sort3 {
  bool operator()(cis_string s1, cis_string s2) const {
    return s1 > s2;
  }
};


std::wstring cis_string::entferne_umlaute() {
    std::wstring tmp = this->get_cis_string_data();

    for (int i = 0; i < tmp.size(); ++i) {
        tmp.at(i) = towlower(tmp.at(i));
        if (tmp.at(i) == L'ä' )     tmp.at(i) = L'a';
        if (tmp.at(i) == L'ö' )     tmp.at(i) = L'o';
        if (tmp.at(i) == L'ü' )     tmp.at(i) = L'u';
        if (tmp.at(i) == L'Ä' )     tmp.at(i) = L'A';
        if (tmp.at(i) == L'Ö' )     tmp.at(i) = L'O';
        if (tmp.at(i) == L'Ü' )     tmp.at(i) = L'U';

        if (tmp.at(i) == L'ß' )   { tmp.at(i) = L's'; tmp.insert(i+1, L"s"); }    // geht jetzt.
    }
    return tmp;
}

std::wstring cis_string::entferne_umlaute2() {
    std::wstring tmp = this->get_cis_string_data();

    for (int i = 0; i < tmp.size(); ++i) {
        tmp.at(i) = towlower(tmp.at(i));
        if (tmp.at(i) == L'ä' )   { tmp.at(i) = L'a'; tmp.insert(i+1, L"e"); }
        if (tmp.at(i) == L'ö' )   { tmp.at(i) = L'o'; tmp.insert(i+1, L"e"); }
        if (tmp.at(i) == L'ü' )   { tmp.at(i) = L'u'; tmp.insert(i+1, L"e"); }
        if (tmp.at(i) == L'Ä' )   { tmp.at(i) = L'A'; tmp.insert(i+1, L"e"); }
        if (tmp.at(i) == L'Ö' )   { tmp.at(i) = L'O'; tmp.insert(i+1, L"e"); }
        if (tmp.at(i) == L'Ü' )   { tmp.at(i) = L'U'; tmp.insert(i+1, L"e"); }

        if (tmp.at(i) == L'ß' )   { tmp.at(i) = L's'; tmp.insert(i+1, L"s"); }
    }
    return tmp;
}


cis_string& cis_string::operator+(const cis_string &object) const {
  cis_string *tmp = new cis_string;
  tmp->set_data(this->get_data() + object.get_data());  // das '+' ist die Konkatenation aus der string-Klasse!
  return *tmp;  // Achtung! muss mit new alloziiert werden, da sonst Temporär
}


cis_string cis_string::operator=(const std::wstring &str) {
    this->set_data(str);
    return *this;
}


cis_string cis_string::operator=(const cis_string &object) {
    this->set_data(object.get_data());
    return *this;
}


cis_string cis_string::operator+=(const std::wstring &str) {
    std::wstring tmp = this->get_data();
    tmp += str;
    this->set_data(tmp);
    return *this;
}


/* Wo kommt das hier her? Darf operator* überhaupt überladen werden??? */
// cis_string& cis_string::operator*(cis_string &object) {
//     this->set_data(this->get_data() + object.get_data());       // das '+' ist die Konkatenation aus der string-Klasse!
//     return *this;
// }


wchar_t cis_string::operator[](const int &i) const {
    std::wstring str1 = get_data();
    return str1.at(i);
}



bool cis_string::operator==(const cis_string &object) const {
    return this->get_data() == object.get_data();
}


bool cis_string::operator!=(const cis_string &object) const {
    return this->get_data() != object.get_data();
}


std::wostream&  operator<<(std::wostream &o, cis_string &object) {
    o << object.get_data();
    return o;
}

std::wostream&  operator<<(std::wostream &o, cis_string const &object) {
    o << object.get_data();
    return o;
}


std::wistream&  operator>>(std::wistream& in, cis_string &object) {
    std::wstring str;
    in >> str;
    object.set_data(str);
    return in;
}


int cis_string::size() const { return get_anzahl_chars(); }

int cis_string::length() const { return get_anzahl_chars(); }

void cis_string::get_data(std::wstring &dest) { dest.assign(get_cis_string_data()); }

std::wstring cis_string::get_data() { return get_cis_string_data(); }

std::wstring cis_string::get_data() const { return get_cis_string_data(); }

void cis_string::set_data(const std::wstring &text) { set_cis_string_data(text); }


cis_string cis_string::to_upper(const cis_string &str) {    // (Max)
    cis_string tmp;
    tmp = str;
    tmp++;
    return tmp;
}


bool compare_cis_string(const cis_string &c1, const cis_string &c2) {      // (Max)
  std::wstring w1=c1.get_data();
  std::wstring w2=c2.get_data();

    if (w1 < w2) 
        return true;
    else
        return false;
}


bool equal_cis_string(cis_string c1, cis_string c2) {
  /*std::wstring w1=c1.get_data();
  std::wstring w2=c2.get_data();*/
  //std::wcout << "equal"<< w1 << "==" << w2 << std::endl;
    if (c1 == c2) 
        return true;
    else
        return false;
}


#endif

}}}

!~Cis_Text.hpp
{{{
/*
    Cis_String.hpp

    Class definitions for
      class Cis_Text

*/


//using namespace std;            /// killed

#ifndef CIS_TEXT_HPP
#define CIS_TEXT_HPP


#include <functional>
#include <vector>
#include <set>
#include <map>

#include "cis_string.hpp"


class Cis_Text {
  private:
    std::vector<cis_string>          Text;
    unsigned int                     Size;
    std::map<cis_string, int, sort1> Freq;

  typedef std::vector<cis_string>::iterator Text_iterator;
  typedef std::vector<cis_string>::const_iterator Text_const_iterator;

  public:
  // (Copy-)Constructors,Desctructors 
    Cis_Text();
   ~Cis_Text();
    Cis_Text(const std::vector<cis_string> &v);
    Cis_Text(const cis_string &c);
    Cis_Text(const Cis_Text &C);    // CC
    Cis_Text(char* file);

  // "méthodes publiques"
    void print() const;
    void drucke(cis_string const &c) const;
    bool find(cis_string const &f) const;
    bool find(std::wstring const &f) const;
    void make_freq();                       ///! Hier muss noch ein const her, muss aber noch in cis_string angepasst werden!
    void print_freq() const;
    void print_stopwords(int i = 10) const;
    Cis_Text my_unique() const;             // MOD jetzt const! Gibt neuen Cis_Text zurück, der nur aus den uniques (==tokens) besteht.
    void empty_data();
    cis_string at(const unsigned int &i) const;
    void push_back(cis_string const &word);
    unsigned int size() const;


  /* Iterators                                  */
    std::vector<cis_string>::iterator begin();
    std::vector<cis_string>::iterator end();

    std::vector<cis_string>::const_iterator begin() const;
    std::vector<cis_string>::const_iterator end() const;


  /* Operators                                  */
    Cis_Text& operator=(Cis_Text const &C);
};

// Vergleichsmöglichkeiten
bool equal_cis_string(cis_string c1, cis_string c2);
bool compare_cis_string(cis_string c1, cis_string c2);
bool austria_compare_w1_lt_w2(std::wstring w1, std::wstring w2);
bool austria_compare_cs1_lt_cs2(cis_string w1, cis_string w2);


#ifndef   CIS_TEXT_CPP
#include "Cis_Text.cpp"
#endif

#endif

}}}
!~Cis_Text.cpp
{{{
/*

        Cis_Text.cpp

       Implementation for
        class Cis_Text

    For (additional) comments on the methods
        please look inside Cis_Text.hpp

*/


/* Change-Log
 * 09/12/2009 DB: class made const save and is
 * (major Change) not using namespace std any more;
 *                Destructor tested
 * 01/12/2009 MH, DB: Several corrections
 * 22/11/2009 DB: First version of Cis_Text
 */


/* TODO
 * [ ] Rückgabe von Referenzen, wo möglich
 * [ ] Test & Implementation von Konstruktor Cis_Text(char* filename) (auch in cis_string)
 * [ ] Rausnehmen der "automatischen Einbung" der cpps in den hpps (unsauber, macht sich auch in Fehlermeldungen
 *     bemerkbar (in file xy included from file abc, in line ....); 
 *     Kompilieren ab dann nur noch mit "g++ main.cpp Klasse1.cpp Klasse2.cpp"
 * [ ] Unnötige Header rausschmeissen, notwendige Header einbinden (es kann sein, dass die Klasse nur läuft,
 *     weil eine andere Klasse vorher eingebunden wurde, die den selben Header benutzt)
 * [ ] Generelles "Aufhübschen": Code-Style-Conventions wieder herstellen
 * [ ] Generelle Tests
 */


#ifndef CIS_TEXT_CPP
#define CIS_TEXT_CPP

#ifndef   CIS_TEXT_HPP
#include "Cis_Text.hpp"
#endif



#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>


Cis_Text::Cis_Text()
    : Size(0), Text(), Freq() {}


Cis_Text::~Cis_Text() {

    if (Debug >= 2) 
        std::wcout << L"[Custom Destructor of class Cis_Text]" << std::endl;

    Text.clear();
    Freq.clear();
    Size = 0;
}


Cis_Text::Cis_Text(const std::vector<cis_string> &v)
    : Text(v)
    , Size(Text.size())
    , Freq() 
    { /* No code */
    }


Cis_Text::Cis_Text(const cis_string &c) {
    Text.push_back(c);
    Size = Text.size();
}


Cis_Text::Cis_Text(const Cis_Text &C) 
    : Text(C.Text)
    , Size(C.Size)
    , Freq(C.Freq) { 
    if (Debug >= 2) 
        std::wcout << L"[Copyconstructor of class Cis_Text]" << std::endl;
    /*
    Text = C.Text;
    Size = C.Size;
    Freq = C.Freq;*/
}


Cis_Text::Cis_Text(char* file) { /*# not implemented yet. #*/}


void Cis_Text::print() const {
    std::wcout << std::endl;
    for (Text_const_iterator it = Text.begin(); it != Text.end(); ++it)
        std::wcout << *it << std::endl;
}


void Cis_Text::drucke(cis_string const &c) const { std::wcout << c << std::endl; }


bool Cis_Text::find(cis_string const &f) const {
    std::vector<cis_string>::const_iterator it = Text.begin();

    for (it = Text.begin(); it != Text.end(); ++it)
        if (it->get_data() == f.get_data())
            return true;
    return false;
};


bool Cis_Text::find(std::wstring const &f) const { //# find(cis_string(f)); };
    Text_const_iterator it = Text.begin();
    while ((it->get_data()) != f) {           // 'get_data() const' wird hier aufgerufen!
        ++it;
        if ((it->get_data()) == f)
            return true;
    }
    return false;
};


void Cis_Text::make_freq() {
    std::vector<cis_string>::iterator it;

    for (it = Text.begin(); it != Text.end(); ++it)
        Freq[--(*it)]++;        // _kleingeschriebene_ Wörter in std::map einfügen
}


void Cis_Text::print_freq() const {
    // drucke die gesamte Freqenzliste mit Hilfe auch von iomanip::setw & left
    for(std::map<cis_string, int, sort1>::const_iterator it = Freq.begin(); it != Freq.end(); ++it)
        std::wcout << std::setw(25) << it->first.get_data() << std::left << std::setw(5) << it->second << std::endl;
}


void Cis_Text::print_stopwords(int i) const {
    std::map<cis_string, int, sort1>::const_iterator it;

    for(it = Freq.begin(); it != Freq.end(); ++it)
        if (it->second >= i)
            std::wcout << std::setw(25) << it->first.get_data() << std::left << std::setw(5) << it->second << std::endl;
}


Cis_Text Cis_Text::my_unique() const {

    /// Zweiten std::vector als Rückgabewert herstellen
    ///   sonst machen spätere Aufrufe wie 
    ///   make_freq() keinen Sinn, weil nur noch
    ///   unique-Wörter da sind. 
    ///   (Scheint nicht nur logisch, ist sogar logisch! ;)
    std::vector<cis_string> T2(Text.begin(), Text.end());

    /// Vor Herstellung der uniques sortieren (notwendig)
    sort(T2.begin(), T2.end(), austria_compare_cs1_lt_cs2);

    //for (it = Text.begin(); it != Text.end(); ++it)
    //     std::wcout << L"sorted [" << *it << L"]" << std::endl;

//     std::vector<cis_string>::iterator    it;
    Text_iterator it;
    /// unique() aus algorithm verwenden
    /// ! Achtung ! Würde Text verändern, deswegen geben wir T2 zurück!
    it = unique(T2.begin(),T2.end(),equal_cis_string);

    /// ! Achtung ! unique() lässt die übrig gebliebenen (doppelten)
    /// Wörter am Ende "liegen". unique() hat uns einen iterator 
    ///   dort hinterlassen, wo diese "übriggebliebenen Wörter
    ///   liegen geblieben sind. ...und ab dort loeschen wir den Rest:
    T2.erase(it, T2.end()); // erase(von, bis)

    return T2;
}


Cis_Text& Cis_Text::operator=(Cis_Text const &C) {
    for (Text_const_iterator it = C.begin(); it != C.end(); ++it)
        this->push_back(*it);
    return *this;
}


void Cis_Text::empty_data() { Text.empty(); Size = 0; }

cis_string Cis_Text::at(const unsigned int &i) const { return Text.at(i); };

void Cis_Text::push_back(const cis_string &word) { Text.push_back(word); }

unsigned int Cis_Text::size() const { return Text.size(); }


/* Iterators                                                                */
std::vector<cis_string>::iterator Cis_Text::begin() { return Text.begin(); }
std::vector<cis_string>::iterator Cis_Text::end()   { return Text.end(); }


std::vector<cis_string>::const_iterator Cis_Text::begin() const { return Text.begin(); }
std::vector<cis_string>::const_iterator Cis_Text::end() const   { return Text.end(); }

#endif

}}}
An dieser Stelle stehen nur die main und beiden neuen ~Klassen-Dateien {{{HashCisString.hpp}}} und {{{HashCisString.cpp}}}.
Für ein komplettes Listing konsultiere bitte die [[Downloads]] (dort gibt es auch die Option, die Listings anzuzeigen und nicht komplett runterladen zu müssen)
Beachte bitte auch die Hinweise zum kompilieren hier gleich in der main.
!main()
{{{
/*
    7.cpp

    Benutzt neue Klasse Cis_Text:
        Wörter einlesen, ausgeben, finden,
        Dubletten entfernen, sortieren,
        Frequenzlisten erstellen und
        häufigste Wörter ausgeben
        (mit 'unordered_map' aus dem
         neuen C++-Standard 0x)

    Daniel Bruder, Susanne Peters,
    Max Hadersbeck

    CIS, LMU, WS 09/10

*/


///////////
// Kompilieren mit:
// g++ -std=c++0x 7.cpp cis_string.cpp Cis_Text.cpp HashCisString.cpp
///////////

#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <iomanip>      // for setw(), left, etc. in wcout <<
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>

#include "cis_string.hpp"
#include "Cis_Text.hpp"

//##define foreach( i, c ) typedef __typeof__( c ) STL_CONTAINERTYPE; for( STL_CONTAINERTYPE::iterator i = c.begin(); i != c.end(); ++i )

using namespace std;

//typedef vector<cis_string>::iterator    cis_it;

void wait(wstring const &str) {wcout << str << L"\nweiter?" << endl; wstring dummy; getline(wcin, dummy); }


int main() {

    /// Locale holen / setzen
    locale      loc("");
    locale::global(loc);

    /// Datei-Handles anlegen
    wifstream   in("sz.txt.utf8");

    /// Wir benutzen den Farbeimer fuer alle Kanaele,
    ///   auf denen wir lesen und schreiben.
    in   .imbue(loc);
    wcin .imbue(loc);
    wcout.imbue(loc);

    /// Ein paar Variablen, die wir brauchen
    wstring             str;
    wstring             w;
    vector<cis_string>  vec;


    /// 2.1 vector fuellen
    while (in >> str)
        vec.push_back(cis_string(str));     // jetzt mit Copyconstructor!

    ///////////////////////////////////////////////////////
    /// Ab hier Aufgabe 3                        //////////
    Cis_Text    T(vec);
    wstring     dummy;

    /// 3.2 print-Methode
    T.print();
    wait(L" DONE WITH PRINT");


    /// 3.3 find()-Methode
    cis_string    find_this(L"Arzt");
    if (T.find(find_this))
        wcout << L"Word >" << find_this << L"< found!" << endl;
    wait(L"DONE WITH FIND()");


    /// 3.4 Dubletten rauswerfen
    Cis_Text T2(T.my_unique()); /// jetzt ueber algorithm::unique()
    //T2 = T.my_unique();      /// operator= gibt es noch nicht
    T2.print();
    wait(L"DONE WITH UNIQUE");

    T.make_freq();
    T.print();
    wait(L"DONE WITH INTERNAL MAP");


    T.print_freq();
    wait(L"DONE WITH PRINTING INTERNAL MAP");

    // 4.2 print_stopwords
    T.print_stopwords(5);   /// drucke alle Woerter mit Frequenz > 5

    return 0;
}

}}}

!~HashCisString.hpp
{{{
/*
        HashCisString.hpp

    Class definitions
      and impelementations for
        class HashCisString

    Max Hadersbeck, Daniel Bruder
    CIS, LMU, Dez '09

*/

/* CHANGELOG
 *
 * 16/12/2009 DB: Construction as a separate class header file
 * 15/12/2009 MH: First version of unordered_(hash)_map from
 *                new/upcoming C++-Standard 'C++0x'
 *
 */


/* COMPILATION / USAGE
 *
 * Needs compilation with g++ -std=c++0x <files>
 * and g++ Version >4.3 !!!
 *
 */



#ifndef HASH_CIS_STRING_HPP
#define HASH_CIS_STRING_HPP

#include <unordered_map>
#include <string>

#include "cis_string.hpp"

// For containers like hash_map the equal and hash classes must be defined!!!
// This class' function operator() generates a hash value for a key.
// Unique hash values (indeces) give quickest access to data.


class HashCisString {
  public:
    enum hash_fnkt {simple,h_boost,funk3};

    HashCisString(hash_fnkt h=simple);
    unsigned int operator()(const cis_string&) const;

  private:
    enum hash_fnkt toHf;
    unsigned int hash_simple(const cis_string&) const;

 ///------------------------------------------------------------
 //    Description:  Implementation of boost's default hash
 //          function (strongly simplified).
 // See at '/usr/include/boost/functional/hash/hash.hpp'.
 //
    unsigned int hash_boost(const cis_string&) const;
};

typedef
  std::unordered_map<cis_string, int, HashCisString> HashMap;

#endif

}}}
!~HashCisString.cpp
{{{
/*
        HashCisString.cpp

    Class impelementations for
        class HashCisString

    Max Hadersbeck, Daniel Bruder
    CIS, LMU, Dez '09

*/

/* CHANGELOG
 *
 * 16/12/2009 DB: Construction as a separate class header file
 * 15/12/2009 MH: First version of unordered_(hash)_map from
 *                new/upcoming C++-Standard 'C++0x'
 *
 */


/* COMPILATION / USAGE
 *
 * Needs compilation with g++ -std=c++0x <files>
 * and g++ Version >4.3 !!!
 *
 */



#ifndef HASH_CIS_STRING_CPP
#define HASH_CIS_STRING_CPP

#include <unordered_map>
#include <string>


#include "cis_string.hpp"
#include "HashCisString.hpp"

// For containers like hash_map the equal and hash classes must be defined!!!
// This class' function operator() generates a hash value for a key.
// Unique hash values (indeces) give quickest access to data.


/**
* Computes the hash value of a string.
* The hash function is the one-at-a-time hash algorithm taken from wikipedia.
*
* @see http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time
* @param str the wstring for which the hash is computed.
* @return the hash value of the string.
*/

/* Constructor                                      */
HashCisString::HashCisString(hash_fnkt h) : toHf(h) { };

unsigned int HashCisString::operator()(const cis_string& str) const {
    if (toHf==simple) {
        return hash_simple(str.get_data());
    }

    if (toHf==h_boost) {
        return hash_boost(str.get_data());
    }
}

unsigned int HashCisString::hash_simple(const cis_string& str) const {
    unsigned int h = 0;
    std::wstring tmp = str.get_data();
    for(size_t i=0; i<str.length(); i++) {
        h += tmp.at(i);
        h += (h << 10);
        h ^= (h >> 6);
    }
        h += (h << 3);
        h ^= (h >> 11);
        h += (h << 15);
    return h;
}

 ///------------------------------------------------------------
 //    Description:  Implementation of boost's default hash
 //          function (strongly simplified).
 // See at '/usr/include/boost/functional/hash/hash.hpp'.
 //
unsigned int HashCisString::hash_boost(const cis_string& str) const {
    unsigned h = 0;
    std::wstring tmp = str.get_data();
    for (unsigned i = 0; i < str.size(); ++i)
    h = 31 * h + tmp.at(i);
    return h;
}
#endif

}}}
!!main()
<code cpp>
/*

    8.cpp

    Einsatz von boost/regex.hpp

    splits und matches

    Daniel Bruder, Susanne Peters
    CIS, LMU, WS 09/10
*/

//Standard stuff
#include <iostream>
#include <fstream>
#include <locale>   // a computational linguist's "best friend"
#include <string>

//Containers
#include <vector>
#include <unordered_map>   // needs compilation with -std=c++0x

//Boost::Regexes
#include <boost/regex.hpp>      // needs extra flags for compilation (see below)
#include <boost/algorithm/string/regex.hpp>
#include <boost/foreach.hpp>    // only for convenience reasons

//Stuff that unordered_map needs
#include "HashCisString.hpp"


/*
 Compile with:
 g++ -L /path/to/boost/headers -lboost_regex -std=c++0x -wall 8.cpp HashCisString.hpp
 or
 g++ -L /path/to/boost/headers one/working/libboost_regex-mt-or-else.a-or.so -std=c++0x -wall 8.cpp HashCisString.hpp

 Good luck and have fun!

*/

/*                                              *
    Thou shalt not take the  whole namespace
*                                               */
/* using namespace std;                         */
using std::wcin;
using std::endl;
using std::wcout;
using std::vector;
using std::wstring;


// Typedefs
typedef wstring triples;
//typedef wchar_t* triples[3]; // fuer spaeter

// Global variables
const int Debug = 3;


/*
    Functions
                                    */


/* Read file into one big string    */
wstring readFile(char* filename, std::locale &l) {
    std::wifstream in(filename, std::ifstream::in);
    in.imbue(l);
    wstring str, s;
    if (in.good()) {
        while (getline(in, s))
            str += s;
    }
    return str;

/*
     string str;
  size_t filesize;

  ifstream file ("test.txt",ios::in|ios::end);
  filesize=file.tellg();

  str.reserve(filesize);

  file.seekg(0);
  while (!file.eof())
  {
    str += file.get();
  }
  cout << str;
  return 0;
}*/
}

/* Split one big string into multiple tokens        */
vector<wstring> my_split(std::wstring regex, wstring& line) {
    vector<wstring> v;
    boost::wregex rx(regex);
    boost::algorithm::split_regex(v, line, rx); // this is enough.
    return v;
}


//vector<triples> trigram(wstring regex, wstring &line) { // Ueberladung, falls mit
//    return trigram(boost::wregex(regex), line); // wstring als "Regex" aufgerufen wird.
//}

//vector<triples> trigram(boost::wregex regexp = boost::wregex(L"..."), wstring &line) {
vector<triples> trigram(wstring regex, wstring &line) {
    vector<triples> vec;    /// mit "default"-regex

    /// Match-Vorbereitungen
    boost::wregex three(regex); // match three (wide-)characters in a row
    wstring::const_iterator offset = line.begin();
    wstring::const_iterator end    = line.end();
    boost::wsmatch          match;
    while (regex_search(offset, end, match, three) && match[0].matched) {
        if (Debug > 2) wcout << match << endl;
        offset =   match[0].second - 2;   // da alle permutationen von trigrammen gesucht
        vec.push_back(wstring(match[0].first, match[0].second)); // Konstruktor mit wstring(von, bis)
    }
    return vec;
}

int main(int argc, char** argv) {

    //Variables for main
    wstring str;

    // Setting up locale
    std::locale loc("");
    std::locale::global(loc);
    wcin.imbue(loc);
    wcout.imbue(loc);

    // Reading file, parsing arguments
    if (argc == 1) {
        wcout << L"Usage: " << argv[0] << L" <utf8.txt>" << endl;
        return 1;
    } else {
        str = readFile(argv[1], loc);
    }

    // Splitting text into tokens
    vector<wstring> tokens = my_split(L"\\W+", str);

    // something every programming language should have:
    BOOST_FOREACH(wstring s, tokens) {  // "Make simple things easy." (Larry Wall)
        wcout << s << endl;             //  via: boost/foreach.hpp :)
    }                                   //(http://www.boost.org/doc/libs/1_35_0/doc/html/foreach.html)


    // Splitting into triples
    vector<triples> trigrams = trigram(L"...", str);
    BOOST_FOREACH(wstring w, trigrams) wcout << w << endl;

    // Building hash of triples
    std::unordered_map<triples, int>   hashTrip;
    BOOST_FOREACH(wstring w, trigrams) hashTrip[w]++;


    //prepare output file
    std::wofstream out;
    if (argv[2] != NULL)
        out.open(argv[2], std::ios::app);
    else
        out.open("tri_deu.txt", std::ios::app);

    // Printing hash of triples with frequency
    typedef std::pair<wstring, int> hashPair; // weil foreach nur ein "," packt
    BOOST_FOREACH(hashPair x, hashTrip) out << x.second << L"\t" << x.first << endl;

    // Finally: done!
    return 0;
}


// Eine Loesung fuer Aufgabe 8.5 >:-)
// echo Aehnlichkeit && cut -f 2 trid_eu.txt | sort > 1 && cut -f 2 td.txt |sort> 2 &&  diff -y 1 2 | perl -ne '$i++ unless /[^<>|]....$/ }{ print 100-100*$i/$.' && echo

</code>
!!~HashCisString.hpp (modfied)
+++[einblenden][wieder ausblenden]
<code cpp>
/*
        HashCisString.hpp

    Class definitions
      and impelementations for
        class HashCisString

    Max Hadersbeck, Daniel Bruder
    CIS, LMU, Dez '09

*/

/* CHANGELOG
 * 14/01/2010 DB: Slightly modified for use with wstring
 * 16/12/2009 DB: Construction as a separate class header file
 * 15/12/2009 MH: First version of unordered_(hash)_map from
 *                new/upcoming C++-Standard 'C++0x'
 *
 */


/* COMPILATION / USAGE
 *
 * Needs compilation with g++ -std=c++0x <files>
 * and g++ Version >4.3 !!!
 *
 */



#ifndef HASH_CIS_STRING_HPP
#define HASH_CIS_STRING_hPP

#include <unordered_map>
#include <string>

//#include "std::wstring.hpp"

// For containers like hash_map the equal and hash classes must be defined!!!
// This class' function operator() generates a hash value for a key.
// Unique hash values (indeces) give quickest access to data.


class HashCisString {
  public:
    enum hash_fnkt {simple,h_boost,funk3};

    HashCisString(hash_fnkt h=simple);
    unsigned int operator()(const std::wstring&) const;

  private:
    enum hash_fnkt toHf;
    unsigned int hash_simple(const std::wstring&) const;

 ///------------------------------------------------------------
 //    Description:  Implementation of boost's default hash
 //          function (strongly simplified).
 // See at '/usr/include/boost/functional/hash/hash.hpp'.
 //
    unsigned int hash_boost(const std::wstring&) const;
};

typedef
  std::unordered_map<std::wstring, int, HashCisString> HashMap;

#endif

</code>
===
!~HashCisString.cpp (modfied)
+++[einblenden][wieder ausblenden]
<code cpp>
/*
        HashCisString.cpp

    Class impelementations for
        class HashCisString

    Max Hadersbeck, Daniel Bruder
    CIS, LMU, Dez '09

*/

/* CHANGELOG
 * 14/01/2010 DB: Slightly Modified for use with wstring
 * 16/12/2009 DB: Construction as a separate class header file
 * 15/12/2009 MH: First version of unordered_(hash)_map from
 *                new/upcoming C++-Standard 'C++0x'
 *
 */


/* COMPILATION / USAGE
 *
 * Needs compilation with g++ -std=c++0x <files>
 * and g++ Version >4.3 !!!
 *
 */



#ifndef HASH_CIS_STRING_CPP
#define HASH_CIS_STRING_CPP

#include <unordered_map>
#include <string>


//#include "cis_string.hpp"
#include "HashCisString.hpp"

// For containers like hash_map the equal and hash classes must be defined!!!
// This class' function operator() generates a hash value for a key.
// Unique hash values (indeces) give quickest access to data.


/**
* Computes the hash value of a string.
* The hash function is the one-at-a-time hash algorithm taken from wikipedia.
*
* @see http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time
* @param str the wstring for which the hash is computed.
* @return the hash value of the string.
*/

/* Constructor                                      */
HashCisString::HashCisString(hash_fnkt h) : toHf(h) { };

unsigned int HashCisString::operator()(const std::wstring& str) const {
    if (toHf==simple) {
        return hash_simple(str);
    }

    if (toHf==h_boost) {
        return hash_boost(str);
    }
}

unsigned int HashCisString::hash_simple(const std::wstring& str) const {
    unsigned int h = 0;
    std::wstring tmp = str;
    for(size_t i=0; i<str.length(); i++) {
        h += tmp.at(i);
        h += (h << 10);
        h ^= (h >> 6);
    }
        h += (h << 3);
        h ^= (h >> 11);
        h += (h << 15);
    return h;
}

 ///------------------------------------------------------------
 //    Description:  Implementation of boost's default hash
 //          function (strongly simplified).
 // See at '/usr/include/boost/functional/hash/hash.hpp'.
 //
unsigned int HashCisString::hash_boost(const std::wstring& str) const {
    unsigned h = 0;
    std::wstring tmp = str;
    for (unsigned i = 0; i < str.size(); ++i)
        h = 31 * h + tmp.at(i);
    return h;
}
#endif

</code>
===
<code cpp>
/*!
 * @brief Aufgabe 9, Verwendung von STL-Algorithms
 * @author Max Hadersbeck, Daniel Bruder
 *
 * Dieses Programm fuehrt die Verwendung der Algorithmen
 * aus der Klasse STL/algorithms vor
 */

/* Compile with g++ -lboost_regex 9.cpp */

#include <iostream>
#include <fstream>
#include <string>
#include <locale>

#include <algorithm>
#include <iterator>

#include <stdlib.h>
#include <cstdlib> // use like this, as it gets
                  // all methods of stdlib.h into namespace std:: (C did not have namespaces)
//Container
#include <vector>

//Boost::Regexes
#include <boost/regex.hpp>      // needs extra flags for compilation (see below)
#include <boost/algorithm/string/regex.hpp>
#include <boost/foreach.hpp>    // only for convenience reasons

using std::wcin;
using std::endl;
using std::wcout;
using std::vector;
using std::wstring;
using std::string;


/** Declarations **/
int  get_www_as_text(const std::string &url,const string &filename);
vector<wstring> my_split(wstring regex, wstring& line);
bool longer_than_5(wstring str);
bool shorter_than_5(wstring str);
bool wstr_compare(wstring str1,wstring str2);
bool austria_compare_w1_lt_w2(wstring w1, wstring w2);
bool comp_austria(const wstring &s1, const wstring &s2);


class wstr_to_lower {
public:
    wstring operator() (wstring wstr) const {        // notice the return type
        for (int i = 0; i < wstr.size(); i++)
            if (!iswlower(wstr.at(i)))
                wstr.at(i) = towlower(wstr.at(i));

        return wstr;
    }
}; // end class wstr_to_lower



int Debug=1;



main(int argc, char** argv) {

    string file="sz.txt.utf8";

    std::locale         mylocale("");
    std::locale::global(mylocale);

    std::wifstream  infile(file.c_str());

    wstring line;

    vector<wstring> tokens;
    vector<wstring> all_words;
    vector<wstring> all_words_lower;
    vector<wstring> all_words_short;
    vector<wstring> all_words_long;
    vector<wstring> all_words_sorted;

    // Um einen ostream_iterator mit einem wostream zu nutzen, heisst es:
    std::ostream_iterator<wstring,wchar_t> output ( std::wcout, L"\n" );
    std::ostream_iterator<wstring,wchar_t> output_komma( std::wcout, L"," );
    // Weil ein wostream einfach ein typedef von basic_ostream<wchar_t> ist.

    if ((infile == NULL)) {
        get_www_as_text("http://de.wikipedia.org/wiki/Gerhard_Polt",file);
        infile.open(file.c_str());
    }

    infile.imbue(mylocale);

    int number=0;
    while (getline(infile,line) && number < 10) {
        // Splitting text into tokens
        tokens = my_split(L"\\W+", line);
        number++;
        wcout << L"Zeile: "<< number << L":" << line << endl;

        std::copy( tokens.begin(), tokens.end(), output ); // Ausgabe
        wcout << L"----------------------------------------" << endl;
        //! 9.1: copy auf ende eines containers
        std::copy(tokens.begin(),tokens.end(),std::back_inserter(all_words));

    }

    //! Ausgabe: copy auf ostream_iterator
    wcout << endl << L"==============================" << endl << L"Alle Wörter Begin" << endl;
    std::copy(all_words.begin(), all_words.end(), std::ostream_iterator<wstring,wchar_t>( std::wcout, L"," ) );
    wcout << endl << L"==============================" << endl << L"Alle Wörter ende" << endl;

    //! 9.2: Transform: Verwendung einer unary-function auf alle Elemente einer range
    std::transform(all_words.begin(),all_words.end(),back_inserter(all_words_lower),wstr_to_lower());

    ///! Ausgabe
    wcout << endl << L"==============================" << endl << L"Alle Wörter LOWER Begin" << endl;
    std::copy(all_words_lower.begin(), all_words_lower.end(), output_komma );
    wcout << endl << L"==============================" << endl << L"Alle Wörter LOWER ende" << endl;


    //! 9.3 Make copies
    std::copy(all_words.begin(),all_words.end(),std::back_inserter(all_words_short));

    //! 9.4 remove alle Woerter kuerzer als 5 Buchstaben
    all_words_short.erase(remove_if(all_words_short.begin(),all_words_short.end(),longer_than_5),
                  all_words_short.end());

    //! Ausgabe
    BOOST_FOREACH(wstring s, all_words_short) wcout << s << endl;

    //! Ausgabe
    wcout << endl << L"==============================" << endl << L"Alle Wörter kürzer als 5 Begin" << endl;
    std::copy(all_words_short.begin(), all_words_short.end(), output_komma );
    wcout << endl << L"==============================" << endl << L"Alle Wörter kürzer als 5  ende" << endl;

    //! 9.5 remove_copy_if
    BOOST_FOREACH(wstring s, all_words) if (longer_than_5(s)) all_words_long.push_back(s);

    wcout << endl << L"==============================" << endl << L"Alle Wörter laenger als 5 Begin" << endl;
    std::copy(all_words_long.begin(), all_words_long.end(), output_komma );
    wcout << endl << L"==============================" << endl << L"Alle Wörter laenger als 5  ende" << endl;


    //! 9.6 Verwenden Sie die STL-Funktion sort, unique  und copy Funktion:
    // Sortieren Sie den vector<wstring> all_words_short und entfernen Sie alle Duplikate mit Hilfe der STL-Funktion unique. Geben Sie das Ergebnis mit STL-Funktion copy auf dem Terminal aus.
    // (siehe Aufgabe 7 oder 8)

	// Einzigartige Elemente ablegen
	vector<wstring> uniq;

	// Sortieren, damit unique arbeiten kann
	//sort(all_words.begin(), all_words.end());		///< 9.6 mit wstring-sort
	sort(all_words.begin(), all_words.end(),comp_austria);	///< 9.7 mit eigenem sort

	// Alle unique-Woerter weiterkopieren
	unique_copy(all_words.begin(), all_words.end(), std::back_inserter(uniq));

	// Ausgabe der uniques
	wcout << endl<< L"UNIQUE BEGIN" << endl;
	BOOST_FOREACH(wstring w, uniq) wcout << w << L", ";
	wcout << endl<< L"UNIQUE END" << endl;

}





vector<wstring> my_split(wstring regex, wstring& line) {
/** @brief Split one big string into multiple tokens        */
/* von Daniel Bruder */
    vector<wstring> v;
    boost::wregex rx(regex);
    boost::algorithm::split_regex(v, line, rx); // this is enough.
    return v;
}


int  get_www_as_text(const string &url,const string &filename) {
/// Achtung: kann Encoding auf ISO-Latin-1 "zurueckschiessen" (DB)!!!
  string tmp_file="file.html";
  string cmd = "wget \""+url+"\" -O "+tmp_file;
  string cmd2("lynx -dump "+tmp_file+" -assume_charset=UTF-8 -hiddenlinks=ignore -nolist -verbose > "+filename);

  if (Debug == 1)
    {
      wstring wcmd(cmd.length(),L' ');
      std::copy(cmd.begin(),cmd.end(),wcmd.begin());
      wcout << "DEBUG: wget cmd: " << wcmd << endl;

      wstring wcmd2(cmd2.length(),L' ');
      std::copy(cmd2.begin(),cmd2.end(),wcmd2.begin());
      wcout << "DEBUG: lynx cmd: " << wcmd2 << endl;
    }

  system(cmd.c_str());
  system(cmd2.c_str());
  return 1;

}

bool longer_than_5(wstring str) { return str.size() >= 5; }
bool shorter_than_5(wstring str) { return str.size() < 5; }


//! bli bla blupp
bool wstr_compare(wstring str1,wstring str2) {
  return str1 > str2;  // Das ist falsch (?)
}



bool austria_compare_w1_lt_w2 (wstring w1, wstring w2){ //Vergleich nach österreichischer Norm (Max)
  std::wstring alphabet(L"aäbcdefghijklmnoöpqrstuüvwxyzAÄBCDEFGHIJKLMNOÖPQRSTUÜVXYZ0123456789");
  bool comp_is_decided=false;
  bool is_lower=true;
  wchar_t letter_first,letter_second;
  size_t found_first,found_second;
  int i;
  i=0;
  while ((i<w1.size() && i<w2.size()) && !comp_is_decided) {
    letter_first = w1.at(i);
    found_first = alphabet.find(letter_first);
    letter_second = w2.at(i);
    found_second = alphabet.find(letter_second);
    if(found_first < found_second){
      comp_is_decided=true;
      is_lower=true;
    }
    else if(found_first == found_second) {
         }
         else {
           comp_is_decided=true;
           is_lower=false;
         }
    i++;
  }
  return is_lower;
}


bool comp_austria(const wstring &s1, const wstring &s2) {
///< sortiert nach österreischer Sortier-Variante (aus Aufgabe 7)

// [...] und die Idee der „Österreicher“
//
// std::wstring char_ord[]=“aäbcdefghijklmnoöpq   …“
//
// mit jedem Buchstaben sucht man die Position im String,
//
// Die Position gibt die Prioritätenordnung aus, je kleiner, desto früher im Alphabet.
//
// Viele Grüße
//
// MAX

    std::wstring ord = L"AaÄäBbCcDdEeFfGgHhIiJjKkLlMmNnOoÖöPpQqRrSsßTtUuÜüVvWwXxYyZz0123456789";    // NEW

    int i = 0;
    while (i < s1.size()) {
        if (i < s2.size()) {
            int ord1 = ord.find(s1[i]);
            int ord2 = ord.find(s2[i]);
            if (ord1 == ord2) {
                i++;
            } else if (ord1 < ord2) {
                return true;
            } else if (ord2 < ord1) {
                return false;
            }
        } else if (i == (s1.size()-1))
            return true;
          else
            return false;
    }
}


</code>
; 2.1 Schreiben Sie ein C++ Programm, das einen String einliest und testet, ob der erste und der letzte Buchstabe eines Strings identisch ist.
<code cpp>
/* 
    2.1 / 2.2
    
    Ein Wort / String einlesen und prüfen, ob der erste und der letzte Buchstabe
    identisch sind.

*/



#include <iostream>
#include <string>

using namespace std;

int main() {
    string  s;
    
    // cin >> s;            // Für "Wörter"; Vorsicht aber mit führenden oder 
    getline(cin, s);        // folgenden Leerzeichen im Stream!
    
    if (s.at(0) == s.at(s.size()-1))
        cout << "Identisch!" << endl;
    else
        cout << "Nicht Identisch" << endl;

    return 0;
}
</code>

;2.2 Schreiben Sie ein C++ Programm, das eine Zeile einliest und testet, ob der erste und der letzte Buchstabe einer Zeile identisch ist.
&rarr; siehe Lösung 2.1

; 2.3 Schreiben sie ein Programm translate. Dieses Programm soll eine Textzeile einlesen und alle Großbuchstaben in Kleinbuchstaben und umgekehrt konvertieren und ausgeben.
<code cpp>
/*
    2.3

    Translate: 
    Liest eine Textzeile ein und wandelt alle Großbuchstaben
    in Kleinbuchstaben und umgekehrt.
    
*/


#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>

using namespace std;


char caseChange(char ch) {  // Unäre Funktion für Variante 3
    if (isupper(ch))
        return tolower(ch);
    else
        return toupper(ch);
}

int main() {
    
    string  s;
    
    getline(cin, s);
    
    // Variante 1: isupper() / tolower()
    for (unsigned int i = 0; i < s.size(); i++) {
        if (isupper(s.at(i))) {
            s.at(i) = tolower(s.at(i));    
        }
        else if (islower(s.at(i)))
            s.at(i) = toupper(s.at(i));
    }
    
    
    //Variante 2: Nutzung der Ascii-Tabelle (nicht locale-fähig!)
    /*
    int diff = 'a' - 'A';
    
    for (int i = 0; i < s.length(); i++) {
        if (s[i] >= 'A' && s[i] < 'a')       // ist GROSS
            s[i] += diff;
        else if (s[i] >= 'a' && s[i] <= 'z')
            s[i] -= diff;
    }
    */
    
    
    // Variante 3: 'Algorithms' aus der Standard Template Library
    // transform(s.begin(), s.end(), s.begin(), caseChange);
    
    cout << s << endl;
    
    return 0;
}
</code>
; 2.4 Was passiert, wenn Sie einen Text mit Umlauten eingeben?
Umlate können nicht gewandelt werden, da die Methoden auf Grundlage der ~Ascii-Tabelle arbeiten.

; 2.5 Schreiben Sie das Programm lesen.cxx von Seite 19 ab und testen Sie verschiedene Eingaben:
* Eingabe einer Zahl
* Eingabe von mehreren Zahlen
* Eingabe eines Wortes (ohne Umlaut)
* Eingabe von zwei Worten (ohne Umlaut)
* Eingabe von Umlauten
* Eingabe einer ganzen Zeile (mit Umlauten)
{{{
#include <iostream>
#include <string>
//
// Filename: lesen.cxx
// Autor: Max
// Here: Buchstabenweises Lesen von stdin
// Datum: April 2002

using namespace std;

int main()
{

  char zeichen;
  while (cin.get(zeichen))
    cout.put(zeichen);

  return 0;
}
}}}

get()/put() arbeiten mit unformatierten Rohdaten vom Stream und haben daher keine Probleme, da sie mehr oder weniger 'bytes auslesen' und wiedergeben.
; 2.2 Für die Strebsamen: Lesen Sie einen String ein und wandeln Sie alle Großbuchstaben in kleine und vice versa!
{{{
/*
	Code
*/
}}}
; 3.1 Schreiben Sie drei C++ Programme: pword_for.cxx, pword_while.cxx und pword_do.cxx Das Programm soll den Benutzer höchstens 5 Mal nach einem Passwort fragen.

//Die interne Abfrageschleife soll beim Programm pword_for.cxx als for Schleife, beim Programm pword_while.cxx als while Schleife und beim Programm pword_do.cxx als do Schleife implementiert werden.

ACHTUNG: Das interne Passwort soll aus der Datei mypasswd.txt gelesen werden. Verwenden Sie also Routinen des FILE I/O aus Kapitel 3.6.
Die Eingaben des Benutzers, auch die Eingaben aus den letzten Programmläufen, sollen in einer Datei log.txt gespeichert werden (TIPP: open for append!).//

<code cpp>
/*
    Passwort-Raten mit for-Schleife

*/
#include <iostream>
#include <fstream>
using namespace std;

int main() {
    string      password;
    ifstream    passFile("mypasswd.txt");

    if(!passFile) {
        cout << "Die Passwort-Datei konnte nicht gelesen werden!" << endl;
        return 1;
    }
    passFile >> password;
    passFile.close();

    ofstream    logFile("log.txt", ios::app);
    string      eingabe;

    for(int i=5; i > 0; i--) {
        cout << "Bitte Passwort eingeben (noch " << i << " Versuch(e)): ";
        cin >> eingabe;
        if(eingabe == password)
            i = 0; // Schleife beenden 
        else if(logFile)
            logFile << eingabe << endl;
    }
    logFile.close();
    
    if(eingabe == password)
        cout << "Das Passwort ist richtig." << endl;
    else
        cout << "Das Passwort wurde 5 mal falsch eingegeben!" << endl;

    return 0;
}
</code>

<code cpp>
/*
    Passwort-Raten mit while-Schleife

*/

#include <iostream>
#include <fstream>
using namespace std;

int main() {
    string      password;
    ifstream    passFile("mypasswd.txt");

    if(!passFile) {
        cout << "Die Passwort-Datei konnte nicht gelesen werden!" << endl;
        return 1;
    }
    passFile >> password;
    passFile.close();

    ofstream    logFile("log.txt", ios::app);
    string      eingabe;
    int         i = 5;

    while(i > 0) {
        cout << "Bitte Passwort eingeben (noch " << i << " Versuch(e)): ";
        cin >> eingabe;
        if(eingabe == password)
            break; // Andere Variante um die Schleife zu beenden 
        else if(logFile)
            logFile << eingabe << endl;
        i = i - 1;
    }
    logFile.close();
    
    if(eingabe == password)
        cout << "Das Passwort ist richtig." << endl;
    else
        cout << "Das Passwort wurde 5 mal falsch eingegeben!" << endl;

    return 0;
}
</code>


<code cpp>
/*
    Passwort-Raten mit do-while-Schleife

*/

#include <iostream>
#include <fstream>
using namespace std;

int main() {
    string      password;
    ifstream    passFile("mypasswd.txt");

    if(!passFile) {
        cout << "Die Passwort-Datei konnte nicht gelesen werden!" << endl;
        return 1;
    }
    passFile >> password;
    passFile.close();

    ofstream    logFile("log.txt", ios::app);
    string      eingabe;
    int         i = 5;

    do {
        cout << "Bitte Passwort eingeben (noch " << i << " Versuch(e)): ";
        cin >> eingabe;
        if(eingabe == password)
            i = 0;
        else if(logFile)
            logFile << eingabe << endl;
        i--;
    } while(i > 0);
    logFile.close();

    if(eingabe == password)
        cout << "Das Passwort ist richtig." << endl;
    else
        cout << "Das Passwort wurde 5 mal falsch eingegeben!" << endl;

    return 0;
}
</code>

; 3.2. Schreiben sie ein Programm count_punct! Dieses Programm soll eine Textzeile einlesen, diese Zeile ausgeben und in der nächsten Zeile die Positionen aller Punktuationszeichen anzeigen.
<code cpp>
/*
	Count-Punct
	Variante 1
*/

#include <iostream>
#include <cctype>
#include <string>
using namespace std;

int main() {
    string str;

    cout << "EINGABE> ";
    getline(cin, str);
    
    cout << "AUSGABE>\n" << str << endl;
    for(int i=0; i<str.length(); i++) {
        if(ispunct(str.at(i)))
            cout << "^";
        else
            cout << " ";
    }
    cout << endl;
    
    return 0;
}
</code>

<code cpp>
/*
	Count-Punct
	Variante 2
*/

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str;

    cout << "EINGABE> ";
    getline(cin, str);
    
    cout << "AUSGABE>\n" << str << endl;
    int p = str.find_first_of(",.;:()?!");
    for(int i=0; p != string::npos; i++) {
        if(i == p) {
            cout << "^";
            p = str.find_first_of(",.;:()?!", i+1);
        }
        else
            cout << " ";
    }
    cout << endl;
    
    return 0;
}
</code>
; 4.1 Schreiben Sie ein Programm, das ein Wort (mit Umlauten) von der Tastatur einliest, die Anzahl der Buchstaben des Wortes ausgibt und jeden zweiten Buchstaben des Wortes ausgibt. Verwenden Sie dazu die Objektklasse wstring und wcin, wcout usw.
<code cpp>
/*

    4.1.cpp

    Wort einlesen,
    Buchstaben zählen,
    jeden zweiten Buchstaben ausgeben

*/


#include <iostream>
#include <locale>
#include <string>

using namespace std;

int main() {

    // Locale einstellen
    locale      loc("");        // locale vom Betriebssystem erfragen
    locale::global(loc);

    // Variablen
    wstring     wstr;

    // Einlesen
    wcin >> wstr;

    // wcout << wstr.size() << endl;

    for (int i = 0; i < wstr.size(); i+=2) {        // "gerade" Buchstaben ausgeben
        wcout << wstr.at(i) << L' ';
    }
    wcout << endl;

    for (int i = 0; i < wstr.size(); i++) {         // "ungerade" Buchstaben auch ausgeben
        if (i % 2 == 1) {
            wcout << L' ' <<  wstr.at(i);
        }
    }
    wcout << endl;


    return 0;
}

</code>
; 4.2 Schreiben Sie ein Programm, das eine Zeile von der Tastatur einliest, die Anzahl der Buchstaben des Wortes ausgibt und die Anfangsbuchstaben der Wörter der Zeile in Groß- bzw. Klein-buchstaben konvertiert und ausgibt.
<code cpp>
/*

    4.2.cpp

    Zeile einlesen,
    Buchstaben jedes Wortes zählen,
    Anfangsbuchstaben in gross/klein ausgeben

    (Lösungsgrundlage: Stefan Partusch)

*/


#include <iostream>
#include <locale>
#include <string>

using namespace std;

int main() {

    // Locale einstellen
    locale      loc("");        // locale vom Betriebssystem erfragen
    locale::global(loc);

    // Variablen
    wstring     line;
    bool        inWord;
    int         alphas = 0;     // auf Wert einstellen, sonst steht etwas aus dem Speicher drin

    // Einlesen
    getline(wcin, line);

    inWord = false;
    for (int i = 0; i <= line.size(); i++) {
        if (i == line.size() || isspace(line.at(i), loc) ) {
            inWord = false;
            if (alphas > 0) {
                wcout << L"Das Wort (vorher) hat " << alphas <<  L" Buchstaben" << endl;
                alphas = 0;
            }
        } else {
            if(isalpha(line.at(i), loc)) {
                if (inWord == false) {
                    inWord = true;

                    if (iswupper(line.at(i)))
                        line.at(i) = towlower(line.at(i));
                    else if (iswlower(line.at(i)))
                        line.at(i) = towupper(line.at(i));

                    wcout << L"Wortanfang: " << line.at(i) << endl;
                }
                alphas++;
            }
        }
    }


    return 0;
}

</code>

; 4.3 Schreiben Sie ein Programm, das eine Zeile von der Tastatur einliest und ausgibt, jedoch sollen alle großen Buchstaben in kleine gewandelt werden, alle kleinen in große.
{{{
   z.B.
   EINGABE> übermorgen
   AUSGABE> ÜBERMORGEN
}}}

<code cpp>
/*
    4.3.cpp

    UTF-8 CaseChange

*/

#include <iostream>
#include <locale>

using namespace std;


// Funktion/"Methode" caseChange wandelt einen ganzen wString:
wstring caseChange(wstring w) {
    for (int i = 0; i < w.size(); i++) {
        if (iswupper(w.at(i)))
            w.at(i) = towlower(w.at(i));
        else if (iswlower(w.at(i)))
            w.at(i) = towupper(w.at(i));
    }
    return w;
}

int main() {

    // Locale einstellen
    locale      loc("");
    locale::global(loc);

    // Variablen deklarieren
    wstring     line;

    // Einlesen
    getline(wcin, line);

    // (gewandelt) Ausgeben
    wcout << caseChange(line) << endl;      // Der Rüchgabewert von caseChange ist "wstring", daher geht das!

    return 0;
}
</code>
;5.1 Schreiben Sie ein C++ Programm "copy_into_utf8.cxx".
//Das Programm soll eine beliebige Datei in eine zweite Datei im utf-8 format kopieren. Das Programm soll den Benutzer nach dem Namen der alten Datei und nach der Kodierung der alten Datei fragen.//
<code cpp>
/*

    5.1.cpp

    Datei mit bestimmter/beliebiger Codierung lesen und als UTF-8 rausschreiben

*/

#include <iostream>
#include <fstream>
#include <locale>

using namespace std;

int main() {

    string  filename;
    string  encoding;

    // Benutzer fragen
    cout << "Welche Datei?" << endl;
    cin >> filename;
    cout << "Welche Codierung?" << endl;
    cin >> encoding;

    // Zu kopierende Datei öffnen
    wifstream   in_stream(filename.c_str());		// In-File öffnen (verlangt c-string)
    locale      infile_loc(encoding.c_str());       // locale-objekt holen für imbue (verlangt c-string)
    in_stream.imbue(infile_loc);                    // Kanal von In-File "einfärben"

    // Zu schreibende Datei öffnen
    filename += ".utf8";                            // Neuer Filename wird hergestellt (append)
    wofstream   out_stream(filename.c_str());
    locale      outfile_loc("de_DE.UTF-8");
    out_stream.imbue(outfile_loc);


    wstring     filecontent;

    if (!in_stream && !out_stream) {
        return 1;
    } else {
        while(getline(in_stream, filecontent)) {
            out_stream << filecontent << endl;		// "endl" muss mit, da getline dieses verwirft!
        }
    }

    // das selbe mit Klammersparung
    /*if (in_stream.good() && out_stream.good())
        while(getline(in_stream, filecontent)) 
            out_stream << filecontent << endl;
    else
        return 1;
    */
    return 0;
}

</code>

;5.2 Schreiben sie ein C++ Programm "wordlist.cxx".
//Dieses Programm soll eine utf-8 Datei lesen und die Wörter der Datei zeilenweise in eine neue Datei kopieren. Die Wörter müssen alle in kleingeschriebene Wörter konvertiert werden. Die Wörter in der neuen Datei dürfen am Ende keine Punktuationszeichen haben. Sie müssen also vor dem Übertragen gelöscht werden.
Der Name der Eingabedatei soll vom Benutzer erfragt werden und die neue Datei soll den Namen der alten Datei bekommen, die Extension des Dateinamens der neuen Datei soll aber _wordlist.txt sein.//
{{{
Beispiel:
      EINGABEFILENAME>text.txt
      AUSGABEFILENAME>text_wordlist.txt
}}}

<code cpp>
/*

    5.2.cpp

    "wordlist"

    Benutzer nach Dateinamen fragen,
    und diese UTF-8-Datei lesen.

    Dann in eine UTF-8-Datei schreiben, die:
        * den Namen <dateiname>_wordlist.txt trägt,
        * dort jedes Wort auf eine eigene Zeile,
        * kleingeschrieben,
        * und vorher von Punktuationszeichen (rechts) befreit.

*/

#include <iostream>
#include <fstream>
#include <locale>
#include <string>

using namespace std;

void tolower(wstring &w) {                   // Die Funktion ist "void", daher kein return
    for (int i = 0; i < w.size(); i++) {     // und schreibt auf das "Original", den wstring &w
        w.at(i) = towlower(w.at(i));
    }
}

int main() {

    // Variablen deklarieren
    string      filename;
    wstring     word;


    // Benutzer fragen
    cout << "Bitte Dateinamen eingeben: " << endl;
    cin >> filename;


    // Neuen Dateinamen herstellen
    const string filename_old = filename;                           // behalten wir ab jetzt (wird nicht mehr verändert)

    size_t      pos = filename.rfind('.');
    if(pos != string::npos)                                         // Wenn Dateiname (von hinten gesehen) einen Punkt enthält...
        filename.insert(pos, "_wordlist");                          // ...dann an dieser Stelle "_wordlist" davor einfügen
    else                                                            // sonst:
        filename += "_wordlist";                                    // "_wordlist" ans Ende schreiben

    cerr << "filename_old " << filename_old << endl;
    cerr << "filename     " << filename     << endl;

    // Locale einstellen
    locale       utf8_loc("de_DE.UTF-8");
    locale::global(utf8_loc);


    // Kanäle zum lesen und rausschreiben öffnen
    wifstream       in(filename_old.c_str());
    wofstream       out(filename.c_str());

    // Kanäle sicherheitshalber einfärben
    in.imbue(utf8_loc);
    out.imbue(utf8_loc);
    wcout.imbue(utf8_loc);


    // Einlesen, Säubern und in Datei schreiben
    if (!in && !out) {
        wcout << L"Something is terribly wrong here..." << endl;
    } else {                                                        // Wenn die Streams sauber geöffnet werden konnten, übernimmt 
        while (in >> word) {                                        // Der ">>"-Operator freundlicherweise das tokensieren (an spaces!)
            //wcout << word << L"  -->  ";                          // (für Debug-Zwecke)
            if (word.find_first_of(L",.!?\"") != string::npos)      // alles, was auf eines dieser Zeichen folgt...
                word = word.erase(word.find_first_of(L",.!?\""));   // wird "weggeschmissen" (etwas rabiat!!)
            tolower(word);                                          // und mit einer eigenen Funktion nach kleingeschrieben konvertiert
            //wcout << word << endl;                                // (für Debug-Zwecke)
            out << word << endl;                                    // in Datei schreiben
        }
    }
    return 0;
}
</code>
;5.3 Erzeugen Sie mit Hlfe von UNIX Befehlen eine Wortliste und geben die 5 wichtigsten Wörter aus.
{{{
cat sz_wordlist.txt | sort | uniq -c | sort -rn | head -5
}}}
//Eine der wichtigsten Eigenschaften eines Tokenizers ist, Zeichenketten, die für sich Entitäten sind, nicht zu trennen. z.B. Datumsangaben, Abkürzungen, ganze Zahlen in Tausenderschreibweise usw.//

;Schreiben Sie ein C++ Programm, das eine Zeile von der Tastatur einliest und testet, ob in der Zeile eine bestimmte Entität vorkommt.
;Schreiben sie Erkenner als C++ Funktionen vom Typ:
{{{
    bool is_a_entity(wstring line,int pos);
    Eingabe: wstring line ... die eingegebene Textzeile
    Ausgabe: int pos ... der Index ab dem die erkannte entity beginnt; npos, falls nichts gefunden wurde.
    Returnvalue: bool ... true, falls gefunden, false, falls nicht gefunden
}}}
;Schreiben Sie...
;6.1 ...einen Erkenner für die entity {{{is_a_dezimaldigit}}}: 
//Dieser erkennt Dezimalzahlen, die als Tausendertrennzeichen einen Punkt haben wie z.B. 1.234.567//
;6.2 ...einen Erkenner für entity  {{{is_a_roman}}}:
//Dieser erkennt römische Zahlen wie XIV usw. V. mit/ohne Punkt hinterher//
;6.3 ...einen Erkenner für Datum:  {{{is_a_date}}}:
//Dieser erkennt Zahlen gefolgt von einem Punkt, der von einem Monat (Einschränkung: maximal 3 Buchstaben) gefolgt wird://
{{{
      z.B.

      31.12.  
      24./25.12.
      24.-25.01.
      1. Aug.
      10. Jan.
      4.Dez.
      15.Apr
}}}
;6.4 ...einen Erkenner für Uhrzeiten:  {{{is_a_time}}}:
//Dieser erkennt Jede Stundenzahl gefolgt von einem Punkt/Doppelpunkt einer einer Minutenzahl://
{{{
      z.B.

      9:30
      8.15
      0.30
}}}
;6.5 ...einen Erkenner für Gedankenabbruch: {{{is_a_think}}}:
//Dieser erkennt z.B.://
{{{
      Wer denkt, dass ich der größte ... bin, der irrt gewaltig.
}}}

;6.6 (freiwillig, für Leute die unterbeschäftigt sind):
//Scheiben Sie das Progamm so um, dass nicht nur eine Zeile von der Tastatur gelesen wird, sondern eine ganze Datei von <stdin> gelesen wird.
(Tipp: Stecken Sie getline in eine while - Schleife).//
Jetzt aber das Problem:
Wird eine Entität gefunden, dann geben Sie als gefundene Position, ab der die Entität beginnt, den Index des ersten Buchstabens der Entität innerhalb der gesamten DATEI aus, nicht den Index innerhalb der aktuellen Zeile!!

;Literaturangabe:
siehe Kapitel 2: Funktionen des Punktes, aus: Volker Severt, Diplomarbeit (2005): Robuste Strategien zur Detektion von Satzgrenzen, Universität Mageburg 

<code cpp>

/*

    is_an_entity


*/


#include <iostream>
#include <locale>
#include <string>
#include <cctype>
#include <algorithm>
#include <vector>

using namespace std;

int             Debug;              // eine globale Variable

bool is_a_roman(wstring &line) {

    size_t      pos_search;
    size_t      pos_to;
    size_t      pos_from;

    pos_search = line.find_first_of(L"IVXCDLM");                                // Arithmetik? Nein danke!

    if (pos_search != string::npos and pos_search == 0 or                       // 'and' bindet stärker als 'or'!
        pos_search != string::npos && iswspace(line.at(pos_search-1))) {        // (und '&&' ist dasselbe wie 'and')

        if (Debug >= 1) wcerr << L"Found Roman beginning at " << pos_search << endl;

        pos_from = pos_search;                                  // diese Stelle merken wir uns...
        pos_to   = pos_search;                                  /// ...und diese Stelle verschieben wir weiter...

        while(pos_search != string::npos) {                     //// ...so lange wie es geht
            pos_to = pos_search;
            if (Debug >= 1) wcerr << L"Found last roman elem at " << pos_to << endl;
            pos_search = line.find_first_of(L"IVXCDLM", ++pos_search);
        }

        if (pos_to < line.length()) {                           // will geprüft sein, damit wir im folgenden nicht "daneben greifen"
            //! Zerhauen!
            if ((pos_to+2 < line.length()    and pos_to+1 == L'.' and iswspace(line.at(pos_to+2)) ) or      // im Satz
                 (pos_to  == line.length()-2 and pos_to+1 == L'.' ))                                       // am Ende der Zeile
                    wcout << L"Found roman from " << pos_from
                          <<              L" to " << pos_to
                          << L" (with terminating '.') at " << ++pos_to;
            else if (pos_to+1 < line.length() and iswspace(line.at(pos_to+1)) or
                     pos_to  == line.length()-1                                  )
                    wcout << L"Found roman from " << pos_from
                          <<              L" to " << pos_to;
            wcout << endl;
        }
        return true;
    }
    else { return false; }
}

bool is_a_time(wstring &line) {

    size_t      pos_from;


    for (int i = 0; i < line.length(); i++) {
        if (iswdigit(line.at(i))) {                                                                     // wenn es eine digit gibt...
            if (Debug >= 1) wcerr << L"is_a_time:: Found possible beginning of time at " << i << endl;
            pos_from = i;                                                                               ///  ...stelle merken...
            i++;                                                                                        //// .... gleich einen schritt weitergehen
            if (iswdigit(line.at(i))) {                                                                 // noch eine Zahl?
                if (Debug >= 1) wcerr << L"is_a_time:: Found a second digit before ':' at " << i << endl;
                i++;                                                                                    /// ... dann noch einen Schritt weiter
            }
            if (line.at(i) == L':' or line.at(i) == L'.') {                                             //// ... sonst das hier
                if (Debug >= 1) wcerr << L"is_a_time:: found ':' at " << i << endl;
                i++;
            }
            if (iswdigit(line.at(i)) and iswdigit(line.at(++i))) {		// etc.
                wcout << L"is_a_time:: Found time from " << pos_from << L" to " << i << endl;
                if (line.at(i+1) == L'h' or line.at(i+1) == L'H')
                    wcout << L"is_a_time:: and the time is followed 'h/H' at " << ++i << endl;
                return true;
            }
        }
    }
    return false;
}

bool is_a_thought(wstring &line) {

    /* 
        die string-Methode 'find' erledigt alles.
    */

    size_t      from;

    from = line.find(L" ... ");
    if (from != string::npos) {
        wcout << L"is_a_thought:: Found a thought from " << from << L" to " << from+4 << endl;
        return true;
    } else

    return false;
}

bool is_a_decimal(wstring line) {

    /* Die Idee um auf eine "richtige" Dezimalzahl zu schließen ist
        den Anfang einer solchen zu finden (also eine Zahl) und
        von dieser aus weiter zu gehen, so lange Zahlen erscheinen
        oder ein Punkt: in diesem Fall merken wir uns, dass die Dezimalzahl mit
        Punktschreibweise gefunden wurde in with_dots = true.
        
        Wenn dem so ist, testen wir von hinten kommend, ob an jeder zu erwartenden Stelle auch entsprechend ein Punkt sitzt.
    */

    size_t      pos_from;
    size_t      pos_to;
    wstring     dec;
    bool        with_dots = false;

    for (int i = 0; i < line.length(); i++) {
        if (iswdigit(line.at(i)) and i == 0 or iswdigit(line.at(i)) and iswspace(line.at(i-1))) {   // word boundary oder Zeilenanfang?
            if (Debug >= 1) wcerr << L"DEC:: Found possible begin of a digit at " << i << endl;
            pos_from = i;
            while(i!=line.length() and (iswdigit(line.at(i)) or line.at(i) == L'.')) {
                if (line.at(i) == L'.') with_dots = true;                                           // Ah: eine Dezimalzahl mit Punkten
                i++;
            }
            if (i == line.length() or iswspace(line.at(i))) {                                       // Word boundary oder Zeilenende?
                pos_to = i-1;
                for (int j = pos_from; j < i; j++) dec += line.at(j);
                if (Debug >= 1) wcerr << L"DEC:: Found possible dec " << dec << endl;               // noch ist nicht sicher, ob es eine "echte" Dezimalzahl ist
                i = line.length();
            }
        }
    }

    bool correct = true;
    wcout << dec << endl;
    for (int i = dec.size()-4; i >= 0; i-=4) {                                                      // sitzen die Dezimalpunkte richtig?
        wcerr << L"DEC:: Testing position " << i << L" which is " << dec.at(i) << endl;
        if (with_dots and i >= 0 and dec.at(i) != L'.') correct = false;
    }
    if (correct == true) {
        wcout << L"DEC:: Found a decimal number from " << pos_from << L" to " << pos_to << endl;    // OK.
        return true;
    }
    return false;
}


bool is_a_date(wstring &line) {
/*

    die einzig vernünftig erscheinende Lösung für diese Aufgabe ist die von Florian Fink

*/
}


int main() {

    locale         loc;
    locale::global(loc);

    wstring        in_line;

    getline(wcin,  in_line);
    Debug = 2;

   is_a_roman(in_line)    ? wcout << L"There is a roman" << endl : wcout << L"Cannot find any romans" << endl;
   is_a_time(in_line)     ? wcout << L"There is a time"  << endl : wcout << L"Cannot find any time"   << endl;
   is_a_thought(in_line)  ? wcout << L"There is a thought"  << endl : wcout << L"There are no thoughts" << endl;
   is_a_decimal(in_line)  ? wcout << L"There is a decimal"  << endl : wcout << L"There are no decimals" << endl;
//     is_a_date(in_line)  ? wcout << L"We have a date"  << endl : wcout << L"We don't have a date" << endl;    // siehe Florian Fink
    return 0;
}

</code>

!!! Nachtrag
Wie bei der Aufgabe zu {{{bool is_a_date(wstring &line) }}} angemerkt, stellt Florian Fink seinen kompletten Lösungsansatz der Aufgabe (sowie der anderen Aufgaben) zur Verfügung; herzlichen Dank an Florian!

{{{
// UEBUNG C++ von  finkf@cip.ifi.lmu.de: Anna Schweiger, Florian Fink
/*
 * FILE: entity.cpp
 * Schreiben Sie ein C++ Programm, das eine Zeile von der Tastatur einliest und testet, 
 * ob in der Zeile eine bestimmte Entität vorkommt.
 *
 * 1. Erkenner für entity  is_a_dezimaldigit
 * Dezimalzahlen, die als Tausendertrennzeichen einen Punkt haben wie z.B. 1.234.567
 *
 * 2. Erkenner für entity  is_a_roman
 * römische Zahlen wie XIV usw. V. mit/ ohne Punkt hinterher
 *
 * 3. Erkenner für Datum:  is_a_date
 * Jede Zahl gefolgt von einem Punkt, der von einem Monat (Einschränkung: maximal 3 Buchstaben) gefolgt wird.
 * z.B.
 * 31.12.  
 * 24./25.12.
 * 24.-25.01.
 * 1. Aug.
 * 10. Jan.
 * 4.Dez.
 * 15.Apr
 * 
 * 4. Erkenner für Uhrzeiten:  is_a_time
 * Jede Stundenzahl gefolgt von einem Punkt/Doppelpunkt einer einer Minutenzahl
 * z.B.
 * 9:30
 * 8.15
 * 0.30
 *
 * 5. Erkenner für Gedankenabbruch  is_a_think
 * z.B.
 * Wer denkt, dass ich der größte ... bin, der irrt gewaltig.
 *
 * 6. (freiwillig, Für Leute die unterbeschäftigt sind)
 * Scheiben Sie das Progamm so um, dass nicht nur eine Zeile von der Tastatur gelesen wird, 
 * sondern eine ganze Datei von <stdin> gelesen wird.
 * (Tipp: Stecken Sie getline in eine while - Schleife).
 * Jetzt aber das Problem:
 * Wird eine Entität gefunden, dann geben Sie als gefundene Position, ab der die Entität beginnt, 
 * den Index des ersten Buchstabens der Entität innerhalb der gesamten DATEI aus, nicht den Index innerhalb der aktuellen Zeile!! 
 */
#include <iostream>
#include <fstream>
#include <locale>
#include <cstdlib>

enum SYM_TYPE {White, Digit, UChar, LChar, Punct, Colon, Dash, Slash, Else};
struct sym{SYM_TYPE sym; wchar_t val;};
const size_t FINAL_STATE = 10000;
const size_t POS_SIZE = 5;

inline void getSym(wchar_t c, sym& s);
inline size_t nextDezState(const sym& s, size_t state);
inline size_t nextRomanState(const sym& s, size_t state);
inline size_t nextTimeState(const sym& s, size_t state);
inline size_t nextDateState(const sym& s, size_t state);
bool is_a_dezimaldigit(const std::wstring& str, size_t& pos);
bool is_a_roman(const std::wstring& str, size_t& pos);
bool is_a_date(const std::wstring& str, size_t& pos);
bool is_a_time(const std::wstring& str, size_t& pos);
bool is_a_think(const std::wstring& str, size_t& pos);
inline void showPos(std::wostream& out, size_t pos[], size_t lineC, size_t offset);
const std::locale LOC = std::locale("");

//returns the enum of the symbol
inline void getSym(wchar_t c, sym& s)
{
  s.val = c;
  if(isupper(c, LOC))
    s.sym = UChar;
  else if(islower(c, LOC))
    s.sym = LChar;
  else if(isdigit(c, LOC))
    s.sym = Digit;
  else if(isspace(c, LOC))
    s.sym = White;
  else
    {
      switch(c)
	{
	case L'.': s.sym = Punct; break;
	case L':': s.sym = Colon; break;
	case L'-': s.sym = Dash; break;
	case L'/': s.sym = Slash; break;
	default: s.sym = Else; break;
	}
    }
}

//returns the next state for dezimal digits
inline size_t nextDezState(const sym& s, size_t state)
{
  switch(state)
    {
    case 1: /*whitespace*/
      {
	if(s.sym == Digit)
	  return 2;
	else 
	  return 0;
      }
    case 2: /*first digit*/
    case 3: /*second digit*/
      {
	if(s.sym == Digit)
	  return state + 1;
	else if(s.sym == Punct)
	  return 5;
	else 
	  return 0;
      }
    case 4:/*third digit*/
      {
	if(s.sym == Punct)
	  return 5;
	else
	  return 0;
      }
    case 5:/*punct*/
      {
	if(s.sym == Digit)
	  return 6;
	else 
	  return 0;
      }
    case 6:/*first digit after punct*/
    case 7:/*second digit after punct*/
      {
	if(s.sym == Digit)
	  return state + 1;
	else 
	  return 0;
      }
    case 8:/*third digit*/
      {
	if(s.sym == White)
	  return FINAL_STATE;
	else if(s.sym == Punct)
	  return 5;
	else 
	  return 0;
      }
    default: return 0;
    }
}

/*
 * dezimal digits like 123.456 1.234 12.345 ...
 * but not 12.00.123 12.000.12 ...
 */
bool is_a_dezimaldigit(const std::wstring& str, size_t& pos)
{
  //preset values
  //std::wcout << "is_a_dezimaldigit" << std::endl;
  pos = std::string::npos;
  size_t start = 0;
  size_t state = 1;
  sym s;

  for(size_t i=0; i<str.length(); i++)
    {
      getSym(str[i], s);
      if(!state)
	{
	  if(s.sym == White)
	    {
	      state = 1;
	      start = i + 1; // we start at the white space start is the next char
	    }
	  else
	    continue;
	}
	else
	  {
	    state = nextDezState(s, state);
	    if(state == FINAL_STATE)
	      {
		pos = start;
		return true;
	      }
	  }
    }
  return false;
}

/*
 * roman numbers: IV. XIV XVI ...
 * but not XXD IIXX ...
 */
bool is_a_roman(const std::wstring& str, size_t& pos)
{
  //std::wcout << "is_a_roman" << std::endl;
  pos = std::string::npos;
  sym s;
  size_t state = 1;
  size_t start = 0;
  for(size_t i=0; i<str.length(); i++)
    {
      getSym(str[i], s);
      if(!state)//state == 0
	{
	  if(s.sym == White)
	    {
	      state = 1;
	      start = i + 1;
	    }
	  else 
	    continue;
	}
      else
	{
	  state = nextRomanState(s, state);
	  if(state == FINAL_STATE)
	    {
	      pos = start;
	      return true;
	    }
	}
    }
  return false;
}

// returns the next state for roman numbers
inline size_t nextRomanState(const sym& s, size_t state)
{
  switch(state)
    {
    case 1: /*whitespace*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 2;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'X')
	      return 4;
	    else if(s.val == L'L')
	      return 5;
	    else if(s.val == L'C')
	      return 6;
	    else if(s.val == L'D')
	      return 7;
	    else if(s.val == L'M')
	      return 8;
	    else return 0;
	  }
	else return 0;
      }
    case 2:/*I*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 9;
	    else if(s.val == L'V')
	      return 10;
	    else if(s.val == L'X')
	      return 11;
	    else return 0;
	  }
	else if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 3: /*V*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 2;
	    else return 0;
	  }
	else if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 4: /*X*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 2;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'L')
	      return 12;
	    else if(s.val == L'C')
	      return 13;
	    else if(s.val == L'X')
	      return 15;
	    else return 0;
	  }
	else if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 5: /*L*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 2;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'X')
	      return 4;
	    else return 0;
	  }
	else if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 6: /*C*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 2;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'X')
	      return 4;
	    else if(s.val == L'L')
	      return 5;
	    else if(s.val == L'C')
	      return 16;
	    else return 0;
	  }
	else if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 7: /*D*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 2;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'X')
	      return 4;
	    else if(s.val == L'L')
	      return 5;
	    else if(s.val == L'C')
	      return 6;
	    else return 0;
	  }
	else if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 8: /*M*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 2;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'X')
	      return 4;
	    else if(s.val == L'L')
	      return 5;
	    else if(s.val == L'C')
	      return 6;
	    else if(s.val == L'D')
	      return 7;
	    else if(s.val == L'M')
	      return 17;
	    else return 0;
	  }
	else if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 9: /*II*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 14;
	    else return 0;
	  }
	else if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 10: /*IV*/
      {
	if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 11: /*IX*/
      {
	if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 12: /*XL*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 2;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'X')
	      return 4;
	    else return 0;
	  }
	else if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 13: /*XC*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'I')
	      return 2;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'X')
	      return 4;
	    else if(s.val == L'L')
	      return 5;
	    else return 0;
	  }
	else if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 14: /**/
      {
	if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 15: /*XX*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'X')
	      return 14;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'I')
	      return 2;
	    else 
	      return 0;
	  }
	if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 16: /*CC*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'C')
	      return 14;
	    else if(s.val == L'L')
	      return 5;
	    else if(s.val == L'X')
	      return 4;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'I')
	      return 2;
	    else 
	      return 0;
	  }
	if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    case 17: /*MM*/
      {
	if(s.sym == UChar)
	  {
	    if(s.val == L'M')
	      return 14;
	    else if(s.val == L'D')
	      return 7;
	    else if(s.val == L'C')
	      return 6;
	    else if(s.val == L'L')
	      return 5;
	    else if(s.val == L'X')
	      return 4;
	    else if(s.val == L'V')
	      return 3;
	    else if(s.val == L'I')
	      return 2;
	    else 
	      return 0;
	  }
	if(s.sym == Punct || s.sym == White)
	  return FINAL_STATE;
	else return 0;
      }
    default: return 0;
    }
}

bool is_a_date(const std::wstring& str, size_t& pos)
{
  pos = std::string::npos;
  size_t start = 0;
  size_t state = 1;
  sym s;
  for(size_t i=0; i<str.length(); i++)
    {
      getSym(str[i], s);
      if(!state) //state == 0
	{
	  if(s.sym == White)
	    {
	      state = 1;
	      start = i + 1;
	    }
	  else
	    continue;
	}
      else
	{
	  state = nextDateState(s, state);
	  if(state == FINAL_STATE)
	    {
	      pos = start;
	      return true;
	    }
	}
    }
  return false;
}

// returns the next state for dates
inline size_t nextDateState(const sym& s, size_t state)
{
  switch(state)
    {
    case 1: /*whitespace*/
      {
	if(s.sym == Digit) return 2;
	else return 0;
      }
    case 2: /*Digit*/
      {
	if(s.sym == Digit) return 3;
	else if(s.sym == Punct) return 4;
	else return 0;
      }
    case 3: /*Digit Digit*/
      {
	if(s.sym == Punct) return 4;
	else return 0;
      }
    case 4: /*Digit(Digit)Punct*/
      {
	if(s.sym == Digit) return 5;
	else if(s.sym == White) return state;
	else if(s.sym == Dash) return 7;
	else if(s.sym == Slash) return 7;
	else if(s.sym == UChar || s.sym == LChar) return 11;
	else return 0;
      }
    case 5: /*Digit(Digit)Punct Digit*/
      {
	if(s.sym == Digit) return 6;
	else if(s.sym == Punct) return 14;
	else if(s.sym == White) return FINAL_STATE;
	else return 0;
      }
    case 6: /*Digit(Digit)Punct Digit Digit*/
      {
	if(s.sym == White) return FINAL_STATE;
	else if(s.sym == Punct) return 14;
	else return 0;
      }
    case 7: /*Digit(Digit)Punct Dash|Slash*/
      {
	if(s.sym == Digit) return 8;
	else if(s.sym == White) return state;
	else return 0;
      }
    case 8: /*Digit(Digit)Punct Dash|Slash Digit*/
      {
	if(s.sym == Digit) return 9;
	else if(s.sym == Punct) return 10;
	else return 0;
      }
    case 9:/*Digit(Digit)Punct Dash|Slash Digit Digit*/
      {
	if(s.sym == Punct) return 10;
	else return 0;
      }
    case 10:/*Digit(Digit)Punct Dash|Slash Digit(Digit)Punct*/
      {
	if(s.sym == Digit) return 5;
	else if(s.sym == White) return state;
	else if(s.sym == UChar || s.sym == LChar) return 11;
	else return 0;
      }
    case 11:/*...Char*/
      {
	if(s.sym == LChar) return 12;
	else if(s.sym == White) return FINAL_STATE;
	else if(s.sym == Punct) return 14;
	else return 0;
      }
    case 12:/*...Char Char*/
      {
	if(s.sym == LChar) return 13;
	else if(s.sym == White) return FINAL_STATE;
	else if(s.sym == Punct) return 14;
	else return 0;
      }
    case 13:/*...Char Char Char*/
      {
	if(s.sym == Punct) return 14;
	else if(s.sym == White) return FINAL_STATE;
	else return 0;
      }
    case 14: /*... Punct*/
      {
	if(s.sym == White) return FINAL_STATE;
	else return 0;
      }
    default: return 0;
    }
}

/*
 * times: 12:00 2:30 12.30 ...
 * but not 12:4 1.2 ...
 */
bool is_a_time(const std::wstring& str, size_t& pos)
{
  //std::wcout << "is_a_time" << std::endl;
  pos = std::string::npos;
  sym s;
  size_t state = 1;
  size_t start = 0;
  for(size_t i=0; i<str.length(); i++)
    {
      getSym(str[i], s);
      if(!state)//state == 0
	{
	  if(s.sym == White)
	    {
	      state = 1;
	      start = i + 1;
	    }
	  else 
	    continue;
	}
      else
	{
	  state = nextTimeState(s, state);
	  if(state == FINAL_STATE)
	    {
	      pos = start;
	      return true;
	    }
	}
    }
  return false;
}

//returns the next state for times
inline size_t nextTimeState(const sym& s, size_t state)
{
  switch(state)
    {
    case 1: /*White*/
      {
	if(s.sym == Digit)
	  {
	    if(s.val == L'0') return 2;
	    if(s.val == L'1') return 3;
	    else if(s.val == L'2') return 4;
	    else return 5;
	  }
	else return 0;
      }
    case 2: /*White 0*/
      {
	if(s.sym == Colon || s.sym == Punct) return 6;
	else if(s.sym == Digit) return 5;
	else return 0;
      }
    case 3: /*White 1*/
      {
	if(s.sym == Punct || s.sym == Colon) return 6;
	else if(s.sym == Digit) return 5;
	else return 0;
      }
    case 4:/*White 2*/
      {
	if(s.sym == Punct || s.sym == Colon) return 6;
	if(s.sym == Digit)
	  {
	    if(s.val == L'0' || s.val == L'1' || s.val == L'2' || s.val == L'3') return 5;
	    else return 0;
	  }
	else return 0;
      }
    case 5:/*White Digit | White Digit Digit*/
      {
	if(s.sym == Punct || s.sym == Colon) return 6;
	else return 0;
      }
    case 6:/*White Digit Digit (Punct|Colon) | White Digit (Pucnt|Colon)*/
      {
	if(s.sym == Digit)
	  {
	    if(s.val == L'0' || s.val == L'1' ||s.val == L'2' ||s.val == L'3' ||s.val == L'4' ||s.val == L'5') return 7;
	    else return 0;
	  }
	else return 0;
      }
    case 7: /*... Digit(0-5)*/
      {
	if(s.sym == Digit) return 8;
	else return 0;
      }
    case 8: /*...Digit(0-5) Digit*/
      {
	if(s.sym == White) return FINAL_STATE;
	else return 0;
      }
    default: return 0;
    }
}

/*
 * three or more dots are a think (not necessarily enclosed by whitespace)
 */
bool is_a_think(const std::wstring& str, size_t& pos)
{
  //  std::wcout << "is_a_think" << std::endl;
  pos = std::string::npos;
  size_t state = 0;
  size_t start = 0;
  sym s;
  for(size_t i=0; i<str.length(); i++)
    {
      getSym(str[i], s);
      switch(state)
	{
	case 0: /*nothing*/
	  {
	    if(s.sym == Punct)
	      {
		state = 1;
		start = i;
	      }
	    break;
	  }
	case 1: /*.*/
	  {
	    if(s.sym == Punct)
	      state = 2;
	    else 
	      state = 0;
	    break;
	  }
	case 2:/*..*/
	  {
	    if(s.sym == Punct)
	      state = FINAL_STATE;
	    else
	      state = 0;
	    break;
	  }
	default: state = 0; break;
	}

      if(state == FINAL_STATE)
	{
	  pos = start;
	  return true;
	}
    }
  return false;
}

//shows informatation about found entites (line number, column and position)
inline void showPos(std::wostream& out, size_t pos[], size_t lineC, size_t offset)
{
  // show indices of the found entities
  if(pos[0] != std::string::npos)
    out << L"Found a dezimal digit at (line / column / overall): " << lineC << " / " << pos[0] << " / " << pos[0] + offset << std::endl;
  if(pos[1] != std::string::npos)
    out << L"Found a roman number at  (line / column / overall): " << lineC << " / " << pos[1] << " / " << pos[1] + offset << std::endl;
  if(pos[2] != std::string::npos)
    out << L"Found a date at          (line / column / overall): " << lineC << " / " << pos[2] << " / " << pos[2] + offset << std::endl;
  if(pos[3] != std::string::npos)
    out << L"Found a time at          (line / column / overall): " << lineC << " / " << pos[3] << " / " << pos[3] + offset << std::endl;
  if(pos[4] != std::string::npos)
    out << L"Found a think at         (line / column / overall): " << lineC << " / " << pos[4] << " / " << pos[4] + offset << std::endl;
  //out << std::endl;
}

int main()
{
  std::locale::global(LOC);

  std::wstring line; // line from stdin
  size_t pos[POS_SIZE]; // array with the positions
  bool found[POS_SIZE]; 
  size_t lineC = 0; // number of lines
  size_t offset = 0; // number of chars

  std::wcout << "Press CTRL + D to stop." << std::endl;
  while(getline(std::wcin, line))
    {
      lineC++;
      if(line == L"") continue;
      line.push_back(L' '); // add whitespace to the end of the string

      found[0] = is_a_dezimaldigit(line, pos[0]);
      found[1] = is_a_roman(line, pos[1]);
      found[2] = is_a_date(line, pos[2]);
      found[3] = is_a_time(line, pos[3]);
      found[4] = is_a_think(line, pos[4]);

      if(found[0] || found[1] || found[2] || found[3] || found[4])
	showPos(std::wcout, pos, lineC, offset);
      else
	std::wcout << L"Nothing was found." << std::endl;
	offset += (line.length()-1); // add offset, ignore whitespace at the end
    }
  return EXIT_SUCCESS;
}
}}}
; Schreiben Sie ein C++ Programm, das eine eigene Klasse {{{cis_string}}} definiert.
Die Klasse {{{cis_string}}} soll mindestens folgende {{{public}}} Komponenten haben:
{{{
	int get_anzahl_chars() ... liefert die Anzahl der Buchstaben der cis_string Daten
	void get_cis_string_data(wstring &text) ... liefert als wstring in den Inhalt String-Daten 
	void set_cis_string_data(wstring text) ... trägt den String text in die cis_string Daten ein.
}}}

Die Klasse {{{cis_string}}} soll mindestens folgende {{{private}}} Komponenten haben:
{{{
	wchar_t data[132] ... alle Buchstaben der cis_string Daten
	int anzahl ...  Anzahl der Buchstaben in dataint get_anzahl() ... liefert die Anzahl der Buchstaben der cis_string Daten
}}}
Schreiben Sie public-member Funktionen für die Klasse {{{cis_string}}}, die folgende Aktionen auf einem Objekt der Klasse {{{cis_string}}} ausführen (Verwenden Sie Ihre Lösung aus den letzten Aufgaben dieses Kurses):
{{{
   1. int cis_string_to_upper() ... konvertiert die Daten des cis_string in Großbuchstaben.
   2. bool first_is_upper() ... liefert wahr/falsch, ob der erste Buchstaben des cis_string ein Großbuchstabe ist (Verwenden Sie Ihre Lösung vom Aufgabenblatt 1, Aufgabe 1)
   3. void translate() ... alle Großbuchstaben in Kleinbuchstaben und umgekehrt konvertieren und ausgeben (Verwenden Sie Ihre Lösung vom Aufgabenblatt 2, Aufgabe 2.3).
}}}

Nun soll folgende {{{main()}}} Funktion möglich sein:
{{{
int main()
{
// Setzen des locale auf utf-8  (Verwenden Sie locale und global ect...)
...

wstring eingabe;
wstring ergebnis;
cis_string text;


wcout << "Bitte geben sie einen String ein :";
text.set_cis_string_data(eingabe);
wcout << "Die Anzahl der Buchstaben ist : "<< text.get_anzahl_chars() << endl;

// test ob der erste Buchstabe groß ist:
if (text.first_is_upper())
	{
	wcout << "Der erste Buchstabe des Strings ist ein großer Buchstabe" << endl;

// Konvertieren auf upper:
text.cis_string_to_upper();
text.get_cis_string_data(ausgabe);
wcout << "TOUPPER: Der interne String von cis_string ist : "<< ausgabe << endl;


// Konvertieren auf Groß/Kleinschreibung:
text.translate();
text.get_cis_string_data(ausgabe);
wcout << "TRANSLATE: Der interne String von cis_string ist : "<< ausgabe << endl;


}
}}}

!!! main()
<code cpp>
/*

	7_main.cpp

    main() zu Klasse cis_string
*/

#include <iostream>
#include <fstream>
#include <string>
#include <locale>

#include "cis_string.hpp"


int main() {

    // Variablen
	locale		LOC("");
	locale::global(LOC);

	wstring		eingabe;
	wstring		ausgabe;

	cis_string	text;


	wcout << L"Bitte geben sie einen String ein: ";
    getline(wcin, eingabe);
	text.set_cis_string_data(eingabe);
	wcout << L"Die Anzahl der Buchstaben ist: " << text.get_anzahl_chars() << endl;


	// Test ob der erste Buchstabe groß ist:
	if (text.first_is_upper())
		wcout << L"Der erste Buchstabe des Strings ist ein großer Buchstabe" << endl;
	else
		wcout << L"Der erste Buchstabe des Strings ist kein großer Buchstabe" << endl;
		

	// Konvertieren auf Groß/Kleinschreibung:
    text.translate();
    wcout << L"TRANSLATE: Der interne String von cis_string ist : " << text.get_cis_string_data() << endl;


	// Konvertieren auf upper:
	text.cis_string_to_upper();

    text.get_cis_string_data(ausgabe);
	wcout << L"TOUPPER: Der interne String von cis_string ist : " << ausgabe << endl;


	return 0;
}
</code>
!!! ~Deklarations-Datei "cis_string.hpp"
<code cpp>
/*
        cis_string.hpp

	Class definitions for 
		class cis_string
		
*/

#ifndef CIS_STRING_HPP
#define CIS_STRING_HPP

#include <iostream>
#include <locale>
#include <string>

using namespace std;

class cis_string {
  public:
	int  get_anzahl_chars();					// ... liefert die Anzahl der Buchstaben der cis_string Daten
	void get_cis_string_data(wstring &text);	// ... liefert als wstring den Inhalt der String-Daten
    wstring get_cis_string_data();              // ... liefert als Rückgabewert den Inhalt der String-Daten (nicht gefordert!)
	void set_cis_string_data(wstring &text);	// ... trägt den String text in die cis_string Daten ein.
	int  cis_string_to_upper(); 				// ... konvertiert die Daten des cis_string in Großbuchstaben.
	bool first_is_upper(); 						// ... liefert wahr/falsch, ob der erste Buchstaben des cis_string ein Großbuchstabe ist
	void translate(); 							// ... alle Großbuchstaben in Kleinbuchstaben und umgekehrt konvertieren und ausgeben
   
  private:
	wchar_t data[132]; 							// ... alle Buchstaben der cis_string Daten
	int anzahl; 								// ... Anzahl der Buchstaben in data
	int get_anzahl();							// ... liefert die Anzahl der Buchstaben der cis_string Daten
	
};

#endif
</code>

!!! Implementationsdatei cis_string.cpp
<code cpp>
/*

        cis_string.cpp

	Class implementation for 
		class cis_string

	For comments on the methods please look inside cis_string.hpp

*/

#ifndef   CIS_STRING_CPP
#define   CIS_STRING_CPP

#ifndef   CIS_STRING_HPP
#include "cis_string.hpp"
#endif

using namespace std;

int cis_string::get_anzahl_chars() {
    int i = 0;
    while (data[i] != L'\0') i++;
    return i;
}


void cis_string::set_cis_string_data(wstring &text) {
    int i = 0;
	for (; i < text.length(); i++)
		data[i] = text.at(i);
     data[i] = L'\0';
}


wstring cis_string::get_cis_string_data() {
    return (wstring)data;
}


void cis_string::get_cis_string_data(wstring &text) {
    text.assign(data);
}



int cis_string::cis_string_to_upper() {
	for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (!iswupper(data[i]))
			data[i] = towupper(data[i]);
}


bool cis_string::first_is_upper() {
	if (iswupper(data[0]))
		return true;
	return false;
}


void cis_string::translate() {
	for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
		if (iswupper(data[i]))
			data[i] = towlower(data[i]);
		else if (iswlower(data[i]))
			data[i] = towupper(data[i]);
		
}

#endif
</code>
;Schreiben Sie ein C++ Programm, das die eigene Klasse {{{cis_string}}} der [[Aufgabe 7]] erweitert.
{{{
      cis_string str; // ist gegeben

   1.

      str++ Konvertiert die Buchstaben eines String in Großbuchstaben
   2.

      --str Konvertiert die Buchstaben eines String in Kleinbuchstaben
   3. str1 < str2 liefert True, falls str1 kleiner als str2 ist. 
    Der Stringvergleich soll Groß- und Kleinbuchstbaen nicht unterscheiden und die Umlaute 'äüöß' 
    nach der alphabetischen Sortierung wie sie die Norm DIN 5007-1 (Variante-1) für Lexika vorschreibt, berücksichtigen.
}}}
[[DIN 5007-1 (Variante-1)|http://de.wikipedia.org/wiki/DIN_5007]]

!main()
<code cpp>
/*

	7_main.cpp

    main() zu Klasse cis_string
*/

#include <iostream>
#include <fstream>
#include <string>
#include <locale>

#include "cis_string.hpp"


int main() {

    // Variablen
	locale		LOC("");
	locale::global(LOC);

	wstring		eingabe;
	wstring		ausgabe;

	cis_string	text;


	wcout << L"Bitte geben sie einen String ein: ";
    getline(wcin, eingabe);
	text.set_cis_string_data(eingabe);
	wcout << L"Die Anzahl der Buchstaben ist: " << text.get_anzahl_chars() << endl;


	// Test ob der erste Buchstabe groß ist:
	if (text.first_is_upper())
		wcout << L"Der erste Buchstabe des Strings ist ein großer Buchstabe" << endl;
	else
		wcout << L"Der erste Buchstabe des Strings ist kein großer Buchstabe" << endl;
		

	// Konvertieren auf Groß/Kleinschreibung:
    text.translate();
    wcout << L"TRANSLATE: Der interne String von cis_string ist : " << text.get_cis_string_data() << endl;


	// Konvertieren auf upper:
    /// In der Klasse cis_string sind drei Moeglichkeiten zum Konvertieren auf Upper vorgesehen:

    /// Variante 1:
        // text.cis_string_to_upper();       // ohne Rueckgabewert, d.h. string muss mit get()-Methode abgeholt werden.

    /// Variante 2:
        /* ++text; */                        // Prefix Operator, der Rueckgabewert ist wstring, also kann 
        // wcout << ++text << endl;          // geschrieben werden

    /// Variante 3:    
        //text++;                           // Postfix Operator, der Rueckgabewert ist wieder void
        //text.get_cis_string_data(ausgabe);// und deswegen muss der konvertierte Text 'abgeholt' werden

	wcout << L"TOUPPER: Der interne String von cis_string ist : " << ++text << endl;

    wcout << L"TOLOWER: Der interne String von cis_string ist : " << --text << endl;


    // Lexikographischer Vergleich
    /// zweite Variable einlesen, mit der verglichen werden soll:
    cis_string    text2;
    
    wcout << L"Bitte geben Sie einen zweiten String ein, mit dem verglichen werden soll: "; 
    getline(wcin, eingabe);
    text2.set_cis_string_data(eingabe);

    wcout << L"Der String mit dem verglichen werden soll, ist: " << text2.get_cis_string_data() << endl;   // Testausgabe

    // Vergleichen:
    /// es kann drei verschiedene Werte geben, daher von der Vorgabe, bool als Rueckgabewert zu haben, abgewichen:
    if      ( (text < text2) > 1  ) wcout << L"text1 ist lexicographisch groesser" << endl;
    else if ( (text < text2) < 0  ) wcout << L"text2 ist lexicographisch groesser" << endl;
    else if ( (text < text2) == 0 ) wcout << L"text1 und text2 sind lexikographisch gleich(wertig)" << endl;

    wcout << L"text2 war: " << text2.get_cis_string_data() << endl;   // Testausgabe

	return 0;
}

</code>

!Deklarationsdatei cis_string.hpp
<code cpp>
/*
        cis_string.hpp

	Class definitions for 
		class cis_string
		
*/

#ifndef CIS_STRING_HPP
#define CIS_STRING_HPP

#include <iostream>
#include <locale>
#include <string>

using namespace std;

class cis_string {
  public:
    //cis_string(const wchar_t text);
	int  get_anzahl_chars();					// ... liefert die Anzahl der Buchstaben der cis_string Daten
	void get_cis_string_data(wstring &text);	// ... liefert als wstring den Inhalt der String-Daten
    wstring get_cis_string_data();              // ... liefert als Rückgabewert den Inhalt der String-Daten (nicht gefordert!)
	void set_cis_string_data(wstring &text);	// ... trägt den String text in die cis_string Daten ein.
	int  cis_string_to_upper(); 				// ... konvertiert die Daten des cis_string in Großbuchstaben.
	int  cis_string_to_lower(); 				// ... konvertiert die Daten des cis_string in klein.
	bool first_is_upper(); 						// ... liefert wahr/falsch, ob der erste Buchstaben des cis_string ein Großbuchstabe ist
	void translate(); 							// ... alle Großbuchstaben in Kleinbuchstaben und umgekehrt konvertieren und ausgeben
    void operator++(int);                       // ... wandelt in GROSS, Achtung: "post–fix–non–const–in–situ–operator"!
    void operator--(int);                       // ... vice versa.
    wstring operator++();                       // ... praefix-Operator
    wstring operator--();                       // ... prefix
    int operator<(cis_string &comparison);      // ... lexikographischer Vergleich: Umlaute werden wie "normale" Buchstaben gezaehlt.
    bool compare(cis_string &comparison);       // ... ebenfalls lexikographischer Verlgeich (achtet aber nicht auf Umlaute!!!)
    wstring entferne_umlaute();                 // ... noetig, damit operator< funktionieren kann
  private:
	wchar_t data[132]; 							// ... alle Buchstaben der cis_string Daten
	int anzahl; 								// ... Anzahl der Buchstaben in data

	
};

#endif

</code>

!Implementationsdatei cis_string.cpp
<code cpp>
/*

        cis_string.cpp

	Class implementation for 
		class cis_string

	For comments on the methods please look inside cis_string.hpp

*/

#ifndef   CIS_STRING_CPP
#define   CIS_STRING_CPP

#ifndef   CIS_STRING_HPP
#include "cis_string.hpp"
#endif

using namespace std;


int cis_string::get_anzahl_chars() {                    // liefert Anzahl der Buchstaben zurueck
    int i = 0;
    while (data[i] != L'\0') i++;
    return i;
}


void cis_string::set_cis_string_data(wstring &text) {
    int i = 0;
    for (; i < text.length(); i++)                      // eine for-Schleife ohne Initialisierung
        data[i] = text.at(i);                           // for-Schleife fuehrt nur dieses aus, die naechste Zeile nicht
    data[i] = L'\0';                                    // wir stellen selbst einen c-String her, der mit '\0' abgeschlossen ist.
}

wstring cis_string::get_cis_string_data() {
    return (wstring)data;                               // cast: kuendigt an, dass dieses Format kommen wird
}



int cis_string::cis_string_to_upper() {                 // in GROSSbuchstaben konvertieren.
	for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (!iswupper(data[i]))
			data[i] = towupper(data[i]);                //! Achtung: Bisher ist wchar data[132] noch nicht const, d.h. die Daten im private Bereich werden veraendert!
}

int cis_string::cis_string_to_lower() {                 // (siehe oben)
	for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (!iswlower(data[i]))
			data[i] = towlower(data[i]);                // (siehe oben)
}

bool cis_string::first_is_upper() {                     // Test, ob erster Buchstabe gross ist.
	if (iswupper(data[0]))
		return true;
	return false;
}


void cis_string::translate() {                          // GroSs -> kLEiN
	for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
		if (iswupper(data[i]))
			data[i] = towlower(data[i]);
		else if (iswlower(data[i]))
			data[i] = towupper(data[i]);
		
}


void cis_string::operator++(int undef) {                // wort++ macht einen to_upper, als suffix-operator, daher "dummy"-Argument: int undef
    cis_string_to_upper();
}


void cis_string::operator--(int undef) {                // siehe oben
    cis_string_to_lower();
}


wstring cis_string::operator++() {                      // praefix Operator _und_ Rueckgabewert ist wstring, daher: wcout << ++text; moeglich.
    cis_string_to_upper();
    return (wstring)data;                               // casting, again
}


wstring cis_string::operator--() {
    cis_string::cis_string_to_lower();
    return (wstring)data;
}


bool cis_string::compare(cis_string &comparison) {      // lexikographsicher Vergleich von zwei cis_strings:
    wstring tmp = this->get_cis_string_data();          // bei cis1.compare(cis2) ist this == "cis1"  

    if (tmp.compare(comparison.get_cis_string_data()) > 0)  // compare() kommt aus der Klasse string!
        return true;
    else
        return false;
}


wstring cis_string::entferne_umlaute() {
    wstring tmp = this->get_cis_string_data();

    for (int i = 0; i < tmp.size(); ++i) {
        tmp.at(i) = towlower(tmp.at(i)); 
        if (tmp.at(i) == L'ä' )     tmp.at(i) = L'a';
        if (tmp.at(i) == L'ö' )     tmp.at(i) = L'o';
        if (tmp.at(i) == L'ü' )     tmp.at(i) = L'u';
        if (tmp.at(i) == L'ß' )     tmp.insert(i, 2 , L's');    // das hier geht irgendwie noch nicht, k.A., muss nochmal checken.
    }
    return tmp;
}


int cis_string::operator<(cis_string &comparison) {
    wstring first = this->entferne_umlaute();                   // 3. umlaute aus den "Komparanten"
    wstring second = comparison.entferne_umlaute();             // 2. deswegen entfernen wir vorher alle
    return first.compare(second);                               // 1. wir benutzen compare() aus der Klasse string!

//     return this->entferne_umlaute().compare(comparison.entferne_umlaute());  // unangenehme kurzschreibweise.
}

#endif

</code>
; Hier die Übersicht über alle bisher implementierten Funktionen aus unserer Klasse {{{cis_string}}}, (inklusive Bonusmaterial):
; [[download cis_string.tar.gz|http://www.cip.ifi.lmu.de/~bruder/cis_string.tar.gz]] (entpacken mit {{{tar xvzf cis_string.tar.gz}}})

+++[main()]
{{{
/*

	9_main.cpp

    main() zu Klasse cis_string
*/

#include <iostream>
#include <fstream>
#include <string>
#include <locale>

#include "cis_string.hpp"


int main() {

    // Variablen
    locale      LOC("");
    locale::global(LOC);

    cis_string s1(L"Hülle");
    cis_string s2,s3,s4;

    wcout << L"s1 ist: " << s1 << L" und die Länge von s1 ist: " << s1.size() << L" bzw. " << s1.length() << endl;

    wcout << L"Bitte geben Sie einen string für s2 ein: " << endl;
    wcin >> s2;

    wcout << L"s1 konkateniert mit s2: " << s1+s2 << endl;

    wcout << L"Bitte geben Sie einen string für s3 ein: " << endl;
    wcin >> s3;

    wcout << L"s4 wird s3 sein (s4 = s3): ";
    s4 = s3;
    wcout << s4 << endl;

    wstring     end;
    wcout << L"s4 wird noch um eine Endung erweitert...\nWelche Endung darf es sein?" << endl;
    wcin >> end;
    s4 += end;

    wcout << L"s4 ist jetzt: " << s4 << endl;

    cis_string  filecontents("infile");                 // Bonus
    wcout << L"[[" << filecontents << L"]]" << endl;

    return 0;
}

}}}
===


+++[Deklaration]
!Deklaration
{{{
/*
        cis_string.hpp

    Class definitions for 
        class cis_string

*/

#ifndef CIS_STRING_HPP
#define CIS_STRING_HPP

#include <iostream>
#include <locale>
#include <string>

using namespace std;


const unsigned int MAX_SIZE = 24288;                     // == irgendeine Hausnummer zum Dateienlesen, etc.




class cis_string {
  public:

    // Konstruktoren
    cis_string();                                   // ... legt ein cis_string-Objekt an
    cis_string(const wstring &text);                // ... legt ein cis_string-Objekt an und Instantiiert mit wstring: cis_string s1(wstr)
    cis_string(const wchar_t* text);                // ... legt ein cis_string-Objekt an und instantiiert es           cis_string s1(L"Biotop")
    cis_string(const char* filename);               // ... (Bonus!) legt ein cis_string-Objekt an und instantiiert es mit einem (UTF8)-Dateiinhalt

    // Setters
    void set_cis_string_data(const wstring &text);  // ... trägt den String text in die cis_string Daten ein.

    // Getters
    int  get_anzahl_chars();                        // ... liefert die Anzahl der Buchstaben der cis_string Daten
    void get_cis_string_data(wstring &text);        // ... liefert als wstring den Inhalt der String-Daten
    wstring get_cis_string_data();                  // ... liefert als Rückgabewert den Inhalt der String-Daten (nicht gefordert!)


    // Converters
    void cis_string_to_upper();                     // ... konvertiert die Daten des cis_string in Großbuchstaben.
    void cis_string_to_lower();                     // ... konvertiert die Daten des cis_string in klein.
    bool first_is_upper();                          // ... liefert wahr/falsch, ob der erste Buchstaben des cis_string ein Großbuchstabe ist
    //void translate();                             // ... alle Großbuchstaben in Kleinbuchstaben und umgekehrt konvertieren
    cis_string translate();                         // ... alle Großbuchstaben in Kleinbuchstaben und umgekehrt konvertieren und ausgeben
    //bool compare(cis_string &comparison);			// ... dont use this for now!


    // Operators
    void operator++(int);                           // ... wandelt in GROSS, "post-fix-non-const-in-situ-operator"!
    void operator--(int);                           // ... vice versa.
    wstring operator++();                           // ... Präfix-Operator, geeignet für Ausgabe: wcout << ++str << endl;
    wstring operator--();                           // ... mutatis mutandis.
    int operator<(cis_string &comparison);          // NEU Lexikographischer Vergleichs-Operator
    cis_string operator+(cis_string &object);       // NEU Konkatenations-Operator (kann verkettet werden: s1 + s2 + s3)
    cis_string operator=(const wstring &str);       // ... Zuweisungsoperator für wstring.
    cis_string operator=(cis_string &object);       // ... Zuweisungsoperator cis_string = cis_string
    cis_string operator+=(const wstring &str);      // ... Bonus! (Ermöglicht cis_string += wstring)

	wchar_t operator[](int i);						// NEU Zugriffs-Operator

    // "Methods for Convenience"
    int size();
    int length();

    void get_data(wstring &text);
    wstring get_data();

    void set_data(const wstring &text);


  private:
    wchar_t data[MAX_SIZE];                         // ... alle Buchstaben der cis_string Daten
    int anzahl;                                     // ... Anzahl der Buchstaben in data
	public:
    wstring entferne_umlaute();                     // ... selbstredend.

};

wostream& operator<<(wostream &o, cis_string::cis_string &object);      // ausserhalb der Klasse!

#ifndef   CIS_STRING_CPP
#include "cis_string.cpp"
#endif

#endif

}}}
===


+++[Implementation]
!Implementation
{{{
/*

        cis_string.cpp

       Implementation for 
        class cis_string

    For (additional) comments on the methods 
        please look inside cis_string.hpp

*/

#ifndef   CIS_STRING_CPP
#define   CIS_STRING_CPP

#ifndef   CIS_STRING_HPP
#include "cis_string.hpp"
#endif


#include <fstream>

using namespace std;


cis_string::cis_string() {
    anzahl = 0;
}


cis_string::cis_string(const wstring &text) {
    set_cis_string_data(text);
}


cis_string::cis_string(const wchar_t* text) {
    int i = -1;
    while (text[++i] != L'\0')
        data[i] = text[i];

    data[i] = L'\0';
    anzahl = --i;
}


cis_string::cis_string(const char* filename) {
    wifstream in(filename, ios::binary);

    in.seekg(0, ios_base::end);
    long size = in.tellg();
    in.seekg(0, ios::beg);

    if (size > MAX_SIZE)     // Wenn Datei größer als xy...
        size = MAX_SIZE-1;   // ... dann "hart" abschneiden

    in.read(data,size);
    data[size+1] = L'\0';
    anzahl = size;
}


int cis_string::get_anzahl_chars() {
    return anzahl;
}


void cis_string::set_cis_string_data(const wstring &text) {
    int i = 0;
    for (; i < text.length(); i++)
        data[i] = text.at(i);
     data[i] = L'\0';

    anzahl = i;
}


wstring cis_string::get_cis_string_data() {
    return (wstring)data;
}


void cis_string::get_cis_string_data(wstring &text) {
    text.assign(data);
}



void cis_string::cis_string_to_upper() {
    for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (!iswupper(data[i]))
            data[i] = towupper(data[i]);
}


void cis_string::cis_string_to_lower() {
    for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (!iswlower(data[i]))
            data[i] = towlower(data[i]);
}


bool cis_string::first_is_upper() {
    if (iswupper(data[0]))
        return true;
    return false;
}


cis_string cis_string::translate() {
    for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (iswupper(data[i]))
            data[i] = towlower(data[i]);
        else if (iswlower(data[i]))
            data[i] = towupper(data[i]);
	return (wstring)data;
}


//cis_string cis_string::translate() {
//	translate();
//	return (wstring)data;
//}

void cis_string::operator++(int undef) {
    cis_string_to_upper();
}


void cis_string::operator--(int undef) {
    cis_string_to_lower();
}


wstring cis_string::operator++() {
    cis_string_to_upper();
    return (wstring)data;
}


wstring cis_string::operator--() {
    cis_string::cis_string_to_lower();
    return (wstring)data;
}


/*		dont use this for now!

bool cis_string::compare(cis_string &comparison) {
    wstring tmp = this->get_cis_string_data();
//     if (this->get_cis_string_data().compare(comparison) > 0)
    if (tmp.compare(comparison.get_cis_string_data()) < 0)
        return true;
    else
        return false;
}
*/


wstring cis_string::entferne_umlaute() {
    wstring tmp = this->get_cis_string_data();

    for (int i = 0; i < tmp.size(); ++i) {
        tmp.at(i) = towlower(tmp.at(i)); 
        if (tmp.at(i) == L'ä' )     tmp.at(i) = L'a';
        if (tmp.at(i) == L'ö' )     tmp.at(i) = L'o';
        if (tmp.at(i) == L'ü' )     tmp.at(i) = L'u';
        if (tmp.at(i) == L'ß' )   { tmp.at(i) = L's'; tmp.insert(i+1, L"s"); }    // geht jetzt.
    }
    return tmp;
}


int cis_string::operator<(cis_string &comparison) {
	cis_string first  = this->entferne_umlaute();
	cis_string second = comparison.entferne_umlaute();

	if (first.get_data() < second.get_data())
		return true;
	else 
		return false;
}


cis_string cis_string::operator+(cis_string &object) {
    cis_string ret(get_data() + object.get_data());       // das '+' ist die Konkatenation aus der string-Klasse!
    return ret;
}


cis_string cis_string::operator=(const wstring &str) {
    this->set_data(str);
    return *this;
}


cis_string cis_string::operator+=(const wstring &str) {
    wstring tmp = this->get_data();
    tmp += str;
    this->set_data(tmp);
    return *this;
}


cis_string cis_string::operator=(cis_string &object) {
    this->set_data(object.get_data());
    return *this;
}


int cis_string::size() { return get_anzahl_chars(); }


int cis_string::length() { return get_anzahl_chars(); }

void cis_string::get_data(wstring &text) { text.assign(get_cis_string_data()); }

wstring cis_string::get_data() { return get_cis_string_data(); }

void cis_string::set_data(const wstring &text) { set_cis_string_data(text); } 

wchar_t cis_string::operator[](int i) {
	wstring str1 = get_data();
	return str1.at(i); 
}


wostream& operator<<(wostream &o, cis_string &object) {
    o << object.get_data();
    return o;
}


wistream& operator>>(wistream& in, cis_string &object) {
    wstring str;
    in >> str;
    object.set_data(str);
    return in;
}


#endif

}}}
===
/***
|''Name:''|BreadCrumbsPlugin|
|''Version:''|2.2.1 (05-July-2007)|
|''Author:''|AlanHecht|
|''Adapted By:''|[[Jack]]|
|''Type:''|Plugin|
!Description
This plugin creates an area at the top of the tiddler area that displays "breadcrumbs" of where you've been. This is especially useful for ~TWs using SinglePageMode by Eric Schulman.
!Usage
Just install the plugin and tag with systemConfig. Optionally position the following div in your PageTemplate to control the positioning of the breadcrumbs menu:
{{{
<div id='breadCrumbs'></div>
}}}
!Revision History
* Original by AlanHecht
* 2.0 Made 2.0.x compatible by [[Jack]]
* Made 2.0.10 compatible (onstart paramifier)
* Bugfix -> return false in onClickTiddlerLink()
* 2.2 Made 2.2.x compatible
!Code
***/

// // Use the following line to set the number of breadcrumbs to display before rotating them off the list.
//{{{
version.extensions.breadCrumbs = {major: 2, minor: 2, revision: 1, date: new Date("Jul 5, 2007")};
var crumbsToShow = 7;
var breadCrumbs = [];

onClickTiddlerLink_orig_breadCrumbs = onClickTiddlerLink;
onClickTiddlerLink = function(e){
 onClickTiddlerLink_orig_breadCrumbs(e);
 breadcrumbsAdd(e);
 return false;
}

restart_orig_breadCrumbs = restart;
function restart() {
 invokeParamifier(params,"onstart");
 var defaultParams = store.getTiddlerText("DefaultTiddlers").parseParams("open",null,false);
 invokeParamifier(defaultParams,"onstart");
 breadCrumbs = [];
 breadcrumbsRefresh();
 window.scrollTo(0,0);
 return false;
}

function breadcrumbsAdd(e) {
 var uniqueCrumb = true;
 var crumbIndex = 0;
 if (!e) var e = window.event;
 var target = resolveTarget(e);
 var thisCrumb="[["+resolveTarget(e).getAttribute("tiddlyLink")+"]]";
 var lastInactiveCrumb = breadCrumbs.length -(breadCrumbs.length < crumbsToShow ? breadCrumbs.length : crumbsToShow);
 for(t=lastInactiveCrumb; t<breadCrumbs.length; t++)
 if(breadCrumbs[t] == thisCrumb) {
 uniqueCrumb = false;
 crumbIndex = t+1;
 }
 if(uniqueCrumb)
 breadCrumbs.push(thisCrumb);
 else
 breadCrumbs = breadCrumbs.slice(0,crumbIndex);
 breadcrumbsRefresh(); 
}

function breadcrumbsRefresh() {
 
 if (!document.getElementById("breadCrumbs")) {
 // Create breadCrumbs div
 var ca = document.createElement("div");
 ca.id = "breadCrumbs";
 ca.style.visibility= "hidden";
 var targetArea = document.getElementById("tiddlerDisplay")||document.getElementById("storyDisplay");
 targetArea.parentNode.insertBefore(ca,targetArea);
 }

 var crumbArea = document.getElementById("breadCrumbs");
 crumbArea.style.visibility = "visible";
 removeChildren(crumbArea);
 createTiddlyButton(crumbArea,"Home",null,restart);
 crumbArea.appendChild(document.createTextNode(" > "));
 
 var crumbLine = "";
 var crumbCount = breadCrumbs.length;
 var firstCrumb = crumbCount -(crumbCount < crumbsToShow ? crumbCount : crumbsToShow);
 for(t=firstCrumb; t<crumbCount; t++) {
 if(t != firstCrumb)
 crumbLine += " > ";
 crumbLine += breadCrumbs[t];
 }
 wikify(crumbLine,crumbArea)
}


//}}}
/***
|Name|CalendarPlugin|
|Source|http://www.TiddlyTools.com/#CalendarPlugin|
|Version|0.0.0|
|Author|SteveRumsby|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|monthly and yearly calendars|

// // updated by Jeremy Sheeley to add cacheing for reminders
// // see http://www.geocities.com/allredfaq/reminderMacros.html
// // ''Changes by ELS 2006.08.23:''
// // added handling for weeknumbers (code supplied by Martin Budden.  see "wn**" comment marks)
// // ''Changes by ELS 2005.10.30:''
// // config.macros.calendar.handler()
// // ^^use "tbody" element for IE compatibility^^
// // ^^IE returns 2005 for current year, FF returns 105... fix year adjustment accordingly^^
// // createCalendarDays()
// // ^^use showDate() function (if defined) to render autostyled date with linked popup^^
// // calendar stylesheet definition
// // ^^use .calendar class-specific selectors, add text centering and margin settings^^


!!!!!Configuration:
<<option chkDisplayWeekNumbers>> Display week numbers //(note: Monday will be used as the start of the week)//
|''First day of week:''|<<option txtCalFirstDay>>|(Monday = 0, Sunday = 6)|
|''First day of weekend:''|<<option txtCalStartOfWeekend>>|(Monday = 0, Sunday = 6)|

!!!!!Syntax:
|{{{<<calendar>>}}}|Produce a full-year calendar for the current year|
|{{{<<calendar year>>}}}|Produce a full-year calendar for the given year|
|{{{<<calendar year month>>}}}|Produce a one-month calendar for the given month and year|
|{{{<<calendar thismonth>>}}}|Produce a one-month calendar for the current month|
|{{{<<calendar lastmonth>>}}}|Produce a one-month calendar for last month|
|{{{<<calendar nextmonth>>}}}|Produce a one-month calendar for next month|

***/
// //Modify this section to change the text displayed for the month and day names, to a different language for example. You can also change the format of the tiddler names linked to from each date, and the colours used.

//{{{
config.macros.calendar = {};

config.macros.calendar.monthnames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
config.macros.calendar.daynames = ["M", "T", "W", "T", "F", "S", "S"];

config.macros.calendar.weekendbg = "#c0c0c0";
config.macros.calendar.monthbg = "#e0e0e0";
config.macros.calendar.holidaybg = "#ffc0c0";

//}}}
// //''Code section:''
// (you should not need to alter anything below here)//
//{{{
if(config.options.txtCalFirstDay == undefined)
  config.options.txtCalFirstDay = 0;
if(config.options.txtCalStartOfWeekend == undefined)
  config.options.txtCalStartOfWeekend = 5;
if(config.options.chkDisplayWeekNumbers == undefined)//wn**
  config.options.chkDisplayWeekNumbers = false;
if(config.options.chkDisplayWeekNumbers)
  config.options.txtCalFirstDay = 0;

config.macros.calendar.tiddlerformat = "0DD/0MM/YYYY";  // This used to be changeable - for now, it isn't// <<smiley :-(>> 

version.extensions.calendar = { major: 0, minor: 6, revision: 0, date: new Date(2006, 1, 22)};
config.macros.calendar.monthdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

config.macros.calendar.holidays = [ ]; // Not sure this is required anymore - use reminders instead
//}}}

// //Is the given date a holiday?
//{{{
function calendarIsHoliday(date)
{
 var longHoliday = date.formatString("0DD/0MM/YYYY");
 var shortHoliday = date.formatString("0DD/0MM");

 for(var i = 0; i < config.macros.calendar.holidays.length; i++) {
   if(config.macros.calendar.holidays[i] == longHoliday || config.macros.calendar.holidays[i] == shortHoliday) {
     return true;
   }
 }
 return false;
}
//}}}

// //The main entry point - the macro handler.
// //Decide what sort of calendar we are creating (month or year, and which month or year)
// // Create the main calendar container and pass that to sub-ordinate functions to create the structure.
// ELS 2005.10.30: added creation and use of "tbody" for IE compatibility and fixup for year >1900//
// ELS 2005.10.30: fix year calculation for IE's getYear() function (which returns '2005' instead of '105')//
// ELS 2006.05.29: add journalDateFmt handling//
//{{{
config.macros.calendar.handler = function(place,macroName,params)
{
   var calendar = createTiddlyElement(place, "table", null, "calendar", null);
   var tbody = createTiddlyElement(calendar, "tbody", null, null, null);
   var today = new Date();
   var year = today.getYear();
   if (year<1900) year+=1900;
 
   // get format for journal link by reading from SideBarOptions (ELS 5/29/06 - based on suggestion by Martin Budden)
   var text = store.getTiddlerText("SideBarOptions");
   this.journalDateFmt = "DD-MMM-YYYY";
   var re = new RegExp("<<(?:newJournal)([^>]*)>>","mg"); var fm = re.exec(text);
   if (fm && fm[1]!=null) { var pa=fm[1].readMacroParams(); if (pa[0]) this.journalDateFmt = pa[0]; }

   if (params[0] == "thismonth")
  {
      cacheReminders(new Date(year, today.getMonth(), 1, 0, 0), 31);
      createCalendarOneMonth(tbody, year, today.getMonth());
  } 
  else if (params[0] == "lastmonth") {
      var month = today.getMonth()-1; if (month==-1) { month=11; year--; }
      cacheReminders(new Date(year, month, 1, 0, 0), 31);
      createCalendarOneMonth(tbody, year, month);
   }
   else if (params[0] == "nextmonth") {
      var month = today.getMonth()+1; if (month>11) { month=0; year++; }
      cacheReminders(new Date(year, month, 1, 0, 0), 31);
      createCalendarOneMonth(tbody, year, month);
   }
   else {
      if (params[0]) year = params[0];
      if(params[1])
      {
         cacheReminders(new Date(year, params[1]-1, 1, 0, 0), 31);
         createCalendarOneMonth(tbody, year, params[1]-1);
      }
      else
      {
         cacheReminders(new Date(year, 0, 1, 0, 0), 366);
         createCalendarYear(tbody, year);
      }
   }
  window.reminderCacheForCalendar = null;
}
//}}}
//{{{
//This global variable is used to store reminders that have been cached
//while the calendar is being rendered.  It will be renulled after the calendar is fully rendered.
window.reminderCacheForCalendar = null;
//}}}
//{{{
function cacheReminders(date, leadtime)
{
  if (window.findTiddlersWithReminders == null)
    return;
  window.reminderCacheForCalendar = {};
  var leadtimeHash = [];
  leadtimeHash [0] = 0;
  leadtimeHash [1] = leadtime;
  var t = findTiddlersWithReminders(date, leadtimeHash, null, 1);
  for(var i = 0; i < t.length; i++) {
    //just tag it in the cache, so that when we're drawing days, we can bold this one.
     window.reminderCacheForCalendar[t[i]["matchedDate"]] = "reminder:" + t[i]["params"]["title"]; 
  }
}
//}}}
//{{{
function createCalendarOneMonth(calendar, year, mon)
{
  var row = createTiddlyElement(calendar, "tr", null, null, null);
  createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, true, year, mon);
  row = createTiddlyElement(calendar, "tr", null, null, null);
  createCalendarDayHeader(row, 1);
  createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}

//{{{
function createCalendarMonth(calendar, year, mon)
{
  var row = createTiddlyElement(calendar, "tr", null, null, null);
  createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, false, year, mon);
  row = createTiddlyElement(calendar, "tr", null, null, null);
  createCalendarDayHeader(row, 1);
  createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}

//{{{
function createCalendarYear(calendar, year)
{
  var row;
  row = createTiddlyElement(calendar, "tr", null, null, null);
  var back = createTiddlyElement(row, "td", null, null, null);
  var backHandler = function() {
      removeChildren(calendar);
      createCalendarYear(calendar, year-1);
    };
  createTiddlyButton(back, "<", "Previous year", backHandler);
  back.align = "center";

  var yearHeader = createTiddlyElement(row, "td", null, "calendarYear", year);
  yearHeader.align = "center";
  //yearHeader.setAttribute("colSpan", 19);
  yearHeader.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?22:19);//wn**

  var fwd = createTiddlyElement(row, "td", null, null, null);
  var fwdHandler = function() {
    removeChildren(calendar);
    createCalendarYear(calendar, year+1);
  };
  createTiddlyButton(fwd, ">", "Next year", fwdHandler);
  fwd.align = "center";

  createCalendarMonthRow(calendar, year, 0);
  createCalendarMonthRow(calendar, year, 3);
  createCalendarMonthRow(calendar, year, 6);
  createCalendarMonthRow(calendar, year, 9);
}
//}}}

//{{{
function createCalendarMonthRow(cal, year, mon)
{
  var row = createTiddlyElement(cal, "tr", null, null, null);
  createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon], false, year, mon);
  createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+1], false, year, mon);
  createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+2], false, year, mon);
  row = createTiddlyElement(cal, "tr", null, null, null);
  createCalendarDayHeader(row, 3);
  createCalendarDayRows(cal, year, mon);
}
//}}}

//{{{
function createCalendarMonthHeader(cal, row, name, nav, year, mon)
{
  var month;
  if(nav) {
    var back = createTiddlyElement(row, "td", null, null, null);
    back.align = "center";
    back.style.background = config.macros.calendar.monthbg;

/*
    back.setAttribute("colSpan", 2);

    var backYearHandler = function() {
      var newyear = year-1;
      removeChildren(cal);
      cacheReminders(new Date(newyear, mon , 1, 0, 0), 31);
      createCalendarOneMonth(cal, newyear, mon);
    };
    createTiddlyButton(back, "<<", "Previous year", backYearHandler);
*/
    var backMonHandler = function() {
      var newyear = year;
      var newmon = mon-1;
      if(newmon == -1) { newmon = 11; newyear = newyear-1;}
      removeChildren(cal);
      cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
      createCalendarOneMonth(cal, newyear, newmon);
    };
    createTiddlyButton(back, "<", "Previous month", backMonHandler);


    month = createTiddlyElement(row, "td", null, "calendarMonthname", name)
//    month.setAttribute("colSpan", 3);
//    month.setAttribute("colSpan", 5);
    month.setAttribute("colSpan", config.options.chkDisplayWeekNumbers?6:5);//wn**

    var fwd = createTiddlyElement(row, "td", null, null, null);
    fwd.align = "center";
    fwd.style.background = config.macros.calendar.monthbg; 

//    fwd.setAttribute("colSpan", 2);
    var fwdMonHandler = function() {
      var newyear = year;
      var newmon = mon+1;
      if(newmon == 12) { newmon = 0; newyear = newyear+1;}
      removeChildren(cal);
      cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
      createCalendarOneMonth(cal, newyear, newmon);
    };
    createTiddlyButton(fwd, ">", "Next month", fwdMonHandler);
/*
    var fwdYear = createTiddlyElement(row, "td", null, null, null);
    var fwdYearHandler = function() {
      var newyear = year+1;
      removeChildren(cal);
      cacheReminders(new Date(newyear, mon , 1, 0, 0), 31);
      createCalendarOneMonth(cal, newyear, mon);
    };
    createTiddlyButton(fwd, ">>", "Next year", fwdYearHandler);
*/
  } else {
    month = createTiddlyElement(row, "td", null, "calendarMonthname", name)
    //month.setAttribute("colSpan", 7);
    month.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?8:7);//wn**
  }
  month.align = "center";
  month.style.background = config.macros.calendar.monthbg;
}
//}}}

//{{{
function createCalendarDayHeader(row, num)
{
  var cell;
  for(var i = 0; i < num; i++) {
    if (config.options.chkDisplayWeekNumbers) createTiddlyElement(row, "td");//wn**
    for(var j = 0; j < 7; j++) {
      var d = j + (config.options.txtCalFirstDay - 0);
      if(d > 6) d = d - 7;
      cell = createTiddlyElement(row, "td", null, null, config.macros.calendar.daynames[d]);
      if(d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))
        cell.style.background = config.macros.calendar.weekendbg;
    }
  }
}
//}}}

//{{{
function createCalendarDays(row, col, first, max, year, mon)
{
  var i;
  if (config.options.chkDisplayWeekNumbers){
    if (first<=max) {
      var ww = new Date(year,mon,first);
      createTiddlyElement(row, "td", null, null, "w"+ww.getWeek());//wn**
    }
    else createTiddlyElement(row, "td", null, null, null);//wn**
  }
  for(i = 0; i < col; i++) {
    createTiddlyElement(row, "td", null, null, null);
  }
  var day = first;
  for(i = col; i < 7; i++) {
    var d = i + (config.options.txtCalFirstDay - 0);
    if(d > 6) d = d - 7;
    var daycell = createTiddlyElement(row, "td", null, null, null);
    var isaWeekend = ((d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))? true:false);

    if(day > 0 && day <= max) {
      var celldate = new Date(year, mon, day);
      // ELS 2005.10.30: use <<date>> macro's showDate() function to create popup
      if (window.showDate) {
        showDate(daycell,celldate,"popup","DD",config.macros.calendar.journalDateFmt,true, isaWeekend); // ELS 5/29/06 - use journalDateFmt 
      } else {
        if(isaWeekend) daycell.style.background = config.macros.calendar.weekendbg;
        var title = celldate.formatString(config.macros.calendar.tiddlerformat);
        if(calendarIsHoliday(celldate)) {
          daycell.style.background = config.macros.calendar.holidaybg;
        }
        if(window.findTiddlersWithReminders == null) {
          var link = createTiddlyLink(daycell, title, false);
          link.appendChild(document.createTextNode(day));
        } else {
          var button = createTiddlyButton(daycell, day, title, onClickCalendarDate);
        }
      }
    }
    day++;
  }
}
//}}}

// //We've clicked on a day in a calendar - create a suitable pop-up of options.
// //The pop-up should contain:
// // * a link to create a new entry for that date
// // * a link to create a new reminder for that date
// // * an <hr>
// // * the list of reminders for that date
//{{{
function onClickCalendarDate(e)
{
  var button = this;
  var date = button.getAttribute("title");
  var dat = new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0, 2));

  date = dat.formatString(config.macros.calendar.tiddlerformat);
  var popup = createTiddlerPopup(this);
  popup.appendChild(document.createTextNode(date));
  var newReminder = function() {
    var t = store.getTiddlers(date);
    displayTiddler(null, date, 2, null, null, false, false);
    if(t) {
      document.getElementById("editorBody" + date).value += "\n<<reminder day:" + dat.getDate() +
                                                                                         " month:" + (dat.getMonth()+1) +
                                                                                         " year:" + (dat.getYear()+1900) + " title: >>";
    } else {
      document.getElementById("editorBody" + date).value = "<<reminder day:" + dat.getDate() +
                                                                                       " month:" + (dat.getMonth()+1) +
                                                                                       " year:" + (dat.getYear()+1900) + " title: >>";
    }
  };
  var link = createTiddlyButton(popup, "New reminder", null, newReminder); 
  popup.appendChild(document.createElement("hr"));

  var t = findTiddlersWithReminders(dat, [0,14], null, 1);
  for(var i = 0; i < t.length; i++) {
    link = createTiddlyLink(popup, t[i].tiddler, false);
    link.appendChild(document.createTextNode(t[i].tiddler));
  }
}
//}}}

//{{{
function calendarMaxDays(year, mon)
{
 var max = config.macros.calendar.monthdays[mon];
 if(mon == 1 && (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) {
 max++;
 }
 return max;
}
//}}}

//{{{
function createCalendarDayRows(cal, year, mon)
{
 var row = createTiddlyElement(cal, "tr", null, null, null);

 var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
 if(first1 < 0) first1 = first1 + 7;
 var day1 = -first1 + 1;
 var first2 = (new Date(year, mon+1, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
 if(first2 < 0) first2 = first2 + 7;
 var day2 = -first2 + 1;
 var first3 = (new Date(year, mon+2, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
 if(first3 < 0) first3 = first3 + 7;
 var day3 = -first3 + 1;

 var max1 = calendarMaxDays(year, mon);
 var max2 = calendarMaxDays(year, mon+1);
 var max3 = calendarMaxDays(year, mon+2);

 while(day1 <= max1 || day2 <= max2 || day3 <= max3) {
 row = createTiddlyElement(cal, "tr", null, null, null);
 createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
 createCalendarDays(row, 0, day2, max2, year, mon+1); day2 += 7;
 createCalendarDays(row, 0, day3, max3, year, mon+2); day3 += 7;
 }
}
//}}}

//{{{
function createCalendarDayRowsSingle(cal, year, mon)
{
 var row = createTiddlyElement(cal, "tr", null, null, null);

 var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
 if(first1 < 0) first1 = first1+ 7;
 var day1 = -first1 + 1;
 var max1 = calendarMaxDays(year, mon);

 while(day1 <= max1) {
 row = createTiddlyElement(cal, "tr", null, null, null);
 createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
 }
}
//}}}

// //ELS 2005.10.30: added styles
//{{{
setStylesheet(".calendar, .calendar table, .calendar th, .calendar tr, .calendar td { text-align:center; } .calendar, .calendar a { margin:0px !important; padding:0px !important; }", "calendarStyles");
//}}}
// // override cookie settings for CalendarPlugin:
//{{{
config.options.txtCalFirstDay=6;
config.options.txtCalStartOfWeekend=5;
//}}}
; [Last Update: 17.12.2009, [[Download|Downloads]]]
!~Cis_Text.hpp
{{{
/*
    Cis_String.hpp

    Class definitions for
      class Cis_Text

*/


//using namespace std;            /// killed

#ifndef CIS_TEXT_HPP
#define CIS_TEXT_HPP


#include <functional>
#include <vector>
#include <set>
#include <map>

#include "cis_string.hpp"
//#include "cis_string.cpp"           /// wegen structs sort1 aus cis_string etc., schlecht!
#include "HashCisString.hpp"


class Cis_Text {
  private:
    std::vector<cis_string>          Text;
    unsigned int                     Size;
    std::unordered_map<cis_string,
        int, HashCisString>          Freq;//(HashCisString::simple);
    //std::map<cis_string, int, sort1> Freq;

  //typedef
    //std::unordered_map<cis_string, int, HashCisString, HashCisStringEqual> HashMap;

  typedef
    std::vector<cis_string>::iterator       Text_iterator;
  typedef
    std::vector<cis_string>::const_iterator Text_const_iterator;
  typedef
    std::unordered_map<cis_string, int, sort1>::const_iterator Freq_const_iterator;
    //std::map<cis_string, int, sort1>::const_iterator Freq_const_it;

  public:
  // (Copy-)Constructors,Desctructors
    Cis_Text();
   ~Cis_Text();
    Cis_Text(const std::vector<cis_string> &v);
    Cis_Text(const cis_string &c);
    Cis_Text(const Cis_Text &C);    // CC
    Cis_Text(char* file);

  // "méthodes publiques"
    void print() const;
    void drucke(cis_string const &c) const;
    bool find(cis_string const &f) const;
    bool find(std::wstring const &f) const;
    void make_freq();                       ///! Hier muss noch ein const her, muss aber noch in cis_string angepasst werden!
    void print_freq() const;
    void print_stopwords(int i = 10) const;
    Cis_Text my_unique() const;             // MOD jetzt const! Gibt neuen Cis_Text zurück, der nur aus den uniques (==tokens) besteht.
    void empty_data();
    cis_string at(const unsigned int &i) const;
    void push_back(cis_string const &word);
    unsigned int size() const;


  /* Iterators                                  */
    std::vector<cis_string>::iterator begin();
    std::vector<cis_string>::iterator end();

    std::vector<cis_string>::const_iterator begin() const;
    std::vector<cis_string>::const_iterator end() const;


  /* Operators                                  */
    Cis_Text& operator=(Cis_Text const &C);
};

// Vergleichsmöglichkeiten
bool equal_cis_string(cis_string c1, cis_string c2);
bool compare_cis_string(cis_string c1, cis_string c2);
bool austria_compare_w1_lt_w2(std::wstring w1, std::wstring w2);
bool austria_compare_cs1_lt_cs2(cis_string w1, cis_string w2);


//#ifndef   CIS_TEXT_CPP
//#include "Cis_Text.cpp"
//#endif

#endif

}}}
!~Cis_Text.cpp
{{{
/*

        Cis_Text.cpp

       Implementation for
        class Cis_Text

    For (additional) comments on the methods
        please look inside Cis_Text.hpp

*/


/* Change-Log
 * 09/12/2009 DB: class made const save and is
 * (major Change) not using namespace std any more;
 *                Destructor tested
 * 01/12/2009 MH, DB: Several corrections
 * 22/11/2009 DB: First version of Cis_Text
 */


/* TODO
 * [ ] Rückgabe von Referenzen, wo möglich, notwendig, oder sinnvoll
 * [-] Test & Implementation von Konstruktor Cis_Text(char* filename) (auch in cis_string)
 * [ ]  Besser: per ifstream_iterator<cis_string> direkt im Konstruktor verwenden:
 *          z.B.: Cis_Text T(file.begin(), file.end())
 * [X] Rausnehmen der "automatischen Einbindung" der cpps in den hpps (unsauber, macht sich auch in Fehlermeldungen
 *     bemerkbar (in file xy included from file abc, in line ....);
 *     Kompilieren ab dann nur noch mit "g++ main.cpp Klasse1.cpp Klasse2.cpp"
 * [ ] Unnötige Header rausschmeissen, notwendige Header einbinden (es kann sein, dass die Klasse nur läuft,
 *     weil eine andere Klasse vorher eingebunden wurde, die den selben Header benutzt)
 * [ ] Generelles "Aufhübschen": Code-Style-Conventions wieder herstellen
 * [ ] Generelle Tests
 */


#ifndef CIS_TEXT_CPP
#define CIS_TEXT_CPP

#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>

#include "Cis_Text.hpp"
#include "cis_string.hpp"
#include "HashCisString.hpp"

Cis_Text::Cis_Text()
    : Size(0), Text(), Freq() {}


Cis_Text::~Cis_Text() {

    if (Debug >= 2)
        std::wcout << L"[Custom Destructor of class Cis_Text]" << std::endl;

    Text.clear();
    Freq.clear();
    Size = 0;
}


Cis_Text::Cis_Text(const std::vector<cis_string> &v)
    : Text(v)
    , Size(Text.size())
    , Freq()
    { /* No code */
    }


Cis_Text::Cis_Text(const cis_string &c) {
    Text.push_back(c);
    Size = Text.size();
}


Cis_Text::Cis_Text(const Cis_Text &C)
    : Text(C.Text)
    , Size(C.Size)
    , Freq(C.Freq) {
    if (Debug >= 2)
        std::wcout << L"[Copyconstructor of class Cis_Text]" << std::endl;
    /*
    Text = C.Text;
    Size = C.Size;
    Freq = C.Freq;*/
}


Cis_Text::Cis_Text(char* file) { /*# not implemented yet. #*/}


void Cis_Text::print() const {
    std::wcout << std::endl;
    for (Text_const_iterator it = Text.begin(); it != Text.end(); ++it)
        std::wcout << *it << std::endl;
}


void Cis_Text::drucke(cis_string const &c) const { std::wcout << c << std::endl; }


bool Cis_Text::find(cis_string const &f) const {
    std::vector<cis_string>::const_iterator it = Text.begin();

    for (it = Text.begin(); it != Text.end(); ++it)
        if (it->get_data() == f.get_data())
            return true;
    return false;
};


bool Cis_Text::find(std::wstring const &f) const { //# find(cis_string(f)); };
    Text_const_iterator it = Text.begin();
    while ((it->get_data()) != f) {           // 'get_data() const' wird hier aufgerufen!
        ++it;
        if ((it->get_data()) == f)
            return true;
    }
    return false;
};


void Cis_Text::make_freq() {
    std::vector<cis_string>::iterator it;

    for (it = Text.begin(); it != Text.end(); ++it)
        Freq[--(*it)]++;        // _kleingeschriebene_ Wörter in std::map einfügen
}


void Cis_Text::print_freq() const {
    // drucke die gesamte Freqenzliste mit Hilfe auch von iomanip::setw & left
    //for(std::unordered_map<cis_string, int, sort1>::const_iterator it = Freq.begin(); it != Freq.end(); ++it)
    for(Freq_const_iterator it = Freq.begin(); it != Freq.end(); ++it)
        std::wcout << std::setw(25) << it->first.get_data() << std::left << std::setw(5) << it->second << std::endl;
}


void Cis_Text::print_stopwords(int i) const {
    //std::unordered_map<cis_string, int, sort1>::const_iterator it;
    Freq_const_iterator it;
    for(it = Freq.begin(); it != Freq.end(); ++it)
        if (it->second >= i)
            std::wcout << std::setw(25) << it->first.get_data() << std::left << std::setw(5) << it->second << std::endl;
}


Cis_Text Cis_Text::my_unique() const {

    /// Zweiten std::vector als Rückgabewert herstellen
    ///   sonst machen spätere Aufrufe wie
    ///   make_freq() keinen Sinn, weil nur noch
    ///   unique-Wörter da sind.
    ///   (Scheint nicht nur logisch, ist sogar logisch! ;)
    std::vector<cis_string> T2(Text.begin(), Text.end());

    /// Vor Herstellung der uniques sortieren (notwendig)
    sort(T2.begin(), T2.end(), austria_compare_cs1_lt_cs2);

    //for (it = Text.begin(); it != Text.end(); ++it)
    //     std::wcout << L"sorted [" << *it << L"]" << std::endl;

//     std::vector<cis_string>::iterator    it;
    Text_iterator it;
    /// unique() aus algorithm verwenden
    /// ! Achtung ! Würde Text verändern, deswegen geben wir T2 zurück!
    it = unique(T2.begin(),T2.end(),equal_cis_string);

    /// ! Achtung ! unique() lässt die übrig gebliebenen (doppelten)
    /// Wörter am Ende "liegen". unique() hat uns einen iterator
    ///   dort hinterlassen, wo diese "übriggebliebenen Wörter
    ///   liegen geblieben sind. ...und ab dort loeschen wir den Rest:
    T2.erase(it, T2.end()); // erase(von, bis)

    return T2;
}


Cis_Text& Cis_Text::operator=(Cis_Text const &C) {
    for (Text_const_iterator it = C.begin(); it != C.end(); ++it)
        this->push_back(*it);
    return *this;
}


void Cis_Text::empty_data() { Text.empty(); Size = 0; }

cis_string Cis_Text::at(const unsigned int &i) const { return Text.at(i); };

void Cis_Text::push_back(const cis_string &word) { Text.push_back(word); }

unsigned int Cis_Text::size() const { return Text.size(); }


/* Iterators                                                                */
std::vector<cis_string>::iterator Cis_Text::begin() { return Text.begin(); }
std::vector<cis_string>::iterator Cis_Text::end()   { return Text.end(); }


std::vector<cis_string>::const_iterator Cis_Text::begin() const { return Text.begin(); }
std::vector<cis_string>::const_iterator Cis_Text::end() const   { return Text.end(); }

#endif

}}}
: Vorlesung, Skript, Jobangebot
: ''Max Hadersbeck''

: Korrektur der Hausaufgaben
: ''Susanne Peters''

: Tutorium
: ''Daniel Bruder''

: (Zu Anfang noch:) Musterlösungen der Aufgaben
: ''Stefan (Mighty) Partusch''

: ~Wiki-Engine (Original)
: ''Jeremy Ruston''
: http://www.tiddlywiki.com
/***
|''Name:''|CryptoFunctionsPlugin|
|''Description:''|Support for cryptographic functions|
***/
//{{{
if(!version.extensions.CryptoFunctionsPlugin) {
version.extensions.CryptoFunctionsPlugin = {installed:true};

//--
//-- Crypto functions and associated conversion routines
//--

// Crypto "namespace"
function Crypto() {}

// Convert a string to an array of big-endian 32-bit words
Crypto.strToBe32s = function(str)
{
	var be = Array();
	var len = Math.floor(str.length/4);
	var i, j;
	for(i=0, j=0; i<len; i++, j+=4) {
		be[i] = ((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
	}
	while (j<str.length) {
		be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
		j++;
	}
	return be;
};

// Convert an array of big-endian 32-bit words to a string
Crypto.be32sToStr = function(be)
{
	var str = "";
	for(var i=0;i<be.length*32;i+=8)
		str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
	return str;
};

// Convert an array of big-endian 32-bit words to a hex string
Crypto.be32sToHex = function(be)
{
	var hex = "0123456789ABCDEF";
	var str = "";
	for(var i=0;i<be.length*4;i++)
		str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
	return str;
};

// Return, in hex, the SHA-1 hash of a string
Crypto.hexSha1Str = function(str)
{
	return Crypto.be32sToHex(Crypto.sha1Str(str));
};

// Return the SHA-1 hash of a string
Crypto.sha1Str = function(str)
{
	return Crypto.sha1(Crypto.strToBe32s(str),str.length);
};

// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
Crypto.sha1 = function(x,blen)
{
	// Add 32-bit integers, wrapping at 32 bits
	add32 = function(a,b)
	{
		var lsw = (a&0xFFFF)+(b&0xFFFF);
		var msw = (a>>16)+(b>>16)+(lsw>>16);
		return (msw<<16)|(lsw&0xFFFF);
	};
	// Add five 32-bit integers, wrapping at 32 bits
	add32x5 = function(a,b,c,d,e)
	{
		var lsw = (a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
		var msw = (a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
		return (msw<<16)|(lsw&0xFFFF);
	};
	// Bitwise rotate left a 32-bit integer by 1 bit
	rol32 = function(n)
	{
		return (n>>>31)|(n<<1);
	};

	var len = blen*8;
	// Append padding so length in bits is 448 mod 512
	x[len>>5] |= 0x80 << (24-len%32);
	// Append length
	x[((len+64>>9)<<4)+15] = len;
	var w = Array(80);

	var k1 = 0x5A827999;
	var k2 = 0x6ED9EBA1;
	var k3 = 0x8F1BBCDC;
	var k4 = 0xCA62C1D6;

	var h0 = 0x67452301;
	var h1 = 0xEFCDAB89;
	var h2 = 0x98BADCFE;
	var h3 = 0x10325476;
	var h4 = 0xC3D2E1F0;

	for(var i=0;i<x.length;i+=16) {
		var j,t;
		var a = h0;
		var b = h1;
		var c = h2;
		var d = h3;
		var e = h4;
		for(j = 0;j<16;j++) {
			w[j] = x[i+j];
			t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=16;j<20;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=20;j<40;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k2);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=40;j<60;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),(b&c)|(d&(b|c)),w[j],k3);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=60;j<80;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k4);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}

		h0 = add32(h0,a);
		h1 = add32(h1,b);
		h2 = add32(h2,c);
		h3 = add32(h3,d);
		h4 = add32(h4,e);
	}
	return Array(h0,h1,h2,h3,h4);
};


}
//}}}
/***
|Name|DcTableOfContentsPlugin|
|Author|[[Doug Compton|http://www.zagware.com/tw/plugins.html#DcTableOfContentsPlugin]]|
|Contributors|[[Lewcid|http://lewcid.org]], [[FND|http://devpad.tiddlyspot.com]]|
|Source|[[FND|http://devpad.tiddlyspot.com#DcTableOfContentsPlugin]]|
|Version|0.4.0|
|~CoreVersion|2.2|
<<showtoc>>
!Description
This macro will insert a table of contents reflecting the headings that are used in a tiddler and will be automatically updated when you make changes.  Each item in the table of contents can be clicked on to jump to that heading.  It can be used either inside of select tiddlers or inside a system wide template.

A parameter can be used to show the table of contents of a seperate tiddler, &lt;<showtoc tiddlerTitle>&gt;

It will also place a link beside each header which will jump the screen to the top of the current tiddler.  This will only be displayed if the current tiddler is using the &lt;<showtoc>&gt; macro.

The appearance of the table of contents and the link to jump to the top can be modified using CSS.  An example of this is given below.

!Usage
!!Only in select tiddlers
The table of contents above is an example of how to use this macro in a tiddler.  Just insert &lt;<showtoc>&gt; in a tiddler on a line by itself.

It can also display the table of contents of another tiddler by using the macro with a parameter, &lt;<showtoc tiddlerTitle>&gt;
!!On every tiddler
It can also be used in a template to have it show on every tiddler.  An example ViewTemplate is shown below.

//{{{
<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler permalink references jump'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'>Created <span macro='view created date DD-MM-YY'></span>, updated <span macro='view modified date DD-MM-YY'></span></div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class="toc" macro='showtoc'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
//}}}

!Examples
If you had a tiddler with the following headings:
{{{
!Heading1a
!!Heading2a
!!Heading2b
!!!Heading3
!Heading1b
}}}
this table of contents would be automatically generated:
* Heading1a
** Heading2a
** Heading2b
*** Heading3
* Heading1b
!Changing how it looks
To modifiy the appearance, you can use CSS similiar to the below.
//{{{
.dcTOC ul {
	color: red;
	list-style-type: lower-roman;
}
.dcTOC a {
	color: green;
	border: none;
}

.dcTOC a:hover {
	background: white;
	border: solid 1px;
}
.dcTOCTop {
	font-size: 2em;
	color: green;
}
//}}}

!Revision History
!!v0.1.0 (2006-04-07)
* initial release
!!v0.2.0 (2006-04-10)
* added the [top] link on headings to jump to the top of the current tiddler
* appearance can now be customized using CSS
* all event handlers now return false
!!v0.3.0 (2006-04-12)
* added the ability to show the table of contents of a seperate tiddler
* fixed an error when a heading had a ~WikiLink in it
!!v0.3.5 (2007-10-16)
* updated formatter object for compatibility with TiddlyWiki v2.2 (by Lewcid)
!!v0.4.0 (2007-11-14)
* added toggle button for collapsing/expanding table of contents element
* refactored documentation
!To Do
* code sanitizing/rewrite
* documentation refactoring
* use shadow tiddler for styles
!Code
***/
//{{{

version.extensions.DcTableOfContentsPlugin= {
	major: 0, minor: 4, revision: 0,
	type: "macro",
	source: "http://devpad.tiddlyspot.com#DcTableOfContentsPlugin"
};

// Replace heading formatter with our own
for (var n=0; n<config.formatters.length; n++) {
	var format = config.formatters[n];
	if (format.name == 'heading') {
		format.handler = function(w) {
			// following two lines is the default handler
			var e = createTiddlyElement(w.output, "h" + w.matchLength);
			w.subWikifyTerm(e, this.termRegExp); //updated for TW 2.2+

			// Only show [top] if current tiddler is using showtoc
			if (w.tiddler.isTOCInTiddler == 1) {
				// Create a container for the default CSS values
				var c = createTiddlyElement(e, "div");
				c.setAttribute("style", "font-size: 0.5em; color: blue;");
				// Create the link to jump to the top
				createTiddlyButton(c, " [top]", "Go to top of tiddler", window.scrollToTop, "dcTOCTop", null, null);
			}
		}
		break;
	}
}

config.macros.showtoc = {
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var text = "";
		var title = "";
		var myTiddler = null;

		// Did they pass in a tiddler?
		if (params.length) {
			title = params[0];
			myTiddler = store.getTiddler(title);
		} else {
			myTiddler = tiddler;
		}

		if (myTiddler == null) {
			wikify("ERROR: Could not find " + title, place);
			return;
		}

		var lines = myTiddler .text.split("\n");
		myTiddler.isTOCInTiddler = 1;

		// Create a parent container so the TOC can be customized using CSS
		var r = createTiddlyElement(place, "div", null, "dcTOC");
		/* // create toggle button
		createTiddlyButton(r, "toggle", "show/collapse table of contents",
			function() { config.macros.showtoc.toggleElement(this.nextSibling); },
			"toggleButton")
*/
		// Create a container so the TOC can be customized using CSS
		var c = createTiddlyElement(r, "div");

		if (lines != null) {
			for (var x=0; x<lines.length; x++) {
				var line = lines[x];
				if (line.substr(0,1) == "!") {
					// Find first non ! char
					for (var i=0; i<line.length; i++) {
						if (line.substr(i, 1) != "!") {
							break;
						}
					}
					var desc = line.substring(i);
					// Remove WikiLinks
					desc = desc.replace(/\[\[/g, "");
					desc = desc.replace(/\]\]/g, "");

					text += line.substr(0, i).replace(/[!]/g, '#');
					text += '<html><a href="javascript:;" onClick="window.scrollToHeading(\'' + title + '\', \'' + desc+ '\', event)">' + desc+ '</a></html>\n';
				}
			}
		}
		wikify(text, c);
	}
}

config.macros.showtoc.toggleElement = function(e) {
	if(e) {
		if(e.style.display != "none") {
			e.style.display = "none";
		} else {
			e.style.display = "";
		}
	}
};

window.scrollToTop = function(evt) {
	if (! evt)
		var evt = window.event;

	var target = resolveTarget(evt);
	var tiddler = story.findContainingTiddler(target);

	if (! tiddler)
		return false;

	window.scrollTo(0, ensureVisible(tiddler));

	return false;
};

window.scrollToHeading = function(title, anchorName, evt) {
	var tiddler = null;

	if (! evt)
		var evt = window.event;

	if (title) {
		story.displayTiddler(store.getTiddler(title), title, null, false);
		tiddler = document.getElementById(story.idPrefix + title);
	} else {
		var target = resolveTarget(evt);
		tiddler = story.findContainingTiddler(target);
	}

	if (tiddler == null)
		return false;
	
	var children1 = tiddler.getElementsByTagName("h1");
	var children2 = tiddler.getElementsByTagName("h2");
	var children3 = tiddler.getElementsByTagName("h3");
	var children4 = tiddler.getElementsByTagName("h4");
	var children5 = tiddler.getElementsByTagName("h5");

	var children = new Array();
	children = children.concat(children1, children2, children3, children4, children5);

	for (var i = 0; i < children.length; i++) {
		for (var j = 0; j < children[i].length; j++) {
			var heading = children[i][j].innerHTML;

			// Remove all HTML tags
			while (heading.indexOf("<") >= 0) {
				heading = heading.substring(0, heading.indexOf("<")) + heading.substring(heading.indexOf(">") + 1);
			}

			// Cut off the code added in showtoc for TOP
			heading = heading.substr(0, heading.length-6);

			if (heading == anchorName) {
				var y = findPosY(children[i][j]);
				window.scrollTo(0,y);
				return false;
			}
		}
	}
	return false
};
//}}}
[[Aktuelles]]
/***
|''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");

}
//}}}
! Programme / Code
|>|>| ''Letztes Update''|
|!Klasse | +++[cis_string] [[download|http://www.cip.ifi.lmu.de/~bruder/cis_string.tar.gz]] [[see|cis_string (code)]]===| [[17.12.2009|Aktuelles]]|
|!Klasse | +++[Cis_Text] [[download|http://www.cip.ifi.lmu.de/~bruder/Cis_Text.tar.gz]] [[see|Cis_Text (code)]]===| [[17.12.2009|Aktuelles]]|
|!Klasse | +++[HashCisString] [[download|http://www.cip.ifi.lmu.de/~bruder/HashCisString.tar.gz]] [[see|HashCisString (code)]]===| [[17.12.2009|Aktuelles]]|
|>| +++[Aufgabe 3 komplett] [[download|http://www.cip.ifi.lmu.de/~bruder/3.tar.gz]] [[see|Aufgabe 13]]===| [[22.11.2009|Aktuelles]]|
|>| +++[Aufgabe 4 komplett] [[download|http://www.cip.ifi.lmu.de/~bruder/4.tar.gz]] [[see|Aufgabe 14]]===| [[02.12.2009|Aktuelles]]|
|>| +++[Aufgabe 6 komplett] [[download|http://www.cip.ifi.lmu.de/~bruder/6.tar.gz]] [[see|Aufgabe 16]]===| [[10.12.2009|Aktuelles]]|
|>| +++[Aufgabe 7 komplett] [[download|http://www.cip.ifi.lmu.de/~bruder/7.tar.gz]] [[see|Aufgabe 17]]===| [[17.12.2009|Aktuelles]]|
|>| +++[Aufgabe 8 komplett] [[download|http://www.cip.ifi.lmu.de/~bruder/8.tar.gz]] [[see|Aufgabe 18]]===| [[14.01.2010|Aktuelles]]|
|>| +++[Aufgabe 9 komplett] [[download|http://www.cip.ifi.lmu.de/~bruder/9.tar.gz]] [[see|Aufgabe 19]]===| [[22.01.2010|Aktuelles]]|

!!! Hinweise
; Das entpacken von {{{.tar}}} / {{{.tar.gz}}}-Dateien:
Dateien mit der Endung {{{.tar}}} oder {{{.tar.gz}}} haben bereits eine lange Tradition auf Unix/Linux Systemen. Das heisst, jeder der etwas auf sich (oder seine Programme) hält, wird sie auch in diesem Format verpacken. Das wiederum heisst auch, dass jeder der auch etwas auf sich hält diese Dateien zu irgendeinem Zeitpunkt sicher einmal benutzen und damit entpacken will. Allerdings ist vielen die Benutzung stets kryptisch geblieben, //das// wiederum aus Gründen die gar nicht sein müssen, wenn man sich für folgendes interessiert:

{{{.tar}}}-Dateien kommen noch aus Zeiten, da man Bandmaschinen benutzte (~Tape-Archives) und bieten eine tolle Funktionalität, wie z.B. updaten aller Dateien in einem {{{.tar}}}-File u.v.w.m (hierzu kann man auch in {{{man tar}}} nachlesen). {{{.tar}}}-Dateien sind in aller Regel //nicht komprimiert//. Es ist die Endung {{{.gz}}}, die anzeigt, dass die Datei mit dem {{{gzip}}}-Algorithmus komprimiert wurde. {{{.tar}}} selbst ist nur eine Zusammenfassung der enthaltenen Dateien (ein sog. "tarball"). Mit diesem profunden Halbwissen lassen sich nun {{{.tar}}} / {{{.tar.gz}}}-Dateien kinderleicht entpacken (und selbst packen).

Häufig sieht man Hinweise, die sagen "entpacken sie xyz.tar.gz mit folgendem Befehl {{{tar xzvf xyz.tar.gz}}}", aber was hat das zu bedeuten?

Nun, die Syntax von {{{tar}}} ist die folgende:
{{{
> tar --help
Aufruf: tar [OPTION...] [DATEI]...
GNU „tar“ fasst viele Dateien in einem einzigen Archiv auf Platte oder Band
zusammen und kann einzelne Dateien aus dem Archiv wieder herstellen.

Beispiele:
  %s -cf archiv.tar foo bar  # archiv.tar mit den Dateien foo und bar erzeugen
  %s -tvf archiv.tar         # Inhalt von archiv.tar ausführlich anzeigen
  %s -xf archiv.tar          # alle Dateien aus archiv.tar extrahieren

 Hauptsächlicher Arbeitsmodus:

  -A, --catenate, --concatenate   tar-Dateien an ein Archiv anfügen
  -c, --create               ein neues Archiv anlegen
  -d, --diff, --compare      Unterschiede zwischen Archiv und Dateisystem
                             suchen
      --delete               aus dem Archiv löschen (nicht auf Magnetband!)
  -r, --append               Dateien hinten an das Archiv anfügen
  -t, --list                 den Inhalt eines Archivs auflisten
      --test-label           den Archiv-Teil-Namen überprüfen und beenden
  -u, --update               nur Dateien anfügen, die neuer als die Kopie im
                             Archiv sind
  -x, --extract, --get       Dateien aus einem Archiv extrahieren
}}}
Der Befehl {{{tar xzvf xyz.tar.gz}}} bedeutet damit folgendes:
* {{{x}}} ''extract''
* {{{z}}} ''dekomprimiere''
* {{{v}}} ''verbose'' ("sprich mit mir!" bzw: sage mir, welche Dateien du gerade bearbeitest)
* {{{f}}} ''file'': bitte verwende die Datei xyz.tar.gz als die zu bearbeitende Datei
; Mit diesem Wissen nun lassen sich die eigenen wertvollen Erzeugnisse jahrelanger *nix-Arbeit für andere verpacken:
{{{tar czf zyx.tar.gz file.a file.b file.c      # create and zip the file zyx.tar.gz}}}
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]] wikibar'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
/***
|''Name:''|FootnotesPlugin|
|''Description:''|Create automated tiddler footnotes.|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#FootnotesPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.01|
|''Date:''|10/25/07|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.2|

!!Usage:
*To create a footnote, just put the footnote text inside triple backticks.
*Footnotes are numbered automatically, and listed at the bottom of the tiddler.
*{{{Creating a footnote is easy. ```This is the text for my footnote```}}}
*[[Example|FootnotesDemo]]
***/
// /%
//!BEGIN-PLUGIN-CODE
config.footnotesPlugin = {
	backLabel: "back",
	prompt:"show footnote"
};

config.formatters.unshift( {
    name: "footnotes",
    match: "```",
    lookaheadRegExp: /```((?:.|\n)*?)```/g,
    handler: function(w)
    {
        this.lookaheadRegExp.lastIndex = w.matchStart;
        var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
        if(lookaheadMatch && lookaheadMatch.index == w.matchStart )
            {
			var tiddler = story.findContainingTiddler(w.output);
			if (!tiddler.notes)
				tiddler.notes = [];
			var title = tiddler.getAttribute("tiddler");
			tiddler.notes.pushUnique(lookaheadMatch[1]);
			var pos = tiddler.notes.indexOf(lookaheadMatch[1]) + 1;
			createTiddlyButton(w.output,pos,config.footnotesPlugin.prompt,function(){var x = document.getElementById(title+"ftn"+pos);window.scrollTo(0,ensureVisible(x)+(ensureVisible(x)<findScrollY()?(findWindowHeight()-x.offsetHeight):0));return false;},"ftnlink",title+"ftnlink"+pos);			
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
            }
    }
});

old_footnotes_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template,force)
{
    var tiddler = old_footnotes_refreshTiddler.apply(this,arguments);
	if (tiddler.notes && tiddler.notes.length)
	{
		var holder = createTiddlyElement(null,"div",null,"footnoteholder");
		var list = createTiddlyElement(holder,"ol",title+"footnoteholder");
		for (var i=0; i<tiddler.notes.length; i++)
		{
			var ftn = createTiddlyElement(list,"li",title+"ftn"+(i+1),"footnote");
			wikify(tiddler.notes[i]+" ",ftn);
			createTiddlyButton(ftn,"["+config.footnotesPlugin.backLabel+"]",config.footnotesPlugin.backLabel,function(){window.scrollTo(0,ensureVisible(document.getElementById(this.parentNode.id.replace("ftn","ftnlink"))));return false;},"ftnbklink");
		}
		var count = tiddler.childNodes.length;
		for (var j=0; j<count; j++){
			if(hasClass(tiddler.childNodes[j],"viewer")){
				var viewer = tiddler.childNodes[j];	
			}
		}
		viewer.appendChild(holder);
		tiddler.notes = [];
	}
    return tiddler;
};

setStylesheet(
".tiddler a.ftnlink {vertical-align: super; font-size: 0.8em; color:red;}\n"+
".tiddler a.ftnlink:hover, .tiddler .footnoteholder a.ftnbklink:hover{color:#fff;background:red;}\n"+
".tiddler div.footnoteholder{margin:1.8em 1.0em; padding:0.1em 1.0em 0.1em 1.0em ;border-left: 1px solid #ccc;}"+
".tiddler footnoteholder ol {font-size: 0.9em; line-height: 1.2em;}\n"+
".tiddler .footnoteholder li.footnote {margin: 0 0 5px 0;}\n"+
".tiddler .footnoteholder a.ftnbklink{color:red;}\n","FootNotesStyles");
//!END-PLUGIN-CODE
// %/
[[Themen]]
/***
|Name|GotoPlugin|
|Source|http://www.TiddlyTools.com/#GotoPlugin|
|Version|1.4.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|view any tiddler by entering it's title - displays list of possible matches|

''View a tiddler by typing its title and pressing //enter//.''  Input just enough to uniquely match a single tiddler title and ''press //enter// to auto-complete the title for you!!''  If multiple titles match your input, a list is displayed.  You can scroll-and-click (or use arrows+enter) to select/view a tiddler, or press //escape// to close the listbox to resume typing.  When the listbox is ''//not//'' being displayed, press //escape// to clear the current text input and start over.

Note: ''At any time, you can move the focus directly to the text input field by using the ~ALT-G keyboard shortcut.''
!!!!!Examples
<<<
| //IMPORTANT NOTE:// ''As of version 1.4.0 (2007.04.25), the {{{<<goto>>}}} macro has been renamed to {{{<<gotoTiddler>>}}}'' |
syntax: {{{<<gotoTiddler quiet insert inputstyle liststyle>>}}}
All parameters are optional.
* ''quiet'' prevents //automatic// display of the list as each character is typed.  To view the list when ''quiet'', use //down// or //enter//.
* ''insert'' causes the selected tiddler title to be inserted into the tiddler source currently being edited (use with EditTemplate)
* ''inputstyle'' and ''liststyle'' are CSS declarations that modify the default input and listbox styles.  Note: styles containing spaces must be surrounded by ({{{"..."}}} or {{{'...'}}}) or ({{{[[...]]}}}).
{{{<<gotoTiddler>>}}}
<<gotoTiddler>>
{{{<<gotoTiddler quiet>>}}}
<<gotoTiddler quiet>>
{{{<<goto width:20em width:20em>>}}}
<<gotoTiddler width:20em width:20em>>

You can also invoke the macro with the "insert" keyword.  When used in the [[EditTemplate]], like this:
{{{
<span macro="gotoTiddler insert"></span>
}}}
it allows you to type/select a tiddler title, and instantly insert a link to that title (e.g. {{{[[TiddlerName]]}}}) into the tiddler source being edited.
<<<
!!!!!Configuration
<<<
The following ~TiddlyWiki search options (see AdvancedOptions) are applied when matching tiddler titles:
><<option chkRegExpSearch>> use regular expressions (text patterns)
><<option chkCaseSensitiveSearch>> use case sensitive matching
You can also create a tiddler tagged with <<tag systemConfig>> to control listing of tiddlers/shadows/tags, as well as the maximum height of the listbox.  //The default values are shown below://
//{{{
config.macros.gotoTiddler.includeTiddlers=true;
config.macros.gotoTiddler.includeShadows=true;
config.macros.gotoTiddler.includeTags=true;
config.macros.gotoTiddler.listMaxSize=10;
//}}}
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''GotoPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revisions
<<<
''2007.04.25 [1.4.0]'' renamed macro from "goto" to "gotoTiddler".  This was necessary to avoid a fatal syntax error in Opera (and other browsers) that require strict adherence to ECMAScript 1.5 standards which defines the identifier "goto" as "reserved for FUTURE USE"... *sigh*
''2007.04.21 [1.3.2]'' in html definition, removed DIV around droplist (see 1.2.6 below).  It created more layout problems then it solved. :-(
''2007.04.01 [1.3.1]'' in processItem(), ensure that correct textarea field is found by checking for edit=="text" attribute
''2007.03.30 [1.3.0]'' tweak SideBarOptions shadow to automatically add {{{<<goto>>}}} when using default sidebar content
''2007.03.30 [1.2.6]'' in html definition, added DIV around droplist to fix IE problem where list appears next to input field instead of below it.  
''2007.03.28 [1.2.5]'' in processItem(), set focus to text area before setting selection (needed for IE to get correct selection 'range')
''2007.03.28 [1.2.4]'' added prompt for 'pretty text' when inserting a link into tiddler content
''2007.03.28 [1.2.3]'' added local copy of core replaceSelection() and modified for different replace logic
''2007.03.27 [1.2.2]'' in processItem(), use story.getTiddlerField() to retrieve textarea control
''2007.03.26 [1.2.1]'' in html, use either 'onkeydown' (IE) or 'onkeypress' (Moz) event to process <esc> key sooner, to prevent <esc> from 'bubbling up' to the tiddler (which will close the current editor).
''2007.03.26 [1.2.0]'' added support for optional "insert" keyword param. When used in [[EditTemplate]], (e.g. {{{<span macro="goto insert"></span>}}}) it triggers alternative processing: instead of displaying the selected tiddler, that tiddler's title is inserted into a tiddler's textarea edit field surrounded by {{{[[...]]}}}.
''2006.05.10 [1.1.2]'' when filling listbox, set selection to 'heading' item... auto-select first tiddler title when down/enter moves focus into listbox
''2006.05.08 [1.1.1]'' added accesskey ("G") to input field html (also set when field gets focus).  Also, inputKeyHandler() skips non-printing/non-editing keys. 
''2006.05.08 [1.1.0]'' added heading to listbox for better feedback (also avoids problems with 1-line droplist)
''2006.05.07 [1.0.0]'' list matches against tiddlers/shadows/tags.  input field auto-completion... 1st enter=complete matching input (or show list)... 2nd enter=view tiddler.  optional "quiet" param controls when listbox appears.
''2006.05.06 [0.5.0]'' added handling for enter (13), escape(27), and down(40) keys.   Change 'ondblclick' to 'onclick' for list handler to view tiddlers (suggested by Florian Cauvin - prevents unintended trigger of tiddler editor).  shadow titles inserted into list instead of appended to the end.
''2006.05.05 [0.0.0]'' started
<<<
!!!!!Credits
>This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
!!!!!Code
***/
//{{{
version.extensions.gotoTiddler = {major: 1, minor: 4, revision: 0, date: new Date(2007,4,25)};

// automatically tweak shadow SideBarOptions to add "sendTiddler" toolbar command (following "editTiddler")
config.shadowTiddlers.SideBarOptions=config.shadowTiddlers.SideBarOptions.replace(/<<search>>/,"{{button{goto}}}\n<<gotoTiddler>><<search>>");

config.macros.gotoTiddler= { 
	handler:
	function(place,macroName,params) {
		var quiet=(params[0] && params[0]=="quiet"); if (quiet) params.shift();
		var insert=(params[0] && params[0]=="insert"); if (insert) params.shift();
		var instyle=params.shift(); if (!instyle) instyle="";
		var liststyle=params.shift(); if (!liststyle) liststyle="";
		var keyevent=window.event?"onkeydown":"onkeypress";
		createTiddlyElement(place,"span").innerHTML
			=this.html.replace(/%keyevent%/g,keyevent).replace(/%insert%/g,insert).replace(/%quiet%/g,quiet).replace(/%instyle%/g,instyle).replace(/%liststyle%/g,liststyle);
	},

	html:
	'<form onsubmit="return false" style="display:inline;margin:0;padding:0">\
		<input name=gotoTiddler type=text autocomplete="off" accesskey="G" style="%instyle%"\
			title="enter a tiddler title"\
			onfocus="this.select(); this.setAttribute(\'accesskey\',\'G\');"\
			%keyevent%="return config.macros.gotoTiddler.inputEscKeyHandler(event,this,this.form.list);"\
			onkeyup="return config.macros.gotoTiddler.inputKeyHandler(event,this,this.form.list,%quiet%,%insert%);">\
		<select name=list style="%liststyle%;display:none;position:absolute"\
			onchange="if (!this.selectedIndex) this.selectedIndex=1;"\
			onblur="this.style.display=\'none\';"\
			%keyevent%="return config.macros.gotoTiddler.selectKeyHandler(event,this,this.form.gotoTiddler,%insert%);"\
			onclick="return config.macros.gotoTiddler.processItem(this.value,this.form.gotoTiddler,this,%insert%);">\
		</select>\
	</form>',
	
	getItems:
	function() {
		var items=[];
		var tiddlers=store.reverseLookup("tags","excludeSearch",false,"title");
		if (this.includeTiddlers) for(var t=0; t<tiddlers.length; t++) items.push(tiddlers[t].title);
		if (this.includeShadows) for (var t in config.shadowTiddlers) items.pushUnique(t);
		if (this.includeTags) { var tags=store.getTags(); for(var t=0; t<tags.length; t++) items.pushUnique(tags[t][0]); }
		return items;
	},
	includeTiddlers: true, includeShadows: true, includeTags: true,

	getItemSuffix:
	function(t) {
		if (store.tiddlerExists(t)) return "";  // tiddler
		if (store.isShadowTiddler(t)) return " (shadow)"; // shadow
		return " (tag)"; // tag 
	},

	keyProcessed:
	function(ev) { // utility function: exits handler and prevents browser from processing the keystroke
		ev.cancelBubble=true; // IE4+
		try{event.keyCode=0;}catch(e){}; // IE5
		if (window.event) ev.returnValue=false; // IE6
		if (ev.preventDefault) ev.preventDefault(); // moz/opera/konqueror
		if (ev.stopPropagation) ev.stopPropagation(); // all
		return false;
	},

	inputEscKeyHandler:
	function(event,here,list) {
		var key=event.keyCode;
		// escape... hide list (2nd esc=clears input)
		if (key==27) {
			if (list.style.display=="none")
				here.value=here.defaultValue;
			list.style.display="none";
			return this.keyProcessed(event);
		}
		return true; // key bubbles up
	},

	inputKeyHandler:
	function(event,here,list,quiet,insert) {
		var key=event.keyCode;
		// non-printing chars... bubble up, except: backspace=8, enter=13, space=32, down=40, delete=46
		if (key<48) switch(key) { case 8: case 13: case 32: case 40: case 46: break; default: return true; }
		// blank input... if down/enter... fall through (list all)... else, hide list
		if (!here.value.length && !(key==40 || key==13))
			{ list.style.display="none"; return this.keyProcessed(event); }
		// find matching items...
		var pattern=config.options.chkRegExpSearch?here.value:here.value.escapeRegExp();
		var re=new RegExp(pattern,config.options.chkCaseSensitiveSearch?"mg":"img");
		var found = []; var items=this.getItems();
		for(var t=0; t<items.length; t++) if(items[t].search(re)!=-1) found.push(items[t]);
		// matched one item... enter... not *exact* match... autocomplete input field
		if (found.length==1 && quiet && key==13 && here.value!=found[0])
			{ list.style.display="none"; here.value=found[0]; return this.keyProcessed(event); }
		// no match/exact match... enter... create/show it
		if (found.length<2 && key==13)
			return this.processItem(found.length?found[0]:here.value,here,list,insert);
		// quiet/no match... hide list...
		list.style.display=(!quiet && found.length)?"block":"none";
		// no matches... key bubbles up
		if (!found.length) return true;
		// down/enter... show/move to list...
		if (key==40 || key==13)  { list.style.display="block"; list.focus(); }
		// list is showing... fill list...
		if (list.style.display!="none") {
			while (list.length > 0) list.options[0]=null; // clear list...
			found.sort();
			list.options[0]=new Option(found.length==1?this.listMatchMsg:this.listHeading.format([found.length]),"",false,false);
			for (var t=0; t<found.length; t++)  // fill list...
				list.options[t+1]=new Option(found[t]+this.getItemSuffix(found[t]),found[t],false,false);
			list.size=(found.length<this.listMaxSize?found.length:this.listMaxSize)+1; // resize list...
			list.selectedIndex=(key==40 || key==13)?1:0;
		}
		return true; // key bubbles up
	},
	listMaxSize: 10,
	listHeading: 'Found %0 matching titles:',
	listMatchMsg: 'Press enter to open tiddler...',

	selectKeyHandler:
	function(event,list,editfield,insert) {
		if (event.keyCode==27) // escape... hide list, move to edit field
			{ editfield.focus(); list.style.display="none"; return this.keyProcessed(event); }
		if (event.keyCode==13 && list.value.length) // enter... view selected item
			{ this.processItem(list.value,editfield,list,insert); return this.keyProcessed(event); }
		return true; // key bubbles up
	},

	askForText: "Enter the text to display for this link",

	processItem:
	function(title,here,list,insert) {
		if (!title.length) return; here.value=title; list.style.display='none';
		if (insert) {
			var tidElem=story.findContainingTiddler(here); if (!tidElem) { here.focus(); return false; }
			var e=story.getTiddlerField(tidElem.getAttribute("tiddler"),"text");
			if (!e||e.getAttribute("edit")!="text") return false;
			var txt=prompt(this.askForText,title); if (!txt||!txt.length) { here.focus(); return false; }
			e.focus(); // put focus on target field before setting selection
			this.replaceSelection(e,"[["+txt+"|"+title+"]]"); // insert selected tiddler as a PrettyLink
		}
		else
			story.displayTiddler(null,title); // show selected tiddler
		return false;
	},

	replaceSelection:
	function (e,text) { // copied from 2.1.3 core and then tweaked
		if (e.setSelectionRange) {
			var oldpos = e.selectionStart;
			var isRange=e.selectionEnd-e.selectionStart;
			e.value = e.value.substr(0,e.selectionStart) + text + e.value.substr(e.selectionEnd);
			e.setSelectionRange( isRange?oldpos:oldpos+text.length, oldpos+text.length);
			var linecount = e.value.split('\n').length;
			var thisline = e.value.substr(0,e.selectionStart).split('\n').length-1;
			e.scrollTop = Math.floor((thisline-e.rows/2)*e.scrollHeight/linecount);
		}
		else if (document.selection) {
			var range = document.selection.createRange();
			if (range.parentElement() == e)	{
				var isCollapsed = range.text == "";
				range.text = text;
				 if (!isCollapsed) {
					range.moveStart('character', -text.length);
					range.select();
				}
			}
		}
	}
}
//}}}
/***
|Name|GotoboxPlugin|
|Description|a box that switches you to the entered tiddler|
|Author|Ricardo SIGNES|
|License|BSD|
|Version|0.2.2|
***/
//{{{
version.extensions.gotoBox = {
  major: 0,
  minor: 2, 
  revision: 2,
};

config.macros.gotoBox = new Object;
config.macros.gotoBox.handler = function(place,macroName)
{
  var btn = createTiddlyButton(place,"goto","jump to a named tiddler",null);
  var txt = createTiddlyElement(place,"input",null,"txtOptionInput");
  txt.onkeyup = this.onKeyPress;
  // txt.setAttribute("size",this.sizeTextbox);
  txt.setAttribute("accessKey","G");
  // txt.setAttribute("autocomplete","off");
}

config.macros.gotoBox.onKeyPress = function(e)
{
  if(!e) var e = window.event;
  switch(e.keyCode) {
    case 13: // Ctrl-Enter
    case 10: // Ctrl-Enter on IE PC
      config.macros.gotoBox.gotoTiddler(this.value);
    case 27: // Escape
      this.value = "";
      clearMessage();
      break;
    }
}

config.macros.gotoBox.gotoTiddler = function(title) {
  if (config.breadCrumbs) {
  config.breadCrumbs.restartHome();
  } else {
    story.closeTiddler(title);
  }
  story.displayTiddler('top', title);
}
//}}}
;[Last Update: 17.12.2009, [[Download|Downloads]]]
!~HashCisString.hpp
{{{
/*
        HashCisString.hpp

    Class definitions
      and impelementations for
        class HashCisString

    Max Hadersbeck, Daniel Bruder
    CIS, LMU, Dez '09

*/

/* CHANGELOG
 *
 * 16/12/2009 DB: Construction as a separate class header file
 * 15/12/2009 MH: First version of unordered_(hash)_map from
 *                new/upcoming C++-Standard 'C++0x'
 *
 */


/* COMPILATION / USAGE
 *
 * Needs compilation with g++ -std=c++0x <files>
 * and g++ Version >4.3 !!!
 *
 */



#ifndef HASH_CIS_STRING_HPP
#define HASH_CIS_STRING_HPP

#include <unordered_map>
#include <string>

#include "cis_string.hpp"

// For containers like hash_map the equal and hash classes must be defined!!!
// This class' function operator() generates a hash value for a key.
// Unique hash values (indeces) give quickest access to data.


class HashCisString {
  public:
    enum hash_fnkt {simple,h_boost,funk3};

    HashCisString(hash_fnkt h=simple);
    unsigned int operator()(const cis_string&) const;

  private:
    enum hash_fnkt toHf;
    unsigned int hash_simple(const cis_string&) const;

 ///------------------------------------------------------------
 //    Description:  Implementation of boost's default hash
 //          function (strongly simplified).
 // See at '/usr/include/boost/functional/hash/hash.hpp'.
 //
    unsigned int hash_boost(const cis_string&) const;
};

typedef
  std::unordered_map<cis_string, int, HashCisString> HashMap;

#endif

}}}
!~HashCisString.cpp
{{{
/*
        HashCisString.cpp

    Class impelementations for
        class HashCisString

    Max Hadersbeck, Daniel Bruder
    CIS, LMU, Dez '09

*/

/* CHANGELOG
 *
 * 16/12/2009 DB: Construction as a separate class header file
 * 15/12/2009 MH: First version of unordered_(hash)_map from
 *                new/upcoming C++-Standard 'C++0x'
 *
 */


/* COMPILATION / USAGE
 *
 * Needs compilation with g++ -std=c++0x <files>
 * and g++ Version >4.3 !!!
 *
 */



#ifndef HASH_CIS_STRING_CPP
#define HASH_CIS_STRING_CPP

#include <unordered_map>
#include <string>


#include "cis_string.hpp"
#include "HashCisString.hpp"

// For containers like hash_map the equal and hash classes must be defined!!!
// This class' function operator() generates a hash value for a key.
// Unique hash values (indeces) give quickest access to data.


/**
* Computes the hash value of a string.
* The hash function is the one-at-a-time hash algorithm taken from wikipedia.
*
* @see http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time
* @param str the wstring for which the hash is computed.
* @return the hash value of the string.
*/

/* Constructor                                      */
HashCisString::HashCisString(hash_fnkt h) : toHf(h) { };

unsigned int HashCisString::operator()(const cis_string& str) const {
    if (toHf==simple) {
        return hash_simple(str.get_data());
    }

    if (toHf==h_boost) {
        return hash_boost(str.get_data());
    }
}

unsigned int HashCisString::hash_simple(const cis_string& str) const {
    unsigned int h = 0;
    std::wstring tmp = str.get_data();
    for(size_t i=0; i<str.length(); i++) {
        h += tmp.at(i);
        h += (h << 10);
        h ^= (h >> 6);
    }
        h += (h << 3);
        h ^= (h >> 11);
        h += (h << 15);
    return h;
}

 ///------------------------------------------------------------
 //    Description:  Implementation of boost's default hash
 //          function (strongly simplified).
 // See at '/usr/include/boost/functional/hash/hash.hpp'.
 //
unsigned int HashCisString::hash_boost(const cis_string& str) const {
    unsigned h = 0;
    std::wstring tmp = str.get_data();
    for (unsigned i = 0; i < str.size(); ++i)
    h = 31 * h + tmp.at(i);
    return h;
}
#endif

}}}
<<importTiddlers>>
/***
|''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"
//}}}
! Referenzen
* [[www.cplusplusplus.com|http://www.cplusplus.com/reference/]]
* [[www.cppreference.com|http://www.cppreference.com/wiki/]]

! Kurswebsite
http://www.cis.uni-muenchen.de/kurse/max/C++/index.html
/***
|Name|LinksToPlugin|
|Description|command for a popup of tiddlers linked to by current tiddler|
|Author|Ricardo SIGNES|
|License|BSD|
|Version|0.2.1|
***/
//{{{
config.commands.linksTo = {
  text: "links to",
  tooltip: "Jump to a tiddler this one links to",
  popupNone: "No links",
};

config.commands.linksTo.handler = function(event,src,title) {
  tiddler = store.getTiddler(title);
  tiddler.changed();
  var popup = Popup.create(src);
  if(popup) {
    if (tiddler.links.length == 0) {
      createTiddlyText(
        createTiddlyElement(popup,"li",null,"disabled"),this.popupNone
      );
    } else {
      for (i = 0; i < tiddler.links.length; i++) {
        createTiddlyLink(createTiddlyElement(popup,"li"),tiddler.links[i],true);
      }
    }
  }
  Popup.show(popup,false);
  event.cancelBubble = true;
  if (event.stopPropagation) event.stopPropagation();
  return false;
}
//}}}
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
 major: 1, minor: 1, revision: 0, 
 date: new Date("mar 17, 2007"), 
 source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};

if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};

bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
 if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){ 
  url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
 }
 return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
+++[Aktuelles]
[[Aktuelles]]
[[Archiv]]
===
----
+++[Themen]
[[Aktuelle Aufgaben|Themen]]
[[Alte Aufgaben]]
===

[[Downloads, Programme, Code|Downloads]]
----
[[Tutoren]]
[[Credits]]
[[Links]]

/***
|Name|NestedSlidersPlugin|
|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|Documentation|http://www.TiddlyTools.com/#NestedSlidersPluginInfo|
|Version|2.4.9|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|show content in nest-able sliding/floating panels, without creating separate tiddlers for each panel's content|
!!!!!Documentation
>see [[NestedSlidersPluginInfo]]
!!!!!Configuration
<<<
<<option chkFloatingSlidersAnimate>> allow floating sliders to animate when opening/closing
>Note: This setting can cause 'clipping' problems in some versions of InternetExplorer.
>In addition, for floating slider animation to occur you must also allow animation in general (see [[AdvancedOptions]]).
<<<
!!!!!Revisions
<<<
2008.11.15 - 2.4.9 in adjustNestedSlider(), don't make adjustments if panel is marked as 'undocked' (CSS class).  In onClickNestedSlider(), SHIFT-CLICK docks panel (see [[MoveablePanelPlugin]])
|please see [[NestedSlidersPluginInfo]] for additional revision details|
2005.11.03 - 1.0.0 initial public release.  Thanks to RodneyGomes, GeoffSlocock, and PaulPetterson for suggestions and experiments.
<<<
!!!!!Code
***/
//{{{
version.extensions.NestedSlidersPlugin= {major: 2, minor: 4, revision: 9, date: new Date(2008,11,15)};

// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkFloatingSlidersAnimate===undefined)
	config.options.chkFloatingSlidersAnimate=false; // avoid clipping problems in IE

// default styles for 'floating' class
setStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \
	background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");

// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
	window.removeCookie=function(name) {
		document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;'; 
	}
}

config.formatters.push( {
	name: "nestedSliders",
	match: "\\n?\\+{3}",
	terminator: "\\s*\\={3}\\n?",
	lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\@\\[\\>]*\\^)?)?(\\*)?(\\@)?(?:\\{\\{([\\w]+[\\s\\w]*)\\{)?(\\[[^\\]]*\\])?(\\[[^\\]]*\\])?(?:\\}{3})?(\\#[^:]*\\:)?(\\>)?(\\.\\.\\.)?\\s*",
	handler: function(w)
		{
			lookaheadRegExp = new RegExp(this.lookahead,"mg");
			lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = lookaheadRegExp.exec(w.source)
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
				var defopen=lookaheadMatch[1];
				var cookiename=lookaheadMatch[2];
				var header=lookaheadMatch[3];
				var panelwidth=lookaheadMatch[4];
				var transient=lookaheadMatch[5];
				var hover=lookaheadMatch[6];
				var buttonClass=lookaheadMatch[7];
				var label=lookaheadMatch[8];
				var openlabel=lookaheadMatch[9];
				var panelID=lookaheadMatch[10];
				var blockquote=lookaheadMatch[11];
				var deferred=lookaheadMatch[12];

				// location for rendering button and panel
				var place=w.output;

				// default to closed, no cookie, no accesskey, no alternate text/tip
				var show="none"; var cookie=""; var key="";
				var closedtext=">"; var closedtip="";
				var openedtext="<"; var openedtip="";

				// extra "+", default to open
				if (defopen) show="block";

				// cookie, use saved open/closed state
				if (cookiename) {
					cookie=cookiename.trim().slice(1,-1);
					cookie="chkSlider"+cookie;
					if (config.options[cookie]==undefined)
						{ config.options[cookie] = (show=="block") }
					show=config.options[cookie]?"block":"none";
				}

				// parse label/tooltip/accesskey: [label=X|tooltip]
				if (label) {
					var parts=label.trim().slice(1,-1).split("|");
					closedtext=parts.shift();
					if (closedtext.substr(closedtext.length-2,1)=="=")	
						{ key=closedtext.substr(closedtext.length-1,1); closedtext=closedtext.slice(0,-2); }
					openedtext=closedtext;
					if (parts.length) closedtip=openedtip=parts.join("|");
					else { closedtip="show "+closedtext; openedtip="hide "+closedtext; }
				}

				// parse alternate label/tooltip: [label|tooltip]
				if (openlabel) {
					var parts=openlabel.trim().slice(1,-1).split("|");
					openedtext=parts.shift();
					if (parts.length) openedtip=parts.join("|");
					else openedtip="hide "+openedtext;
				}

				var title=show=='block'?openedtext:closedtext;
				var tooltip=show=='block'?openedtip:closedtip;

				// create the button
				if (header) { // use "Hn" header format instead of button/link
					var lvl=(header.length>5)?5:header.length;
					var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,buttonClass,title);
					btn.onclick=onClickNestedSlider;
					btn.setAttribute("href","javascript:;");
					btn.setAttribute("title",tooltip);
				}
				else
					var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,buttonClass);
				btn.innerHTML=title; // enables use of HTML entities in label

				// set extra button attributes
				btn.setAttribute("closedtext",closedtext);
				btn.setAttribute("closedtip",closedtip);
				btn.setAttribute("openedtext",openedtext);
				btn.setAttribute("openedtip",openedtip);
				btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
				btn.defOpen=defopen!=null; // save default open/closed state (boolean)
				btn.keyparam=key; // save the access key letter ("" if none)
				if (key.length) {
					btn.setAttribute("accessKey",key); // init access key
					btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus
				}
				btn.setAttribute("hover",hover?"true":"false");
				btn.onmouseover=function(ev) {
					// optional 'open on hover' handling
					if (this.getAttribute("hover")=="true" && this.sliderPanel.style.display=='none') {
						document.onclick.call(document,ev); // close transients
						onClickNestedSlider(ev); // open this slider
					}
					// mouseover on button aligns floater position with button
					if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this,this.sliderPanel);
				}

				// create slider panel
				var panelClass=panelwidth?"floatingPanel":"sliderPanel";
				if (panelID) panelID=panelID.slice(1,-1); // trim off delimiters
				var panel=createTiddlyElement(place,"div",panelID,panelClass,null);
				panel.button = btn; // so the slider panel know which button it belongs to
				btn.sliderPanel=panel; // so the button knows which slider panel it belongs to
				panel.defaultPanelWidth=(panelwidth && panelwidth.length>2)?panelwidth.slice(1,-1):"";
				panel.setAttribute("transient",transient=="*"?"true":"false");
				panel.style.display = show;
				panel.style.width=panel.defaultPanelWidth;
				panel.onmouseover=function(event) // mouseover on panel aligns floater position with button
					{ if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this.button,this); }

				// render slider (or defer until shown) 
				w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
				if ((show=="block")||!deferred) {
					// render now if panel is supposed to be shown or NOT deferred rendering
					w.subWikify(blockquote?createTiddlyElement(panel,"blockquote"):panel,this.terminator);
					// align floater position with button
					if (window.adjustSliderPos) window.adjustSliderPos(place,btn,panel);
				}
				else {
					var src = w.source.substr(w.nextMatch);
					var endpos=findMatchingDelimiter(src,"+++","===");
					panel.setAttribute("raw",src.substr(0,endpos));
					panel.setAttribute("blockquote",blockquote?"true":"false");
					panel.setAttribute("rendered","false");
					w.nextMatch += endpos+3;
					if (w.source.substr(w.nextMatch,1)=="\n") w.nextMatch++;
				}
			}
		}
	}
)

function findMatchingDelimiter(src,starttext,endtext) {
	var startpos = 0;
	var endpos = src.indexOf(endtext);
	// check for nested delimiters
	while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {
		// count number of nested 'starts'
		var startcount=0;
		var temp = src.substring(startpos,endpos-1);
		var pos=temp.indexOf(starttext);
		while (pos!=-1)  { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }
		// set up to check for additional 'starts' after adjusting endpos
		startpos=endpos+endtext.length;
		// find endpos for corresponding number of matching 'ends'
		while (startcount && endpos!=-1) {
			endpos = src.indexOf(endtext,endpos+endtext.length);
			startcount--;
		}
	}
	return (endpos==-1)?src.length:endpos;
}
//}}}
//{{{
window.onClickNestedSlider=function(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	while (theTarget && theTarget.sliderPanel==undefined) theTarget=theTarget.parentNode;
	if (!theTarget) return false;
	var theSlider = theTarget.sliderPanel;
	var isOpen = theSlider.style.display!="none";

	// if SHIFT-CLICK, dock panel first (see [[MoveablePanelPlugin]])
	if (e.shiftKey && config.macros.moveablePanel) config.macros.moveablePanel.dock(theSlider,e);

	// toggle label
	theTarget.innerHTML=isOpen?theTarget.getAttribute("closedText"):theTarget.getAttribute("openedText");
	// toggle tooltip
	theTarget.setAttribute("title",isOpen?theTarget.getAttribute("closedTip"):theTarget.getAttribute("openedTip"));

	// deferred rendering (if needed)
	if (theSlider.getAttribute("rendered")=="false") {
		var place=theSlider;
		if (theSlider.getAttribute("blockquote")=="true")
			place=createTiddlyElement(place,"blockquote");
		wikify(theSlider.getAttribute("raw"),place);
		theSlider.setAttribute("rendered","true");
	}

	// show/hide the slider
	if(config.options.chkAnimate && (!hasClass(theSlider,'floatingPanel') || config.options.chkFloatingSlidersAnimate))
		anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		theSlider.style.display = isOpen ? "none" : "block";

	// reset to default width (might have been changed via plugin code)
	theSlider.style.width=theSlider.defaultPanelWidth;

	// align floater panel position with target button
	if (!isOpen && window.adjustSliderPos) window.adjustSliderPos(theSlider.parentNode,theTarget,theSlider);

	// if showing panel, set focus to first 'focus-able' element in panel
	if (theSlider.style.display!="none") {
		var ctrls=theSlider.getElementsByTagName("*");
		for (var c=0; c<ctrls.length; c++) {
			var t=ctrls[c].tagName.toLowerCase();
			if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")
				{ try{ ctrls[c].focus(); } catch(err){;} break; }
		}
	}
	var cookie=theTarget.sliderCookie;
	if (cookie && cookie.length) {
		config.options[cookie]=!isOpen;
		if (config.options[cookie]!=theTarget.defOpen) window.saveOptionCookie(cookie);
		else window.removeCookie(cookie); // remove cookie if slider is in default display state
	}

	// prevent SHIFT-CLICK from being processed by browser (opens blank window... yuck!)
	// prevent clicks *within* a slider button from being processed by browser
	// but allow plain click to bubble up to page background (to close transients, if any)
	if (e.shiftKey || theTarget!=resolveTarget(e))
		{ e.cancelBubble=true; if (e.stopPropagation) e.stopPropagation(); }
	Popup.remove(); // close open popup (if any)
	return false;
}
//}}}
//{{{
// click in document background closes transient panels 
document.nestedSliders_savedOnClick=document.onclick;
document.onclick=function(ev) { if (!ev) var ev=window.event; var target=resolveTarget(ev);

	if (document.nestedSliders_savedOnClick)
		var retval=document.nestedSliders_savedOnClick.apply(this,arguments);
	// if click was inside a popup... leave transient panels alone
	var p=target; while (p) if (hasClass(p,"popup")) break; else p=p.parentNode;
	if (p) return retval;
	// if click was inside transient panel (or something contained by a transient panel), leave it alone
	var p=target; while (p) {
		if ((hasClass(p,"floatingPanel")||hasClass(p,"sliderPanel"))&&p.getAttribute("transient")=="true") break;
		p=p.parentNode;
	}
	if (p) return retval;
	// otherwise, find and close all transient panels...
	var all=document.all?document.all:document.getElementsByTagName("DIV");
	for (var i=0; i<all.length; i++) {
		 // if it is not a transient panel, or the click was on the button that opened this panel, don't close it.
		if (all[i].getAttribute("transient")!="true" || all[i].button==target) continue;
		// otherwise, if the panel is currently visible, close it by clicking it's button
		if (all[i].style.display!="none") window.onClickNestedSlider({target:all[i].button})
		if (!hasClass(all[i],"floatingPanel")&&!hasClass(all[i],"sliderPanel")) all[i].style.display="none";
	}
	return retval;
};
//}}}
//{{{
// adjust floating panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel) {
	if (hasClass(panel,"floatingPanel") && !hasClass(panel,"undocked")) {
		// see [[MoveablePanelPlugin]] for use of 'undocked'
		var rightEdge=document.body.offsetWidth-1;
		var panelWidth=panel.offsetWidth;
		var left=0;
		var top=btn.offsetHeight; 
		if (place.style.position=="relative" && findPosX(btn)+panelWidth>rightEdge) {
			left-=findPosX(btn)+panelWidth-rightEdge; // shift panel relative to button
			if (findPosX(btn)+left<0) left=-findPosX(btn); // stay within left edge
		}
		if (place.style.position!="relative") {
			var left=findPosX(btn);
			var top=findPosY(btn)+btn.offsetHeight;
			var p=place; while (p && !hasClass(p,'floatingPanel')) p=p.parentNode;
			if (p) { left-=findPosX(p); top-=findPosY(p); }
			if (left+panelWidth>rightEdge) left=rightEdge-panelWidth;
			if (left<0) left=0;
		}
		panel.style.left=left+"px"; panel.style.top=top+"px";
	}
}
//}}}
//{{{
// TW2.1 and earlier:
// hijack Slider stop handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function()
	{ this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }

// TW2.2+
// hijack Morpher stop handler so sliderPanel/floatingPanel overflow is visible after animation has completed
if (version.major+.1*version.minor+.01*version.revision>=2.2) {
	Morpher.prototype.coreStop = Morpher.prototype.stop;
	Morpher.prototype.stop = function() {
		this.coreStop.apply(this,arguments);
		var e=this.element;
		if (hasClass(e,"sliderPanel")||hasClass(e,"floatingPanel")) {
			// adjust panel overflow and position after animation
			e.style.overflow = "visible";
			if (window.adjustSliderPos) window.adjustSliderPos(e.parentNode,e.button,e);
		}
	};
}
//}}}
/***
|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
|''Version:''|1.0.7 (2007-03-07)|
|''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, 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//.|
|''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.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: 7,
    date: new Date(2007, 2, 7), 
    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[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 = 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)
		{
		clearMessage();
		story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);
		story.focusTiddler(title,"text");
		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;
		}
	};
})();

// 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, 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.

<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
! Erste Schritte
C++ //kompiliert// (im Gegensatz zu anderen Sprachen) den Programmcode in //direkt ausführbaren Maschinencode//, sprich: ausführbare Programmdateien. Unter Windows kennt man diese als {{{.exe}}}, unter Unix tragen sie den sogenannten "executable flag":
{{{
[3] » dbr » MOST-6 » ~ › g++ Biber.cpp 
[4] » dbr » MOST-6 » ~ › ls -la

-rw-r--r--@  1 dbr   staff     154 29 Apr 13:50 Biber.cpp
-rwxr-xr-x   1 dbr   staff   13068 29 Apr 13:50 a.out
   ^  ^  ^  ausführbar für: 'user', 'group' und 'others'
[5] » dbr » MOST-6 » ~ › ./a.out    <--- ausführen im aktuellen Verzeichnis
Biber beherrschen die Welt (seit Anbeginn der Zeit)!

[6] » dbr » MOST-6 » ~ › 
}}}

Neben den Rechnern im ~CIP-Pool ist unter Windows wie auch auf Mac ist das generelle Vorgehen das selbe:
; Programmcode schreiben (Biber.cpp) &rarr; kompilieren (g++) &rarr; ausführen (&rarr; Programmcode verbessern)
/***
|Name|SaveTiddlerToFilePlugin|
|Source|http://www.TiddlyTools.com/#SaveTiddlerToFilePlugin|
|Documentation|http://www.TiddlyTools.com/#SaveTiddlerToFilePlugin|
|Version|1.0.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|toolbar command to save tiddler source definition to an external text file|
!!!!!Usage/Example
<<<
Embedded as a macro in tiddler content:
{{{
<<saveTiddlerToFile label:text prompt:text filename:text path:text>>
}}}
or, as a tiddler toolbar command in [[ViewTemplate]]:
{{{
<span class='toolbar' macro='toolbar saveTiddlerToFile'></span>
}}}
where:
* ''label'' //(optional)//<br>specifies the text to display for the command
* ''prompt'' //(optional)//<br>specifies the mouseover 'tooltip' text for the command
* ''filename'' //(optional)//<br>specifies the default filename to create.  You can use "*" within the filename as a 'substitution marker' that will be automatically replaced with the current tiddler's title.    If ''file'' is omitted, a system-specific 'ask for filename' dialog box will be displayed, using 'tiddlername.tid' as the suggested default filename.  //Note: if the tiddler is a plugin (tagged with <<tag systemConfig>>), then the suggested filename will use ".js" instead of ".tid"//
* ''path'' //(optional)//<br>specifies the default folder in which to create the output file.  If the path begins with "./" (or ".\" for Windows) it is treated as a relative path, and the path containing the current document will be prepended to create a full path reference.  Otherwise, the specified path must be a full path reference.  You can use "*" within the path as a 'substitution marker' that will be automatically replaced with the current tiddler's title.  If ''path'' is omitted, the path containing the current document will be used by default.
Examples:
>{{{<<saveTiddlerToFile>>}}}<br>Try it: <<saveTiddlerToFile>>
>{{{<<saveTiddlerToFile label:"save 'txt' file to current folder..." filename:*.txt>>}}}<br>Try it: <<saveTiddlerToFile label:"save 'txt' file to current folder..." filename:*.txt>>
>{{{<<saveTiddlerToFile label:"save 'txt' file to archive..." filename:*.txt path:./archive>>}}}<br>Try it: <<saveTiddlerToFile label:"save 'txt' file to archive..." filename:*.txt path:./archive>>
<<<
!!!!!Configuration
<<<
When {{{<span class='toolbar' macro='toolbar saveTiddlerToFile'></span>}}} is used to create a tiddler toolbar command, the default values for all parameters are applied (e.g., you will be prompted to select/enter a filename with a ".tid" or ".js" extension).  You can override these defaults by writing the following into a tiddler tagged with <<tag systemConfig>>:
{{{
config.commands.saveTiddlerToFile.filename="...";
config.commands.saveTiddlerToFile.path="...";
}}}
<<<
!!!!!Revisions
<<<
2008.04.22 [1.1.0] converted from inline script to tiddler toolbar command
2007.06.26 [1.0.0] initial release as inline script
<<<
!!!!!Code
***/
//{{{
version.extensions.saveTiddlerToFile = {major: 1, minor: 1, revision: 0, date: new Date(2008,4,22)};

config.macros.saveTiddlerToFile = {
	label: "save this tiddler to a file",
	prompt: "save this tiddler's SOURCE text to a local file",
	askmsg: "select an output filename for this tiddler",
	okmsg: "Tiddler source written to %0",
	failmsg: "An error occurred while creating %0",
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		params = paramString.parseParams("anon",null,true,false,false);
		var label=getParam(params,"label",this.label);
		var prompt=getParam(params,"prompt",this.prompt);
		var filename=getParam(params,"filename","");
		var path=getParam(params,"path","");
		var btn=createTiddlyButton(place,label,prompt,
			function(event){config.macros.saveTiddlerToFile.go(this,event)});
		btn.setAttribute("filename",filename);
		btn.setAttribute("path",path);
	},
	go: function(src,event) {
		var cms=config.macros.saveTiddlerToFile; // abbreviation
		var here=story.findContainingTiddler(src); if (!here) return;
		var tid=here.getAttribute('tiddler');
		var filename=src.getAttribute("filename")||"";
		filename=filename.replace(/\*/g,tid);
		var path=src.getAttribute("path")||"";
		path=path.replace(/\*/g,tid);
		if (!path.length||path.substr(0,2)=="./"||path.substr(0,2)==".\\") {
			var curr=getLocalPath(document.location.href);
			var slashpos=curr.lastIndexOf("/"); if (slashpos==-1) slashpos=curr.lastIndexOf("\\"); 
			if (slashpos!=-1) curr=curr.substr(0,slashpos+1); // remove filename, leave trailing slash
			var trailingslash=curr.indexOf("\\")!=-1?"\\":"/"; // fixup for missing trailing slash
			if (path.length && path.substr(path.length,1)!=trailingslash) path+=trailingslash;
			path=!path.length?curr:curr+path.substr(2); // convert relative path to absolute path
		}
		var deffn=tid+(store.getTiddler(tid).isTagged("systemConfig")?".js":".tid");
		var target=filename.length?path+filename:cms.askForFilename(cms.askmsg,path,deffn); // ask
		if (!target||!target.length) return false; // cancelled by user
		var msg=saveFile(target,store.getTiddlerText(tid))?cms.okmsg:cms.failmsg;
		clearMessage(); displayMessage(msg.format([target]),"file:///"+target.replace(/\\/g,'/'));
	},
	askForFilename: function(msg,path,file) {
		if(window.Components) { // moz
			try {
				netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
				var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
				var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
				picker.init(window, msg, nsIFilePicker.modeSave);
				var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
				thispath.initWithPath(path);
				picker.displayDirectory=thispath;
				picker.defaultExtension='tid';
				picker.defaultString=file;
				picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
				if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
			}
			catch(e) { alert('error during local file access: '+e.toString()) }
		}
		else { // IE
			try { // XP/Vista only
				var s = new ActiveXObject('UserAccounts.CommonDialog');
				s.Filter='All files|*.*|Text files|*.txt;*.tid;*.js|HTML files|*.htm;*.html|';
				s.FilterIndex=2; // default to TEXT files;
				s.InitialDir=path;
				s.FileName=file;
				if (s.showOpen()) var result=s.FileName;
			}
			catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
		}
		return result;
	}
}

// // toolbar definition
config.commands.saveTiddlerToFile= {
	text: "file",
	tooltip: config.macros.saveTiddlerToFile.prompt,
	filename: "",
	path: "",
	handler: function(event,src,title) {
		var ccs=config.commands.saveTiddlerToFile;
		if (ccs.filename.length) src.setAttribute("filename",ccs.filename);
		if (ccs.path.length) src.setAttribute("path",ccs.path);
		config.macros.saveTiddlerToFile.go(src,event);
		return false;
	}
};
//}}}
<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>
– Tutorium WS 2009/10
Fortgeschrittene Programmierung mit C++
http://www.cip.ifi.lmu.de/~bruder/
/***
!Metadata:
|''Name:''|Slider2Plugin|
|''Description:''||
|''Version:''|1.0.1|
|''Date:''|Mar 20, 2007|
|''Source:''|http://www.sourceforge.net/projects/ptw/|
|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 1.5+ (the firefox extension, XTML Ruby support, is required)|
!Syntax:
{{{
	<<slider2 tiddlerTitle sliderTitle toolsip>>
	or {{custClass{<<slider2 tiddlerTitle sliderTitle toolsip>><<slider2 ...>>...<slider2...>>}}}
}}}
<<<
tiddlerTitle: the title of tiddler to include in the slider
sliderTitletitle: text of the slider
toolsip: tooltip text of the slider
custClass: optional, for grouping the sliders and/or assigning a group style.
<<<
!Revision History:
|''Version''|''Date''|''Note''|
|1.0.1|Mar 20, 2007|Added animation collapse|
|1.0.0|Mar 18, 2007|Initial release|
!Code section:
***/
//{{{
config.slider2 = {};
config.macros.slider2 = {
	onClickSlider: function(e){
		if (!e) var e = window.event;
		var n = this.nextSibling;
		var isOpen = n.style.display != "none";
		var nodes = this.parentNode.childNodes;
		for(var i=0; i<nodes.length; i++){
			if(nodes[i].title && nodes[i].title != this.title){
				if(nodes[i].nextSibling.className = "sliderPanel"){
					if(config.slider2[this.parentNode.className] == nodes[i].title){
						if(config.options.chkAnimate)
							anim.startAnimating(new Slider(nodes[i].nextSibling, false,e.shiftKey || e.altKey,"none"));
						else 
							nodes[i].nextSibling.style.display = "none";
					}
				}
			}
		}
		if (config.options.chkAnimate)
			setTimeout(function(){anim.startAnimating(new Slider(n,!
isOpen,null,"none"));},300);
//			anim.startAnimating(new Slider(n,!isOpen,e.shiftKey || e.altKey,"none"));
		else
			n.style.display = isOpen ? "none" : "block";
		config.slider2[this.parentNode.className] = isOpen ? "" : this.title;
		return false;
	},

	createSlider: function(place,title,tooltip){
		var btn = createTiddlyButton(place,title,tooltip,this.onClickSlider);
		var panel = createTiddlyElement(place,"div",null,"sliderPanel",null);
		panel.style.display = "none";
		return panel;
	},

	handler: function(place,macroName,params){
		params[2] = params[2]?params[2]:params[0];
		var panel = this.createSlider(place,params[1],params[2]);
		var text = store.getTiddlerText(params[0]);
		if(text)
			wikify(text,panel,null,store.getTiddler(params[0]));
	}
};
//}}}
/***
|''Name:''|SparklinePlugin|
|''Description:''|Sparklines macro|
***/
//{{{
if(!version.extensions.SparklinePlugin) {
version.extensions.SparklinePlugin = {installed:true};

//--
//-- Sparklines
//--

config.macros.sparkline = {};
config.macros.sparkline.handler = function(place,macroName,params)
{
	var data = [];
	var min = 0;
	var max = 0;
	var v;
	for(var t=0; t<params.length; t++) {
		v = parseInt(params[t]);
		if(v < min)
			min = v;
		if(v > max)
			max = v;
		data.push(v);
	}
	if(data.length < 1)
		return;
	var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
	box.title = data.join(",");
	var w = box.offsetWidth;
	var h = box.offsetHeight;
	box.style.paddingRight = (data.length * 2 - w) + "px";
	box.style.position = "relative";
	for(var d=0; d<data.length; d++) {
		var tick = document.createElement("img");
		tick.border = 0;
		tick.className = "sparktick";
		tick.style.position = "absolute";
		tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
		tick.style.left = d*2 + "px";
		tick.style.width = "2px";
		v = Math.floor(((data[d] - min)/(max-min)) * h);
		tick.style.top = (h-v) + "px";
		tick.style.height = v + "px";
		box.appendChild(tick);
	}
};


}
//}}}
[[StyleSheetSyntaxHighlighter]]
/***
StyleSheet for ~SyntaxHighlighter
***/

/*{{{*/
.dp-highlighter
{
	font-family: "Consolas", "Courier New", Courier, mono, serif;
	font-size: 12px;
	background-color: #E7E5DC;
	width: 99%;
	overflow: auto;
	margin: 18px 0 18px 0 !important;
	padding-top: 1px; /* adds a little border on top when controls are hidden */
}

/* clear styles */
.dp-highlighter ol,
.dp-highlighter ol li,
.dp-highlighter ol li span 
{
	margin: 0;
	padding: 0;
	border: none;
}

.dp-highlighter a,
.dp-highlighter a:hover
{
	background: none;
	border: none;
	padding: 0;
	margin: 0;
}

.dp-highlighter .bar
{
	padding-left: 45px;
}

.dp-highlighter.collapsed .bar,
.dp-highlighter.nogutter .bar
{
	padding-left: 0px;
}

.dp-highlighter ol
{
	list-style: decimal; /* for ie */
	background-color: #fff;
	margin: 0px 0px 1px 45px !important; /* 1px bottom margin seems to fix occasional Firefox scrolling */
	padding: 0px;
	color: #5C5C5C;
}

.dp-highlighter.nogutter ol,
.dp-highlighter.nogutter ol li
{
	list-style: none !important;
	margin-left: 0px !important;
}

.dp-highlighter ol li,
.dp-highlighter .columns div
{
	list-style: decimal-leading-zero; /* better look for others, override cascade from OL */
	list-style-position: outside !important;
	border-left: 3px solid #6CE26C;
	background-color: #F8F8F8;
	color: #5C5C5C;
	padding: 0 3px 0 10px !important;
	margin: 0 !important;
	line-height: 14px;
}

.dp-highlighter.nogutter ol li,
.dp-highlighter.nogutter .columns div
{
	border: 0;
}

.dp-highlighter .columns
{
	background-color: #F8F8F8;
	color: gray;
	overflow: hidden;
	width: 100%;
}

.dp-highlighter .columns div
{
	padding-bottom: 5px;
}

.dp-highlighter ol li.alt
{
	background-color: #FFF;
	color: inherit;
}

.dp-highlighter ol li span
{
	color: black;
	background-color: inherit;
}

/* Adjust some properties when collapsed */

.dp-highlighter.collapsed ol
{
	margin: 0px;
}

.dp-highlighter.collapsed ol li
{
	display: none;
}

/* Additional modifications when in print-view */

.dp-highlighter.printing
{
	border: none;
}

.dp-highlighter.printing .tools
{
	display: none !important;
}

.dp-highlighter.printing li
{
	display: list-item !important;
}

/* Styles for the tools */

.dp-highlighter .tools
{
	padding: 3px 8px 3px 10px;
	font: 9px Verdana, Geneva, Arial, Helvetica, sans-serif;
	color: silver;
	background-color: #f8f8f8;
	padding-bottom: 10px;
	border-left: 3px solid #6CE26C;
}

.dp-highlighter.nogutter .tools
{
	border-left: 0;
}

.dp-highlighter.collapsed .tools
{
	border-bottom: 0;
}

.dp-highlighter .tools a
{
	font-size: 9px;
	color: #a0a0a0;
	background-color: inherit;
	text-decoration: none;
	margin-right: 10px;
}

.dp-highlighter .tools a:hover
{
	color: red;
	background-color: inherit;
	text-decoration: underline;
}

/* About dialog styles */

.dp-about { background-color: #fff; color: #333; margin: 0px; padding: 0px; }
.dp-about table { width: 100%; height: 100%; font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; }
.dp-about td { padding: 10px; vertical-align: top; }
.dp-about .copy { border-bottom: 1px solid #ACA899; height: 95%; }
.dp-about .title { color: red; background-color: inherit; font-weight: bold; }
.dp-about .para { margin: 0 0 4px 0; }
.dp-about .footer { background-color: #ECEADB; color: #333; border-top: 1px solid #fff; text-align: right; }
.dp-about .close { font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; background-color: #ECEADB; color: #333; width: 60px; height: 22px; }

/* Language specific styles */

.dp-highlighter .comment, .dp-highlighter .comments { color: #008200; background-color: inherit; }
.dp-highlighter .string { color: blue; background-color: inherit; }
.dp-highlighter .keyword { color: #069; font-weight: bold; background-color: inherit; }
.dp-highlighter .preprocessor { color: gray; background-color: inherit; }

/*}}}*/
/***
!Metadata:
|''Name:''|SyntaxHighlighterPlugin|
|''Description:''|Code Syntax Highlighter Plugin for TiddlyWiki.|
|''Version:''|1.1.3|
|''Date:''|Oct 24, 2008|
|''Source:''|http://www.coolcode.cn/show-310-1.html|
|''Author:''|Ma Bingyao (andot (at) ujn (dot) edu (dot) cn)|
|''License:''|[[GNU Lesser General Public License|http://www.gnu.org/licenses/lgpl.txt]]|
|''~CoreVersion:''|2.4.1|
|''Browser:''|Firefox 1.5+; InternetExplorer 6.0; Safari; Opera; Chrome; etc.|

!Syntax:
{{{
<code options>
codes
</code>
}}}

!Examples:
{{{
<code java>
public class HelloWorld {
    public static void main(String args[]) {
        System.out.println("HelloWorld!");
    }
}
</code>
}}}

!Revision History:
|''Version''|''Date''|''Note''|
|1.1.2|Oct 15, 2008|Optimize Highlight|
|1.0.0|Oct 13, 2008|Initial release|

!Code section:
***/
//{{{
var dp={sh:{Toolbar:{},Utils:{},RegexLib:{},Brushes:{},Strings:{AboutDialog:"<html><head><title>About...</title></head><body class=\"dp-about\"><table cellspacing=\"0\"><tr><td class=\"copy\"><p class=\"title\">dp.SyntaxHighlighter</div><div class=\"para\">Version: {V}</p><p><a href=\"http://www.dreamprojections.com/syntaxhighlighter/?ref=about\" target=\"_blank\">http://www.dreamprojections.com/syntaxhighlighter</a></p>&copy;2004-2007 Alex Gorbatchev.</td></tr><tr><td class=\"footer\"><input type=\"button\" class=\"close\" value=\"OK\" onClick=\"window.close()\"/></td></tr></table></body></html>"},ClipboardSwf:null,Version:"1.5.1"}};dp.SyntaxHighlighter=dp.sh;dp.sh.Toolbar.Commands={ExpandSource:{label:"+ expand source",check:function($){return $.collapse},func:function($,_){$.parentNode.removeChild($);_.div.className=_.div.className.replace("collapsed","")}},ViewSource:{label:"view plain",func:function($,_){var A=dp.sh.Utils.FixForBlogger(_.originalCode).replace(/</g,"&lt;"),B=window.open("","_blank","width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=0");B.document.write("<textarea style=\"width:99%;height:99%\">"+A+"</textarea>");B.document.close()}},CopyToClipboard:{label:"copy to clipboard",check:function(){return window.clipboardData!=null||dp.sh.ClipboardSwf!=null},func:function($,A){var B=dp.sh.Utils.FixForBlogger(A.originalCode).replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&");if(window.clipboardData)window.clipboardData.setData("text",B);else if(dp.sh.ClipboardSwf!=null){var _=A.flashCopier;if(_==null){_=document.createElement("div");A.flashCopier=_;A.div.appendChild(_)}_.innerHTML="<embed src=\""+dp.sh.ClipboardSwf+"\" FlashVars=\"clipboard="+encodeURIComponent(B)+"\" width=\"0\" height=\"0\" type=\"application/x-shockwave-flash\"></embed>"}alert("The code is in your clipboard now")}},PrintSource:{label:"print",func:function($,B){var _=document.createElement("IFRAME"),A=null;_.style.cssText="position:absolute;width:0px;height:0px;left:-500px;top:-500px;";document.body.appendChild(_);A=_.contentWindow.document;dp.sh.Utils.CopyStyles(A,window.document);A.write("<div class=\""+B.div.className.replace("collapsed","")+" printing\">"+B.div.innerHTML+"</div>");A.close();_.contentWindow.focus();_.contentWindow.print();alert("Printing...");document.body.removeChild(_)}},About:{label:"?",func:function(_){var A=window.open("","_blank","dialog,width=300,height=150,scrollbars=0"),$=A.document;dp.sh.Utils.CopyStyles($,window.document);$.write(dp.sh.Strings.AboutDialog.replace("{V}",dp.sh.Version));$.close();A.focus()}}};dp.sh.Toolbar.Create=function(B){var A=document.createElement("DIV");A.className="tools";for(var _ in dp.sh.Toolbar.Commands){var $=dp.sh.Toolbar.Commands[_];if($.check!=null&&!$.check(B))continue;A.innerHTML+="<a href=\"#\" onclick=\"dp.sh.Toolbar.Command('"+_+"',this);return false;\">"+$.label+"</a>"}return A};dp.sh.Toolbar.Command=function(_,$){var A=$;while(A!=null&&A.className.indexOf("dp-highlighter")==-1)A=A.parentNode;if(A!=null)dp.sh.Toolbar.Commands[_].func($,A.highlighter)};dp.sh.Utils.CopyStyles=function(A,_){var $=_.getElementsByTagName("link");for(var B=0;B<$.length;B++)if($[B].rel.toLowerCase()=="stylesheet")A.write("<link type=\"text/css\" rel=\"stylesheet\" href=\""+$[B].href+"\"></link>")};dp.sh.Utils.FixForBlogger=function($){return(dp.sh.isBloggerMode==true)?$.replace(/<br\s*\/?>|&lt;br\s*\/?&gt;/gi,"\n"):$};dp.sh.RegexLib={MultiLineCComments:new RegExp("/\\*[\\s\\S]*?\\*/","gm"),SingleLineCComments:new RegExp("//.*$","gm"),SingleLinePerlComments:new RegExp("#.*$","gm"),DoubleQuotedString:new RegExp("\"(?:\\.|(\\\\\\\")|[^\\\"\"\\n])*\"","g"),SingleQuotedString:new RegExp("'(?:\\.|(\\\\\\')|[^\\''\\n])*'","g")};dp.sh.Match=function(_,$,A){this.value=_;this.index=$;this.length=_.length;this.css=A};dp.sh.Highlighter=function(){this.noGutter=false;this.addControls=true;this.collapse=false;this.tabsToSpaces=true;this.wrapColumn=80;this.showColumns=true};dp.sh.Highlighter.SortCallback=function($,_){if($.index<_.index)return-1;else if($.index>_.index)return 1;else if($.length<_.length)return-1;else if($.length>_.length)return 1;return 0};dp.sh.Highlighter.prototype.CreateElement=function(_){var $=document.createElement(_);$.highlighter=this;return $};dp.sh.Highlighter.prototype.GetMatches=function(_,B){var $=0,A=null;while((A=_.exec(this.code))!=null)this.matches[this.matches.length]=new dp.sh.Match(A[0],A.index,B)};dp.sh.Highlighter.prototype.AddBit=function($,A){if($==null||$.length==0)return;var C=this.CreateElement("SPAN");$=$.replace(/ /g,"&nbsp;");$=$.replace(/</g,"&lt;");$=$.replace(/\n/gm,"&nbsp;<br>");if(A!=null){if((/br/gi).test($)){var _=$.split("&nbsp;<br>");for(var B=0;B<_.length;B++){C=this.CreateElement("SPAN");C.className=A;C.innerHTML=_[B];this.div.appendChild(C);if(B+1<_.length)this.div.appendChild(this.CreateElement("BR"))}}else{C.className=A;C.innerHTML=$;this.div.appendChild(C)}}else{C.innerHTML=$;this.div.appendChild(C)}};dp.sh.Highlighter.prototype.IsInside=function(_){if(_==null||_.length==0)return false;for(var A=0;A<this.matches.length;A++){var $=this.matches[A];if($==null)continue;if((_.index>$.index)&&(_.index<$.index+$.length))return true}return false};dp.sh.Highlighter.prototype.ProcessRegexList=function(){for(var $=0;$<this.regexList.length;$++)this.GetMatches(this.regexList[$].regex,this.regexList[$].css)};dp.sh.Highlighter.prototype.ProcessSmartTabs=function(E){var B=E.split("\n"),$="",D=4,A="\t";function _(A,E,_){var B=A.substr(0,E),C=A.substr(E+1,A.length),$="";for(var D=0;D<_;D++)$+=" ";return B+$+C}function C(B,C){if(B.indexOf(A)==-1)return B;var D=0;while((D=B.indexOf(A))!=-1){var $=C-D%C;B=_(B,D,$)}return B}for(var F=0;F<B.length;F++)$+=C(B[F],D)+"\n";return $};dp.sh.Highlighter.prototype.SwitchToList=function(){var C=this.div.innerHTML.replace(/<(br)\/?>/gi,"\n"),B=C.split("\n");if(this.addControls==true)this.bar.appendChild(dp.sh.Toolbar.Create(this));if(this.showColumns){var A=this.CreateElement("div"),_=this.CreateElement("div"),E=10,G=1;while(G<=150)if(G%E==0){A.innerHTML+=G;G+=(G+"").length}else{A.innerHTML+="&middot;";G++}_.className="columns";_.appendChild(A);this.bar.appendChild(_)}for(var G=0,D=this.firstLine;G<B.length-1;G++,D++){var $=this.CreateElement("LI"),F=this.CreateElement("SPAN");$.className=(G%2==0)?"alt":"";F.innerHTML=B[G]+"&nbsp;";$.appendChild(F);this.ol.appendChild($)}this.div.innerHTML=""};dp.sh.Highlighter.prototype.Highlight=function(C){function A($){return $.replace(/^\s*(.*?)[\s\n]*$/g,"$1")}function $($){return $.replace(/\n*$/,"").replace(/^\n*/,"")}function _(B){var E=dp.sh.Utils.FixForBlogger(B).split("\n"),C=new Array(),D=new RegExp("^\\s*","g"),$=1000;for(var F=0;F<E.length&&$>0;F++){if(A(E[F]).length==0)continue;var _=D.exec(E[F]);if(_!=null&&_.length>0)$=Math.min(_[0].length,$)}if($>0)for(F=0;F<E.length;F++)E[F]=E[F].substr($);return E.join("\n")}function D(A,$,_){return A.substr($,_-$)}var F=0;if(C==null)C="";this.originalCode=C;this.code=$(_(C));this.div=this.CreateElement("DIV");this.bar=this.CreateElement("DIV");this.ol=this.CreateElement("OL");this.matches=new Array();this.div.className="dp-highlighter";this.div.highlighter=this;this.bar.className="bar";this.ol.start=this.firstLine;if(this.CssClass!=null)this.ol.className=this.CssClass;if(this.collapse)this.div.className+=" collapsed";if(this.noGutter)this.div.className+=" nogutter";if(this.tabsToSpaces==true)this.code=this.ProcessSmartTabs(this.code);this.ProcessRegexList();if(this.matches.length==0){this.AddBit(this.code,null);this.SwitchToList();this.div.appendChild(this.bar);this.div.appendChild(this.ol);return}this.matches=this.matches.sort(dp.sh.Highlighter.SortCallback);for(var E=0;E<this.matches.length;E++)if(this.IsInside(this.matches[E]))this.matches[E]=null;for(E=0;E<this.matches.length;E++){var B=this.matches[E];if(B==null||B.length==0)continue;this.AddBit(D(this.code,F,B.index),null);this.AddBit(B.value,B.css);F=B.index+B.length}this.AddBit(this.code.substr(F),null);this.SwitchToList();this.div.appendChild(this.bar);this.div.appendChild(this.ol)};dp.sh.Highlighter.prototype.GetKeywords=function($){return"\\b"+$.replace(/ /g,"\\b|\\b")+"\\b"};dp.sh.BloggerMode=function(){dp.sh.isBloggerMode=true};dp.sh.HighlightAll=function(N,B,K,I,O,E){function A(){var $=arguments;for(var _=0;_<$.length;_++){if($[_]==null)continue;if(typeof($[_])=="string"&&$[_]!="")return $[_]+"";if(typeof($[_])=="object"&&$[_].value!="")return $[_].value+""}return null}function J($,_){for(var A=0;A<_.length;A++)if(_[A]==$)return true;return false}function L(A,B,C){var _=new RegExp("^"+A+"\\[(\\w+)\\]$","gi"),$=null;for(var D=0;D<B.length;D++)if(($=_.exec(B[D]))!=null)return $[1];return C}function C(B,A,_){var $=document.getElementsByTagName(_);for(var C=0;C<$.length;C++)if($[C].getAttribute("name")==A)B.push($[C])}var T=[],P=null,M={},$="innerHTML";C(T,N,"pre");C(T,N,"textarea");if(T.length==0)return;for(var R in dp.sh.Brushes){var F=dp.sh.Brushes[R].Aliases;if(F==null)continue;for(var G=0;G<F.length;G++)M[F[G]]=R}for(G=0;G<T.length;G++){var _=T[G],U=A(_.attributes["class"],_.className,_.attributes["language"],_.language),Q="";if(U==null)continue;U=U.split(":");Q=U[0].toLowerCase();if(M[Q]==null)continue;P=new dp.sh.Brushes[M[Q]]();_.style.display="none";P.noGutter=(B==null)?J("nogutter",U):!B;P.addControls=(K==null)?!J("nocontrols",U):K;P.collapse=(I==null)?J("collapse",U):I;P.showColumns=(E==null)?J("showcolumns",U):E;var D=document.getElementsByTagName("head")[0];if(P.Style&&D){var S=document.createElement("style");S.setAttribute("type","text/css");if(S.styleSheet)S.styleSheet.cssText=P.Style;else{var H=document.createTextNode(P.Style);S.appendChild(H)}D.appendChild(S)}P.firstLine=(O==null)?parseInt(L("firstline",U,1)):O;P.Highlight(_[$]);P.source=_;_.parentNode.insertBefore(P.div,_)}};version.extensions.SyntaxHighLighterPlugin={major:1,minor:1,revision:3,date:new Date(2008,10,24)};dp.sh.ClipboardSwf="clipboard.swf";dp.sh.Highlight=function(_,Q,B,J,H,M,D){function A(){var $=arguments;for(var _=0;_<$.length;_++){if($[_]==null)continue;if(typeof($[_])=="string"&&$[_]!="")return $[_]+"";if(typeof($[_])=="object"&&$[_].value!="")return $[_].value+""}return null}function I($,_){for(var A=0;A<_.length;A++)if(_[A]==$)return true;return false}function K(A,B,C){var _=new RegExp("^"+A+"\\[(\\w+)\\]$","gi"),$=null;for(var D=0;D<B.length;D++)if(($=_.exec(B[D]))!=null)return $[1];return C}var N=null,$="innerHTML";if(this.registered==undefined){var L={};for(var O in dp.sh.Brushes){var E=dp.sh.Brushes[O].Aliases;if(E==null)continue;for(var F=0;F<E.length;F++)L[E[F]]=O}this.registered=L}Q=Q.split(":");language=Q[0].toLowerCase();if(this.registered[language]==null)return;N=new dp.sh.Brushes[this.registered[language]]();_.style.display="none";N.noGutter=(B==null)?I("nogutter",Q):!B;N.addControls=(J==null)?!I("nocontrols",Q):J;N.collapse=(H==null)?I("collapse",Q):H;N.showColumns=(D==null)?I("showcolumns",Q):D;var C=document.getElementsByTagName("head")[0],P=document.getElementById(N.CssClass);if(N.Style&&C&&!P){P=document.createElement("style");P.setAttribute("id",N.CssClass);P.setAttribute("type","text/css");if(P.styleSheet)P.styleSheet.cssText=N.Style;else{var G=document.createTextNode(N.Style);P.appendChild(G)}C.appendChild(P)}N.firstLine=(M==null)?parseInt(K("firstline",Q,1)):M;N.Highlight(_[$]);N.source=_;_.parentNode.insertBefore(N.div,_)};config.formatters.push({name:"SyntaxHighlighter",match:"^<code[\\s]+[^>]+>\\n",element:"pre",handler:function(_){this.lookaheadRegExp=/<code[\s]+([^>]+)>\n((?:^[^\n]*\n)+?)(^<\/code>$\n?)/mg;this.lookaheadRegExp.lastIndex=_.matchStart;var $=this.lookaheadRegExp.exec(_.source);if($&&$.index==_.matchStart){var C=$[1],B=$[2];if(config.browser.isIE)B=B.replace(/\n/g,"\r");var A=createTiddlyElement(_.output,this.element,null,null,B);dp.sh.Highlight(A,C);_.nextMatch=$.index+$[0].length}}});config.formatterHelpers.enclosedTextHelper=function(_){this.lookaheadRegExp.lastIndex=_.matchStart;var $=this.lookaheadRegExp.exec(_.source);if($&&$.index==_.matchStart){var B=$[1];if(config.browser.isIE)B=B.replace(/\n/g,"\r");var A=createTiddlyElement(_.output,this.element,null,null,B);switch(_.matchText){case"/*{{{*/\n":dp.sh.Highlight(A,"css");break;case"//{{{\n":dp.sh.Highlight(A,"js");break;case"<!--{{{-->\n":dp.sh.Highlight(A,"xml");break}_.nextMatch=$.index+$[0].length}};dp.sh.Brushes.AS3=function(){var _="class interface package",$="Array Boolean Date decodeURI decodeURIComponent encodeURI encodeURIComponent escape "+"int isFinite isNaN isXMLName Number Object parseFloat parseInt "+"String trace uint unescape XML XMLList "+"Infinity -Infinity NaN undefined "+"as delete instanceof is new typeof "+"break case catch continue default do each else finally for if in "+"label return super switch throw try while with "+"dynamic final internal native override private protected public static "+"...rest const extends function get implements namespace set "+"import include use "+"AS3 flash_proxy object_proxy "+"false null this true "+"void Null";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"blockcomment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"definition"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp("var","gm"),css:"variable"}];this.CssClass="dp-as";this.Style=".dp-as .comment { color: #009900; font-style: italic; }"+".dp-as .blockcomment { color: #3f5fbf; }"+".dp-as .string { color: #990000; }"+".dp-as .preprocessor { color: #0033ff; }"+".dp-as .definition { color: #9900cc; font-weight: bold; }"+".dp-as .keyword { color: #0033ff; }"+".dp-as .variable { color: #6699cc; font-weight: bold; }"};dp.sh.Brushes.AS3.prototype=new dp.sh.Highlighter();dp.sh.Brushes.AS3.Aliases=["as","actionscript","ActionScript","as3","AS3"];dp.sh.Brushes.Bash=function(){var _="alias bg bind break builtin cd command compgen complete continue "+"declare dirs disown echo enable eval exec exit export fc fg "+"getopts hash help history jobs kill let local logout popd printf "+"pushd pwd read readonly return set shift shopt source "+"suspend test times trap type typeset ulimit umask unalias unset wait",$="case do done elif else esac fi for function if in select then "+"time until while";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("[()[\\]{}]","g"),css:"delim"},{regex:new RegExp("\\$\\w+","g"),css:"vars"},{regex:new RegExp("\\w+=","g"),css:"vars"},{regex:new RegExp("\\s-\\w+","g"),css:"flag"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"builtin"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-bash";this.Style=".dp-bash .builtin {color: maroon; font-weight: bold;}"+".dp-bash .comment {color: gray;}"+".dp-bash .delim {font-weight: bold;}"+".dp-bash .flag {color: green;}"+".dp-bash .string {color: red;}"+".dp-bash .vars {color: blue;}"};dp.sh.Brushes.Bash.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Bash.Aliases=["bash","sh"];dp.sh.Brushes.Batch=function(){var _="APPEND ATTRIB CD CHDIR CHKDSK CHOICE CLS COPY DEL ERASE DELTREE "+"DIR EXIT FC COMP FDISK FIND FORMAT FSUTIL HELP JOIN "+"LABEL LOADFIX MK MKDIR MEM MEMMAKER MORE MOVE MSD PCPARK "+"PRINT RD RMDIR REN SCANDISK SHARE SORT SUBST SYS "+"TIME DATE TREE TRUENAME TYPE UNDELETE VER XCOPY",$="DO ELSE FOR IN CALL CHOICE GOTO SHIFT PAUSE ERRORLEVEL "+"IF NOT EXIST LFNFOR START SETLOCAL ENDLOCAL ECHO SET";this.regexList=[{regex:new RegExp("REM.*$","gm"),css:"comment"},{regex:new RegExp("::.*$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("[()[\\]{}]","g"),css:"delim"},{regex:new RegExp("%\\w+%","g"),css:"vars"},{regex:new RegExp("%%\\w+","g"),css:"vars"},{regex:new RegExp("\\w+=","g"),css:"vars"},{regex:new RegExp("@\\w+","g"),css:"keyword"},{regex:new RegExp(":\\w+","g"),css:"keyword"},{regex:new RegExp("\\s/\\w+","g"),css:"flag"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"builtin"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-batch";this.Style=".dp-batch .builtin {color: maroon; font-weight: bold;}"+".dp-batch .comment {color: gray;}"+".dp-batch .delim {font-weight: bold;}"+".dp-batch .flag {color: green;}"+".dp-batch .string {color: red;}"+".dp-batch .vars {color: blue;font-weight: bold;}"};dp.sh.Brushes.Batch.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Batch.Aliases=["batch","dos"];dp.sh.Brushes.ColdFusion=function(){this.CssClass="dp-coldfusion";this.Style=".dp-coldfusion { font: 13px \"Courier New\", Courier, monospace; }"+".dp-coldfusion .tag, .dp-coldfusion .tag-name { color: #990033; }"+".dp-coldfusion .attribute { color: #990033; }"+".dp-coldfusion .attribute-value { color: #0000FF; }"+".dp-coldfusion .cfcomments { background-color: #FFFF99; color: #000000; }"+".dp-coldfusion .cfscriptcomments { color: #999999; }"+".dp-coldfusion .keywords { color: #0000FF; }"+".dp-coldfusion .mgkeywords { color: #CC9900; }"+".dp-coldfusion .numbers { color: #ff0000; }"+".dp-coldfusion .strings { color: green; }";this.mgKeywords="setvalue getvalue addresult viewcollection viewstate";this.keywords="var eq neq gt gte lt lte not and or true false "+"abs acos addsoaprequestheader addsoapresponseheader "+"arrayappend arrayavg arrayclear arraydeleteat arrayinsertat "+"arrayisempty arraylen arraymax arraymin arraynew "+"arrayprepend arrayresize arrayset arraysort arraysum "+"arrayswap arraytolist asc asin atn binarydecode binaryencode "+"bitand bitmaskclear bitmaskread bitmaskset bitnot bitor bitshln "+"bitshrn bitxor ceiling charsetdecode charsetencode chr cjustify "+"compare comparenocase cos createdate createdatetime createobject "+"createobject createobject createobject createobject createodbcdate "+"createodbcdatetime createodbctime createtime createtimespan "+"createuuid dateadd datecompare dateconvert datediff dateformat "+"datepart day dayofweek dayofweekasstring dayofyear daysinmonth "+"daysinyear de decimalformat decrementvalue decrypt decryptbinary "+"deleteclientvariable directoryexists dollarformat duplicate encrypt "+"encryptbinary evaluate exp expandpath fileexists find findnocase "+"findoneof firstdayofmonth fix formatbasen generatesecretkey "+"getauthuser getbasetagdata getbasetaglist getbasetemplatepath "+"getclientvariableslist getcontextroot getcurrenttemplatepath "+"getdirectoryfrompath getencoding getexception getfilefrompath "+"getfunctionlist getgatewayhelper gethttprequestdata gethttptimestring "+"getk2serverdoccount getk2serverdoccountlimit getlocale "+"getlocaledisplayname getlocalhostip getmetadata getmetricdata "+"getpagecontext getprofilesections getprofilestring getsoaprequest "+"getsoaprequestheader getsoapresponse getsoapresponseheader "+"gettempdirectory gettempfile gettemplatepath gettickcount "+"gettimezoneinfo gettoken hash hour htmlcodeformat htmleditformat "+"iif incrementvalue inputbasen insert int isarray isbinary isboolean "+"iscustomfunction isdate isdebugmode isdefined isk2serverabroker "+"isk2serverdoccountexceeded isk2serveronline isleapyear islocalhost "+"isnumeric isnumericdate isobject isquery issimplevalue issoaprequest "+"isstruct isuserinrole isvalid isvalid isvalid iswddx isxml "+"isxmlattribute isxmldoc isxmlelem isxmlnode isxmlroot javacast "+"jsstringformat lcase left len listappend listchangedelims listcontains "+"listcontainsnocase listdeleteat listfind listfindnocase listfirst "+"listgetat listinsertat listlast listlen listprepend listqualify "+"listrest listsetat listsort listtoarray listvaluecount "+"listvaluecountnocase ljustify log log10 lscurrencyformat lsdateformat "+"lseurocurrencyformat lsiscurrency lsisdate lsisnumeric lsnumberformat "+"lsparsecurrency lsparsedatetime lsparseeurocurrency lsparsenumber "+"lstimeformat ltrim max mid min minute month monthasstring now "+"numberformat paragraphformat parameterexists parsedatetime pi "+"preservesinglequotes quarter queryaddcolumn queryaddrow querynew "+"querysetcell quotedvaluelist rand randomize randrange refind "+"refindnocase releasecomobject removechars repeatstring replace "+"replacelist replacenocase rereplace rereplacenocase reverse right "+"rjustify round rtrim second sendgatewaymessage setencoding "+"setlocale setprofilestring setvariable sgn sin spanexcluding "+"spanincluding sqr stripcr structappend structclear structcopy "+"structcount structdelete structfind structfindkey structfindvalue "+"structget structinsert structisempty structkeyarray structkeyexists "+"structkeylist structnew structsort structupdate tan timeformat "+"tobase64 tobinary toscript tostring trim ucase urldecode urlencodedformat "+"urlsessionformat val valuelist week wrap writeoutput xmlchildpos "+"xmlelemnew xmlformat xmlgetnodetype xmlnew xmlparse xmlsearch xmltransform "+"xmlvalidate year yesnoformat";this.stringMatches=new Array();this.attributeMatches=new Array()};dp.sh.Brushes.ColdFusion.prototype=new dp.sh.Highlighter();dp.sh.Brushes.ColdFusion.Aliases=["coldfusion","cf"];dp.sh.Brushes.ColdFusion.prototype.ProcessRegexList=function(){function B(_,$){_[_.length]=$}function A(A,$){for(var _=0;_<A.length;_++)if(A[_]==$)return _;return-1}var _=null,$=null;this.GetMatches(new RegExp("\\b(\\d+)","gm"),"numbers");this.GetMatches(new RegExp(this.GetKeywords(this.mgKeywords),"igm"),"mgkeywords");this.GetMatches(dp.sh.RegexLib.SingleLineCComments,"cfscriptcomments");this.GetMatches(dp.sh.RegexLib.MultiLineCComments,"cfscriptcomments");this.GetMatches(new RegExp("(&lt;|<)!---[\\s\\S]*?---(&gt;|>)","gm"),"cfcomments");$=new RegExp("(cfset\\s*)?([:\\w-.]+)\\s*=\\s*(\".*?\"|'.*?')*","gm");while((_=$.exec(this.code))!=null){if(_[1]!=undefined&&_[1]!="")continue;if(_[3]!=undefined&&_[3]!=""&&_[3]!="\"\""&&_[3]!="''"){B(this.matches,new dp.sh.Match(_[2],_.index,"attribute"));B(this.matches,new dp.sh.Match(_[3],_.index+_[0].indexOf(_[3]),"attribute-value"));B(this.stringMatches,_[3]);B(this.attributeMatches,_[2])}}this.GetMatches(new RegExp("(&lt;|<)/*\\?*(?!\\!)|/*\\?*(&gt;|>)","gm"),"tag");$=new RegExp("(?:&lt;|<)/*\\?*\\s*([:\\w-.]+)","gm");while((_=$.exec(this.code))!=null)B(this.matches,new dp.sh.Match(_[1],_.index+_[0].indexOf(_[1]),"tag-name"));$=new RegExp(this.GetKeywords(this.keywords),"igm");while((_=$.exec(this.code))!=null)if(A(this.attributeMatches,_[0])==-1)B(this.matches,new dp.sh.Match(_[0],_.index,"keywords"));$=new RegExp("cfset\\s*.*(\".*?\"|'.*?')","gm");while((_=$.exec(this.code))!=null)if(_[1]!=undefined&&_[1]!=""){B(this.matches,new dp.sh.Match(_[1],_.index+_[0].indexOf(_[1]),"strings"));B(this.stringMatches,_[1])}while((_=dp.sh.RegexLib.DoubleQuotedString.exec(this.code))!=null)if(A(this.stringMatches,_[0])==-1)B(this.matches,new dp.sh.Match(_[0],_.index,"strings"));while((_=dp.sh.RegexLib.SingleQuotedString.exec(this.code))!=null)if(A(this.stringMatches,_[0])==-1)B(this.matches,new dp.sh.Match(_[0],_.index,"strings"))};dp.sh.Brushes.Cpp=function(){var _="ATOM BOOL BOOLEAN BYTE CHAR COLORREF DWORD DWORDLONG DWORD_PTR "+"DWORD32 DWORD64 FLOAT HACCEL HALF_PTR HANDLE HBITMAP HBRUSH "+"HCOLORSPACE HCONV HCONVLIST HCURSOR HDC HDDEDATA HDESK HDROP HDWP "+"HENHMETAFILE HFILE HFONT HGDIOBJ HGLOBAL HHOOK HICON HINSTANCE HKEY "+"HKL HLOCAL HMENU HMETAFILE HMODULE HMONITOR HPALETTE HPEN HRESULT "+"HRGN HRSRC HSZ HWINSTA HWND INT INT_PTR INT32 INT64 LANGID LCID LCTYPE "+"LGRPID LONG LONGLONG LONG_PTR LONG32 LONG64 LPARAM LPBOOL LPBYTE LPCOLORREF "+"LPCSTR LPCTSTR LPCVOID LPCWSTR LPDWORD LPHANDLE LPINT LPLONG LPSTR LPTSTR "+"LPVOID LPWORD LPWSTR LRESULT PBOOL PBOOLEAN PBYTE PCHAR PCSTR PCTSTR PCWSTR "+"PDWORDLONG PDWORD_PTR PDWORD32 PDWORD64 PFLOAT PHALF_PTR PHANDLE PHKEY PINT "+"PINT_PTR PINT32 PINT64 PLCID PLONG PLONGLONG PLONG_PTR PLONG32 PLONG64 POINTER_32 "+"POINTER_64 PSHORT PSIZE_T PSSIZE_T PSTR PTBYTE PTCHAR PTSTR PUCHAR PUHALF_PTR "+"PUINT PUINT_PTR PUINT32 PUINT64 PULONG PULONGLONG PULONG_PTR PULONG32 PULONG64 "+"PUSHORT PVOID PWCHAR PWORD PWSTR SC_HANDLE SC_LOCK SERVICE_STATUS_HANDLE SHORT "+"SIZE_T SSIZE_T TBYTE TCHAR UCHAR UHALF_PTR UINT UINT_PTR UINT32 UINT64 ULONG "+"ULONGLONG ULONG_PTR ULONG32 ULONG64 USHORT USN VOID WCHAR WORD WPARAM WPARAM WPARAM "+"char bool short int __int32 __int64 __int8 __int16 long float double __wchar_t "+"clock_t _complex _dev_t _diskfree_t div_t ldiv_t _exception _EXCEPTION_POINTERS "+"FILE _finddata_t _finddatai64_t _wfinddata_t _wfinddatai64_t __finddata64_t "+"__wfinddata64_t _FPIEEE_RECORD fpos_t _HEAPINFO _HFILE lconv intptr_t "+"jmp_buf mbstate_t _off_t _onexit_t _PNH ptrdiff_t _purecall_handler "+"sig_atomic_t size_t _stat __stat64 _stati64 terminate_function "+"time_t __time64_t _timeb __timeb64 tm uintptr_t _utimbuf "+"va_list wchar_t wctrans_t wctype_t wint_t signed",$="break case catch class const __finally __exception __try "+"const_cast continue private public protected __declspec "+"default delete deprecated dllexport dllimport do dynamic_cast "+"else enum explicit extern if for friend goto inline "+"mutable naked namespace new noinline noreturn nothrow "+"register reinterpret_cast return selectany "+"sizeof static static_cast struct switch template this "+"thread throw true false try typedef typeid typename union "+"using uuid virtual void volatile whcar_t while";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^ *#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"datatypes"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-cpp";this.Style=".dp-cpp .datatypes { color: #2E8B57; font-weight: bold; }"};dp.sh.Brushes.Cpp.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Cpp.Aliases=["cpp","c","c++"];dp.sh.Brushes.CSharp=function(){var $="abstract as base bool break byte case catch char checked class const "+"continue decimal default delegate do double else enum event explicit "+"extern false finally fixed float for foreach get goto if implicit in int "+"interface internal is lock long namespace new null object operator out "+"override params private protected public readonly ref return sbyte sealed set "+"short sizeof stackalloc static string struct switch this throw true try "+"typeof uint ulong unchecked unsafe ushort using virtual void while";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-c";this.Style=".dp-c .vars { color: #d00; }"};dp.sh.Brushes.CSharp.prototype=new dp.sh.Highlighter();dp.sh.Brushes.CSharp.Aliases=["c#","c-sharp","csharp"];dp.sh.Brushes.CSS=function(){var _="ascent azimuth background-attachment background-color background-image background-position "+"background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top "+"border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color "+"border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width "+"border-bottom-width border-left-width border-width border cap-height caption-side centerline clear clip color "+"content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display "+"elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font "+"height letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top "+"margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans "+"outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page "+"page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position "+"quotes richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress "+"table-layout text-align text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em "+"vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index",$="above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder "+"both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed "+"continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double "+"embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia "+"gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic "+"justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha "+"lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower "+"navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset "+"outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side "+"rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow "+"small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize "+"table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal "+"text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin "+"upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow",A="[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif";this.regexList=[{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\#[a-zA-Z0-9]{3,6}","g"),css:"value"},{regex:new RegExp("(-?\\d+)(.\\d+)?(px|em|pt|:|%|)","g"),css:"value"},{regex:new RegExp("!important","g"),css:"important"},{regex:new RegExp(this.GetKeywordsCSS(_),"gm"),css:"keyword"},{regex:new RegExp(this.GetValuesCSS($),"g"),css:"value"},{regex:new RegExp(this.GetValuesCSS(A),"g"),css:"value"}];this.CssClass="dp-css";this.Style=".dp-css .value { color: black; }"+".dp-css .important { color: red; }"};dp.sh.Highlighter.prototype.GetKeywordsCSS=function($){return"\\b([a-z_]|)"+$.replace(/ /g,"(?=:)\\b|\\b([a-z_\\*]|\\*|)")+"(?=:)\\b"};dp.sh.Highlighter.prototype.GetValuesCSS=function($){return"\\b"+$.replace(/ /g,"(?!-)(?!:)\\b|\\b()")+":\\b"};dp.sh.Brushes.CSS.prototype=new dp.sh.Highlighter();dp.sh.Brushes.CSS.Aliases=["css"];dp.sh.Brushes.Delphi=function(){var $="abs addr and ansichar ansistring array as asm begin boolean byte cardinal "+"case char class comp const constructor currency destructor div do double "+"downto else end except exports extended false file finalization finally "+"for function goto if implementation in inherited int64 initialization "+"integer interface is label library longint longword mod nil not object "+"of on or packed pansichar pansistring pchar pcurrency pdatetime pextended "+"pint64 pointer private procedure program property pshortstring pstring "+"pvariant pwidechar pwidestring protected public published raise real real48 "+"record repeat set shl shortint shortstring shr single smallint string then "+"threadvar to true try type unit until uses val var varirnt while widechar "+"widestring with word write writeln xor";this.regexList=[{regex:new RegExp("\\(\\*[\\s\\S]*?\\*\\)","gm"),css:"comment"},{regex:new RegExp("{(?!\\$)[\\s\\S]*?}","gm"),css:"comment"},{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\{\\$[a-zA-Z]+ .+\\}","g"),css:"directive"},{regex:new RegExp("\\b[\\d\\.]+\\b","g"),css:"number"},{regex:new RegExp("\\$[a-zA-Z0-9]+\\b","g"),css:"number"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-delphi";this.Style=".dp-delphi .number { color: blue; }"+".dp-delphi .directive { color: #008284; }"+".dp-delphi .vars { color: #000; }"};dp.sh.Brushes.Delphi.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Delphi.Aliases=["delphi","pascal"];dp.sh.Brushes.Java=function(){var $="abstract assert boolean break byte case catch char class const "+"continue default do double else enum extends "+"false final finally float for goto if implements import "+"instanceof int interface long native new null "+"package private protected public return "+"short static strictfp super switch synchronized this throw throws true "+"transient try void volatile while";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b","gi"),css:"number"},{regex:new RegExp("(?!\\@interface\\b)\\@[\\$\\w]+\\b","g"),css:"annotation"},{regex:new RegExp("\\@interface\\b","g"),css:"keyword"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-j";this.Style=".dp-j .annotation { color: #646464; }"+".dp-j .number { color: #C00000; }"};dp.sh.Brushes.Java.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Java.Aliases=["java"];dp.sh.Brushes.JScript=function(){var $="abstract boolean break byte case catch char class const continue debugger "+"default delete do double else enum export extends false final finally float "+"for function goto if implements import in instanceof int interface long native "+"new null package private protected public return short static super switch "+"synchronized this throw throws transient true try typeof var void volatile while with";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-c"};dp.sh.Brushes.JScript.prototype=new dp.sh.Highlighter();dp.sh.Brushes.JScript.Aliases=["js","jscript","javascript"];dp.sh.Brushes.Lua=function(){var $="break do end else elseif function if local nil not or repeat return and then until while this",_="math\\.\\w+ string\\.\\w+ os\\.\\w+ debug\\.\\w+ io\\.\\w+ error fopen dofile coroutine\\.\\w+ arg getmetatable ipairs loadfile loadlib loadstring longjmp print rawget rawset seek setmetatable assert tonumber tostring";this.regexList=[{regex:new RegExp("--\\[\\[[\\s\\S]*\\]\\]--","gm"),css:"comment"},{regex:new RegExp("--[^\\[]{2}.*$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"func"},];this.CssClass="dp-lua"};dp.sh.Brushes.Lua.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Lua.Aliases=["lua"];dp.sh.Brushes.Mxml=function(){this.CssClass="dp-mxml";this.Style=".dp-mxml .cdata { color: #000000; }"+".dp-mxml .tag { color : #0000ff; }"+".dp-mxml .tag-name { color: #0000ff; }"+".dp-mxml .script { color: green; }"+".dp-mxml .metadata { color: green; }"+".dp-mxml .attribute { color: #000000; }"+".dp-mxml .attribute-value { color: #990000; }"+".dp-mxml .trace { color: #cc6666; }"+".dp-mxml .var { color: #6699cc; }"+".dp-mxml .comment { color: #009900; }"+".dp-mxml .string { color: #990000; }"+".dp-mxml .keyword { color: blue; }"};dp.sh.Brushes.Mxml.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Mxml.Aliases=["mxml"];dp.sh.Brushes.Mxml.prototype.ProcessRegexList=function(){function H(_,$){_[_.length]=$}function B(B,_){var A=0,$=false;for(A=0;A<B.length;A++)if(_.index>B[A].firstIndex&&_.index<B[A].lastIndex)$=true;return $}var $=0,F=null,D=null,A=null,C="",E=new Array(),_="abstract boolean break byte case catch char class const continue debugger "+"default delete do double else enum export extends false final finally float "+"for function goto if implements import in instanceof int interface long native "+"new null package private protected public return short static super switch "+"synchronized this throw throws transient true try typeof var void volatile while with",G=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords("trace"),"gm"),css:"trace"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"keyword"}];A=new RegExp("&lt;\\!\\[CDATA\\[(.|\\s)*?\\]\\]&gt;","gm");while((F=A.exec(this.code))!=null){C=F[0].substr(0,12);H(this.matches,new dp.sh.Match(C,F.index,"cdata"));C=F[0].substr(12,F[0].length-12-6);for(var I=0;I<G.length;I++)while((D=G[I].regex.exec(C))!=null)H(this.matches,new dp.sh.Match(D[0],F.index+12+D.index,G[I].css));C=F[0].substr(F[0].length-6,6);H(this.matches,new dp.sh.Match(C,F.index+F[0].length-6,"cdata"));E.push({firstIndex:F.index,lastIndex:F.index+F[0].length-1})}this.GetMatches(new RegExp("(&lt;|<)!--\\s*.*?\\s*--(&gt;|>)","gm"),"comments");A=new RegExp("([:\\w-.]+)\\s*=\\s*(\".*?\"|'.*?'|\\w+)*|(\\w+)","gm");while((F=A.exec(this.code))!=null){if(F[1]==null)continue;if(B(E,F))continue;H(this.matches,new dp.sh.Match(F[1],F.index,"attribute"));if(F[2]!=undefined)H(this.matches,new dp.sh.Match(F[2],F.index+F[0].indexOf(F[2]),"attribute-value"))}A=new RegExp("(?:&lt;|<)/*\\?*\\s*([:\\w-.]+)","gm");while((F=A.exec(this.code))!=null){if(B(E,F))continue;C=F[0].substr(4,F[0].length-4);switch(C){case"mx:Script":case"/mx:Script":H(this.matches,new dp.sh.Match(F[0]+"&gt;",F.index,"script"));break;case"mx:Metadata":case"/mx:Metadata":H(this.matches,new dp.sh.Match(F[0]+"&gt;",F.index,"metadata"));break;default:H(this.matches,new dp.sh.Match(F[0],F.index,"tag-name"));break}}A=new RegExp("\\?&gt;|&gt;|/&gt;","gm");while((F=A.exec(this.code))!=null){if(B(E,F))continue;H(this.matches,new dp.sh.Match(F[0],F.index,"tag"))}};dp.sh.Brushes.Perl=function(){var _="abs accept alarm atan2 bind binmode bless caller chdir chmod chomp chop chown chr chroot close closedir connect cos crypt dbmclose dbmopen defined delete dump each endgrent endhostent endnetent endprotoent endpwent endservent eof exec exists exp fcntl fileno flock fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getppid getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt glob gmtime grep hex import index int ioctl join keys kill lc lcfirst length link listen localtime lock log lstat m map mkdir msgctl msgget msgrcv msgsnd no oct open opendir ord pack pipe pop pos print printf prototype push q qq quotemeta qw qx rand read readdir readline readlink readpipe recv ref rename reset reverse rewinddir rindex rmdir scalar seek seekdir semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unlink unpack unshift untie utime values vec waitpid wantarray warn write qr",$="s select goto die do package redo require return continue for foreach last next wait while use if else elsif eval exit unless switch case",A="my our local";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("(\\$|@|%)\\w+","g"),css:"vars"},{regex:new RegExp(this.GetKeywords(_),"gmi"),css:"func"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(A),"gm"),css:"declarations"}];this.CssClass="dp-perl"};dp.sh.Brushes.Perl.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Perl.Aliases=["perl"];dp.sh.Brushes.Php=function(){var _="abs acos acosh addcslashes addslashes "+"array_change_key_case array_chunk array_combine array_count_values array_diff "+"array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill "+"array_filter array_flip array_intersect array_intersect_assoc array_intersect_key "+"array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map "+"array_merge array_merge_recursive array_multisort array_pad array_pop array_product "+"array_push array_rand array_reduce array_reverse array_search array_shift "+"array_slice array_splice array_sum array_udiff array_udiff_assoc "+"array_udiff_uassoc array_uintersect array_uintersect_assoc "+"array_uintersect_uassoc array_unique array_unshift array_values array_walk "+"array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert "+"basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress "+"bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir "+"checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists "+"closedir closelog copy cos cosh count count_chars date decbin dechex decoct "+"deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log "+"error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded "+"feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents "+"fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype "+"floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf "+"fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname "+"gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt "+"getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext "+"gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set "+"interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double "+"is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long "+"is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault "+"is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br "+"parse_ini_file parse_str parse_url passthru pathinfo readlink realpath rewind rewinddir rmdir "+"round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split "+"str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes "+"stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk "+"strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime "+"strtoupper strtr strval substr substr_compare",$="and or xor __FILE__ __LINE__ array as break case "+"cfunction class const continue declare default die do else "+"elseif empty enddeclare endfor endforeach endif endswitch endwhile "+"extends for foreach function include include_once global if "+"new old_function return static switch use require require_once "+"var while __FUNCTION__ __CLASS__ "+"__METHOD__ abstract interface public implements extends private protected throw";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\$\\w+","g"),css:"vars"},{regex:new RegExp(this.GetKeywords(_),"gmi"),css:"func"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-c"};dp.sh.Brushes.Php.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Php.Aliases=["php"];dp.sh.Brushes.Python=function(){var $="and assert break class continue def del elif else "+"except exec finally for from global if import in is "+"lambda not or pass print raise return try yield while",_="None True False self cls class_";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:new RegExp("^\\s*@\\w+","gm"),css:"decorator"},{regex:new RegExp("(['\"]{3})([^\\1])*?\\1","gm"),css:"comment"},{regex:new RegExp("\"(?!\")(?:\\.|\\\\\\\"|[^\\\"\"\\n\\r])*\"","gm"),css:"string"},{regex:new RegExp("'(?!')*(?:\\.|(\\\\\\')|[^\\''\\n\\r])*'","gm"),css:"string"},{regex:new RegExp("\\b\\d+\\.?\\w*","g"),css:"number"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"special"}];this.CssClass="dp-py";this.Style=".dp-py .builtins { color: #ff1493; }"+".dp-py .magicmethods { color: #808080; }"+".dp-py .exceptions { color: brown; }"+".dp-py .types { color: brown; font-style: italic; }"+".dp-py .commonlibs { color: #8A2BE2; font-style: italic; }"};dp.sh.Brushes.Python.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Python.Aliases=["py","python"];dp.sh.Brushes.Ruby=function(){var $="alias and BEGIN begin break case class def define_method defined do each else elsif "+"END end ensure false for if in module new next nil not or raise redo rescue retry return "+"self super then throw true undef unless until when while yield",_="Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload "+"Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol "+"ThreadGroup Thread Time TrueClass";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp(":[a-z][A-Za-z0-9_]*","g"),css:"symbol"},{regex:new RegExp("(\\$|@@|@)\\w+","g"),css:"variable"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"builtin"}];this.CssClass="dp-rb";this.Style=".dp-rb .symbol { color: #a70; }"+".dp-rb .variable { color: #a70; font-weight: bold; }"};dp.sh.Brushes.Ruby.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Ruby.Aliases=["ruby","rails","ror"];dp.sh.Brushes.Sql=function(){var _="abs avg case cast coalesce convert count current_timestamp "+"current_user day isnull left lower month nullif replace right "+"session_user space substring sum system_user upper user year",$="absolute action add after alter as asc at authorization begin bigint "+"binary bit by cascade char character check checkpoint close collate "+"column commit committed connect connection constraint contains continue "+"create cube current current_date current_time cursor database date "+"deallocate dec decimal declare default delete desc distinct double drop "+"dynamic else end end-exec escape except exec execute false fetch first "+"float for force foreign forward free from full function global goto grant "+"group grouping having hour ignore index inner insensitive insert instead "+"int integer intersect into is isolation key last level load local max min "+"minute modify move name national nchar next no numeric of off on only "+"open option order out output partial password precision prepare primary "+"prior privileges procedure public read real references relative repeatable "+"restrict return returns revoke rollback rollup rows rule schema scroll "+"second section select sequence serializable set size smallint static "+"statistics table temp temporary then time timestamp to top transaction "+"translation trigger true truncate uncommitted union unique update values "+"varchar varying view when where with work",A="all and any between cross in join like not null or outer some";this.regexList=[{regex:new RegExp("--(.*)$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp(this.GetKeywords(_),"gmi"),css:"func"},{regex:new RegExp(this.GetKeywords(A),"gmi"),css:"op"},{regex:new RegExp(this.GetKeywords($),"gmi"),css:"keyword"}];this.CssClass="dp-sql";this.Style=".dp-sql .func { color: #ff1493; }"+".dp-sql .op { color: #808080; }"};dp.sh.Brushes.Sql.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Sql.Aliases=["sql"];dp.sh.Brushes.Vb=function(){var $="AddHandler AddressOf AndAlso Alias And Ansi As Assembly Auto "+"Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate "+"CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType "+"Date Decimal Declare Default Delegate Dim DirectCast Do Double Each "+"Else ElseIf End Enum Erase Error Event Exit False Finally For Friend "+"Function Get GetType GoSub GoTo Handles If Implements Imports In "+"Inherits Integer Interface Is Let Lib Like Long Loop Me Mod Module "+"MustInherit MustOverride MyBase MyClass Namespace New Next Not Nothing "+"NotInheritable NotOverridable Object On Option Optional Or OrElse "+"Overloads Overridable Overrides ParamArray Preserve Private Property "+"Protected Public RaiseEvent ReadOnly ReDim REM RemoveHandler Resume "+"Return Select Set Shadows Shared Short Single Static Step Stop String "+"Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until "+"Variant When While With WithEvents WriteOnly Xor";this.regexList=[{regex:new RegExp("'.*$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-vb"};dp.sh.Brushes.Vb.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Vb.Aliases=["vb","vb.net"];dp.sh.Brushes.Xml=function(){this.CssClass="dp-xml";this.Style=".dp-xml .cdata { color: #ff1493; }"+".dp-xml .tag, .dp-xml .tag-name { color: #069; font-weight: bold; }"+".dp-xml .attribute { color: red; }"+".dp-xml .attribute-value { color: blue; }"};dp.sh.Brushes.Xml.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Xml.Aliases=["xml","xhtml","xslt","html","xhtml"];dp.sh.Brushes.Xml.prototype.ProcessRegexList=function(){function B(_,$){_[_.length]=$}var $=0,A=null,_=null;this.GetMatches(new RegExp("(&lt;|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](&gt;|>)","gm"),"cdata");this.GetMatches(new RegExp("(&lt;|<)!--\\s*.*?\\s*--(&gt;|>)","gm"),"comments");_=new RegExp("([:\\w-.]+)\\s*=\\s*(\".*?\"|'.*?'|\\w+)*|(\\w+)","gm");while((A=_.exec(this.code))!=null){if(A[1]==null)continue;B(this.matches,new dp.sh.Match(A[1],A.index,"attribute"));if(A[2]!=undefined)B(this.matches,new dp.sh.Match(A[2],A.index+A[0].indexOf(A[2]),"attribute-value"))}this.GetMatches(new RegExp("(&lt;|<)/*\\?*(?!\\!)|/*\\?*(&gt;|>)","gm"),"tag");_=new RegExp("(?:&lt;|<)/*\\?*\\s*([:\\w-.]+)","gm");while((A=_.exec(this.code))!=null)B(this.matches,new dp.sh.Match(A[1],A.index+A[0].indexOf(A[1]),"tag-name"))}
//}}}
/***
|''Name:''|TableSortingPlugin|
|''Description:''|Dynamically sort tables by clicking on column headers|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TableSortingPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.02|
|''Date:''|25-01-2008|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
!!Usage:
* Make sure your table has a header row
** {{{|Name|Phone Number|Address|h}}}<br> Note the /h/ that denote a header row 
* Give the table a class of 'sortable'
** {{{
|sortable|k
|Name|Phone Number|Address|h
}}}<br>Note the /k/ that denotes a class name being assigned to the table.
* To disallow sorting by a column, place {{{<<nosort>>}}} in it's header
* To automatically sort a table by a column, place {{{<<autosort>>}}} in the header for that column
** Or to sort automatically but in reverse order, use {{{<<autosort reverse>>}}}

!!Example:
|sortable|k
|Name |Salary |Extension |Performance |File Size |Start date |h
|ZBloggs, Fred |$12000.00 |1353 |+1.2 |74.2Kb |Aug 19, 2003 21:34:00 |
|ABloggs, Fred |$12000.00 |1353 |1.2 |3350b |09/18/2003 |
|CBloggs, Fred |$12000 |1353 |1.200 |55.2Kb |August 18, 2003 |
|DBloggs, Fred |$12000.00 |1353 |1.2 |2100b |07/18/2003 |
|Bloggs, Fred |$12000.00 |1353 |01.20 |6.156Mb |08/17/2003 05:43 |
|Turvey, Kevin |$191200.00 |2342 |-33 |1b |02/05/1979 |
|Mbogo, Arnold |$32010.12 |2755 |-21.673 |1.2Gb |09/08/1998 |
|Shakespeare, Bill |£122000.00|3211 |6 |33.22Gb |12/11/1961 |
|Shakespeare, Hamlet |£9000 |9005 |-8 |3Gb |01/01/2002 |
|Fitz, Marvin |€3300.30 |5554 |+5 |4Kb |05/22/1995 |

***/
// /%
//!BEGIN-PLUGIN-CODE
config.tableSorting = {
	
	darrow: "\u2193",
	
	uarrow: "\u2191",
	
	getText : function (o) {
		var p = o.cells[SORT_INDEX];
		return p.innerText || p.textContent || '';
	},
	
	sortTable : function (o,rev) {
		SORT_INDEX = o.getAttribute("index");
		var c = config.tableSorting;
		var T = findRelated(o.parentNode,"TABLE");
		if(T.tBodies[0].rows.length<=1) 
			return;
		var itm = "";
		var i = 0;
		while (itm == "" && i < T.tBodies[0].rows.length) {
			itm = c.getText(T.tBodies[0].rows[i]).trim();
			i++;
		}
		if (itm == "") 
			return; 	
		var r = [];
		var S = o.getElementsByTagName("span")[0];		
		c.fn = c.sortAlpha; 
		if(!isNaN(Date.parse(itm)))
			c.fn = c.sortDate; 
		else if(itm.match(/^[$|£|€|\+|\-]{0,1}\d*\.{0,1}\d+$/)) 
			c.fn = c.sortNumber; 
		else if(itm.match(/^\d*\.{0,1}\d+[K|M|G]{0,1}b$/)) 
			c.fn = c.sortFile; 
		for(i=0; i<T.tBodies[0].rows.length; i++) {
			 r[i]=T.tBodies[0].rows[i]; 
		} 
		r.sort(c.reSort);
		if(S.firstChild.nodeValue==c.darrow || rev) {
			r.reverse();
			S.firstChild.nodeValue=c.uarrow;
		} 
		else 
			S.firstChild.nodeValue=c.darrow;
		var thead = T.getElementsByTagName('thead')[0]; 
		var headers = thead.rows[thead.rows.length-1].cells;
		for(var k=0; k<headers.length; k++) {
			if(!hasClass(headers[k],"nosort"))
				addClass(headers[k].getElementsByTagName("span")[0],"hidden");
		}
		removeClass(S,"hidden");
		for(i=0; i<r.length; i++) { 
			T.tBodies[0].appendChild(r[i]);
			c.stripe(r[i],i);
			for(var j=0; j<r[i].cells.length;j++){
				removeClass(r[i].cells[j],"sortedCol");
			}
			addClass(r[i].cells[SORT_INDEX],"sortedCol");
		}
	},
	
	stripe : function (e,i){
		var cl = ["oddRow","evenRow"];
		i&1? cl.reverse() : cl;
		removeClass(e,cl[1]);
		addClass(e,cl[0]);
	},
	
	sortNumber : function(v) {
		var x = parseFloat(this.getText(v).replace(/[^0-9.-]/g,''));
		return isNaN(x)? 0: x;
	},
	
	sortDate : function(v) {
		return Date.parse(this.getText(v));
	},

	sortAlpha : function(v) {
		return this.getText(v).toLowerCase();
	},
	
	sortFile : function(v) { 		
		var j, q = config.messages.sizeTemplates, s = this.getText(v);
		for (var i=0; i<q.length; i++) {
			if ((j = s.toLowerCase().indexOf(q[i].template.replace("%0\u00a0","").toLowerCase())) != -1)
				return q[i].unit * s.substr(0,j);
		}
		return parseFloat(s);
	},
	
	reSort : function(a,b){
		var c = config.tableSorting;
		var aa = c.fn(a);
		var bb = c.fn(b);
		return ((aa==bb)? 0 : ((aa<bb)? -1:1));
	}
};

Story.prototype.tSort_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template,force,customFields,defaultText){
	var elem = this.tSort_refreshTiddler.apply(this,arguments);
	if(elem){
		var tables = elem.getElementsByTagName("TABLE");
		var c = config.tableSorting;
		for(var i=0; i<tables.length; i++){
			if(hasClass(tables[i],"sortable")){
				var x = null, rev, table = tables[i], thead = table.getElementsByTagName('thead')[0], headers = thead.rows[thead.rows.length-1].cells;
				for (var j=0; j<headers.length; j++){
					var h = headers[j];
					if (hasClass(h,"nosort"))
						continue;
					h.setAttribute("index",j);
					h.onclick = function(){c.sortTable(this); return false;};
					h.ondblclick = stopEvent;
					if(h.getElementsByTagName("span").length == 0)
						createTiddlyElement(h,"span",null,"hidden",c.uarrow); 
					if(!x && hasClass(h,"autosort")) {
						x = j;
						rev = hasClass(h,"reverse");
					}
				}
				if(x)
					c.sortTable(headers[x],rev);		
			}
		}
	}
	return elem; 
};

setStylesheet("table.sortable span.hidden {visibility:hidden;}\n"+
	"table.sortable thead {cursor:pointer;}\n"+
	"table.sortable .nosort {cursor:default;}\n"+
	"table.sortable td.sortedCol {background:#ffc;}","TableSortingPluginStyles");

function stopEvent(e){
	var ev = e? e : window.event;
	ev.cancelBubble = true;
	if (ev.stopPropagation) ev.stopPropagation();
	return false;	
}	

config.macros.nosort={
	handler : function(place){
		addClass(place,"nosort");
	}	
};

config.macros.autosort={
	handler : function(place,m,p,w,pS){
		addClass(place,"autosort"+" "+pS);		
	}	
};
//!END-PLUGIN-CODE
// %/
<<tagCloud>>
//(wie wir vereinbart haben, zählen wir im Wintersemester 2009/10 "Aufgabe 11" als "Aufgabe 1" um jedermann Stress zu ersparen; die alten Aufgaben (und Lösungen;) befinden sich ein bisschen weiter unten oder auch einfach direkt [[hier|Alte Aufgaben]])//
!! Aufgabe 1
* [[Datei einlesen und Tokenisieren mit Locale und Container|Aufgabe 11]]
!! Aufgabe 2
* [[Datei einlesen, Tokenisieren, in Container speichern, Vergleichs-Operatoren definieren und Bigramme ausgeben, Beginn der Klasse cis_string|Aufgabe 12]]
!! Aufgabe 3
* [[Datei einlesen, Tokenisieren, in Container speichern, Dubletten entfernen, sortieren in Set, Beginn der Klasse Cis_Text|Aufgabe 13]]
!! Aufgabe 4
* [[Datei einlesen, Tokenisieren, in Container speichern, Frequenzliste erzeugen (und ausgeben)|Aufgabe 14]]
!! Aufgabe 5
* [["Arbeiten mit const"|Aufgabe 15]]
!! Aufgabe 6
* [[Klassen "const-save" machen|Aufgabe 16]]
!! Aufgabe 7
* [[Umstellen auf unordered_map aus dem kommenden Standard und andere (kleine) Aufräumarbeiten; Einführung zweier neuer Klassen-Dateien: HashCisString.cpp und -.hpp|Aufgabe 17]]
!! Aufgabe 8
* [[Einsatz von boost/regex.hpp: splits und matches |Aufgabe 18]]
!! Aufgabe 9
* [[Verwendung von STL -Algorithms|Aufgabe 19]]

! Alte Aufgaben
[[Aufgaben aus dem Sommersemester 2009|Alte Aufgaben]]
/***
|''Name:''|TiddlerListMacro|
|''Version:''|2.0.10 (01-May-2006)|
|''Source''|http://jackparke.googlepages.com/jtw.html#TiddlerListMacro ([[del.icio.us|http://del.icio.us/post?url=http://jackparke.googlepages.com/jtw.html%23TiddlerListMacro]])|
|''Author:''|[[Jack]]|
|''Type:''|Macro|
|''Documentation:''|[[TiddlerListMacroDocumentation]]|
!Usage
{{{<<tiddlerList parameter1:"value1" parameter2:"value2" ...>>}}}
See TiddlerListMacroDocumentation and TiddlerListMacroExamples
!Code
***/
//{{{
version.extensions.tiddlerList = {major: 2, minor: 0, revision: 10, date: new Date("May 2, 2006")};
// template = [header, item, separator, group, footer]
config.macros.tiddlerList={
 formats : {list:true, nlist:true, span:true, stack:true, csv:true, table:true},
 templates : {
 list : [ "%0\n", "* %0\n", "", "%group\n", "%0\n"],
 nlist : [ "%0", "# %0\n", "", "%group\n", "%0\n"],
 span : [ "%0", "%0", " ", "%group", "%0"],
 stack : [ "%0", "%0", "\n", "%group", "%0"],
 csv : [ "%0", "%0", ", ", "%0", "%0\n"],
 table : ["|!%0|\n", "|%0|\n", "", "|%group|\n", "|%0|\n"]
 },
 dateFormat : "DD MMM YYYY"
}

if (typeof gCurrentTiddler == 'undefined')
 var gCurrentTiddler;

config.macros.tiddlerList.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
 // Some globals
 var count=0, groupCount=0, theGroup="", lastGroup="";
 var currentTiddler = tiddler;
 gCurrentTiddler = tiddler;
 var listWikiText="";
 var formats = this.formats;
 
 // SQL-Like parameters
 var parameters = paramString.parseParams("name",null,true);
 var pTags = parameters[0]["tags"]?parameters[0]["tags"][0].split(","):[];
 var pOrder = parameters[0]["order"]?parameters[0]["order"][0]:"title";
 var pTop = parameters[0]["top"]?parameters[0]["top"][0]:-1;
 var pText = parameters[0]["text"]?parameters[0]["text"][0]:"";
 var pTitle = parameters[0]["title"]?parameters[0]["title"][0]:"";
 var pSearch = parameters[0]["search"]?parameters[0]["search"][0]:"";
 var pFilter = parameters[0]["filter"]?parameters[0]["filter"][0]:"";
 var pHeader = parameters[0]["header"]?paramFormat(parameters[0]["header"][0]):"";
 var pFooter = parameters[0]["footer"]?paramFormat(parameters[0]["footer"][0]):"";
 var pGroup = parameters[0]["group"]?parameters[0]["group"][0]:"";
 var pDateFormat = parameters[0]["dateFormat"]?parameters[0]["dateFormat"][0]:this.dateFormat;
 var pCustomParameter = parameters[0]["customParameter"]?parameters[0]["customParameter"][0]:"";
 var pFormat = parameters[0]["format"]?parameters[0]["format"][0]:"list";
 pFormat = formats[pFormat]?pFormat:"list"
 
 // Separator
 var pSeparator = parameters[0]["separator"]?paramFormat(parameters[0]["separator"][0]):(parameters[0]["seperator"]?paramFormat(parameters[0]["seperator"][0]):this.templates[pFormat][2])

 // Template for group
 var pGroupTemplate = this.templates[pFormat][3];
 if (parameters[0]["groupTemplate"])
 pGroupTemplate = paramFormat(parameters[0]["groupTemplate"][0])
 pGroupTemplate = pGroupTemplate.replace("$))", ">>")
 
 // Template for group footer
 var pGroupFooterTemplate = "";
 if (parameters[0]["groupFooterTemplate"])
 pGroupFooterTemplate = paramFormat(parameters[0]["groupFooterTemplate"][0])
 pGroupFooterTemplate = pGroupFooterTemplate.replace("$))", ">>")
 
 // Template for item
 var pItemTemplate = this.templates[pFormat][1];
 if (parameters[0]["itemTemplate"])
 pItemTemplate = paramFormat(parameters[0]["itemTemplate"][0])
 pItemTemplate = pItemTemplate.replace("$))", ">>").replace("%link", "%0").replace("%item", "%1").replace("%abstract", "%2").replace("%text", "%3").replace("%created", "%4").replace("%modified", "%5").replace("%modifier", "%6").replace("%group", "%7").replace("%title", "%8").replace("%tags", "%9").replace("%nolink", "%10").replace("%custom", "%11")
 // Template for footer
 var pFooterTemplate = this.templates[pFormat][4].replace("%count", "%1")

 // Get all tiddlers
 var tiddlers = store.reverseLookup("tags","excludeLists",false);

 // Sorting
 if(!pOrder)
 pOrder = "title";
 if (pOrder.match(/^\-/i)) {
 pOrder = pOrder.substr(1)
 var sortDesc = true;
 }
 if (sortDesc)
 tiddlers.sort(function (a,b) {if(a[pOrder] == b[pOrder]) return(0); else return (a[pOrder] > b[pOrder]) ? -1 : +1; });
 else
 tiddlers.sort(function (a,b) {if(a[pOrder] == b[pOrder]) return(0); else return (a[pOrder] < b[pOrder]) ? -1 : +1; });

 // Header
 if (pHeader)
 listWikiText += formatItem(this.templates[pFormat][0], [pHeader], pFormat)
 
 for(var t=0; t<tiddlers.length; t++) {
 tiddler = tiddlers[t];
 if (pText!="" && tiddler.text=="") tiddler.text=store.getValue(tiddler, 'text')
 if (pTop==-1 || count<pTop) {
 if (pText=="" || tiddler.text.match(pText)) {
 if (pTitle=="" || tiddler.title.match(pTitle)) {
 if (pSearch=="" || (tiddler.title.match(pSearch) || tiddler.text.match(pSearch))) {
 if (pFilter=="" || eval(pFilter)) {
 if (pTags.length==0 || compareArrays(tiddler.tags, pTags, "all")) {
 count++;
 if (tiddler.text=="") tiddler.text=store.getValue(tiddler, 'text')
 // Grouping
 if (pGroup) {
 theGroup = eval(pGroup);
 if(theGroup != lastGroup) {
 groupCount++;
 if (pGroupFooterTemplate && groupCount>1)
 listWikiText += pGroupFooterTemplate.replace("%group", theGroup)
 listWikiText += pGroupTemplate.replace("%group", theGroup)
 lastGroup = theGroup;
 }
 }
 // Separators
 if (count>1) listWikiText += pSeparator;
 //Plaintext title
 var noLink = tiddler.title.match(config.textPrimitives.wikiLink)?"~" + tiddler.title:tiddler.title;
 // Custom parameter
 if (pCustomParameter)
 var custom="";
 try {
 custom = eval(pCustomParameter)
 } catch (e) {}
 // List individual tiddler
 listWikiText += formatItem(pItemTemplate,["[[" + tiddler.title + "]]",count,tiddler.text.substr(0,300),tiddler.text,tiddler.created.formatString(pDateFormat),tiddler.modified.formatString(pDateFormat),tiddler.modifier,theGroup,tiddler.title,tiddler.tags.join(" "),noLink,custom], pFormat)
 }
 }
 }
 }
 }
 }
 }
 
 // Last group footer
 if (pGroup && pGroupFooterTemplate && count>0)
 listWikiText += pGroupFooterTemplate.replace("%group", theGroup)

 // Footer
 if (pFooter) {
 pFooter = pFooter.replace("%count", count)
 listWikiText += formatItem(pFooterTemplate, [pFooter], pFormat)
 }
 
 // Render result
 if (!parameters[0]["debug"])
 wikify(listWikiText,place, null, currentTiddler)
 else
 place.innerHTML = "<textarea style=\"width:100%;\" rows=30>" + listWikiText + "</textarea>"
 
 
 // Local functions
 
 function paramFormat(param) {
 // Allow "\n" in non evalled parameters
 return param.replace(/\\n/g, "\n");
 }
 
 function formatItem(template, values, format) {
 // Fill template with values (depending on list format)
 if (format.match(/table/) && values[0].match(/\|/))
 return ("%0\n").format(values)
 else
 return template.format(values)
 }
 
 function compareArrays(array, values, logic) {
 // Compare items in array with AND("all") or OR("any") logic
 var matches=0;
 for(var v=0; v<values.length; v++)
 if(values[v].match(/^\-/) && !array.contains(values[v].substr(1)))
 matches++;
 else if (array.contains(values[v]))
 matches++;
 return ((logic=="all" && matches==values.length) || (logic!="all" && matches>0))
 }
 
}

String.prototype.prettyTrim = function(len,prefix,postfix) {
 var result = this.trim().replace(/\r\n/g,' ').replace(/\n/g,' ');
 if (!prefix) prefix = '';
 if (!postfix) postfix = '';
 if (result.length > len - 3)
 return prefix + result.substr(0,len) + '...' + postfix;
 else if (result.length > 0)
 return prefix + result + postfix;
 else
 return result;
}

//}}}
/***
|''Name:''|TiddlerNotesPlugin|
|''Description:''|Add notes to tiddlers without modifying the original content|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TiddlerNotesPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.1|
|''Date:''|26/10/07|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|

!!Concept:
*The TiddlerNotesPlugin allows you to add notes to tiddlers, without needing to edit the original tiddler. This means that your original content will remain unaltered, and if you update it in the future, you won’t lose your notes. Notes are stored in separate tiddlers, but can be viewed and edited from within the original tiddler.
*For a tiddler titled "~MySlide", the notes are by default saved in a tiddler titled "~MySlide-Notes" and is given a tag of "Notes". The suffix and tags of the notes tiddlers are customizable. You can have one or multiple notes per tiddlers. So it is possible to have for example, teacher's notes and student's notes in the same file.
*Notes can be configured to start off blank, or pre-filled with the contents of the original tiddler.

!!Usage:
*{{{<<notes>>}}} is the simplest usage form.
* additional optional parameters include:
**{{{heading:}}} the heading to use for the notes box
**{{{tag:}}} the tag to be given to the notes tiddler
**{{{suffix:}}} the suffix to be used when naming the notes tiddler
* a full macro call could look like: {{{<<notes heading:"My Notes" tag:"NoteTiddlers" suffix:"Comments">>}}}
* To avoid adding {{{<<notes>>}}} to each tiddler you want notes for, you could add the macro call to the ViewTemplate
** below the line {{{<div class='viewer' macro='view text wikified'></div>}}} add the following line: <br> {{{<div class='viewer' macro='notes'></div>}}}
** Used in combination with the ~HideWhenPlugin or ~PublisherPlugin, you could have notes be shown only for tiddlers with specific tags. The ~PublisherPlugin would allow you for instance to only have the ~TeachersNotes visible to the teacher, and the ~StudentsNotes for the same tiddler visible to the Student.

!!Configuration
*<<option chkPrefillNotes>> Enable to pre-fill notes with the original tiddler's contents

!!Demo:
* [[MySlide]]

***/
// /%
//!BEGIN-PLUGIN-CODE

if (!config.options.chkPrefillNotes)
	config.options.chkPrefillNotes = false;
	
function createTiddlyElement(theParent,theElement,theID,theClass,theText,attribs)
{
	var e = document.createElement(theElement);
	if(theClass != null)
		e.className = theClass;
	if(theID != null)
		e.setAttribute("id",theID);
	if(theText != null)
		e.appendChild(document.createTextNode(theText));
	if(attribs){
		for(var n in attribs){
			e.setAttribute(n,attribs[n]);
		}
	}
	if(theParent != null)
		theParent.appendChild(e);
	return e;
}

function createTiddlyButton(theParent,theText,theTooltip,theAction,theClass,theId,theAccessKey,attribs)
{
	var theButton = document.createElement("a");
	if(theAction) {
		theButton.onclick = theAction;
		theButton.setAttribute("href","javascript:;");
	}
	if(theTooltip)
		theButton.setAttribute("title",theTooltip);
	if(theText)
		theButton.appendChild(document.createTextNode(theText));
	if(theClass)
		theButton.className = theClass;
	else
		theButton.className = "button";
	if(theId)
		theButton.id = theId;
	if(attribs){
		for(var n in attribs){
			e.setAttribute(n,attribs[n]);
		}
	}
	if(theParent)
		theParent.appendChild(theButton);
	if(theAccessKey)
		theButton.setAttribute("accessKey",theAccessKey);
	return theButton;
}

config.macros.notes={
	
	cancelWarning: "Are you sure you want to abandon changes to your notes for '%0'?",
	editLabel: "edit notes",
	editTitle: "double click to edit",
	saveLabel: "save notes",
	saveTitle: "double click to save",
	cancelLabel: "cancel",
	heading: "Notes",
	suffix: "Notes",
	tag: "Notes",
	
	saveNotes: function(ev){
		e = ev? ev : window.event;
		var theTarget = resolveTarget(e);
		if (theTarget.nodeName.toLowerCase() == "textarea")
			return false;
		var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
		story.setDirty(title,false);
		var box = document.getElementById("notesContainer"+title);
		var textarea = document.getElementById("notesTextArea"+title);
		if(textarea.getAttribute("oldText")!=textarea.value && !hasClass(theTarget,"cancelNotesButton")){
			var suffix = box.getAttribute("suffix");
			var t = store.getTiddler(title+"-"+suffix);
			store.saveTiddler(title+"-"+suffix,title+"-"+suffix,textarea.value,config.options.txtUserName,new Date(),t?t.tags:box.getAttribute("tag"),t?t.fields:{});
		}
		story.refreshTiddler(title,1,true);
		autoSaveChanges(true);
		return false;
	},
	
	editNotes: function(box,tiddler){
		removeChildren(box);
		story.setDirty(tiddler,true);
		box.title = this.saveTitle;
		box.ondblclick = this.saveNotes;
		createTiddlyButton(box,this.cancelLabel,this.cancelLabel,this.saveNotes,"cancelNotesButton");
		createTiddlyButton(box,this.saveLabel,this.saveLabel,this.saveNotes,"saveNotesButton");
		wikify("!!"+box.getAttribute("heading")+"\n",box);
		addClass(box,"editor");
		var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
		var wrapper2 = createTiddlyElement(wrapper1,"div");
		var e = createTiddlyElement(wrapper2,"textarea","notesTextArea"+tiddler);
		var v = store.getValue(tiddler+"-"+box.getAttribute("suffix"),"text");
		if(!v) 
			v = config.options.chkPrefillNotes? store.getValue(tiddler,"text"):'';
		e.value = v;
		e.setAttribute("oldText",v);
		var rows = 10;
		var lines = v.match(/\n/mg);
		var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
		if(lines != null && lines.length > rows)
			rows = lines.length + 5;
		rows = Math.min(rows,maxLines);
		e.setAttribute("rows",rows);
		box.appendChild(wrapper1);
	},
	
	editNotesButtonOnclick: function(e){
		var title = story.findContainingTiddler(this).getAttribute("tiddler");
		var box = document.getElementById("notesContainer"+title);
		config.macros.notes.editNotes(box,title);
		return false;
	},
	
	ondblclick : function(ev){
		e = ev? ev : window.event;
		var theTarget = resolveTarget(e);
		var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
		var box = document.getElementById("notesContainer"+title);
		config.macros.notes.editNotes(box,title);
		e.cancelBubble = true;
		if(e.stopPropagation) e.stopPropagation();
		return false;
	},
	
	handler : function(place,macroName,params,wikifier,paramString,tiddler){
		
		params = paramString.parseParams("anon",null,true,false,false);
		var heading = getParam(params,"heading",this.heading);
		var tag = getParam(params,"tag",this.tag);
		var suffix = getParam(params,"suffix",this.suffix);
		var box = createTiddlyElement(place,"div","notesContainer"+tiddler.title,"TiddlerNotes",null,{"source":tiddler.title,params:paramString,heading:heading,tag:tag,suffix:suffix});
		createTiddlyButton(box,this.editLabel,this.editLabel,this.editNotesButtonOnclick,"editNotesButton");
		wikify("!!"+heading+"\n",box);
		box.title=this.editTitle;
		box.ondblclick = this.ondblclick;
		wikify("<<tiddler [["+tiddler.title+"-"+suffix+"]]>>",box);
	}		
};

Story.prototype.old_notes_closeTiddler = Story.prototype.closeTiddler;
Story.prototype.closeTiddler = function(title,animate,unused){
	if(story.isDirty(title)) {
		if(!confirm(config.macros.notes.cancelWarning.format([title])))
			return false;
	}
	return this.old_notes_closeTiddler.apply(this,arguments);
}

setStylesheet(".TiddlerNotes {\n"+ " background:#eee;\n"+ " border:1px solid #ccc;\n"+ " padding:10px;\n"+ " margin:15px;\n"+ "}\n"+ "\n"+ ".cancelNotesButton,.editNotesButton, .saveNotesButton {\n"+ " float:right;\n"+ " border:1px solid #ccc;\n"+ " padding:2px 5px;\n"+ "}\n"+ "\n"+ ".saveNotesButton{\n"+ " margin-right:0.5em;\n"+ "}\n"+ "\n"+ ".TiddlerNotes.editor textarea{\n"+ " border:1px solid #ccc;\n"+ "}","NotesPluginStyles");
//!END-PLUGIN-CODE
// %/
/***
|Name|TiddlerToCPlugin|
|Source|[[FND's DevPad|http://devpad.tiddlyspot.com/#TiddlerToCPlugin]]|
|Version|0.7|
|Author|FND|
|Contributors|[[Saq|http://tw.lewcid.org]]|
|License|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|N/A|
|Overrides|N/A|
|Description|create a table of contents from a tiddler's headings|
!Notes
Doug Compton has written a similar, though much more advanced plugin for this purpose, called [[DcTableOfContentsPlugin|http://devpad.tiddlyspot.com/#DcTableOfContentsPlugin]].
!Usage
Add {{{<<ToC>>}}} to the desired tiddler(s). Alternatively, a parameter can be used to display the table of contents for another tiddler: {{{<<ToC "tiddlerName">>}}}.
The styling can be modified in the [[StyleSheetTableOfContents]] shadow tiddler.
<<ToC>>
!Changelog
!!v0.5a (2007-05-20)
* initial release
!!v0.5b (2007-05-20)
* renamed to TiddlerToCPlugin (to prevent confusion with the existing [[TableOfContentsPlugin|http://tiddlytools.com/#TableOfContentsPlugin]])
!!v0.6 (2007-05-21)
* several bugfixes and significant improvements regarding the macro code (thanks Saq)
!!v0.7 (2007-08-29)
* fixed error for tiddlers not containing any headings
!Issues / To Do
* add links to sections (problematic, as there are no anchors, yet?)
* introduce thresholds (minimum amount of headings to show a ToC, maximum depth)
!Code
***/
//{{{
/*
** Styles (can be customized in the StyleSheetTableOfContents shadow tiddler)
*/

config.shadowTiddlers.StyleSheetTableOfContents = "/*{{{*/\n"
	+ ".ToC {\n\tfloat: left; /* auto-width */\n\tmargin: 0 2em 2em 0;\n\tborder: 1px solid #aaa;\n\tpadding: 5px;\n\tbackground-color: #eee;\n}\n\n"
	+ ".ToC ol {\n\tmargin: 0 1em;\n}\n\n"
	+ "h1 {\n\tclear: left;\n}\n"
	+ "/*}}}*/";
store.addNotification("StyleSheetTableOfContents", refreshStyles);

/*
** Macro Code
*/

config.macros.ToC = { label: "Add Table of Contents", prompt: "Add Table of Contents" }; // DEBUG: obsolete?
config.macros.ToC.handler =
	function(place, macroName, params, wikifier, paramString, tiddler) {
		// process parameters
		if (params[0]) { // tiddler name
			tiddler = store.getTiddler(params[0]);
		}
		// create table of contents
		generateToC(place, tiddler);
		return false; // DEBUG: ?
}

/*
** Main Code
*/

generateToC = function(place, tiddler) {
	// retrieve headings
	var RegEx = /^!+(.*)$/gim;
	var tiddlerContents = tiddler.text.match(RegEx);
	// create ToC
	if(tiddlerContents) {
		var ToC = "";
		for(var i = 0; i < tiddlerContents.length; i++) {
			ToC += tiddlerContents[i] + "\n";
		}
		// replace headings markup with list markup
		for(var i = 0; i < 6; i++) { // DEBUG: inefficient!? (use a single RegEx instead? problem: JavaScript RegEx limitations)
			ToC = ToC.replace(/^(#*)!/gim, "$1#");
		}
		// add ToC wrapper container
		ToC = "{{ToC{\n''Table of Contents''\n" + ToC + "}}}\n";
		// add ToC to tiddler
		wikify(ToC, place);
	}
	return false;
}
//}}}
/***

|Name|ToggleSideBarMacro|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#ToggleSideBarMacro|
|Version|1.0|
|Requires|~TW2.x|
!Description:
Provides a button for toggling visibility of the SideBar. You can choose whether the SideBar should initially be hidden or displayed.

!Demo
<<toggleSideBar "Toggle Sidebar">>

!Usage:
{{{<<toggleSideBar>>}}} <<toggleSideBar>>
additional options:
{{{<<toggleSideBar label tooltip show/hide>>}}} where:
label = custom label for the button,
tooltip = custom tooltip for the button,
show/hide = use one or the other, determines whether the sidebar is shown at first or not.
(default is to show the sidebar)

You can add it to your tiddler toolbar, your MainMenu, or where you like really.
If you are using a horizontal MainMenu and want the button to be right aligned, put the following in your StyleSheet:
{{{ .HideSideBarButton {float:right;} }}}

!History
*23-07-06: version 1.0: completely rewritten, now works with custom stylesheets too, and easier to customize start behaviour. 
*20-07-06: version 0.11
*27-04-06: version 0.1: working.

!Code
***/
//{{{
config.macros.toggleSideBar={};

config.macros.toggleSideBar.settings={
         styleHide :  "#sidebar { display: none;}\n"+"#contentWrapper #displayArea { margin-right: 1em;}\n"+"",
         styleShow : " ",
         arrow1: "«",
         arrow2: "»"
};

config.macros.toggleSideBar.handler=function (place,macroName,params,wikifier,paramString,tiddler)
{
          var tooltip= params[1]||'toggle sidebar';
          var mode = (params[2] && params[2]=="hide")? "hide":"show";
          var arrow = (mode == "hide")? this.settings.arrow1:this.settings.arrow2;
          var label= (params[0]&&params[0]!='.')?params[0]+" "+arrow:arrow;
          var theBtn = createTiddlyButton(place,label,tooltip,this.onToggleSideBar,"button HideSideBarButton");
          if (mode == "hide")
             { 
             (document.getElementById("sidebar")).setAttribute("toggle","hide");
              setStylesheet(this.settings.styleHide,"ToggleSideBarStyles");
             }
};

config.macros.toggleSideBar.onToggleSideBar = function(){
          var sidebar = document.getElementById("sidebar");
          var settings = config.macros.toggleSideBar.settings;
          if (sidebar.getAttribute("toggle")=='hide')
             {
              setStylesheet(settings.styleShow,"ToggleSideBarStyles");
              sidebar.setAttribute("toggle","show");
              this.firstChild.data= (this.firstChild.data).replace(settings.arrow1,settings.arrow2);
              }
          else
              {    
               setStylesheet(settings.styleHide,"ToggleSideBarStyles");
               sidebar.setAttribute("toggle","hide");
               this.firstChild.data= (this.firstChild.data).replace(settings.arrow2,settings.arrow1);
              }

     return false;
}

setStylesheet(".HideSideBarButton .button {font-weight:bold; padding: 0 5px;}\n","ToggleSideBarButtonStyles");

//}}}
<<emptyTrash>>
/***
|''Name:''|TrashPlugin|
|''Version:''|1.1.0TT.2|
|''Source:''|http://ido-xp.tiddlyspot.com/#TrashPlugin|
|''Author:''|Ido Magal (idoXatXidomagalXdotXcom)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.0|

!Description
This plugin provides trash bin functionality.  Instead of being permanently removed, deleted tiddlers are tagged with "Trash."  Empty the trash by clicking on the <<emptyTrash>> button in the [[Trash]] tiddler. Holding down CTRL while clicking on "delete" will bypass the trash.

!Installation instructions
Create a new tiddler in your wiki and copy the contents of this tiddler into it.  Name it the same and tag it with "systemConfig".
Save and reload your wiki.

!Uninstallation instructions
1. Empty the [[Trash]] ( <<emptyTrash>> )
2. Delete this tiddler.

!Revisions
* V1.1.0TT.2 (TiddlyTools variant) (May 18, 2008)
** when creating the Trash tiddler, pass an empty tags array [] instead of a null value, so other plugins (e.g., InstantTimestampPlugin) won't fail
* V1.1.0TT.1 (TiddlyTools variant) (Dec 21, 2006) 
** only call setDirty() when actually removing tiddlers from trash
* V1.1.0 (Dec 12, 2006) 
** added movedMsg (feedback when tiddler is tagged as Trash)
** make sure tiddler actually exists before tagging it with "Trash"
** fetch correct tiddler before checking for "systemConfig" tag
* V1.0.3TT.1 (TiddlyTools variant) (Dec 11, 2006) 
** don't create Trash tiddler until needed
** remove Trash tiddler when no trash remains
** don't tag Trash tiddler with "TrashPlugin"
** moved all user-visible strings to variables so they can be translated by 'lingo' plugins
** use displayMessage() instead of alert()
* v1.0.3 (Dec 11, 2006)
** Fixed broken reference to core deleteTiddler.
** Now storing reference to core deleteTiddler in emptyTrash macro.
** Reduced deleteTiddler hijacking to only the handler.
* v1.0.2 (Dec 11, 2006)
** EmptyTrash now uses removeTiddler instead of deleteTiddler.
** Supports trashing systemConfig tiddlers (adds systemConfigDisable tag).
* v1.0.1 (Dec 10, 2006)
** Replaced TW version with proper Core reference.
** Now properly hijacking deleteTiddler command.
* v1.0.0 (Dec 10, 2006)
** First draft.

!To Do
* Make trash keep only n days worth of garbage.
* Add undo.
* rename deleted tiddlers?

!Code
***/
//{{{

config.macros.emptyTrash = 
{
	tag: "Trash",
	movedMsg: "'%0' has been tagged as '%1'",
	label: "empty trash",
	tooltip: "Delete all items tagged as %0",
	tooltipOlder: "Delete items tagged as %0 that are older than %1 days old",
	emptyMsg: "The trash is empty",
	noneToDeleteMsg: "There are no items in the trash older than %0 days",
	confirmMsg: "The following tiddlers will be deleted:\n\n'%0'\n\nIs it OK to proceed?",
	deletedMsg: "Deleted '%0'",

	handler: function ( place,macroName,params,wikifier,paramString,tiddler )
	{
		var namedParams = (paramString.parseParams(daysOld))[0];
		var daysOld = namedParams['daysOld'] ? namedParams['daysOld'][0] : 0; // default
		var buttonTitle = namedParams['title'] ? namedParams['title'][0] : this.label;
		var buttonTip=this.tooltip.format([ config.macros.emptyTrash.tag ])
		if (daysOld) buttonTip=this.tooltipOlder.format([ config.macros.emptyTrash.tag,daysOld ])
		createTiddlyButton ( place, buttonTitle, buttonTip, this.emptyTrash( daysOld ));
	},

	emptyTrash: function( daysOld )
	{
		return function()
		{
			var collected = [];
			var compareDate = new Date();
			compareDate.setDate( compareDate.getDate() - daysOld );
			store.forEachTiddler(function ( title,tiddler )
			{
				if ( tiddler.tags.contains( config.macros.emptyTrash.tag ) && tiddler.modified < compareDate )
					collected.push( title );
			});

			if ( collected.length == 0 )
			{
				if ( daysOld == 0 )
					displayMessage( config.macros.emptyTrash.emptyMsg );
				else
					displayMessage( config.macros.emptyTrash.emptyMsg.format( [daysOld] ) );
			}
			else {
				if (	confirm( config.macros.emptyTrash.confirmMsg.format( [collected.join( "', '" )] ) ) )
				{
					for ( var i=0;i<collected.length;i++ )
					{
						store.removeTiddler( collected[i] );
						store.setDirty( true );
						displayMessage( config.macros.emptyTrash.deletedMsg.format( [collected[i]] ) );
					}
				}
			}
			// remove Trash tiddler if no trash remains
			if ( store.getTaggedTiddlers( config.macros.emptyTrash.tag ).length == 0 ) {
				story.closeTiddler( config.macros.emptyTrash.tag,true,false);
				store.removeTiddler( config.macros.emptyTrash.tag );
			}
			else
				story.refreshTiddler( config.macros.emptyTrash.tag,false,true );
		}
	}
}

////////////////// hijack delete command

config.macros.emptyTrash.orig_deleteTiddler_handler = config.commands.deleteTiddler.handler;
config.commands.deleteTiddler.handler = function( event,src,title )
	{
		// if tiddler exists (i.e., not a NEW, unsaved tiddler in edit mode) and not bypassing Trash (holding CTRL key)
		if ( store.tiddlerExists( title ) && !event.ctrlKey )
		{
			// if Trash tiddler doesn't exist yet, create it now...
			if (!store.tiddlerExists( config.macros.emptyTrash.tag ))
				store.saveTiddler( config.macros.emptyTrash.tag,config.macros.emptyTrash.tag,
					"<<emptyTrash>>","TrashPlugin",new Date(),[], {});
			// set tags on tiddler
			store.setTiddlerTag( title,1,config.macros.emptyTrash.tag );
			store.setTiddlerTag( title,1,"excludeLists" );
			store.setTiddlerTag( title,1,"excludeMissing" );
			var tiddler=store.fetchTiddler(title);
			if (tiddler.tags.contains( "systemConfig" ))
				store.setTiddlerTag( title,1,"systemConfigDisable" );
			// close tiddler, autosave file (if set), and give user feedback
			story.closeTiddler( title,true,event.shiftKey || event.altKey );
			if( config.options.chkAutoSave )
				saveChanges();
			displayMessage(config.macros.emptyTrash.movedMsg.format( [ title,config.macros.emptyTrash.tag ] ));
		}
		else {
			config.macros.emptyTrash.orig_deleteTiddler_handler.apply( this, arguments );
		}
		story.refreshTiddler( config.macros.emptyTrash.tag,false,true );
		return false;
	};
//}}}
/***
Contains the stuff you need to use Tiddlyspot
Note you must also have UploadPlugin installed
***/
//{{{

// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'ss08';

// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too

// disable autosave in d3
if (window.location.protocol != "file:")
	config.options.chkGTDLazyAutoSave = false;

// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
	SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
	SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
	OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
	DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
	MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}

// create some shadow tiddler content
merge(config.shadowTiddlers,{

'WelcomeToTiddlyspot':[
 "This document is a ~TiddlyWiki from tiddlyspot.com.  A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below.  Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
 "<<tiddler TspotControls>>",
 "See also GettingStarted.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick.  You can make changes and save them locally without being connected to the Internet.  When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]].  Also visit [[TiddlyWiki Guides|http://tiddlywikiguides.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help.  If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site.  Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),

'TspotControls':[
 "| tiddlyspot password:|<<option pasUploadPassword>>|",
 "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
 "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[announcements|http://announce.tiddlyspot.com/]], [[blog|http://tiddlyspot.com/blog/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),

'TspotSidebar':[
 "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),

'TspotOptions':[
 "tiddlyspot password:",
 "<<option pasUploadPassword>>",
 ""
].join("\n")

});
//}}}
...für eure Fragen und Anregungen, Kritik, Lob und Häme sind die Tutoren per email unter folgenden Adressen erreichbar (oder in der Mensa beim Kaffee trinken):
* Susanne Peters: ''peterssu % cip.ifi.lmu.de''
* Daniel Bruder: ''bruder % cip.ifi.lmu.de''
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'
};

config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");

merge(config.macros.option.types, {
	'pas': {
		elementType: "input",
		valueField: "value",
		eventName: "onkeyup",
		className: "pasOptionInput",
		typeValue: config.macros.option.passwordInputType,
		create: function(place,type,opt,className,desc) {
			// password field
			config.macros.option.genericCreate(place,'pas',opt,className,desc);
			// checkbox linked with this password "save this password on this computer"
			config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);			
			// text savePasswordCheckboxLabel
			place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
		},
		onChange: config.macros.option.genericOnChange
	}
});

merge(config.optionHandlers['chk'], {
	get: function(name) {
		// is there an option linked with this chk ?
		var opt = name.substr(3);
		if (config.options[opt]) 
			saveOptionCookie(opt);
		return config.options[name] ? "true" : "false";
	}
});

merge(config.optionHandlers, {
	'pas': {
 		get: function(name) {
			if (config.options["chk"+name]) {
				return encodeCookie(config.options[name].toString());
			} else {
				return "";
			}
		},
		set: function(name,value) {config.options[name] = decodeCookie(value);}
	}
});

// need to reload options to load passwordOptions
loadOptionsCookie();

/*
if (!config.options['pasPassword'])
	config.options['pasPassword'] = '';

merge(config.optionsDesc,{
		pasPassword: "Test password"
	});
*/
//}}}

/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.0|
|''Date:''|May 5, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (#3125)|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 0,
	date: new Date("May 5, 2007"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0 (#3125)'
};

//
// Environment
//

if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;	// true to activate both in Plugin and UploadService
	
//
// Upload Macro
//

config.macros.upload = {
// default values
	defaultBackupDir: '',	//no backup
	defaultStoreScript: "store.php",
	defaultToFilename: "index.html",
	defaultUploadDir: ".",
	authenticateUser: true	// UploadService Authenticate User
};
	
config.macros.upload.label = {
	promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
	promptParamMacro: "Save and Upload this TiddlyWiki in %0",
	saveLabel: "save to web", 
	saveToDisk: "save to disk",
	uploadLabel: "upload"	
};

config.macros.upload.messages = {
	noStoreUrl: "No store URL in parmeters or options",
	usernameOrPasswordMissing: "Username or password missing"
};

config.macros.upload.handler = function(place,macroName,params) {
	if (readOnly)
		return;
	var label;
	if (document.location.toString().substr(0,4) == "http") 
		label = this.label.saveLabel;
	else
		label = this.label.uploadLabel;
	var prompt;
	if (params[0]) {
		prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0], 
			(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
	} else {
		prompt = this.label.promptOption;
	}
	createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};

config.macros.upload.action = function(params)
{
		// for missing macro parameter set value from options
		var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
		var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
		var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
		var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
		var username = params[4] ? params[4] : config.options.txtUploadUserName;
		var password = config.options.pasUploadPassword; // for security reason no password as macro parameter	
		// for still missing parameter set default value
		if ((!storeUrl) && (document.location.toString().substr(0,4) == "http")) 
			storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
		if (storeUrl.substr(0,4) != "http")
			storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
		if (!toFilename)
			toFilename = bidix.basename(window.location.toString());
		if (!toFilename)
			toFilename = config.macros.upload.defaultToFilename;
		if (!uploadDir)
			uploadDir = config.macros.upload.defaultUploadDir;
		if (!backupDir)
			backupDir = config.macros.upload.defaultBackupDir;
		// report error if still missing
		if (!storeUrl) {
			alert(config.macros.upload.messages.noStoreUrl);
			clearMessage();
			return false;
		}
		if (config.macros.upload.authenticateUser && (!username || !password)) {
			alert(config.macros.upload.messages.usernameOrPasswordMissing);
			clearMessage();
			return false;
		}
		bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password); 
		return false; 
};

config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir) 
{
	if (!storeUrl)
		return null;
		var dest = bidix.dirname(storeUrl);
		if (uploadDir && uploadDir != '.')
			dest = dest + '/' + uploadDir;
		dest = dest + '/' + toFilename;
	return dest;
};

//
// uploadOptions Macro
//

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		wizard.createWizard(place,this.wizardTitle);
		wizard.addStep(this.step1Title,this.step1Html);
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		markList.parentNode.insertBefore(listWrapper,markList);
		wizard.setValue("listWrapper",listWrapper);
		this.refreshOptions(listWrapper,false);
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http") 
			uploadCaption = config.macros.upload.label.saveLabel;
		else
			uploadCaption = config.macros.upload.label.uploadLabel;
		
		wizard.setButtons([
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, 
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
				
			]);
	},
	refreshOptions: function(listWrapper) {
		var uploadOpts = [
			"txtUploadUserName",
			"pasUploadPassword",
			"txtUploadStoreUrl",
			"txtUploadDir",
			"txtUploadFilename",
			"txtUploadBackupDir",
			"chkUploadLog",
			"txtUploadLogMaxLine",
			]
		var opts = [];
		for(i=0; i<uploadOpts.length; i++) {
			var opt = {};
			opts.push()
			opt.option = "";
			n = uploadOpts[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
			opts.push(opt);
		}
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
				h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
			}
		}
		
	},
	onCancel: function(e)
	{
		backstage.switchTab(null);
		return false;
	},
	
	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'} 
			]}
}

//
// upload functions
//

if (!bidix.upload) bidix.upload = {};

if (!bidix.upload.messages) bidix.upload.messages = {
	//from saving
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to upload backup file",
	rssSaved: "RSS feed uploaded",
	rssFailed: "Failed to upload RSS feed file",
	emptySaved: "Empty template uploaded",
	emptyFailed: "Failed to upload empty template file",
	mainSaved: "Main TiddlyWiki file uploaded",
	mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
	//specific upload
	loadOriginalHttpPostError: "Can't get original file",
	aboutToSaveOnHttpPost: 'About to upload on %0 ...',
	storePhpNotFound: "The store script '%0' was not found."
};

bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
	var callback = function(status,uploadParams,original,url,xhr) {
		if (!status) {
			displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
			return;
		}
		if (bidix.debugMode) 
			alert(original.substr(0,500)+"\n...");
		// Locate the storeArea div's 
		var posDiv = locateStoreArea(original);
		if((posDiv[0] == -1) || (posDiv[1] == -1)) {
			alert(config.messages.invalidFileError.format([localPath]));
			return;
		}
		bidix.upload.uploadRss(uploadParams,original,posDiv);
	};
	
	if(onlyIfDirty && !store.isDirty())
		return;
	clearMessage();
	// save on localdisk ?
	if (document.location.toString().substr(0,4) == "file") {
		var path = document.location.toString();
		var localPath = getLocalPath(path);
		saveChanges();
	}
	// get original
	var uploadParams = Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
	var originalPath = document.location.toString();
	// If url is a directory : add index.html
	if (originalPath.charAt(originalPath.length-1) == "/")
		originalPath = originalPath + "index.html";
	var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
	var log = new bidix.UploadLog();
	log.startUpload(storeUrl, dest, uploadDir,  backupDir);
	displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
	if (bidix.debugMode) 
		alert("about to execute Http - GET on "+originalPath);
	var r = doHttp("GET",originalPath,null,null,null,null,callback,uploadParams,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

bidix.upload.uploadRss = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		if(status) {
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
			bidix.upload.uploadMain(params[0],params[1],params[2]);
		} else {
			displayMessage(bidix.upload.messages.rssFailed);			
		}
	};
	// do uploadRss
	if(config.options.chkGenerateAnRssFeed) {
		var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
		var rssUploadParams = Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
		bidix.upload.httpUpload(rssUploadParams,convertUnicodeToUTF8(generateRss()),callback,Array(uploadParams,original,posDiv));
	} else {
		bidix.upload.uploadMain(uploadParams,original,posDiv);
	}
};

bidix.upload.uploadMain = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		var log = new bidix.UploadLog();
		if(status) {
			// if backupDir specified
			if ((params[3]) && (responseText.indexOf("backupfile:") > -1))  {
				var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
				displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
			}
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
			store.setDirty(false);
			log.endUpload("ok");
		} else {
			alert(bidix.upload.messages.mainFailed);
			displayMessage(bidix.upload.messages.mainFailed);
			log.endUpload("failed");			
		}
	};
	// do uploadMain
	var revised = bidix.upload.updateOriginal(original,posDiv);
	bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};

bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
	var localCallback = function(status,params,responseText,url,xhr) {
		url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
		if (xhr.status == httpStatus.NotFound)
			alert(bidix.upload.messages.storePhpNotFound.format([url]));
		if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
			alert(responseText);
			if (responseText.indexOf("Debug mode") >= 0 )
				responseText = responseText.substring(responseText.indexOf("\n\n")+2);
		} else if (responseText.charAt(0) != '0') 
			alert(responseText);
		if (responseText.charAt(0) != '0')
			status = null;
		callback(status,params,responseText,url,xhr);
	};
	// do httpUpload
	var boundary = "---------------------------"+"AaB03x";	
	var uploadFormName = "UploadPlugin";
	// compose headers data
	var sheader = "";
	sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
	sheader += uploadFormName +"\"\r\n\r\n";
	sheader += "backupDir="+uploadParams[3] +
				";user=" + uploadParams[4] +
				";password=" + uploadParams[5] +
				";uploaddir=" + uploadParams[2];
	if (bidix.debugMode)
		sheader += ";debug=1";
	sheader += ";;\r\n"; 
	sheader += "\r\n" + "--" + boundary + "\r\n";
	sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
	sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
	sheader += "Content-Length: " + data.length + "\r\n\r\n";
	// compose trailer data
	var strailer = new String();
	strailer = "\r\n--" + boundary + "--\r\n";
	data = sheader + data + strailer;
	if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
	var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
	if (!posDiv)
		posDiv = locateStoreArea(original);
	if((posDiv[0] == -1) || (posDiv[1] == -1)) {
		alert(config.messages.invalidFileError.format([localPath]));
		return;
	}
	var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
				store.allTiddlersAsHtml() + "\n" +
				original.substr(posDiv[1]);
	var newSiteTitle = getPageTitle().htmlEncode();
	revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
	revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
	revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
	revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
	revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
	return revised;
};

//
// UploadLog
// 
// config.options.chkUploadLog :
//		false : no logging
//		true : logging
// config.options.txtUploadLogMaxLine :
//		-1 : no limit
//      0 :  no Log lines but UploadLog is still in place
//		n :  the last n lines are only kept
//		NaN : no limit (-1)

bidix.UploadLog = function() {
	if (!config.options.chkUploadLog) 
		return; // this.tiddler = null
	this.tiddler = store.getTiddler("UploadLog");
	if (!this.tiddler) {
		this.tiddler = new Tiddler();
		this.tiddler.title = "UploadLog";
		this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
		this.tiddler.created = new Date();
		this.tiddler.modifier = config.options.txtUserName;
		this.tiddler.modified = new Date();
		store.addTiddler(this.tiddler);
	}
	return this;
};

bidix.UploadLog.prototype.addText = function(text) {
	if (!this.tiddler)
		return;
	// retrieve maxLine when we need it
	var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
	if (isNaN(maxLine))
		maxLine = -1;
	// add text
	if (maxLine != 0) 
		this.tiddler.text = this.tiddler.text + text;
	// Trunck to maxLine
	if (maxLine >= 0) {
		var textArray = this.tiddler.text.split('\n');
		if (textArray.length > maxLine + 1)
			textArray.splice(1,textArray.length-1-maxLine);
			this.tiddler.text = textArray.join('\n');		
	}
	// update tiddler fields
	this.tiddler.modifier = config.options.txtUserName;
	this.tiddler.modified = new Date();
	store.addTiddler(this.tiddler);
	// refresh and notifiy for immediate update
	story.refreshTiddler(this.tiddler.title);
	store.notify(this.tiddler.title, true);
};

bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir,  backupDir) {
	if (!this.tiddler)
		return;
	var now = new Date();
	var text = "\n| ";
	var filename = bidix.basename(document.location.toString());
	if (!filename) filename = '/';
	text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
	text += config.options.txtUserName + " | ";
	text += "[["+filename+"|"+location + "]] |";
	text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
	text += uploadDir + " | ";
	text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
	text += backupDir + " |";
	this.addText(text);
};

bidix.UploadLog.prototype.endUpload = function(status) {
	if (!this.tiddler)
		return;
	this.addText(" "+status+" |");
};

//
// Utilities
// 

bidix.checkPlugin = function(plugin, major, minor, revision) {
	var ext = version.extensions[plugin];
	if (!
		(ext  && 
			((ext.major > major) || 
			((ext.major == major) && (ext.minor > minor))  ||
			((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
			// write error in PluginManager
			if (pluginInfo)
				pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
			eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
	}
};

bidix.dirname = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(0, lastpos);
	} else {
		return filePath.substring(0, filePath.lastIndexOf("\\"));
	}
};

bidix.basename = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("#")) != -1) 
		filePath = filePath.substring(0, lastpos);
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(lastpos + 1);
	} else
		return filePath.substring(filePath.lastIndexOf("\\")+1);
};

bidix.initOption = function(name,value) {
	if (!config.options[name])
		config.options[name] = value;
};

//
// Initializations
//

// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);

// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");

//optionsDesc
merge(config.optionsDesc,{
	txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
	txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
	txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
	txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
	txtUploadUserName: "Upload Username",
	pasUploadPassword: "Upload Password",
	chkUploadLog: "do Logging in UploadLog (default: true)",
	txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});

// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');


/* don't want this for tiddlyspot sites

// Backstage
merge(config.tasks,{
	uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");

*/


//}}}


!17.07.2009
Der [[arithmetische-Ausdrücke-Parser|Aufgabe 10]] von Fred Béchet ist online. Neben einem reinen "Recognize", also erkennen, ob der Ausdruck ein gültiger Ausdruck der Grammatik ist, parst er die Eingabe auch, in diesem Fall berechnet den Wert des Ausdrucks. Dabei beachtet er auch ~Punkt-vor-Strich, beachtlich! 
!03.07.2009
Es gibt jetzt unter [[Aufgabe 9]] eine "große" Klasse, die alles , was wir bisher gemacht haben, zusammenfasst. Die letzten Themen waren zwar nicht unbedingt leicht zu verdauen, aber alle haben sich tapfer gezeigt und das Motto "dranbleiben" gilt sich nach wie vor! 
In den alten main()-Dateien ([[Aufgabe 7]], [[Aufgabe 8]])sieht man auch nach wie vor die Funktionalität, die unsere Klasse {{{cis_string}}} bisher bietet...
!23.06.2009
Die Lösung von [[Aufgabe 7, die Implementation der Klasse "cis_string"|Aufgabe 7]] ist schon vor dem Tutorium da. Florian Fink hat seine Lösung zum Datumserkenner aus [[Aufgabe 6]] zur Verfügung gestellt, diese wird noch nachgereicht, und es gilt für alle: //Schön Dranbleiben!//
!02.06.2009
Die Lösung von [[Aufgabe 4]] ist da. (Etwas verspätet, aber naja) ...und die Lösung zur [[Aufgabe 5]] ist auch schon da.
!29.05.2009
Ich habe gerade [[eine gute Seite|http://www.augustcouncil.com/~tgibson/tutorial/iotips.html]] gefunden, die das Thema Input/Output, Streams und Probleme, die im Zusammenhang mit getline() auftauchen können, ganz erfrischend nochmal darstellt. Es werden hier die Themen behandelt: //was machen mit Zeichen, die auf dem Stream bleiben? Welche Zeichen können auf dem Stream bleiben?// etc.
! 27.05.2009
Morgen, also am 28.05., besprechen wir [[Aufgabe 4]] ''und'' [[Aufgabe 5]]. Dafür lassen wir uns ein klein bisschen mehr Zeit (ca. 17 Uhr) und gehen danach auf ein Bier zum Chinesischen Turm.
! 17.05.2009
Die [[Musterlösungen von Aufgabe 3|Aufgabe 3]] und die auf nächste Woche zu lösende [[Aufgabe 4]] sind im Wiki.
! 11.05.2009
[[Musterlösung|Themen]] von Aufgabe 2 ist da.
! 30.04.2009
Das Kapitel [[Themen]] ist jetzt aufgeräumt, was wir in der ersten Stunde besprochen haben, ist jetzt unter [[Aufgabe 0]] gelistet, damit alles seine Ordnung hat, und was wir heute besprochen haben ist [[hier|Aufgabe 1]]
! 29.04.2009
Es gibt einen (bisher) noch [[ganz kleinen Artikel|Programmentwicklung]], als Kurzzusammenfassung quasi, zum generellen Vorgehen, wie man ein Programm nicht nur schreibt, sondern dann auch kompiliert und ausführt. Wenn noch etwas unklar bleibt, lasst es mich wissen, dann kann ich das auch einbauen... In diesem Sinne: bis morgen! D.
!23.04.2009
* ...was ich ganz vergessen hatte: unsere email-Adressen vielleicht mal aufzuschreiben! [[Hier|Tutoren]] sind sie.
* [[Links zu den gezeigten Referenzen|Links]] sind nun auch da.
* Die Lösung zu [[Aufgabe 0]] wurde mit einem schöneren ~Syntax-Highlighting ausgestattet ;) – viel Spass damit
/***
|''Name:''|WikiBar|
|''Version:''|2.0.0 beta3|
|''Source:''|[[AiddlyWiki|http://aiddlywiki.sourceforge.net]]|
|''Author:''|[[Arphen Lin|mailto:arphenlin@gmail.com]]|
|''Type:''|toolbar macro command extension|
|''Required:''|TiddlyWiki 2.0.0 beta6|
!Description
WikiBar is a toolbar that gives access to most of TiddlyWiki's formatting features with a few clicks. It's a handy tool for people who are not familiar with TiddlyWiki syntax.
Besides, with WikiBar-addons, users can extend the power of WikiBar.
!Support browser
*Firefox 1.5
!Revision history
*v2.0.0 beta3 (2005/12/30)
** remove macros (replaced by TWMacro addon)
** add wikibar command in toolbar automatically
** rename DOIT to HANDLER
** rename TIP to TOOLTIP
*v2.0.0 beta2 (2005/12/21)
** re-design Wikibar addon framework
*v2.0.0 beta1 (2005/12/14)
** Note:
*** WikiBarPlugin is renamed to WikiBar
** New Features:
*** support TiddlyWiki 2.0.0 template mechanism
*** new wikibar data structure
*** new wikibar-addon framework for developers
**** support dynamic popup menu generator
*** support most new macros added in TiddlyWiki 2.0.0
*** multi-level popup menu
*** fix wikibar tab stop
*** remove paletteSelector
** Known Bugs:
*** popup-menu and color-picker can't be closed correctly
*** some macros can't be displayed correctly in previewer
*** text in previewer will be displayed italic
*v1.2.0 (2005/11/21)
**New Features:
***User defined color palettes supported
####Get color palettes from [[ColorZilla Palettes|http://www.iosart.com/firefox/colorzilla/palettes.html]].
####Save the palette file(*.gpl) as a new tiddler and tag it with 'ColorPalettes', then you can use it in WikiBar.
***WikiBar style sheet supported
***Click on document to close current colorPicker, paletteSelector or aboutWikibar
*v1.1.1 (2005/11/03)
**Bugs fixed:
***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello%20world!'
*v1.1.0 (2005/11/01)
**Bugs fixed:
***WikiBar overruns (reported by by GeoffS <gslocock@yahoo.co.uk>)
**New features:
***Insert a color code at the cursor. (Thanks to RunningUtes <RunningUtes@gmail.com>)
***Enable gradient macro. (Thanks to RunningUtes <RunningUtes@gmail.com>)
***Insert tiddler comment tags {{{/% ... %/}}}. (new feature supported by TiddlyWiki 1.2.37)
***Insert DateFormatString for {{{<<today>>}}} macro. (new feature supported by TiddlyWiki 1.2.37)
**Enhanced:
***Allow optional parameters in syntax.
**Bugs:
***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello%20world!'
*v1.0.0 (2005/10/30)
**Initial release
!Code
***/
//{{{
config.macros.wikibar = {major: 2, minor: 0, revision: 0, beta: 3, date: new Date(2005,12,30)};
config.macros.wikibar.handler = function(place,macroName,params,wikifier,paramString,tiddler){
  if(!(tiddler instanceof Tiddler))  {return;}
	story.setDirty(tiddler.title,true);
  place.id = 'wikibar'+tiddler.title;
  place.className = 'toolbar wikibar';
};
function wikibar_install(){
  config.commands.wikibar = {
  	text: 'wikibar',
  	tooltip: 'wikibar on/off',
  	handler: function(e,src,title) {
      if(!e){ e = window.event; }
      var theButton = resolveTarget(e);
      theButton.id = 'wikibarButton'+title;
      wikibarPopup.remove();
      wikibar_installAddons(theButton, title);
      wikibar_createWikibar(title);
      return(false);
    }
  };
  config.shadowTiddlers['EditTemplate'] = wikibar_addWikibarCommand(config.shadowTiddlers['EditTemplate']);
  var tiddler = store.getTiddler('EditTemplate');
  if(tiddler){
    tiddler.text = wikibar_addWikibarCommand(tiddler.text);
  }
}
function wikibar_installAddons(theButton, title){
 	var tiddlers = store.getTaggedTiddlers('wikibarAddons');
	if(!tiddlers)	  { return; }
	theButton.addons=[];
  for(var i=0; i<tiddlers.length; i++){
    try{
      eval(tiddlers[i].text);
      try{
        wikibar_addonInstall(title);
        wikibar_addonInstall = null;
        theButton.addons.push({ok:true, name:tiddlers[i].title});
      }catch(ex){
        theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});
      }
    }catch(ex){
      theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});
    }
  }
}
function wikibar_addWikibarCommand(tiddlerText){
  var div = document.createElement('div');
  div.style.display = 'none';
  div.innerHTML = tiddlerText;
  for(var i=0; i<div.childNodes.length; i++){
    var o=div.childNodes[i];
    if(o.tagName==='DIV'){
      if(o.className=='toolbar'){
        var macroText = o.getAttribute('macro').trim();
        if(macroText.search('wikibar')<=0){
          macroText += ' wikibar';
          o.setAttribute('macro', macroText);
        }
        break;
      }
    }
  }
  return div.innerHTML.replace(/\"/g, "\'");
}
function wikibar_processSyntaxParams(theSyntax, params){
  try{
    var pcr = 'AplWikibarPcr';
    var rx=null;
    var allParams=null;
    if(params){
      if(typeof(params)=='object'){
        for(var i=0; i<params.length; i++){
          if(params[i]){
            params[i] = params[i].replace(new RegExp('%','g'), pcr).trim();
            rx = '(\\[%'+(i+1)+'\\])' + '|' + '(%'+(i+1)+')';
            theSyntax = theSyntax.replace(new RegExp(rx,'g'), params[i] );
          }
        }
        allParams = params.join(' ').trim();
      }else{
        allParams = params.replace(new RegExp('%','g'), pcr).trim();
        rx = /(\[%1{1}\])|(%1{1})/g;
        theSyntax = theSyntax.replace(rx, allParams);
      }
    }
    if(allParams){
      theSyntax = theSyntax.replace(new RegExp('%N{1}','g'), allParams);
    }
    rx=/\[%(([1-9]{1,}[0-9]{0,})|(N{1}))\]/g;
    theSyntax = theSyntax.replace(rx, '');
    rx=/%(([1-9]{1,}[0-9]{0,})|(N{1}))/g;
    if( theSyntax.match(rx) ){
      throw 'Not enough parameters! ' + theSyntax;
    }
    theSyntax=theSyntax.replace(new RegExp(pcr,'g'), '%');
    return theSyntax;
  } catch(ex){
    return null;
  }
}
function wikibar_resolveEditItem(tiddlerWrapper, itemName){
  if(tiddlerWrapper.hasChildNodes()){
    var c=tiddlerWrapper.childNodes;
    for(var i=0; i<c.length; i++){
      var txt=wikibar_resolveEditItem(c[i], itemName);
      if(!txt){
        continue;
      }else{
        return txt;
      }
    }
  }
  return ((tiddlerWrapper.getAttribute && tiddlerWrapper.getAttribute('edit')==itemName)? tiddlerWrapper : null);
}
function wikibar_resolveEditItemValue(tiddlerWrapper, itemName){
  var o = wikibar_resolveEditItem(tiddlerWrapper, itemName);
  return (o? o.value.replace(/\r/mg,'') : null);
}
function wikibar_resolveTiddlerEditorWrapper(obj){
  if(obj.id=='tiddlerDisplay'){return null;}
  if((obj.getAttribute && obj.getAttribute('macro')=='edit text')){return obj;}
  return wikibar_resolveTiddlerEditorWrapper(obj.parentNode);
}
function wikibar_resolveTiddlerEditor(obj){
  if(obj.hasChildNodes()){
    var c = obj.childNodes;
    for(var i=0; i<c.length; i++){
      var o=wikibar_resolveTiddlerEditor(c[i]);
      if(o){ return o;}
    }
  }
  return ((obj.getAttribute && obj.getAttribute('edit')=='text')? obj : null);
}
function wikibar_resolveTargetButton(obj){
  if(obj.id && obj.id.substring(0,7)=='wikibar'){ return null; }
  if(obj.tiddlerTitle){
    return obj;
  }else{
    return wikibar_resolveTargetButton(obj.parentNode);
  }
}
function wikibar_isValidMenuItem(tool){
  if(!tool){  return false; }
  if(tool.TYPE=='MENU' || tool.TYPE=='MAIN_MENU'){
    for(var key in tool){
      if(key.substring(0,8)=='DYNAITEM'){ return true; }
      if(wikibar_isValidMenuItem(tool[key])){ return true; }
    }
    return false;
  }else{
    return (tool.HANDLER? true : false);
  }
}
function wikibar_editFormat(param){
  var editor = param.button.editor;
  var params = param.params;
  clearMessage();
  if(!editor){ return; }
  var repText = wikibar_processSyntaxParams(this.syntax, params);
  if(repText===null){ return; }
	var st = editor.scrollTop;
	var ss = editor.selectionStart;
	var se = editor.selectionEnd;
	var frontText= '';
	var endText  = '';
	var fullText = editor.value;
	if(se>ss && ss>=0){
	  frontText  = fullText.substring(0, ss);
	  endText    = fullText.substring(se, fullText.length);
	}
	else if(ss===0 && (se===0 || se == fullText.length) ){
    endText    = fullText;
	}
	else if(se==ss && ss>0){
    frontText  = fullText.substring(0, ss);
    endText    = fullText.substring(se, fullText.length);
	}
	if(repText.indexOf('user_text')>=0 && this.hint){
		repText = repText.replace('user_text', this.hint);
	}
	editor.value = frontText + repText + endText;
	editor.selectionStart = ss;
	editor.selectionEnd   = ss + repText.length;
	editor.scrollTop      = st;
	editor.focus();
}
function wikibar_editFormatByWord(param){
  var editor = param.button.editor;
  var params = param.params;
  clearMessage();
  if(!editor){return;}
  var repText = wikibar_processSyntaxParams(this.syntax, params);
  if(repText===null){ return; }
	var st = editor.scrollTop;
	var ss = editor.selectionStart;
	var se = editor.selectionEnd;
	var frontText= '';
	var selText  = '';
	var endText  = '';
	var fullText = editor.value;
	if(se>ss && ss>=0){
	  frontText  = fullText.substring(0, ss);
	  selText	   = fullText.substring(ss,se);
	  endText    = fullText.substring(se, fullText.length);
	}
	else if(ss===0 && (se===0 || se == fullText.length) ){
    endText    = fullText;
	}
	else if(se==ss && ss>0){
    frontText  = fullText.substring(0, ss);
    endText    = fullText.substring(se, fullText.length);
	  if(!( fullText.charAt(ss-1).match(/\W/gi) || fullText.charAt(ss).match(/\W/gi) )){
      var m = frontText.match(/\W/gi);
      if(m){
        ss = frontText.lastIndexOf(m[m.length-1])+1;
      }
      else{
        ss = 0;
      }
      m = endText.match(/\W/gi);
      if(m){
        se += endText.indexOf(m[0]);
      }
      else{
        se = fullText.length;
      }
      frontText = fullText.substring(0, ss);
  	  endText   = fullText.substring(se, fullText.length);
  	  selText   = fullText.substring(ss,se);
	  }
	}
	if(selText.length>0){
		repText = repText.replace('user_text', selText);
	}
	if(repText.indexOf('user_text')>=0 && this.hint){
		repText = repText.replace('user_text', this.hint);
	}
	editor.value = frontText + repText + endText;
	editor.selectionStart = ss;
	editor.selectionEnd   = ss + repText.length;
	editor.scrollTop      = st;
	editor.focus();
}
function wikibar_editFormatByCursor(param){
  var editor = param.button.editor;
  var params = param.params;
  clearMessage();
  if(!editor){ return; }
  var repText = wikibar_processSyntaxParams(this.syntax, params);
  if(repText===null){ return; }
	var st = editor.scrollTop;
	var ss = editor.selectionStart;
	var se = editor.selectionEnd;
	var frontText= '';
	var endText  = '';
	var fullText = editor.value;
	if(se>ss && ss>=0){
	  frontText  = fullText.substring(0, ss);
	  endText    = fullText.substring(se, fullText.length);
	}
	else if(ss===0 && (se===0 || se == fullText.length) ){
    endText    = fullText;
	}
	else if(se==ss && ss>0){
    frontText  = fullText.substring(0, ss);
    endText    = fullText.substring(se, fullText.length);
	}
	if(repText.indexOf('user_text')>=0 && this.hint){
		repText = repText.replace('user_text', this.hint);
	}
	editor.value = frontText + repText + endText;
	editor.selectionStart = ss;
	editor.selectionEnd   = ss + repText.length;
	editor.scrollTop      = st;
	editor.focus();
}
function wikibar_editFormatByLine(param){
  var editor = param.button.editor;
  var params = param.params;
  clearMessage();
  if(!editor){ return; }
  var repText = wikibar_processSyntaxParams(this.syntax, params);
  if(repText===null){ return; }
	var st = editor.scrollTop;
	var ss = editor.selectionStart;
	var se = editor.selectionEnd;
	var frontText= '';
	var selText  = '';
	var endText  = '';
	var fullText = editor.value;
	if(se>ss && ss>=0){
		if(this.byBlock){
	    frontText  = fullText.substring(0, ss);
	    selText		 = fullText.substring(ss,se);
	    endText    = fullText.substring(se, fullText.length);
		}
		else{
	  	se = ss;
		}
	}
  if(ss===0 && (se===0 || se == fullText.length) ){
    var m=fullText.match(/(\n|\r)/g);
    if(m){
      se = fullText.indexOf(m[0]);
    }else{
      se = fullText.length;
    }
    selText    = fullText.substring(0, se);
    endText    = fullText.substring(se, fullText.length);
	}
	else if(se==ss && ss>0){
    frontText  = fullText.substring(0, ss);
    endText    = fullText.substring(se, fullText.length);
    m = frontText.match(/(\n|\r)/g);
    if(m){
      ss = frontText.lastIndexOf(m[m.length-1])+1;
    }
    else{
      ss = 0;
    }
    m = endText.match(/(\n|\r)/g);
    if(m){
      se += endText.indexOf(m[0]);
    }
    else{
      se = fullText.length;
    }
    frontText = fullText.substring(0, ss);
	  selText   = fullText.substring(ss,se);
	  endText   = fullText.substring(se, fullText.length);
	}
	if(selText.length>0){
		repText = repText.replace('user_text', selText);
	}
	if(repText.indexOf('user_text')>=0 && this.hint){
		repText = repText.replace('user_text', this.hint);
	}
	if(this.byBlock){
    if( (frontText.charAt(frontText.length-1)!='\n') && ss>0 ){
    	repText = '\n' + repText;
    }
    if( (endText.charAt(0)!='\n') || se==fullText.length){
    	repText += '\n';
    }
	}
	editor.value = frontText + repText + endText;
	editor.selectionStart = ss;
	editor.selectionEnd   = ss + repText.length;
	editor.scrollTop      = st;
	editor.focus();
}
function wikibar_editFormatByTableCell(param){
  var editor = param.button.editor;
  var params = param.params;
  clearMessage();
  if(!editor){ return; }
  var repText = wikibar_processSyntaxParams(this.syntax, params);
  if(repText===null){ return; }
	var st = editor.scrollTop;
	var ss = editor.selectionStart;
	var se = editor.selectionEnd;
	var frontText= '';
	var selText  = '';
	var endText  = '';
	var fullText = editor.value;
	if(ss===0 || ss==fullText.length){
		throw 'not valid cell!';
	}
	se=ss;
  frontText  = fullText.substring(0, ss);
  endText    = fullText.substring(se, fullText.length);
  i=frontText.lastIndexOf('\n');
  j=frontText.lastIndexOf('|');
  if(i>j || j<0){
  	throw 'not valid cell!';
  }
	ss = j+1;
  i=endText.indexOf('\n');
  j=endText.indexOf('|');
  if(i<j || j<0){
  	throw 'not valid cell!';
  }
  se += j;
  frontText = fullText.substring(0, ss-1);
  selText   = fullText.substring(ss,se);
  endText   = fullText.substring(se+1, fullText.length);
	if(this.key.substring(0,5)=='align'){
		selText = selText.trim();
		if(	selText=='>' || selText=='~' ||	selText.substring(0,8)=='bgcolor(')	{return; }
	}
	if(selText.length>0){
		repText = repText.replace('user_text', selText);
	}
	if(repText.indexOf('user_text')>=0 && this.hint){
		repText = repText.replace('user_text', this.hint);
	}
	editor.value = frontText + repText + endText;
	editor.selectionStart = ss;
	editor.selectionEnd   = ss + repText.length - 2;
	editor.scrollTop      = st;
	editor.focus();
}
function wikibar_editSelectAll(param){
  var editor = param.button.editor;
	editor.selectionStart = 0;
	editor.selectionEnd   = editor.value.length;
	editor.scrollTop      = 0;
	editor.focus();
}
function wikibar_doPreview(param){
  var theButton = param.button;
  var editor = param.button.editor;
  var wikibar = theButton.parentNode;
  if(!wikibar)  { return; }
  title = theButton.tiddlerTitle;
  var editorWrapper = wikibar_resolveTiddlerEditorWrapper(editor);
  var tiddlerWrapper = editorWrapper.parentNode;
  var previewer = document.getElementById('previewer'+title);
  if(previewer){
    previewer.parentNode.removeChild(previewer);
    editorWrapper.style.display = 'block';
    visible=true;
  }else{
    previewer = document.createElement('div');
    previewer.id = 'previewer'+title;
    previewer.className = 'viewer previewer';
    previewer.style.height = (editor.offsetHeight) + 'px';
    wikify(editor.value, previewer);
    tiddlerWrapper.insertBefore(previewer, editorWrapper);
    editorWrapper.style.display = 'none';
    visible=false;
  }
  var pv=null;
  for(var i=0; i<wikibar.childNodes.length; i++){
    try{
      var btn = wikibar.childNodes[i];
      if(btn.toolItem.key == 'preview'){ pv=btn; }
      if(btn.toolItem.key != 'preview'){
        btn.style.display = visible ? '': 'none';
      }
    }catch(ex){}
  }
  if(!pv) { return; }
  if(visible){
    pv.innerHTML = '<font face=\"verdana\">&infin;</font>';
    pv.title = 'preview current tiddler';
  }
  else{
    pv.innerHTML = '<font face=\"verdana\">&larr;</font>';
    pv.title = 'back to editor';
  }
}
function wikibar_doListAddons(param){
  clearMessage();
  var title = param.button.tiddlerTitle;
  var wikibarButton = document.getElementById('wikibarButton'+title);
  var ok=0, fail=0;
  for(var i=0; i<wikibarButton.addons.length; i++){
    var addon=wikibarButton.addons[i];
    if(addon.ok){
      displayMessage('[ o ] '+addon.name);
      ok++;
    }
    else{
      displayMessage('[ x ] '+addon.name + ': ' + addon.error);
      fail++;
    }
  }
  displayMessage('---------------------------------');
  displayMessage(ok + ' ok ; ' + fail + ' failed');
}
function wikibar_getColorCode(param){
  var cbOnPickColor = function(colorCode, param){
    param.params = colorCode;
    param.button.toolItem.doMore(param);
  };
  wikibarColorTool.openColorPicker(param.button, cbOnPickColor, param);
}
function wikibar_getLinkUrl(param){
  var url= prompt('Please enter the link target', (this.param? this.param : ''));
  if (url && url.trim().length>0){
    param.params = url;
    this.doMore(param);
  }
}
function wikibar_getTableRowCol(param){
  var rc= prompt('Please enter (rows x cols) of the table', '2 x 3');
  if (!rc || (rc.trim()).length<=0){ return; }
  var arr = rc.toUpperCase().split('X');
  if(arr.length != 2)   { return; }
  for(var i=0; i<arr.length; i++){
    if(isNaN(arr[i].trim()))  { return; }
  }
  var rows = parseInt(arr[0].trim(), 10);
  var cols = parseInt(arr[1].trim(), 10);
  var txtTable='';
  for(var r=0; r<rows; r++){
    for(var c=0; c<=cols; c++){
      if(c===0){
        txtTable += '|';
      }else{
        txtTable += ' |';
      }
    }
    txtTable += '\n';
  }
  if(txtTable.trim().length>0){
    param.params = txtTable.trim();
    this.doMore(param);
  }
}
function wikibar_getMacroParam(param){
  var p = prompt('Please enter the parameters of macro \"' + this.key + '\":' +
                 '\nSyntax: ' + this.syntax +
                 '\n\nNote: '+
                 '\n%1,%2,... - parameter needed'+
                 '\n[%1] - optional parameter'+
                 '\n%N   - more than one parameter(1~n)'+
                 '\n[%N] - any number of parameters(0~n)'+
                 '\n\nPS:'+
                 '\n1. Parameters should be seperated with space character'+
                 '\n2. Use \" to wrap the parameter that includes space character, ex: \"hello world\"'+
                 '\n3. Input the word(null) for the optional parameter ignored',
                 (this.param? this.param : '') );
  if(!p)  { return; }
  p=p.readMacroParams();
  for(var i=0; i<p.length; i++){
    var s=p[i].trim();
    if(s.indexOf(' ')>0){ p[i]="'"+s+"'"; }
    if(s.toLowerCase()=='null'){ p[i]=null; }
  }
  param.params = p;
  this.doMore(param);
}
function wikibar_getMorePalette(unused){
  clearMessage();
  displayMessage('Get more color palettes(*.gpl) from ColorZilla Palettes site', 'http:\/\/www.iosart.com/firefox/colorzilla/palettes.html');
  displayMessage('Save it as a new tiddler with \"ColorPalettes\" tag');
}
function wikibar_createWikibar(title){
  var theWikibar = document.getElementById('wikibar' + title);
  if(theWikibar){
    if(theWikibar.hasChildNodes()){
      theWikibar.style.display = (theWikibar.style.display=='block'? 'none':'block');
      return;
    }
  }
  var tiddlerWrapper = document.getElementById('tiddler'+title);
  var theTextarea = wikibar_resolveTiddlerEditor(tiddlerWrapper);
  if(!theTextarea){
    clearMessage();
    displayMessage('WikiBar only works in tiddler edit mode now');
    return;
  }else{
    if(!theTextarea.id){ theTextarea.id = 'editor'+title; }
    if(!theTextarea.parentNode.id){ theTextarea.parentNode.id='editorWrapper'+title;  }
  }
  if(theWikibar){
    theWikibar = document.getElementById('wikibar'+title);
  }else{
    var editorWrapper = wikibar_resolveTiddlerEditorWrapper(theTextarea);
    theWikibar = createTiddlyElement(tiddlerWrapper, 'div', 'wikibar'+title, 'toolbar');
    addClass(theWikibar, 'wikibar');
    var previewer = document.getElementById('previewer'+title);
    if(previewer){
      tiddlerWrapper.insertBefore(theWikibar, previewer);
    }else{
      tiddlerWrapper.insertBefore(theWikibar, editorWrapper);
    }
  }
  wikibar_createMenu(theWikibar,wikibarStore,title,theTextarea);
  if(config.options['chkWikibarSetEditorHeight'] && config.options['txtWikibarEditorRows']){
    theTextarea.rows = config.options['txtWikibarEditorRows'];
  }
  setStylesheet(
    '.wikibar{text-align:left;visibility:visible;margin:2px;padding:1px;}.previewer{overflow:auto;display:block;border:1px solid;}#colorPicker{position:absolute;display:none;z-index:10;margin:0px;padding:0px;}#colorPicker table{margin:0px;padding:0px;border:2px solid #000;border-spacing:0px;border-collapse:collapse;}#colorPicker td{margin:0px;padding:0px;border:1px solid;font-size:11px;text-align:center;cursor:auto;}#colorPicker .header{background-color:#fff;}#colorPicker .button{background-color:#fff;cursor:pointer;cursor:hand;}#colorPicker .button:hover{padding-top:3px;padding-bottom:3px;color:#fff;background-color:#136;}#colorPicker .cell{padding:4px;font-size:7px;cursor:crosshair;}#colorPicker .cell:hover{padding:10px;}.wikibarPopup{position:absolute;z-index:10;border:1px solid #014;color:#014;background-color:#cef;}.wikibarPopup table{margin:0;padding:0;border:0;border-spacing:0;border-collapse:collapse;}.wikibarPopup .button:hover{color:#eee;background-color:#014;}.wikibarPopup .disabled{color:#888;}.wikibarPopup .disabled:hover{color:#888;background-color:#cef;}.wikibarPopup tr .seperator hr{margin:0;padding:0;background-color:#cef;width:100%;border:0;border-top:1px dashed #014;}.wikibarPopup tr .icon{font-family:verdana;font-weight:bolder;}.wikibarPopup tr .marker{font-family:verdana;font-weight:bolder;}.wikibarPopup td{font-size:0.9em;padding:2px;}.wikibarPopup input{border:0;border-bottom:1px solid #014;margin:0;padding:0;font-family:arial;font-size:100%;background-color:#fff;}',
  	'WikiBarStyleSheet');
}
function wikibar_createMenu(place,toolset,title,editor){
  if(!wikibar_isValidMenuItem(toolset)){return;}
  if(!(toolset.TYPE=='MAIN_MENU' || toolset.TYPE=='MENU')){ return; }
    for(var key in toolset){
      if(key.substring(0,9)=='SEPERATOR'){
        wikibar_createMenuSeperator(place);
        continue;
      }
      if(key.substring(0,8)=='DYNAITEM'){
        var dynaTools = toolset[key](title,editor);
        if(dynaTools.TYPE && dynaTools.TYPE=='MENU'){
          wikibar_createMenuItem(place,dynaTools,null,editor,title);
        }else{
          dynaTools.TYPE = 'MENU';
          wikibar_createMenu(place, dynaTools, title, editor);
        }
        continue;
      }
      if((toolset[key].TYPE!='MENU' && toolset[key].TYPE!='MAIN_MENU') && !toolset[key].HANDLER){continue;}
      wikibar_createMenuItem(place,toolset,key,editor,title);
    }
}
function wikibar_createMenuItem(place,toolset,key,editor,title){
  if(!key){
    var tool = toolset;
  }else{
    tool = toolset[key];
    tool.key = key;
  }
  if(!wikibar_isValidMenuItem(tool)){return;}
  var toolIsOnMainMenu = (toolset.TYPE=='MAIN_MENU');
  var toolIsMenu = (tool.TYPE=='MENU');
  var theButton;
  if(toolIsOnMainMenu){
    theButton = createTiddlyButton(
                  place,
                  '',
                  (tool.TOOLTIP? tool.TOOLTIP : ''),
                  (toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem),
                  'button');
    theButton.innerHTML = (tool.CAPTION? tool.CAPTION : key);
    theButton.isOnMainMenu = true;
    addClass(theButton, (toolIsMenu? 'menu' : 'item'));
  	place.appendChild( document.createTextNode('\n') );
    if(!toolIsMenu){
      if(config.options['chkWikibarPopmenuOnMouseOver']){
        theButton.onmouseover = function(e){ wikibarPopup.remove(); };
      }
    }
  }else{
    theButton=createTiddlyElement(place, 'tr',key,'button');
    theButton.title = (tool.TOOLTIP? tool.TOOLTIP : '');
    theButton.onclick = (toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem);
    var tdL = createTiddlyElement(theButton, 'td','','marker');
    var td = createTiddlyElement(theButton, 'td');
    var tdR = createTiddlyElement(theButton, 'td','','marker');
    td.innerHTML = (tool.CAPTION? tool.CAPTION : key);
    if(toolIsMenu){
      tdR.innerHTML='&nbsp;&nbsp;&rsaquo;';
    }
    if(tool.SELECTED){
      tdL.innerHTML = '&radic; ';
      addClass(theButton, 'selected');
    }
    if(tool.DISABLED){
      addClass(theButton, 'disabled');
    }
  }
  theButton.tiddlerTitle = title;
  theButton.toolItem = tool;
  theButton.editor = editor;
  theButton.tabIndex = 999;
  if(toolIsMenu){
    if(config.options['chkWikibarPopmenuOnMouseOver']){
      theButton.onmouseover = wikibar_onClickMenuItem;
    }
  }
}
function wikibar_createMenuSeperator(place){
  if(place.id.substring(0,7)=='wikibar')  { return; }
  var onclickSeperator=function(e){
  	if(!e){ e = window.event; }
  	e.cancelBubble = true;
    if (e.stopPropagation){ e.stopPropagation();  }
  	return(false);
  };
  var theButton=createTiddlyElement(place,'tr','','seperator');
  var td = createTiddlyElement(theButton, 'td','','seperator');
  td.colSpan=3;
  theButton.onclick=onclickSeperator;
	td.innerHTML = '<hr>';
}
function wikibar_genWikibarAbout(){
  var toolset={};
  toolset.version = {
    CAPTION: '<center>WikiBar ' +
              config.macros.wikibar.major + '.' +
              config.macros.wikibar.minor + '.' +
              config.macros.wikibar.revision +
              (config.macros.wikibar.beta? ' beta '+config.macros.wikibar.beta : '') +
              '</center>',
    HANDLER: function(){}
  };
  toolset.SEPERATOR = {};
  toolset.author = {
    CAPTION: '<center>Arphen Lin<br>arphenlin@gmail.com</center>',
    TOOLTIP: 'send mail to the author',
    HANDLER: function(){ window.open('mailto:arphenlin@gmail.com'); }
  };
  toolset.website = {
    CAPTION: '<center>aiddlywiki.sourceforge.net</center>',
    TOOLTIP: 'go to the web site of WikiBar',
    HANDLER: function(){ window.open('http:\/\/aiddlywiki.sourceforge.net/'); }
  };
  return toolset;
}
function wikibar_genWikibarOptions(title, editor){
  var toolset={};
  toolset.popOnMouseOver = {
    CAPTION:'popup menu on mouse over',
    SELECTED: config.options['chkWikibarPopmenuOnMouseOver'],
    HANDLER: function(param){
      config.options['chkWikibarPopmenuOnMouseOver'] = !config.options['chkWikibarPopmenuOnMouseOver'];
      saveOptionCookie('chkWikibarPopmenuOnMouseOver');
      var title = param.button.tiddlerTitle;
      var wikibar = document.getElementById('wikibar'+title);
      if(wikibar){ wikibar.parentNode.removeChild(wikibar); }
      wikibar_createWikibar(title);
    }
  };
  toolset.setEditorSize = {
    CAPTION:'set editor height: <input id=\"txtWikibarEditorRows\" type=text size=1 MAXLENGTH=3 value=\"' +
            (config.options['txtWikibarEditorRows']? config.options['txtWikibarEditorRows']:editor.rows) + '\"> ok',
    HANDLER: function(param){
      var input = document.getElementById('txtWikibarEditorRows');
      if(input){
        var rows = parseInt(input.value, 10);
        if(!isNaN(rows)){
          var editor = param.button.editor;
          editor.rows = rows;
        }else{
          rows=config.maxEditRows;
        }
        config.options['txtWikibarEditorRows'] = rows;
        saveOptionCookie('txtWikibarEditorRows');
        config.maxEditRows = rows;
      }
    }
  };
  toolset.setEditorSizeOnLoadingWikibar = {
    CAPTION:'set editor height on loading wikibar',
    SELECTED: config.options['chkWikibarSetEditorHeight'],
    HANDLER: function(param){
      config.options['chkWikibarSetEditorHeight'] = !config.options['chkWikibarSetEditorHeight'];
      saveOptionCookie('chkWikibarSetEditorHeight');
      if(config.options['chkWikibarSetEditorHeight']){
        var rows = config.options['txtWikibarEditorRows'];
        if(!isNaN(rows)){ rows = 15; }
        var editor = param.button.editor;
        editor.rows = rows;
        config.options['txtWikibarEditorRows'] = rows;
        saveOptionCookie('txtWikibarEditorRows');
      }
    }
  };
  toolset.SEPERATOR = {};
  toolset.update = {
    CAPTION: 'check for updates',
    DISABLED: true,
    HANDLER: function(){}
  };
  return toolset;
}
function wikibar_genPaletteSelector(){
  try{
  	var cpTiddlers = store.getTaggedTiddlers('ColorPalettes');
  	if(!cpTiddlers) { return; }
  	var palettes=[];
  	palettes.push(wikibarColorTool.defaultPaletteName);
  	for(var i=0; i<cpTiddlers.length; i++){
  		palettes.push(cpTiddlers[i].title.trim());
  	}
    var toolset={};
    for(i=0; i<palettes.length; i++){
      toolset[palettes[i]] = {
        TOOLTIP: palettes[i],
        SELECTED: (palettes[i]==wikibarColorTool.paletteName),
        HANDLER: wikibar_doSelectPalette
      };
    }
    return toolset;
  }catch(ex){ return null; }
}
function wikibar_onClickItem(e){
	if(!e){ e = window.event; }
	var theTarget = resolveTarget(e);
	if(theTarget.tagName=='INPUT'){
    e.cancelBubble = true;
    if (e.stopPropagation){ e.stopPropagation(); }
    return;
	}
	var theButton = wikibar_resolveTargetButton(theTarget);
	if(!theButton){ return(false);  }
  	var o = theButton.toolItem;
    if(!o) { return; }
    var param = {
      event: e,
      button: theButton
    };
    if(o.HANDLER){ o.HANDLER(param);  }
  if(o.DISABLED){
    e.cancelBubble = true;
    if (e.stopPropagation){ e.stopPropagation(); }
  }
	return(false);
}
function wikibar_onClickMenuItem(e){
	if(!e){ e = window.event; }
	var theButton = wikibar_resolveTargetButton(resolveTarget(e));
	if(!theButton){ return(false);  }
	e.cancelBubble = true;
	if (e.stopPropagation){ e.stopPropagation(); }
    var title = theButton.tiddlerTitle;
    var editor = theButton.editor;
    var tool = theButton.toolItem;
    if(!tool) { return; }
    var popup = wikibarPopup.create(this);
  	if(popup){
      wikibar_createMenu(popup,tool,title,editor);
      if(!popup.hasChildNodes()){
        wikibarPopup.remove();
      }else{
        wikibarPopup.show(popup, false);
      }
    }
	return(false);
}
var wikibarColorTool = {
  defaultPaletteName : 'default',
  defaultColumns : 16,
  defaultPalette : [
    '#FFF','#DDD','#CCC','#BBB','#AAA','#999','#666','#333','#111','#000','#FC0','#F90','#F60','#F30','#C30','#C03',
    '#9C0','#9D0','#9E0','#E90','#D90','#C90','#FC3','#FC6','#F96','#F63','#600','#900','#C00','#F00','#F36','#F03',
    '#CF0','#CF3','#330','#660','#990','#CC0','#FF0','#C93','#C63','#300','#933','#C33','#F33','#C36','#F69','#F06',
    '#9F0','#CF6','#9C3','#663','#993','#CC3','#FF3','#960','#930','#633','#C66','#F66','#903','#C39','#F6C','#F09',
    '#6F0','#9F6','#6C3','#690','#996','#CC6','#FF6','#963','#630','#966','#F99','#F39','#C06','#906','#F3C','#F0C',
    '#3F0','#6F3','#390','#6C0','#9F3','#CC9','#FF9','#C96','#C60','#C99','#F9C','#C69','#936','#603','#C09','#303',
    '#0C0','#3C0','#360','#693','#9C6','#CF9','#FFC','#FC9','#F93','#FCC','#C9C','#969','#939','#909','#636','#606',
    '#060','#3C3','#6C6','#0F0','#3F3','#6F6','#9F9','#CFC','#9CF','#FCF','#F9F','#F6F','#F3F','#F0F','#C6C','#C3C',
    '#030','#363','#090','#393','#696','#9C9','#CFF','#39F','#69C','#CCF','#C9F','#96C','#639','#306','#90C','#C0C',
    '#0F3','#0C3','#063','#396','#6C9','#9FC','#9CC','#06C','#369','#99F','#99C','#93F','#60C','#609','#C3F','#C0F',
    '#0F6','#3F6','#093','#0C6','#3F9','#9FF','#699','#036','#039','#66F','#66C','#669','#309','#93C','#C6F','#90F',
    '#0F9','#6F9','#3C6','#096','#6FF','#6CC','#366','#069','#36C','#33F','#33C','#339','#336','#63C','#96F','#60F',
    '#0FC','#6FC','#3C9','#3FF','#3CC','#399','#033','#39C','#69F','#00F','#00C','#009','#006','#003','#63F','#30F',
    '#0C9','#3FC','#0FF','#0CC','#099','#066','#3CF','#6CF','#09C','#36F','#0CF','#09F','#06F','#03F','#03C','#30C'
  ],
	colorPicker : null,
  pickColorHandler: null,
  userData: null
};
wikibarColorTool.paletteName = wikibarColorTool.defaultPaletteName;
wikibarColorTool.columns = wikibarColorTool.defaultColumns;
wikibarColorTool.palette = wikibarColorTool.defaultPalette;
wikibarColorTool.onPickColor = function(e){
	if (!e){ e = window.event; }
	var theCell = resolveTarget(e);
	if(!theCell){ return(false); }
    color = theCell.bgColor.toLowerCase();
    if(!color)  { return; }
    wikibarColorTool.displayColorPicker(false);
    if(wikibarColorTool.pickColorHandler){
      wikibarColorTool.pickColorHandler(color, wikibarColorTool.userData);
    }
	return(false);
};
wikibarColorTool.onMouseOver = function(e){
	if (!e){ e = window.event; }
	var theButton = resolveTarget(e);
	if(!theButton){ return(false);  }
  	if(!wikibarColorTool)  { return; }
    color = theButton.bgColor.toUpperCase();
    if(!color)  { return; }
    td=document.getElementById('colorPickerInfo');
  	if(!td) { return; }
  	td.bgColor = color;
  	td.innerHTML = '<span style=\"color:#000;\">'+color+'</span>&nbsp;&nbsp;&nbsp;' +
  	               '<span style=\"color:#fff;\">'+color+'</span>';
	e.cancelBubble = true;
	if (e.stopPropagation){ e.stopPropagation(); }
	return(false);
};
wikibarColorTool.openColorPicker = function(theTarget, pickColorHandler, userData){
  wikibarColorTool.skipClickDocumentEvent = true;
  wikibarColorTool.pickColorHandler = pickColorHandler;
  wikibarColorTool.userData = userData;
  wikibarColorTool.moveColorPicker(theTarget);
};
wikibarColorTool.convert3to6HexColor = function(c){
  c=c.trim();
  var rx=/^\#(\d|[a-f])(\d|[a-f])(\d|[a-f])$/gi;
  return (rx.test(c)? c.replace(rx, '#$1$1$2$2$3$3') : c);
};
wikibarColorTool.numToHexColor = function (n){
  if(typeof(n)=='number' && (n>=0 && n<=255)) {
  		s = n.toString(16).toLowerCase();
  		return ((s.length==1)? '0'+s : s);
  }else{
	 return null;
	}
};
wikibarColorTool.renderColorPalette = function(){
	if(wikibarColorTool.paletteName==wikibarColorTool.defaultPaletteName){
		wikibarColorTool.palette=wikibarColorTool.defaultPalette;
		wikibarColorTool.columns=wikibarColorTool.defaultColumns;
		return;
	}
	tiddlerText = (store.getTiddlerText(wikibarColorTool.paletteName, '')).trim();
	if(tiddlerText.length<=0) { return; }
	var cpContents = tiddlerText.split('\n');
	var colors=[];
	columns = wikibarColorTool.defaultColumns;
	var tmpArray=null;
	errCount=0;
	for(var i=0; i<cpContents.length; i++){
		cpLine=cpContents[i].trim();
    if( (!cpLine) || (cpLine.length<=0) || (cpLine.charAt(0) == '#') ){ continue; }
		if(cpLine.substring(0,8).toLowerCase()=='columns:'){
			tmpArray = cpLine.split(':');
			try{
				columns = parseInt(tmpArray[1],10);
			}catch(ex){
				columns = wikibarColorTool.defaultColumns;
			}
		}else{
			tmpArray = cpLine.replace('\t', ' ').split(/[ ]{1,}/);
			try{
				color='';
				for(var j=0; j<3; j++){
          c=parseInt(tmpArray[j].trim(), 10);
          if(isNaN(c)){
						break;
          }else{
						c=wikibarColorTool.numToHexColor(c);
						if(!c) {break;}
            color+=c;
					}
				}
				if(color.length==6){
					colors.push('#'+color);
				}	else {
					throw 'error';
				}
			}catch(ex){
			}
		}
	}
	if(colors.length>0){
		wikibarColorTool.palette = colors;
		wikibarColorTool.columns = columns;
	}else{
		throw 'renderColorPalette(): No color defined in the palette.';
	}
};
wikibarColorTool.displayColorPicker = function(visible){
  if(wikibarColorTool.colorPicker){
    wikibarColorTool.colorPicker.style.display = (visible? 'block' : 'none');
  }
};
wikibarColorTool.moveColorPicker = function(theTarget){
  if(!wikibarColorTool.colorPicker){
  	wikibarColorTool.createColorPicker();
  }
	var cp = wikibarColorTool.colorPicker;
	var rootLeft = findPosX(theTarget);
  var rootTop = findPosY(theTarget);
  var popupLeft = rootLeft;
  var popupTop = rootTop;
  var popupWidth = cp.offsetWidth;
  var winWidth = findWindowWidth();
  if(popupLeft + popupWidth > winWidth){
	  popupLeft = winWidth - popupWidth;
	}
  cp.style.left = popupLeft + 'px';
  cp.style.top = popupTop + 'px';
  wikibarColorTool.displayColorPicker(true);
};
wikibarColorTool.createColorPicker = function(unused, palette){
  if(palette){	wikibarColorTool.paletteName=palette; }
	wikibarColorTool.renderColorPalette();
	wikibarColorTool.colorPicker = document.createElement('div');
	wikibarColorTool.colorPicker.id = 'colorPicker';
	document.body.appendChild(wikibarColorTool.colorPicker);
  var theTable = document.createElement('table');
  wikibarColorTool.colorPicker.appendChild(theTable);
  var theTR = document.createElement('tr');
	theTable.appendChild(theTR);
	var theTD = document.createElement('td');
	theTD.className = 'header';
	theTD.colSpan = wikibarColorTool.columns;
	theTD.innerHTML = wikibarColorTool.paletteName;
  theTR.appendChild(theTD);
  for(var i=0; i<wikibarColorTool.palette.length; i++){
    if((i%wikibarColorTool.columns)===0){
      theTR = document.createElement('tr');
      theTable.appendChild(theTR);
    }
    theTD = document.createElement('td');
    theTD.className = 'cell';
    theTD.bgColor = wikibarColorTool.convert3to6HexColor(wikibarColorTool.palette[i]);
    theTD.onclick = wikibarColorTool.onPickColor;
    theTD.onmouseover = wikibarColorTool.onMouseOver;
    theTR.appendChild(theTD);
  }
  rest = wikibarColorTool.palette.length % wikibarColorTool.columns;
  if(rest>0){
    theTD = document.createElement('td');
		theTD.colSpan = wikibarColorTool.columns-rest;
    theTD.bgColor = '#000000';
    theTR.appendChild(theTD);
  }
  theTR = document.createElement('tr');
	theTable.appendChild(theTR);
	theTD = document.createElement('td');
	theTD.colSpan = wikibarColorTool.columns;
	theTD.id = 'colorPickerInfo';
  theTR.appendChild(theTD);
};
wikibarColorTool.onDocumentClick = function(e){
	if (!e){ e = window.event; }
	if(wikibarColorTool.skipClickDocumentEvent) {
	  wikibarColorTool.skipClickDocumentEvent = false;
    return true;
	}
	if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){
    wikibarColorTool.displayColorPicker(false);
  }
	return true;
};
function wikibar_doSelectPalette(param){
	clearMessage();
	var theButton = param.button;
	if(!theButton.toolItem.key)  { return; }
	var palette = theButton.toolItem.key;
	var oldPaletteName = wikibarColorTool.paletteName;
	if(oldPaletteName != palette){
		try{
			wikibarColorTool.createColorPicker(theButton, palette);
			displayMessage('Palette \"'+palette+'\" ('+ wikibarColorTool.palette.length +' colors) is selected');
		}catch(ex){
			errMsg = ex;
			if(errMsg.substring(0,18)=='renderColorPalette'){
				displayMessage('Invalid palette \"' + palette + '\", please check it out!');
				wikibarColorTool.createColorPicker(theButton, oldPaletteName);
			}
		}
	}
}
var wikibarPopup = {
  skipClickDocumentEvent: false,
	stack: []
};
wikibarPopup.resolveRootPopup = function(o){
  if(o.isOnMainMenu){  return null; }
  if(o.className.substring(0,12)=='wikibarPopup'){  return o;}
  return wikibarPopup.resolveRootPopup(o.parentNode);
};
wikibarPopup.create = function(root){
  for(var i=0; i<wikibarPopup.stack.length; i++){
    var p=wikibarPopup.stack[i];
    if(p.root==root){
      wikibarPopup.removeFrom(i+1);
      return null;
    }
  }
  var rootPopup = wikibarPopup.resolveRootPopup(root);
  if(!rootPopup){
    wikibarPopup.remove();
  }else{
    wikibarPopup.removeFromRootPopup(rootPopup);
  }
	var popup = createTiddlyElement(document.body,'div','wikibarPopup'+root.toolItem.key,'wikibarPopup');
	var pop = createTiddlyElement(popup,'table','','');
	wikibarPopup.stack.push({rootPopup: rootPopup, root: root, popup: popup});
	return pop;
};
wikibarPopup.show = function(unused,slowly){
	var curr = wikibarPopup.stack[wikibarPopup.stack.length-1];
	var overlayWidth = 1;
  var rootLeft, rootTop, rootWidth, rootHeight, popupLeft, popupTop, popupWidth;
  if(curr.rootPopup){
  	rootLeft = findPosX(curr.rootPopup);
  	rootTop = findPosY(curr.root);
  	rootWidth = curr.rootPopup.offsetWidth;
  	popupLeft = rootLeft + rootWidth - overlayWidth;
  	popupTop = rootTop;
  }else{
  	rootLeft = findPosX(curr.root);
  	rootTop = findPosY(curr.root);
  	rootHeight = curr.root.offsetHeight;
  	popupLeft = rootLeft;
  	popupTop = rootTop + rootHeight;
  }
	var winWidth = findWindowWidth();
	popupWidth = curr.popup.offsetWidth;
	if(popupLeft + popupWidth > winWidth){
		popupLeft = rootLeft - popupWidth + overlayWidth;
	}
	curr.popup.style.left = popupLeft + 'px';
	curr.popup.style.top = popupTop + 'px';
	curr.popup.style.display = 'block';
	addClass(curr.root, 'highlight');
	if(config.options.chkAnimate){
		anim.startAnimating(new Scroller(curr.popup,slowly));
	}else{
		window.scrollTo(0,ensureVisible(curr.popup));
	}
};
wikibarPopup.remove = function(){
	if(wikibarPopup.stack.length > 0){
		wikibarPopup.removeFrom(0);
  }
};
wikibarPopup.removeFrom = function(from){
	for(var t=wikibarPopup.stack.length-1; t>=from; t--){
		var p = wikibarPopup.stack[t];
		removeClass(p.root,'highlight');
		p.popup.parentNode.removeChild(p.popup);
  }
	wikibarPopup.stack = wikibarPopup.stack.slice(0,from);
};
wikibarPopup.removeFromRootPopup = function(from){
  for(var t=0; t<wikibarPopup.stack.length; t++){
    var p = wikibarPopup.stack[t];
    if(p.rootPopup==from){
      wikibarPopup.removeFrom(t);
      break;
    }
  }
};
wikibarPopup.onDocumentClick = function(e){
	if (!e){ e = window.event; }
	if(wikibarPopup.skipClickDocumentEvent){
	 wikibarPopup.skipClickDocumentEvent=false;
	 return true;
	}
	if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){
		wikibarPopup.remove();
	}
	return true;
};
var wikibarStore = {
  TYPE: 'MAIN_MENU',
  help:{
    TYPE:'MENU',
    CAPTION: '<font face=\"verdana\">?</font>',
    TOOLTIP:     'about WikiBar',
    options:{
      TYPE:'MENU',
      DYNAITEM: wikibar_genWikibarOptions
    },
    about:{
      TYPE:'MENU',
      DYNAITEM: wikibar_genWikibarAbout
    }
  },
  preview:{
    TOOLTIP:     'preview this tiddler',
    CAPTION: '<font face=\"verdana\">&infin;</font>',
    HANDLER: wikibar_doPreview
  },
	line:{
		TOOLTIP:    'horizontal line',
		CAPTION: '<font face=\"verdana\">&mdash;</font>',
		syntax: '\n----\n',
		HANDLER: wikibar_editFormatByCursor
	},
	crlf:{
		TOOLTIP:    'new line',
		CAPTION: '<font face=\"verdana\">&para;</font>',
		syntax: '\n',
		HANDLER: wikibar_editFormatByCursor
	},
	selectAll:{
		TOOLTIP:    'select all',
		CAPTION: '<font face=\"verdana\">&sect;</font>',
		HANDLER: wikibar_editSelectAll
	},
	deleteSelected:{
		TOOLTIP:    'delete selected',
		CAPTION: '<font face=\"verdana\">&times;</font>',
		syntax: '',
		HANDLER: wikibar_editFormat
	},
  textFormat:{
    TYPE: 'MENU',
    CAPTION: 'text',
    TOOLTIP: 'text formatters',
    ignore:{
			TOOLTIP:     'ignore wiki word',
			CAPTION: 'ignore wikiWord',
			syntax:  '~user_text',
			hint:    'wiki_word',
			HANDLER:    wikibar_editFormatByWord
		},
		bolder:{
			TOOLTIP:     'bolder text',
			CAPTION: '<strong>bolder</strong>',
			syntax:  "''user_text''",
			hint:		 'bold_text',
			HANDLER:    wikibar_editFormatByWord
		},
		italic:{
			TOOLTIP:    'italic text',
			CAPTION: '<em>italic</em>',
			syntax: '\/\/user_text\/\/',
			hint:		'italic_text',
			HANDLER: wikibar_editFormatByWord
		},
		underline:{
			TOOLTIP:    'underline text',
			CAPTION: '<u>underline</u>',
			syntax: '__user_text__',
			hint:		'underline_text',
			HANDLER: wikibar_editFormatByWord
		},
		strikethrough:{
			TOOLTIP:    'strikethrough text',
			CAPTION: '<strike>strikethrough</strike>',
			syntax: '==user_text==',
			hint:		'strikethrough_text',
			HANDLER: wikibar_editFormatByWord
		},
		superscript:{
			TOOLTIP:    'superscript text',
			CAPTION: 'X<sup>superscript</sup>',
			syntax: '^^user_text^^',
			hint:		'superscript_text',
			HANDLER: wikibar_editFormatByWord
		},
		subscript:{
			TOOLTIP:    'subscript text',
			CAPTION: 'X<sub>subscript</sub>',
			syntax: '~~user_text~~',
			hint:		'subscript_text',
			HANDLER: wikibar_editFormatByWord
		},
		comment:{
			TOOLTIP:    'comment text',
			CAPTION: 'comment text',
			syntax: '/%user_text%/',
			hint:		'comment_text',
			HANDLER: wikibar_editFormatByWord
		},
		monospaced:{
			TOOLTIP:    'monospaced text',
			CAPTION: '<code>monospaced</code>',
			syntax: '{{{user_text}}}',
			hint:		'monospaced_text',
			HANDLER: wikibar_editFormatByWord
		}
  },
  paragraph:{
    TYPE: 'MENU',
    TOOLTIP: 'paragarph formatters',
    list:{
      TYPE: 'MENU',
      TOOLTIP: 'list tools',
      bullet:{
  			TOOLTIP:    'bullet point',
  			syntax: '*user_text',
  			hint:		'bullet_text',
  			HANDLER: wikibar_editFormatByLine
  		},
  		numbered:{
  			TOOLTIP:    'numbered list',
  			syntax: '#user_text',
  			hint:		'numbered_text',
  			HANDLER: wikibar_editFormatByLine
  		}
    },
    heading:{
      TYPE: 'MENU',
      heading1:{
  		  CAPTION:'<h1>Heading 1</h1>',
  			TOOLTIP:    'Heading 1',
  			syntax: '!user_text',
  			hint:		'heading_1',
  			HANDLER: wikibar_editFormatByLine
  		},
  		heading2:{
  		  CAPTION:'<h2>Heading 2<h2>',
  			TOOLTIP:    'Heading 2',
  			syntax: '!!user_text',
  			hint:		'heading_2',
  			HANDLER: wikibar_editFormatByLine
  		},
  		heading3:{
  		  CAPTION:'<h3>Heading 3</h3>',
  			TOOLTIP:    'Heading 3',
  			syntax: '!!!user_text',
  			hint:		'heading_3',
  			HANDLER: wikibar_editFormatByLine
  		},
  		heading4:{
  		  CAPTION:'<h4>Heading 4</h4>',
  			TOOLTIP:    'Heading 4',
  			syntax: '!!!!user_text',
  			hint:		'heading_4',
  			HANDLER: wikibar_editFormatByLine
  		},
  		heading5:{
  		  CAPTION:'<h5>Heading 5</h5>',
  			TOOLTIP:    'Heading 5',
  			syntax: '!!!!!user_text',
  			hint:		'heading_5',
  			HANDLER: wikibar_editFormatByLine
  		}
    },
    comment:{
      TYPE: 'MENU',
      commentByLine:{
  			CAPTION:'comment by line',
  			TOOLTIP:    'line comment',
  			syntax: '/%user_text%/',
  			hint:		'comment_text',
  			HANDLER: wikibar_editFormatByLine
  		},
  		commentByBlock:{
  			CAPTION:'comment by block',
  			TOOLTIP:    'block comment',
  			syntax: '/%\nuser_text\n%/',
  			hint:		'comment_text',
  			byBlock: true,
  			HANDLER: wikibar_editFormatByLine
  		}
    },
    monospaced:{
      TYPE: 'MENU',
  		monosByLine:{
  			CAPTION: 	'monospaced by line',
  			TOOLTIP:    'line monospaced',
  			syntax: '{{{\nuser_text\n}}}',
  			hint:		'monospaced_text',
  			HANDLER: wikibar_editFormatByLine
  		},
  		monosByBlock:{
  			CAPTION: 	'monospaced by block',
  			TOOLTIP:    'block monospaced',
  			syntax: '{{{\nuser_text\n}}}',
  			hint:		'monospaced_text',
  			byBlock: true,
  			HANDLER: wikibar_editFormatByLine
  		}
    },
    quote:{
      TYPE: 'MENU',
  		quoteByLine:{
  			CAPTION: 	'quote by line',
  			TOOLTIP:    'line quote',
  			syntax: '>user_text',
  			hint:		'quote_text',
  			HANDLER: wikibar_editFormatByLine
  		},
  		quoteByBlcok:{
  			CAPTION: 	'quote by block',
  			TOOLTIP:    'block quote',
  			syntax: '<<<\nuser_text\n<<<',
  			hint:		'quote_text',
  			byBlock: true,
  			HANDLER: wikibar_editFormatByLine
  		}
    },
    plugin:{
      TYPE: 'MENU',
      code:{
  			CAPTION: 	'code area',
  			TOOLTIP:    'block monospaced for plugin',
  			syntax: '\n\/\/{{{\nuser_text\n\/\/}}}\n',
  			hint:		'monospaced_plugin_code',
  			byBlock: true,
  			HANDLER: wikibar_editFormatByLine
  		},
  		commentByLine:{
  			CAPTION: 	'comment by line',
  			TOOLTIP:    'line comment',
  			syntax: '\/\/user_text',
  			hint:		'plugin_comment',
  			HANDLER: wikibar_editFormatByLine
  		},
  		commentByBlock:{
  			CAPTION: 	'comment by block',
  			TOOLTIP:    'block comment',
  			syntax: '\/\***\nuser_text\n***\/',
  			hint:		'plugin_comment',
  			byBlock: true,
  			HANDLER: wikibar_editFormatByLine
  		}
    },
    css:{
      TYPE: 'MENU',
      code:{
  			CAPTION: 	'code area',
  			TOOLTIP:    'block monospaced for css',
  			syntax: '\n\nuser_text\n\n',
  			hint:		'monospaced_css_code',
  			byBlock: true,
  			HANDLER: wikibar_editFormatByLine
  		},
  		commentByLine:{
  			CAPTION: 	'comment by line',
  			TOOLTIP:    'line comment',
  			syntax: '',
  			hint:		'css_comment',
  			HANDLER: wikibar_editFormatByLine
  		},
  		commentByBlock:{
  			CAPTION: 	'comment by block',
  			TOOLTIP:    'block comment',
  			syntax: '',
  			hint:		'css_comment',
  			byBlock: true,
  			HANDLER: wikibar_editFormatByLine
  		}
    }
  },
  color:{
    TYPE: 'MENU',
    TOOLTIP: 'color tools',
    highlight:{
		  CAPTION:'highlight text',
			TOOLTIP:    'highlight text',
			syntax: '@@user_text@@',
			hint:		'highlight_text',
			HANDLER: wikibar_editFormatByWord
		},
		color:{
		  CAPTION:'text color',
			TOOLTIP:    'text color',
			hint:		'your_text',
			syntax: '@@color(%1):user_text@@',
			HANDLER:   wikibar_getColorCode,
			doMore: wikibar_editFormatByWord
		},
		bgcolor:{
		  CAPTION:'background color',
			TOOLTIP:    'background color',
			hint:		'your_text',
			syntax: '@@bgcolor(%1):user_text@@',
			HANDLER: wikibar_getColorCode,
			doMore: wikibar_editFormatByWord
		},
		colorcode:{
      CAPTION:'color code',
      TOOLTIP:    'insert color code',
      syntax: '%1',
      HANDLER: wikibar_getColorCode,
      doMore: wikibar_editFormatByCursor
    },
    'color palette':{
      TYPE:'MENU',
      DYNAITEM: wikibar_genPaletteSelector,
  		SEPERATOR:{},
  		morePalette:{
  		  CAPTION:'more palettes',
  		  TOOLTIP:'get more palettes',
  		  HANDLER: wikibar_getMorePalette
  		}
    }
  },
  link:{
    TYPE: 'MENU',
    TOOLTIP: 'insert link',
    wiki:{
		  CAPTION:'wiki link',
			TOOLTIP:    'wiki link',
			syntax: '[[user_text]]',
			hint:		'wiki_word',
			HANDLER: wikibar_editFormatByWord
		},
		pretty:{
			CAPTION: 	'pretty link',
			TOOLTIP:    'pretty link',
			syntax: '[[user_text|%1]]',
			hint:		'pretty_word',
			param:	'PrettyLink Target',
			HANDLER:   wikibar_getLinkUrl,
			doMore: wikibar_editFormatByWord
		},
		url:{
			TOOLTIP:    'url link',
			syntax: '[[user_text|%1]]',
			hint:		'your_text',
			param:	'http:\/\/...',
			HANDLER:   wikibar_getLinkUrl,
			doMore: wikibar_editFormatByWord
		},
		image:{
			TOOLTIP:    'image link',
			syntax: '[img[user_text|%1]]',
			hint:		'alt_text',
			param:	'image/icon.jpg',
			HANDLER:   wikibar_getLinkUrl,
			doMore: wikibar_editFormatByWord
		}
  },
  macro:{},
  more:{
    TYPE: 'MENU',
    TOOLTIP: 'more tools',
    table:{
      TYPE: 'MENU',
      TOOLTIP: 'table',
      table:{
  		  CAPTION:'create table',
  			TOOLTIP:    'create a new table',
  			syntax: '\n%1\n',
  			HANDLER: wikibar_getTableRowCol,
  			doMore: wikibar_editFormatByWord
  		},
  		header:{
  			TOOLTIP:    'table header text',
  			syntax: '|user_text|c',
  			hint:		'table_header',
  			HANDLER: wikibar_editFormatByWord
  		},
  		cell:{
  			TOOLTIP:    'create a tabel cell',
  			syntax: '|user_text|',
  			hint:		'your_text',
  			HANDLER: wikibar_editFormatByWord
  		},
  		columnHeader:{
  		  CAPTION:'column header',
  			TOOLTIP:    'create a column header cell',
  			syntax: '|!user_text|',
  			hint:		'column_header',
  			HANDLER: wikibar_editFormatByWord
  		},
  	  cell:{
  	    TYPE: 'MENU',
        CAPTION: 'cell options',
    		bgcolor:{
    			CAPTION: 	'background color',
    			TOOLTIP:    'cell bgcolor',
    			syntax: '|bgcolor(%1):user_text|',
    			hint:		'your_text',
    			HANDLER: wikibar_getColorCode,
    			doMore: wikibar_editFormatByTableCell
    		},
    		alignLeft:{
    			CAPTION: 	'align left',
    			TOOLTIP:    'left align cell text',
    			syntax: '|user_text|',
    			hint:		'your_text',
    			HANDLER: wikibar_editFormatByTableCell
    		},
    		alignCenter:{
    			CAPTION: 	'align center',
    			TOOLTIP:    'center align cell text',
    			syntax: '| user_text |',
    			hint:		'your_text',
    			HANDLER: wikibar_editFormatByTableCell
    		},
    		alignRight:{
    			CAPTION: 	'align right',
    			TOOLTIP:    'right align cell text',
    			syntax: '| user_text|',
    			hint:		'your_text',
    			HANDLER: wikibar_editFormatByTableCell
    		}
    	}
    },
    html:{
      TYPE: 'MENU',
      html:{
  			CAPTION: 	'&lt;html&gt;',
  			TOOLTIP:    'html tag',
  			syntax: '<html>\nuser_text\n</html>',
  			hint:		'html_content',
  			byBlock: true,
  			HANDLER: wikibar_editFormatByLine
  		}
    }
  },
  addon:{
    TYPE: 'MENU',
    TOOLTIP:'3rd party tools',
    'about addons':{
      TOOLTIP: 'list loaded addons',
      HANDLER: wikibar_doListAddons
    },
    SEPERATOR:{}
  }
};
addEvent(document, 'click', wikibarColorTool.onDocumentClick);
addEvent(document, 'click', wikibarPopup.onDocumentClick);
wikibar_install();
//}}}
/***
!WikiBar CSS 說明
*井號開頭表示 id, ex: #colorPicker
*點號開頭表示 class, ex: .wikibar

!WikiBar Colors Used
*@@bgcolor(#014):color(#fff): #014 - 選單邊框@@
*@@bgcolor(#014):color(#fff): #014 - 選單字體色@@
*@@bgcolor(#cef): #cef - 選單底色@@
*@@bgcolor(#eee): #eee - 選單字體色:游標滑過時@@
*@@bgcolor(#014):color(#fff): #014 - 選單底色:游標滑過時@@
*@@bgcolor(#888): #888 - 無效選單字體色@@
*@@bgcolor(#cef): #cef - 無效選單底色:游標滑過時@@
*@@bgcolor(#014):color(#fff): #014 - 分隔線顏色@@

!wikibar: 工具列, 繼承 .toolbar /%==============================================%/
***/
/*{{{*/
.wikibar {
  text-align: left;
  visibility: visible;
  margin:2px; padding:1px;
}
/*}}}*/

/***
!previewer: 預覽區, 繼承 .viewer /%==============================================%/
***/
/*{{{*/
.previewer {overflow:auto; display:block; border:1px solid;}
/*}}}*/

/***
!colorPicker 調色盤 /%==============================================%/
***/
/*{{{*/
#colorPicker {position:absolute; display:none; z-index:10; margin:0px; padding:0px; }
#colorPicker table {
  margin:0px; padding:0px;
  border:2px solid #000;
  border-spacing: 0px;
  border-collapse: collapse;
}
#colorPicker td {margin:0px; padding:0px; border:1px solid; font-size:11px; text-align:center; cursor:auto;}
#colorPicker .header {background-color: #fff;}
#colorPicker .button {background-color: #fff; cursor:pointer; cursor:hand;}
#colorPicker .button:hover {padding-top:3px; padding-bottom:3px; color:#fff; background-color:#136;}
#colorPicker .cell {padding:4px; font-size:7px; cursor:crosshair;}
#colorPicker .cell:hover {padding:10px;}
/*}}}*/

/***
!wikibarPopup 功能表選單 /%==============================================%/
***/
/*{{{*/
.wikibarPopup{
  position:absolute; z-index:10;
  border: 1px solid #014;
  color: #014; background-color: #cef;
  /*
  max-height:150px;
  overflow-x:hidden; overflow-y:auto;
  */
}

/* 彈出選單 */
.wikibarPopup table{
  margin:0; padding:0;
  border:0;
  border-spacing:0;
  border-collapse:collapse;
}

/* 選單上之按鈕 */
.wikibarPopup .button:hover{color:#eee; background-color: #014;}

/*
.wikibarPopup .selected {background-color: #cf6;}
*/

/* 停用選項 */
.wikibarPopup .disabled {color: #888;}
.wikibarPopup .disabled:hover {color: #888; background-color: #cef;}

/* 分隔線 */
.wikibarPopup tr .seperator hr{
  margin:0; padding:0; background-color: #cef; width: 100%;
  border: 0;
  border-top: 1px dashed #014;
}

/* 選項左右兩邊符號區 */
.wikibarPopup tr .icon   {font-family:verdana; font-weight:bolder;}
.wikibarPopup tr .marker {font-family:verdana; font-weight:bolder;}

/* 選項 */
.wikibarPopup td {font-size:0.9em; padding:2px;}

.wikibarPopup input{
  border:0;
  border-bottom: 1px solid #014;
  margin:0; padding:0;
  font-family: arial;
  font-size:100%;
  background-color: #fff;
}

/*}}}*/
; [Last Update: 17.12.2009, [[Download|Downloads]]]
!cis_string.cpp
{{{
/*

        cis_string.cpp

       Implementation for
        class cis_string

    For (additional) comments on the methods
        please look inside cis_string.hpp

*/


/* Change-Log
 *
 * 09/12/2009 DB: class made const save and is
 * (major Change) not using namespace std any more;
 *                Destructor tested
 *
 * 30/11/2009 DB: Revisions of methods get_data() etc following
 *                introduction of copyconstructor
 * 26/11/2009 MH: Last corrections on copyconstructor
 * 25/11/2009 DB: Change to copyconstructors
 * 00/10/2009 DB: First version of cis_string
 */

/* TODO
 * [ ] Look inside Cis_Text.cpp ;)
 */

#ifndef   CIS_STRING_CPP
#define   CIS_STRING_CPP

//#ifndef   CIS_STRING_HPP // notwendig??
#include "cis_string.hpp"
//#endif


#include <fstream>

// there is no more namespace std

cis_string::cis_string(const int &size) {
    data = new wchar_t[size+1];         // ... alle Buchstaben der cis_string Daten + Terminierende NULL
    anzahl = 0; /// ARGH!   ^-- und genau hier war der Fehler!
}


cis_string::cis_string(const std::wstring &text) {
    anzahl = text.size();
    data = new wchar_t[anzahl+1];
    wcsncpy(data,text.c_str(),anzahl+1);            /// wide-character-c-string-n-copy(from, to, length);

}


cis_string::cis_string(const wchar_t* text) {
    anzahl = wcslen(text);
    data = new wchar_t[anzahl+1];        // ... alle Buchstaben der cis_string Daten + Terminierende NULL
    wcsncpy(data,text,anzahl+1);            /// wide-character-c-string-n-copy(from, to, length);

}


cis_string::cis_string(const char* filename) {      /*! Check functionality, implementation is a long time ago !*/
    std::wifstream in(filename, std::ios::binary);  /* but should be fast anyway */

    in.seekg(0, std::ios_base::end);
    long size = in.tellg();
    in.seekg(0, std::ios::beg);

    data =  new wchar_t[size+1];
    in.read(data,size);
    data[size+1] = L'\0';
    anzahl = size;
}


cis_string::cis_string(const cis_string &str) {        // ... Default Copyconstruktor

    if (Debug >= 2)
        std::wcout << L"[Copyconstructor of class cis_string]" << std::endl;


      anzahl = str.anzahl;
      data = new wchar_t[anzahl+1];        // ... alle Buchstaben der cis_string Daten + Terminierende NULL
      wcsncpy(data, str.data, anzahl+1);

/*     if (Debug >= 2)  std::wcout << L"End Copyconstructor of class cis_string ...  this = ["
        << (*this).get_data() << L"]\tAnzahl = " << (*this).anzahl << std::endl;*/
}


cis_string::~cis_string() {
   //if (Debug >= 2) std::wcout << L"Delete" << std::endl;
    if (Debug >= 2)
        std::wcout << L"[Custom Destructor of class cis_string]" << std::endl;

   delete [] data;
   anzahl = 0;
 }


void cis_string::set_cis_string_data(const std::wstring &text) {
    anzahl = text.length();
    data = new wchar_t[anzahl+1];                         // ... alle Buchstaben der cis_string Daten
    wcsncpy(data,text.c_str(),anzahl+1);
}


int cis_string::get_anzahl_chars() const {
    return anzahl;
}


void cis_string::get_cis_string_data(std::wstring &text) {
    text.assign(data);
}


void cis_string::get_cis_string_data(std::wstring &text) const {
    text.assign(data);
}


std::wstring cis_string::get_cis_string_data() {
    return (std::wstring)data;
}

std::wstring cis_string::get_cis_string_data() const {
/*    const std::wstring tmp(data);
    return tmp;
*/
    return (std::wstring)data;
}


int cis_string::cis_string_to_upper() {
    for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (!iswupper(data[i]))
            data[i] = towupper(data[i]);
}


int cis_string::cis_string_to_lower() {
    for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (!iswlower(data[i]))
            data[i] = towlower(data[i]);
}


bool cis_string::first_is_upper() const {
    if (iswupper(data[0]))
        return true;
    return false;
}


void cis_string::translate() {
    for (int i = 0; i <= cis_string::get_anzahl_chars(); i++)
        if (iswupper(data[i]))
            data[i] = towlower(data[i]);
        else if (iswlower(data[i]))
            data[i] = towupper(data[i]);
}


void cis_string::operator++(int undef) {
    cis_string_to_upper();
}


void cis_string::operator--(int undef) {
    cis_string_to_lower();
}


std::wstring cis_string::operator++() {
    cis_string_to_upper();
    return (std::wstring)data;
}


std::wstring cis_string::operator--() {
    cis_string::cis_string_to_lower();
    return (std::wstring)data;
}

/*        dont use this for now!

bool cis_string::compare(cis_string &comparison) {
    std::wstring tmp = this->get_cis_string_data();
//     if (this->get_cis_string_data().compare(comparison) > 0)
    if (tmp.compare(comparison.get_cis_string_data()) < 0)
        return true;
    else
        return false;
}
*/

bool cis_string::operator<(const cis_string &comparison) const {
    cis_string first = *this;
    cis_string second = comparison;
    if (first.get_data() < second.get_data()) // std::string::operator<()
        return true;
    else
        return false;
}

bool austria_compare_w1_lt_w2 (std::wstring w1, std::wstring w2){ //Vergleich nach österreichischer Norm (Max)
  std::wstring alphabet(L"aäbcdefghijklmnoöpqrstuüvwxyzAÄBCDEFGHIJKLMNOÖPQRSTUÜVXYZ0123456789");
  bool comp_is_decided=false;
  bool is_lower=true;
  wchar_t letter_first,letter_second;
  size_t found_first,found_second;
  int i;
  i=0;
  while ((i<w1.size() && i<w2.size()) && !comp_is_decided) {
    letter_first = w1.at(i);
    found_first = alphabet.find(letter_first);
    letter_second = w2.at(i);
    found_second = alphabet.find(letter_second);
    if(found_first < found_second){
      comp_is_decided=true;
      is_lower=true;
    }
    else if(found_first == found_second) {
         }
         else {
           comp_is_decided=true;
           is_lower=false;
         }
    i++;
  }
  return is_lower;
}

bool austria_compare_cs1_lt_cs2 (cis_string cs1, cis_string cs2){ //Vergleich nach österreichischer Norm (Max)
    return austria_compare_w1_lt_w2(cs1.get_data(),cs2.get_data());
}

//struct sort1 {      /*  to be used as a sorting-criterion, e.g. map<cis_string, int, sort1>  */
//  bool operator()(cis_string s1, cis_string s2) const {
//    return s1 < s2;
//  }
//};


int cis_string::operator^(const cis_string &comparison) const {     /// ^ sortiert nach DIN 5007, Variante 2
    cis_string first  = *this;      /// ... und benutzt im Gegensatz zur Variante 1 die methode entferne_umlaute2()
               first.entferne_umlaute2();        // wegen const umgebaut
    cis_string second = comparison;
               second.entferne_umlaute2(); // wg. const

    if (first.get_data() < second.get_data())
        return true;
    else
        return false;

    return -1;  /// never reached
}

struct sort2 {
  bool operator()(cis_string s1, cis_string s2) const {
    return s1 ^ s2;
  }
};


bool cis_string::operator>(const cis_string &comparison) const {     /// > sortiert nach österreischer Sortier-Variante
// [...] und die Idee der „Österreicher“
//
// std::wstring char_ord[]=“aäbcdefghijklmnoöpq   …“
//
// mit jedem Buchstaben sucht man die Position im String,
//
// Die Position gibt die Prioritätenordnung aus, je kleiner, desto früher im Alphabet.
//
// Viele Grüße
//
// MAX

    std::wstring ord = L"AaÄäBbCcDdEeFfGgHhIiJjKkLlMmNnOoÖöPpQqRrSsTtUuÜüVvWwXxYyZz";    // NEW
    int i = 0;
    while (i < (*this).size()) {
        if (i < comparison.size()) {
            int ord1 = ord.find((*this)[i]);
            int ord2 = ord.find(comparison[i]);
            if (ord1 == ord2) {
                i++;
            } else if (ord1 < ord2) {
                return true;
            } else if (ord2 < ord1) {
                return false;
            }
        } else if (i == ((*this).size()-1))
            return true;
          else
            return false;
    }
}


struct sort3 {
  bool operator()(cis_string s1, cis_string s2) const {
    return s1 > s2;
  }
};


std::wstring cis_string::entferne_umlaute() {
    std::wstring tmp = this->get_cis_string_data();

    for (int i = 0; i < tmp.size(); ++i) {
        tmp.at(i) = towlower(tmp.at(i));
        if (tmp.at(i) == L'ä' )     tmp.at(i) = L'a';
        if (tmp.at(i) == L'ö' )     tmp.at(i) = L'o';
        if (tmp.at(i) == L'ü' )     tmp.at(i) = L'u';
        if (tmp.at(i) == L'Ä' )     tmp.at(i) = L'A';
        if (tmp.at(i) == L'Ö' )     tmp.at(i) = L'O';
        if (tmp.at(i) == L'Ü' )     tmp.at(i) = L'U';

        if (tmp.at(i) == L'ß' )   { tmp.at(i) = L's'; tmp.insert(i+1, L"s"); }    // geht jetzt.
    }
    return tmp;
}

std::wstring cis_string::entferne_umlaute2() {
    std::wstring tmp = this->get_cis_string_data();

    for (int i = 0; i < tmp.size(); ++i) {
        tmp.at(i) = towlower(tmp.at(i));
        if (tmp.at(i) == L'ä' )   { tmp.at(i) = L'a'; tmp.insert(i+1, L"e"); }
        if (tmp.at(i) == L'ö' )   { tmp.at(i) = L'o'; tmp.insert(i+1, L"e"); }
        if (tmp.at(i) == L'ü' )   { tmp.at(i) = L'u'; tmp.insert(i+1, L"e"); }
        if (tmp.at(i) == L'Ä' )   { tmp.at(i) = L'A'; tmp.insert(i+1, L"e"); }
        if (tmp.at(i) == L'Ö' )   { tmp.at(i) = L'O'; tmp.insert(i+1, L"e"); }
        if (tmp.at(i) == L'Ü' )   { tmp.at(i) = L'U'; tmp.insert(i+1, L"e"); }

        if (tmp.at(i) == L'ß' )   { tmp.at(i) = L's'; tmp.insert(i+1, L"s"); }
    }
    return tmp;
}


cis_string& cis_string::operator+(const cis_string &object) const {
  cis_string *tmp = new cis_string;
  tmp->set_data(this->get_data() + object.get_data());  // das '+' ist die Konkatenation aus der string-Klasse!
  return *tmp;  // Achtung! muss mit new alloziiert werden, da sonst Temporär
}


cis_string cis_string::operator=(const std::wstring &str) {
    this->set_data(str);
    return *this;
}


cis_string cis_string::operator=(const cis_string &object) {
    this->set_data(object.get_data());
    return *this;
}


cis_string cis_string::operator+=(const std::wstring &str) {
    std::wstring tmp = this->get_data();
    tmp += str;
    this->set_data(tmp);
    return *this;
}


/* Wo kommt das hier her? Darf operator* überhaupt überladen werden??? */
// cis_string& cis_string::operator*(cis_string &object) {
//     this->set_data(this->get_data() + object.get_data());       // das '+' ist die Konkatenation aus der string-Klasse!
//     return *this;
// }


wchar_t cis_string::operator[](const int &i) const {
    std::wstring str1 = get_data();
    return str1.at(i);
}

wchar_t cis_string::at(const int &i) const {
    std::wstring str1 = get_data();
    return str1.at(i);
}

bool cis_string::operator==(const cis_string &object) const {
    return this->get_data() == object.get_data();
}


bool cis_string::operator!=(const cis_string &object) const {
    return this->get_data() != object.get_data();
}


std::wostream&  operator<<(std::wostream &o, cis_string &object) {
    o << object.get_data();
    return o;
}

std::wostream&  operator<<(std::wostream &o, cis_string const &object) {
    o << object.get_data();
    return o;
}


std::wistream&  operator>>(std::wistream& in, cis_string &object) {
    std::wstring str;
    in >> str;
    object.set_data(str);
    return in;
}


int cis_string::size() const { return get_anzahl_chars(); }

int cis_string::length() const { return get_anzahl_chars(); }

void cis_string::get_data(std::wstring &dest) { dest.assign(get_cis_string_data()); }

std::wstring cis_string::get_data() { return get_cis_string_data(); }

std::wstring cis_string::get_data() const { return get_cis_string_data(); }

void cis_string::set_data(const std::wstring &text) { set_cis_string_data(text); }


cis_string cis_string::to_upper(const cis_string &str) {    // (Max)
    cis_string tmp;
    tmp = str;
    tmp++;
    return tmp;
}


bool compare_cis_string(const cis_string &c1, const cis_string &c2) {      // (Max)
  std::wstring w1=c1.get_data();
  std::wstring w2=c2.get_data();

    if (w1 < w2)
        return true;
    else
        return false;
}


bool equal_cis_string(cis_string c1, cis_string c2) {
  /*std::wstring w1=c1.get_data();
  std::wstring w2=c2.get_data();*/
  //std::wcout << "equal"<< w1 << "==" << w2 << std::endl;
    if (c1 == c2)
        return true;
    else
        return false;
}


#endif

}}}
version.extensions.tagCloud = {major: 1, minor: 0 , revision: 1, date: new Date(2005,8,16)};
//Created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman

config.macros.tagCloud = {
 noTags: "No tag cloud created because there are no tags.",
 tooltip: "%1 tiddlers tagged with '%0'"
};

config.macros.tagCloud.handler = function(place,macroName,params) {
 
var tagCloudWrapper = createTiddlyElement(place,"div",null,"tagCloud",null);

var tags = store.getTags();
for (t=0; t<tags.length; t++) {
  for (p=0;p<params.length; p++) if (tags[t][0] == params[p]) tags[t][0] = "";
}

 if(tags.length == 0) 
   createTiddlyElement(tagCloudWrapper,"span",null,null,this.noTags);
 //Findout the maximum number of tags
 var mostTags = 0;
 for (t=0; t<tags.length; t++) if (tags[t][0].length > 0){
  if (tags[t][1] > mostTags) mostTags = tags[t][1];
 }
 //divide the mostTags into 4 segments for the 4 different tagCloud sizes
 var tagSegment = mostTags / 4;

  for (t=0; t<tags.length; t++) if (tags[t][0].length > 0){
 var tagCloudElement = createTiddlyElement(tagCloudWrapper,"span",null,null,null);
 tagCloudWrapper.appendChild(document.createTextNode(" "));
 var theTag = createTiddlyButton(tagCloudElement,tags[t][0],this.tooltip.format(tags[t]),onClickTag,"tagCloudtag tagCloud" + (Math.round(tags[t][1]/tagSegment)+1));
  theTag.setAttribute("tag",tags[t][0]);
 }

};

setStylesheet(".tagCloud span{height: 1.8em;margin: 3px;}.tagCloud1{font-size: 1.2em;}.tagCloud2{font-size: 1.4em;}.tagCloud3{font-size: 1.6em;}.tagCloud4{font-size: 1.8em;}.tagCloud5{font-size: 1.8em;font-weight: bold;}","tagCloudsStyles");