Sky of flatfish


Requires Javascript.
比目魚的天空 - Linux 也藍藍的!!! - flatfish@2008         powered by TWtBala - TiddlyWiki 2.3.0
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

----
Also see AdvancedOptions
<<importTiddlers>>
Revision 3497
{{{
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,0)
#          kernel /boot/vmlinuz-version ro root=/dev/sda1
#          initrd /boot/initrd-version.img
#boot=/dev/sda

# 預設開機選項,第一項為編號 0
default=0

# 開機選單停留時間,單位為秒
timeout=5

# 開機選單背景圖
splashimage=(hd0,0)/boot/grub/splash.xpm.gz

# 是否開機選單設為隱藏
hiddenmenu

title CentOS (2.6.18-92.1.6.el5)
	root (hd0,0)
	kernel /boot/vmlinuz-2.6.18-92.1.6.el5 ro root=LABEL=/ rhgb quiet
	initrd /boot/initrd-2.6.18-92.1.6.el5.img
title CentOS (2.6.18-92.el5)
	root (hd0,0)
	kernel /boot/vmlinuz-2.6.18-92.el5 ro root=LABEL=/ rhgb quiet
	initrd /boot/initrd-2.6.18-92.el5.img
title CentOS (2.6.26.2 NEW!)
	root (hd0,0)
	kernel /boot/vmlinuz-2.6.26.2 ro root=LABEL=/ rhgb quiet
	initrd /boot/initrd-2.6.26.2.img
title Windows Server 2003 Enterprise Edition
        root (hd0,5)
        makeactive
        chainloader +1

}}}
!!這台機器的主機名稱
{{{
別名:               真1, 真2, ......
}}}
{{{
it:             eric, fisit:             eric, fish, flatfish, root
}}}

{{{
別名:              :include:檔案來源
}}}
{{{
sa:                 :include:/etc/sa.alias
}}}
*/etc/sa.alias
{{{
flatfish
fish
root
}}}
{{{
父目錄	組態檔
}}}
{{{
#
# $Id: auto.master,v 1.4 2005/01/04 14:36:54 raven Exp $
#
# Sample auto.master file
# This is an automounter map and it has the following format
# key [ -mount-options-separated-by-comma ] location
# For details of the format look at autofs(5).
#
/misc   /etc/auto.misc
#
# NOTE: mounts done from a hosts map will be mounted with the
#       "nosuid" and "nodev" options unless the "suid" and "dev"
#       options are explicitly given.
#
/net    -hosts
#
# Include central master map if it can be found using
# nsswitch sources.
#
# Note that if there are entries for /net or /misc (as
# above) in the included master map any keys that are the
# same will not be seen as the first read key seen takes
# precedence.
#
+auto.master

# 真的設定從這裡
/iii	/etc/iii.auto
}}}

<<slider /etc/iii.auto /etc/iii.auto /etc/iii.auto "">>
{{{
ddns-update-style interim;
ignore client-updates;

subnet 192.168.100.0 netmask 255.255.255.0 {

        range dynamic-bootp 192.168.100.128 192.168.100.134
        range dynamic-bootp 192.168.100.228 192.168.100.254;
        option subnet-mask              255.255.255.0;
        option routers                  192.168.100.1;
        option domain-name-servers      192.168.100.1;

# --- default gateway

#       option nis-domain               "domain.org";
#       option domain-name              "domain.org";

#       option time-offset              -18000; # Eastern Standard Time
#       option ntp-servers              192.168.1.1;
#       option netbios-name-servers     192.168.1.1;
# --- Selects point-to-point node (default is hybrid). Don't change this unless
# -- you understand Netbios very well
#       option netbios-node-type 2;

        default-lease-time 21600;
        max-lease-time 43200;

        # we want the nameserver to appear at a fixed address
       host ns {
               hardware ethernet 12:34:56:78:AB:CD;
               fixed-address 192.168.100.168;
#       }
}
}}}
{{{
匯出的目錄	目的(選項)
}}}

{{{
/tmp		192.168.33.0/255.255.255.0(rw,async,no_root_squash)
}}}

*rw / ro
*async / sync
*權限:
##no_root_squash
##root_squash
##all_squash
*anonuid=###
*anongid=###
!!主機名稱解析的順序
{{{
order hosts,bind
}}}
*實際功能被 /etc/nsswitch.conf 取代
!!php 組態設定
*LoadModule 模組名稱 模組檔案

*該檔案是安裝 php 套件時,由 php 提供給 apache 用在 Include 參數用

*php.conf 內仍有 DirectoryIndex index.php
**根據 Include conf.d/php.conf 與原先 DirectoryIndex index.html 的出現前後決定優先權
***建議註解掉 php.conf 中的 DirectoryIndex,並由 httpd.conf 統一控管
{{{
子目錄	選項	資源裝置
}}}

{{{
s34	-rw	192.168.33.34:/tmp
s38	-rw	192.168.33.38:/tmp/QQQ
s149	-rw	192.168.33.149:/tmp
}}}
!!本機登入前的訊息
!!遠端登入前的訊息
{{{
# see "man logrotate" for details
# rotate log files weekly
# 每週執行一次
weekly

# keep 4 weeks worth of backlogs
# 保留最近四週的備分 log 檔,一週一檔
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp -- we'll rotate them here
/var/log/wtmp {
    monthly
    minsize 1M
    create 0664 root utmp
    rotate 1
}

# system-specific logs may be also be configured here.
IP {//RELAY, DISCARD, REJECT//}
*Timeout.queuewarn=4h
*Timeout.queuereturn=5d
*DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl
**限制僅有本機能使用 SMTP 服務
{{{
m4 sendmail.mc > sendmail.cf
}}}
!!以上為考試解答
*service sendmail restart 已含有 script 將 m4 sendmail.mc 執行並作備份
!!登入之後出現的訊息檔
{{{
# 文章 10 天後過期
/remember/:10

# 所有群組(*)文章最短保留 1 天,預設 10 天,最長不限 (never)
*:A:1:10:never
}}}
{{{
mta:			mta 程式,透過 mta 傳送新聞


server:		伺服器位址( IP 或 FQDN )
bindaddress:	繫結 IP
}}}
{{{
# 加入允許服務的網段
auth "localhost" {
    hosts: "localhost, 127.0.0.1, 192.168.33.0/24, stdin"
    default: "<localhost>"
}

# 使用者允許閱讀(R)、貼文(P)、全部(A)
access "localhost" {
    users: "<localhost>"
    newsgroups: "*"
    access: RPA
}
}}}
*變更時區 
{{{
/usr/share/zoneinfo
找出所需要的時區檔案複製到 /etc/localtime
}}}

*/etc/ntp.conf
{{{
# Permit time synchronization with our time source, but do not
# permit the source to query or modify the service on this system.
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery

# Permit all access over the loopback interface.  This could
# be tightened as well, but to do so would effect some of
# the administrative functions.
restrict 127.0.0.1
restrict -6 ::1

# Hosts on local network are less restricted.
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 0.centos.pool.ntp.org
server 1.centos.pool.ntp.org
server 2.centos.pool.ntp.org

#broadcast 192.168.1.255 key 42         # broadcast server
#broadcastclient                        # broadcast client
#broadcast 224.0.1.1 key 42             # multicast server
#multicastclient 224.0.1.1              # multicast client
#manycastserver 239.255.254.254         # manycast server
#manycastclient 239.255.254.254 key 42  # manycast client

# Undisciplined Local Clock. This is a fake driver intended for backup
# and when no outside source of synchronized time is available.
server  127.127.1.0     # local clock
fudge   127.127.1.0 stratum 10

# Drift file.  Put this in a directory which the daemon can write to.
# No symbolic links allowed, either, since the daemon updates the file
# by creating a temporary in the same directory and then rename()'ing
# it to the file.
# 時間偏移值
driftfile /var/lib/ntp/drift

# Key file containing the keys and key identifiers used when operating
# with symmetric key cryptography.
keys /etc/ntp/keys

# Specify the key identifiers which are trusted.
#trustedkey 4 8 42

# Specify the key identifier to use with the ntpdc utility.
#requestkey 8

# Specify the key identifier to use with the ntpq utility.
#controlkey 8
}}}
rsync 伺服器主機設置
{{{
# 自訂的備份主機名稱
[bk1]

# 存放備份檔案的目錄
	path = /tmp/bk/bk1

# 提供 client 做身分驗證的使用者帳號
	auth users = bkuser1

# 執行製作備份檔案的身分
	uid = root
	gid = root

# 密碼檔
	secrets file = /etc/rsyncd.passwd

# 是否設定為唯讀
	read only = no
}}}
{{{
# 全域設定
[global]
	key = value
	:
	:
[      ]
}}}
!!key
*workgroup
*netbios name
*security
**share: 簡易分享模式,使用 guest 帳號
**user: Linux 上帳號為主
***預設進入個人的家目錄
**domain

{{{
[global]
	workgroup = workgroup
	netbios name = flatfishsamba
	security = share

[myshare]
	path = /tmp
	public = yes
	writable = yes
	guest ok = yes
	browseable = yes
	guest account = abc
	create mode = 0644
	directory mode = 0700
}}}
*guest account = {//Linux_account//}
*create mode = {//permission_mode//}
*directory mode = {//permission_mode//}

!!user 模式
*鳥哥 P.20-25
*密碼避免與本機帳戶密碼相同
*密碼另外儲存
*<<slider smbpasswd smbpasswd [[smbpasswd -a flatfish]] "">>
{{{
[global]
	workgroup = workgroup
	netbios name = bradsamba
	security = user
	guest account = abc
	
	encrypy passwords = yes
	smb passwd file = /etc/samba/smbpasswd

[homes]
	browseable = yes
	writable = yes

[myshare]
	path = /tmp
	public = yes
	writable = yes
	guest ok = yes
	browseable = yes
	guest account = abc
	create mode = 0644
	directory mode = 0700

}}}

!!分享印表機
{{{
[printers]
	path = /var/spool/samba
	browseabke = yes
	guest ok = yes
	writable = no
	printable = yes
}}}
*http_port {//開啟服務的連接埠//}
**預設 3128
*icp_port 3130
*cache_peer 設定父子、同輩關係
**cache_peer hostname type http_port icp_port [options]
*cache_mem {//mem_size//}
**預設 8 MB
*cache_swap_low
*cache_swap_high
**swap cache 最少預設 90%,最大到 95%
*maximum_object_size
**每一個 cache 的物件最大限制
*cache_dir {//針對存放物件的檔案系統//} {//實際目錄//} {//容量大小//} {//第一階目錄數//} {//第二階目錄數//}
**Proxy server 的檔案系統:ufs、aufs
**實際目錄:實際運作使用一個獨立分割區
**容量大小,單位為 MB
**第一階目錄、第二階目錄:避免所有物件都存放在一個目錄下,經實測 16 256 的效能最佳
**cache_dir ufs /var/spool/squid 100 16 256
*cache_store_log
*http_access:存取控制

{{{
#       $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options change a
# default value.

#Port 22
#Protocol 2,1       # 使用兩種加密協定,先 2 後 1
Protocol 2            # 加密協定:較複雜的 1024bits 加密
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

# HostKey for protocol version 1
#HostKey /etc/ssh/ssh_host_key
# HostKeys for protocol version 2
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key

# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 1h
#ServerKeyBits 768

# Logging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6

#RSAAuthentication yes
#PubkeyAuthentication yes
#AuthorizedKeysFile     .ssh/authorized_keys

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no
# similar for protocol version 2
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
PasswordAuthentication yes

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no

# GSSAPI options
#GSSAPIAuthentication no
GSSAPIAuthentication yes
#GSSAPICleanupCredentials yes
GSSAPICleanupCredentials yes

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication mechanism.
# Depending on your PAM configuration, this may bypass the setting of
# PasswordAuthentication, PermitEmptyPasswords, and
# "PermitRootLogin without-password". If you just want the PAM account and
# session checks to run without PAM authentication, then enable this but set
# ChallengeResponseAuthentication=no
#UsePAM no
UsePAM yes

# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL
#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10
#PermitTunnel no

# no default banner path
#Banner /some/path

# override default of no subsystems
Subsystem       sftp    /usr/libexec/openssh/sftp-server
}}}
{{{
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.*                                                 /dev/console

# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
# 記錄系統大小訊息,除了 mail, news, authpriv, cron
*.info;mail.none;news.none;authpriv.none;cron.none              /var/log/messages

# The authpriv file has restricted access
# 紀錄登入訊息
authpriv.*                                              /var/log/secure

# Log all the mail messages in one place.
# 『 - 』代表該 log 不需要同步,可以事後再做,減輕負擔
mail.*                                                  -/var/log/maillog


# Log cron stuff
cron.*                                                  /var/log/cron

# Everybody gets emergency messages
*.emerg                                                 *

# Save news errors of level crit and higher in a special file.
uucp,news.crit                                          /var/log/spooler

# Save boot messages also to boot.log
local7.*                                                /var/log/boot.log

#
# INN
#
# 『 .= 』僅有這個優先等級做紀錄
news.=crit                                        /var/log/news/news.crit
news.=err                                         /var/log/news/news.err
news.notice                                       /var/log/news/news.notice
}}}
!!不放進檔案系統資料庫的檔案系統類型、目錄
{{{
PRUNEFS = "auto afs iso9660 sfs udf vmhgfs"
PRUNEPATHS = "/afs /media /net /sfs /tmp /udev /var/spool/cups /var/spool/squid /var/tmp"
}}}
{{{
key=value
}}}
{{{
# 是否允許匿名
anonymous_enable=YES

# 是否允許帳號登入
local_enable=YES

#
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES

# 主動模式,使用 port 20
connect_from_port_20=YES
xferlog_std_format=YES

# 自己聽 → 獨立伺服器
listen=YES

pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
}}}
{{{
# default: off
# description: The rsync server is a good addition to an ftp server, as it \
#       allows crc checksumming etc.
service rsync
{
# 要啟用 rsync 記得將 disable = yes 改成 no
        disable = yes 
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync
        server_args     = --daemon
        log_on_failure  += USERID
}
}}}
{{{
# default: on
# description: The telnet server serves telnet sessions; it uses \
#       unencrypted username/password pairs for authentication.
service telnet
{
        flags           = REUSE
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/sbin/in.telnetd
        log_on_failure  += USERID
        disable         = yes
        only_from       = 192.168.33.128   # 允許名單
        no_access		= 192.168.33.0/24		# 禁止名單
        instances		= 4		# 連線上線
        redirect		= 192.168.33.129	# 重導向
           bind         = 192.168.33.50
	
}
}}}
*disable = yes 表示停用,要啟用則輸入 no
*改完組態檔要重新啟動 xinetd
{{{
ddns-update-style interim;
ignore client-updates;

subnet 192.168.0.0 netmask 255.255.255.0 {

# --- default gateway
        option routers                  192.168.0.1;
        option subnet-mask              255.255.255.0;

        option nis-domain               "domain.org";
        option domain-name              "domain.org";
        option domain-name-servers      192.168.1.1;

        option time-offset              -18000; # Eastern Standard Time
#       option ntp-servers              192.168.1.1;
#       option netbios-name-servers     192.168.1.1;
# --- Selects point-to-point node (default is hybrid). Don't change this unless
# -- you understand Netbios very well
#       option netbios-node-type 2;

        range dynamic-bootp 192.168.0.128 192.168.0.254;
        default-lease-time 21600;
        max-lease-time 43200;

        # we want the nameserver to appear at a fixed address
        host ns {
                next-server marvin.redhat.com;
                hardware ethernet 12:34:56:78:AB:CD;
                fixed-address 207.175.42.254;
        }
}
}}}
{{{
群組名稱 文章篇數 第幾篇文章開始 啟動與否
}}}
{{{
-sh-3.2$ cat active
control 0000000000 0000000001 n
control.cancel 0000000000 0000000001 n
control.checkgroups 0000000000 0000000001 n
control.newgroup 0000000000 0000000001 n
control.rmgroup 0000000000 0000000001 n
junk 0000000000 0000000001 n
}}}
<<toBalaManager>>































































///%

比目魚的天空 - Linux 也藍藍的!!!

''flatfish''@2008 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;powered by TWtBala - TiddlyWiki 2.3.0

<<tagsTree system "" 1 4 index label>>
<<tagsTree os "" 1 4 index label>>
<<tagsTree pb "" 1 4 index label>>
<<tagsTree kl "" 2 4 index label>>
<<tagsTree supplement "" 1 4 index label>>
<<tagsTree twcms "" 1 4 index label>>
<<tagsTree KMKConfig "" 1 4 index label>>
<<tabs txtMainTab "最近更新" "依更新日期排序" TabTimeline "分類" "所有標籤" TabTags "設定文章" "說所有設定文章" TabMoreShadowed>>

<<search>> | [[首頁]] | [[土芭樂 3.0 - 數位新思路|http://tbala.net/]]  |  [[鳥哥的 Linux 私房菜|http://linux.vbird.org/]]  |  <<newTiddler label:"新增文章">>  <<saveChanges>> 
//%/
<<list shadowed>>
<<forEachTiddler
    script '
        window.fetItemsPerPage = 15;

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

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

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

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

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

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

        begin
            'getHeader(context,count)'
>>

// /%
With a little scripting you can use the ~ForEachTiddlerPlugin to display the result "by pages". I.e. you don't display the full result list, but (e.g.) 10 at a time. 
Using a "pagewise" display may be useful when the result may get very large. This way you avoid scrolling the window to see the result. It also speeds up things since less items need to be display at a time.

''Code''
{{{
<<forEachTiddler
    script '
        window.fetItemsPerPage = 10;

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

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

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

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

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

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

        begin
            'getHeader(context,count)'
>>
}}}
// %/





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


<<forEachTiddler 
 where
   'tiddler.tags.contains("macro")'
>>
<<forEachTiddler 
 where
 'tiddler.tags.length == 0'
>>


轉錄自[[billypan101大作|http://www.wretch.cc/blog/billypan101/8891814]]

本文為ubuntu 7.04版,新版7.10的USB安裝法大致相同。另有7.10版裝至硬碟之詳細說明請參考
打死不買Vista,暫時留觀XP,開始學用Ubuntu 7.10之新手完全指南

這篇文章裏,我會非常清楚,一步一步地把如何在一隻4Giga的隨身碟上,安裝最新的ubuntu 7.04版詳細步驟寫出來。

Ubuntu是新一代的Linux作業系統,在國外被認為已經可以取代Windows 作業系統。圖型介面漂亮,必要的功能俱全。最重要的是,它完全免費,不光是作業系統,連用軟體都不必錢。

為什麼要裝在USB隨身碟上?我相信這是一項革命。因為,你可以把所有的軟體帶著走,包括你瀏覽器上的書簽,Cookies,軟體中的特別的設定,你不必在每一台電腦上重新來一次。你不必提著重重的筆記型電腦。更重要的是,你不必每一套軟體裝在每一台電腦上都要再一次合法授權。Ubuntu做的到,它不必安裝,幾乎大部份的PC都可以放上去就用。

如何裝Live Cd版本在網路上已經有人寫過了,不過我現在寫的是裝完整的版本。你可以把新的軟體套件再安裝進去USB,帶了就走,在任何一台個人電腦上使用。工作到一半,你就簡單的存檔,關機,帶走USB隨身碟,離開,插進另一台隨便什麼電腦,開機,叫出存檔,繼續工作。這不是很棒嗎?

我知道你沒玩過Linux,不要怕,就是要把你騙過來,這篇文章就是寫給你看的。Ok,開始了。準備工作

1。你需要上網抓ubuntu 7.04版的CD-ROM安裝光碟iso檔,ubuntu的正體中文官網在 http://www.ubuntu.org.tw/,
一般所用的PC (intel x86)安裝光碟iso版在此 http://tw.archive.ubuntu.com/ubuntu-releases/7.04/ubuntu-7.04-desktop-i386.iso
抓下來,以燒錄軟體燒成一張光碟,這張光碟就可以直接開機執行一般的工作,它也可以拿來安裝。也有AMD,甚至Mac的版本,官網上都有。

2。你必需要有一隻隨身碟,至少要有4G。當然你也可以把ubuntu安裝在硬碟上,可以和winodws系統並存,不過這在ubuntu官網上有詳細的說明,就不是本文的目的了。
我因此去買了一隻宇瞻Apacer AH320 4G的隨身碟,在順發買的,定價1190元。它是賣場上最便宜的一隻,最重要的是它標明了和Linux相容。



光碟燒好,隨身碟準備好,還要了解電腦開機啟動程序一下。先別急著裝,下面這段如果你不太熟,多看幾遍。因為過程中無法上網,會不知道怎麼辦。如果你已很熟,可以跳到ubuntu開機畫面那兒。

我們先把光碟放進DVD/CD Player,隨身碟插入USB裏。退出windows,重新開機。一般的主機版,按下電源開機之後,馬上按『Delete』鍵,就會進入到bios設定程序之中。


此時按『Delete』


出現設定畫面,每一台的畫面可能不一樣,這台我們要設定在"Advanced BIOS Feature"裏,按『Enter』鍵進去。


裏面 First Boot Device (第一開機設備)就是我們要設定的,按『Enter』,出現下面那個框,先選"CDROM",按Enter。連按兩次ESC鍵出去,選擇存檔Yes,就會開始以光碟開機。另外第二第三開機先設成Disabled,硬碟,Windows暫時拋棄在一邊。建議其它USB隨身碟和記憶卡也先拔掉,免得安裝搞混。

運氣好的話(一般是不錯),Ubuntu就載入了。

這是英文介面,30秒之內,按下『F2』,出現語文選單,選最後一個"繁體中文"。(為什麼在最後?每次出國回來,到台灣的班機登機門都是最後的那個,超遠,為什麼?)




按第一個進入。

這樣正體中文的ubuntu 7.04就載入了。這版叫雀躍不已的小鹿,是不是你現在的心情?

進入之後,全新的介面,怎麼辦??放心,有我在。最後學這個:

在畫面上紅色箭頭所指的地方就是瀏覽器Firefox,如果你沒用過也OK,幾乎和IE一樣。要學這個,主要的是你在開機後,就把它打開,在網址輸入:
http://www.wretch.cc/blog/billypan101
這樣就能回到這篇文章,一步一步來做下去了,所以,那個網址,給我背起來!! (抄起來也可以啦....)

所以呢,學會了也背好了,就正式開始吧。Ubuntu通常一開機就能上網,後面有我罩著,別怕。現在就去下載那個iso檔,趁這個空檔去買一隻4G的隨身碟。宅男偶而也要出門,快去!!

你回來了?在ubuntu看到這篇文章了?很好,那個Firefox的plug-in先不必管它。我們先來確定幾件事。
1.。桌面上有Install的圖示。如果沒有,你就是不聽話去下載了別的版本,(LiveCD?),出去再抓過。
2。先來確定USB隨身碟的代號,按上面的 "Places",選"Desktop"


按一下上面"Computer的圖示",看到有"USB FLAS DRIVE:"的那個圖示了嗎?

那個圖示下面有寫 "disk-1"(你的可能是disk或別的),通常這玩意兒也會出現在桌面,抄下這代號,我們不要弄錯。

3。再來的步驟有點詭異,但很必要,首先,點選畫面上方的 "Application","附屬應用程式",執行"終端機",如下圖:


通常Linux新手在這裏會被嚇壞,又不敢上網問,會被笑。其實也沒什麼,這和windows下的執行,cmd,跳進DOS視窗差不多。

在這個終端機視窗中,鍵入
『sudo -i』按Enetr,再鍵入
『sudo gedit』按Enter。目的是以root權限開啟gedit這個程式


你辦到了?真勇敢。詭異的來了,在gedit中鍵入『billypan』,然後選擇存檔,檔名也叫『billypan』,存檔位置,如下圖存在我們確定過是usb隨身碟的那個地方。(我的是disk-1,你的有可能是別的),一定要確定存到USB隨身碟。成功了關掉gedit出去。


billypan??別罵髒話,我是有點自戀,不過這麼做是有苦心的。這些步驟不能出錯,有錯會讓你抓狂的。
再來我們要再進終端機這個程式一次,如下圖在 "ubuntu@ubunru:~$" 之後,這次鍵入『sudo grub』按Enter。


在"grub >"符號後,鍵入『find /billypan』按Enetr:


畫面上出現的 "(hd2,0)" 就是我們要記下的另個東西。你的可能是 "(hd1,0)" 或別的,總之抄下來,這非常重要。
關掉終端機視窗,再執行一次,這次我們換鍵入『sudo fdisk -l』按Enter:

再一次確定隨身碟的代號是 "/dev/sda"(因為後面是4127M,你硬碟不會這麼小吧。)。你的可能是別的,比方 "/dev/sde" 等等。抄下來。退出終端機視窗。

所以我們總共確定了,USB隨身碟竟然有三個代號,(我的分別是 disk-1, (hd2,0), /dev/sda,你的可能是另一組),Linux系統要樣搞我也沒辦法。這三個代號你的和我的可能不一樣。弄清楚,下面的就容易了。

再來就是安裝了。關掉所有視窗,按桌面上的那個Install的圖示。進入安裝步驟:

STEP 1: 不會出錯,按下一頁:


STEP 2: 不會出錯,按下一頁:


STEP 3: 不會出錯,按下一頁:


STEP 4: 會出錯!!小心:


如果要安裝在硬碟,就選預設選項。我們要裝隨身碟,該是選導引,SCSI1那個選項。可是我選這個沒有反應,不給裝。網路上我看文章有人成功的,我不知道是不是用這個裝。我的APacer AH320隨身碟可是有標Linux相容的,而且,最後我也裝成了,但這兒就是不行。也許別的隨身碟可以,也許ubuntu正不給裝。山不轉路轉,我們改由手動:


按下一頁,看到 "/dev/sda"了嗎,這我們確定過,是我們的隨身碟。點它,按 "New partition table" 那個圖示。


出現詢問視窗,按 "繼續"


再來要開始規劃磁碟分區,把游標移到 "free space" 上,按 "New Partition" 那個圖示:

有點可怕,對不對?這是隨身碟,怕什麼。在上面 "New partion size in megabytes"的空欄位中,填入『3500』,表示要用掉 3500M=3.5G。你也可以填入別的數字,不過一定要大於2000。下面 "Mount point:" 空欄中,填入『/』,就是我們通常在網址上用的那條斜線。畫面最後像上面的那樣,對照清楚了,按右下 "OK"。


在 "/dev/sda1" 下面出現了另一個 "free space",點它,再按 "New partition",這次出現的視窗中,分割大小(partiton size)和掛載點(mount point)不必去管他,預設就Ok,我們要改的的格式是 "use as ",點空白欄的右邊那個有小小的上下箭頭符號的地方,如下圖選擇 "swap":


這樣步驟4大底搞定。畫面如下,再來按 "下一頁":


STEP 5: 這裏可以匯入原先在Windows XP中的Documents and Setting一些設定,打勾填入原先Windows XP帳號密碼它就會去抓。Ubuntu想要取代Windwos的陰謀在此昭然若揭,都說了這是一場革命了。不過我現在不要讓事情太複雜化,你要玩,可以,不然,就直接按 "下一頁"過去。


STEP 6: 填入在未來的新系統上要用的帳號和密碼。這裏就不必寫 billypan了,寫你自已的名字吧。密碼兩次要一樣。填好,按下一頁


STEP 7: 會出錯!! 小心!!
這一步是最 後,網路上有網友敗在這裏。關鍵在右下面那個 "Advanced" 圖示,你要把它按出來:


出現詢問視窗:問你要把開機程式裝在那裏?

記得我之前要你找的USB硬碟的代號嗎?那一組三個之中,有一個正是 (hd2,0),這是我的,你自已的或許是 (hd1,0)或 (hd3,)等,把你的代號填進去!!

這裏弄錯,grub往機程式就會去裝在別的地方而不是USB 隨身碟上。如果裝錯,下次進windows xp可能出現 Grub Error 21 的代號。那也沒什麼,以windows xp安裝光碟開機,進入修復主控台,在 c:\windwos>下打『fixmbr』就能修好了。不過,我們可不要這種麼麻煩。

空欄預設是(hd0,0),把它改成你自已的usb隨身碟代號 (hd2,0) 或是(hd1,0).........,這樣才能直接用隨身碟開機玩。之後按按確定。

這個改完,就按Step 7 最後面的Install圖示,開始安裝,這要一點時間。


這時候隨身碟的led燈應該閃個不停。如果你是硬碟的燈在一直閃,那一定是沒有照我的步驟,搞不好是裝到硬碟去了....這也不必難過,乾脆以後就自暴自棄的投入ubuntu的懷抱,把 windows xp給忘了吧.....(什麼?你硬碟裏的A片還沒有copy出來?沒關係,ubuntu也可以用BT,再抓就有了....)

裝完後畫面消失,船過水無痕。最後我們還要進行一步,把grub開機程式設成USB隨身碟。
再一次打開終端機視窗,鍵入『sudo -i』,按Enter,再鍵入『sudo gedit』按Enter:


這次在gedit視窗中,我們要去開啟位在 "disk-1"的檔案。它在子目錄\boot\grub\之下,打開 menu.lst這個檔案:


開啟之後, 按上面的 "Search",選擇 "Replace..."這個功能:


把那個 (hd2,0) (再提醒一次,你的代號可能是別的),填入 "Search for" 空欄中..
下面那個 "Replace with",就直接填入 (hd0,0),意思是要以隨身機當第一開機選項。
填好後按 "Replaced All"圖示,然後在gedit中存檔,出去。


這樣基本上大功告成。按畫面最右上角那個紅色圖示,關機了。

重開機時按delete,我們把開機裝置改成USB-HDD。其它的第2第3設備都選disable,這樣,就進入我們的隨身系統了。


開機時會先進入Grub的選項,按預設項目進入,不然等10秒也可以。開機我算過,大概是120秒。還不錯。我現在正用這個 USB系統上網打部落格的,現在我的桌面如下:


你可以看到,我加裝套件後,youtube可以上,嘸蝦米可以用,可以看.rmvb檔。桌面可以到和Windwos xp十分接近。至於怎麼做,那是下一帖了。網路上文章也不少。現在,我已經愛上ubuntu,決定不買Vista了。(ubuntu也有3D桌面)

最後還有一點。我把這隻UCB隨身碟帶去辦公室的電腦,改bios,開機:





系統完全正常運作,就和在家裏的一樣。youtube,書簽,嘸蝦米,桌面完全一樣。這可不是LiveCD能做到的。隨身免費完整作業系統終於大功告成。

這時候,眼淚不禁流了出來......

本文歡迎在非商業用途下自由引用轉載,但請註明出處。

2007/05/05 補充: 移到第二台電腦時,有時會出現顯卡不相容的問題,這有解決方法,在此: 把我們的 Ubuntu 7.04 USB 隨身作業系統改造成任何電腦都能開機




轉錄自http://www.wretch.cc/blog/billypan101/8891814
acl all src 0.0.0.0/0.0.0.0
acl gooddomain dstdomain .iii.org.tw
acl goodguy src 192.168.33.50-192.168.33.150
acl goodtime time M 11:28-11:30

http_access allow goodtime
http_access allow goodguy
http_access allow gooddomain
http_access deny all
tar -zxvf 
./xxxx.pl
*對象:文字檔 (STDOUT)
*處理後:終端機顯示,不改變元檔案
**利用管線、輸出入重導向
***管線:交給一個指令繼續處理,例如 grep
***輸出入重導向的結果是一個目的地,例如檔案
*1>:重新導向 STDOUT
**可省略為 >
*2>:重新導向STDERR
**2>&1:與 1> 的導向相同
<<slider [[ls /]] [[ls /]] [[ls /]] "">>
<<slider [[ls / /home]] [[ls / /home]] [[ls / /home]] "">>
<<slider [[ls / /hom123]] [[ls / /hom123]] [[ls / /hom123]] "">>
<<slider [[ls / /hom123 1> /tmp/ls.1 2> /tmp/ls.2]] [[ls / /hom123 1> /tmp/ls.1 2> /tmp/ls.2]] [[ls / /hom123 1> /tmp/ls.1 2> /tmp/ls.2]] "">>

*echo $?:上一道指令的傳回值
**相當於 Windows 下的 %errorlevel%
**ls / /hom123:echo $? 會顯示錯誤
**0:正常
**非0:錯誤
*<<slider head head head "">>
*<<slider tail tail tail "">>
*觀看檔案第 11-20 列
{{{
tail -n 20 test1 | head
}}}
*<<slider cut cut cut "">>
*<<slider tr tr tr "">>
*利用 cut + tr 顯示所有帳號、UID、GID
{{{
cut -d":" -f1,3,4 /etc/passwd | tr ":" "\t"
}}}
*<<slider split split split "">>
*<<slider expand expand expand "">>
*<<slider fmt fmt fmt "">>
*<<slider pr pr pr "">>
*<<slider sort sort sort "">>
*<<slider uniq uniq uniq "">>
**{{{sort mypasswd | uniq}}} 與 {{{uniq mypasswd | sort}}} 結果不同
| / |bin |binary |二進制指令檔、工具 |
|~|sbin |system binary |系統管理員專用的指令檔 |
|~|boot |boot |啟動BOOT相關、GRUB |
|~|dev |device |裝置檔案、目錄 |
|~|etc |etc |系統組態檔 |
|~|home |home |使用者的家目錄 |
|~|lib |libary |共享函式庫 |
|~|lost+fount|||
|~|media |media |儲存媒體 |
|~|mnt |mount |外掛裝置 |
|~|opt ||相依關係小的程式 |
|~|selinux |security linux | |
|~|srv |service |對外的服務:(web、ftp)... |
|~|tmp |temp |暫存區 |
|~|usr |usr |應用程式,相當於 program files |
|~|var |variable |變動性的檔案:例如 log、佇列、(Red Hat包含web、ftp)、資料庫 |

*/etc/X11/xorg.conf
**重要的組態設定檔,包含輸出入裝置資訊
*Linux 採 UTF-8 格式,一個中文字佔 3 個 bytes
!模組 (module)
#driver
#協定、服務
#filesystem
/etc/modprobe.conf
/etc/services:網路服務 Well Known 連接埠

!網路設定
/etc/sysconfig/network-scripts/
ifcfg-eth0:第一章乙太網路卡的設定
*DEVICE={//device_alias//}
*BOOTPROTO=[//dhcp,static//]
*HWADDR={//MAC address//} → 除非機器上有兩張相同網卡,否則建議不寫
*ONBOOT=[//yes, no//]
*IPADDR={//IP address//}
*NETMASK={//Subnet mask//}
*GATEWAY={//gateway IP//}
*NETWORK={//子網段//} → 建議不寫,多寫多錯
*BROADCAST={//廣播位址//} → 建議不寫,多寫多錯
設定完執行 ''service network restart''

!!DNS 設定
/etc/hosts:靜態 NS 對應表
/etc/resolv.conf:DNS server 主機位址
/etc/nsswitch.conf:設定 DNS 切換設定組態檔
{{{
#hosts:     db files nisplus nis dns
hosts:      files dns
}}}
*優先順序:Hosts > DNS server
*要啟動 DNS cliend cache:執行 ''nscd''
**組態檔:/etc/nscd.conf
*套件:bind / bind-chroot
**bind-9.3.4-6.P1.el5
**bind-chroot-9.3.4-6.P1.el5
**bind-utils-9.3.4-6.P1.el5

*服務名稱:name@@color:red;d@@
*主要組態檔:@@color:red;/@@etc/named.conf @@color:yellow;← 考試答案@@
**為了安全考量,bind-chroot 會將 / 根目錄改變位址
**參閱 /etc/sysconfig/named
***ROOTDIR=/var/named/chroot
{{{
[root@localhost chroot]# pwd
/var/named/chroot
[root@localhost chroot]# ll
總計 24
drwxr-x--- 2 root named 4096  8月  5 09:37 dev
drwxr-x--- 2 root named 4096  8月  5 09:37 etc
drwxr-x--- 6 root named 4096  8月  5 09:37 var
[root@localhost chroot]#
}}}

*找出 bind 套件已安裝的 named.conf 範本
**rpm -ql bind | grep named.conf
***/usr/share/doc/bind-9.3.4/sample/etc/named.conf 

*named.conf 格式
{{{
設定名稱 {
	key	value;
	子項目{
		key	value;
	};
};
}}}

!建置新的 named.conf 組態設定檔
*切換工作目錄至 ''/var/named/chroot/etc/''
*先從根找起
{{{
zone "." {
        type hint;
        file "";
};
}}}
*下載 Root hint (named.root)
{{{
ftp ftp.internic.net
anonymous
bearflatfish@gmail.com
cd domain
get named.root
bye
}}}
*指定 Root hint 檔案位址
**file @@color:red;"/etc/named.root"@@;
***還記得嗎:bind-chroot 已經幫我們把根目錄改到 /var/named/chroot/,因此這個檔案的來源要寫 /etc/named.root

!建立一個 Master zone
*編輯 named.conf
{{{
zone "flatfish.net" {
        type master;
        file "";
};
}}}
*建立 zone file
**範本 /usr/share/doc/bind-9.3.4/sample/var/named/localhost.zone
*建議將擁有群組改為 named,權限設為 640

!Zone file 詳細說明
*主機名稱可輸入絕對名稱,但需要輸入最後一個『 . 』,不然最後會再加上網域名稱
*NS 紀錄
**名稱可不填,或是填上 @,代表本網域
**內容輸入負責本網域的 Name server 之 FQDN,或是填上 @
***要輸入絕對名稱,例如『 www.flatfish.net@@color:red;font-size:1.2em;.@@ 』
|主機名稱|紀錄類別|優先權|對應主機名稱|
||IN NS|| @ |
*A 紀錄
**主機名稱不輸入則代表本網域對應到該 A 紀錄的 IP 位址
**同一個 A 紀錄名稱可以建立多筆 A 紀錄,client 查詢時以 Round robin 方式輪替回應查詢結果
***會有一個特定順序
|主機名稱|紀錄類別|優先權|對應主機名稱|
|www|IN A||192.168.100.128|
|www|IN A||192.168.100.129|
|www|IN A||192.168.100.130|
*MX 紀錄
**主機名稱輸入 @
|主機名稱|紀錄類別|優先權|對應主機名稱|
| @ |IN MX| 10 |ms1.flatfish.net|

!!SOA 紀錄
|網域|IN SOA|主機名稱(從根表示起的絕對名稱)|負責帳號|五個參數|
*參數若要換行,五個參數以小括號包起來
**serial:版本數 / 序號 (自訂),可到 2^^32^^
***習慣上用日期加上兩碼流水碼表示,例如 2008081301 為 2008 年 8 月 13 日第一次更新
**refresh:通知 slave 每隔 refresh time 向 master 詢問是否有更新
**retry:refresh 失敗時,每隔 retry time 再次向 master 詢問
**expiry:若 master 始終無法回應 slave 的要求,則過了 expiry 則來自 master 的 DNS 資訊將會失效
**mininum:slave 的 TTL 時間,通常與 master 的 TTL 相同

!!DNS 伺服器進階設定
*針對特定 IP 接受查詢
*設定 forward
**設定優先由 forwarders 查詢再由自己查詢,或是只由 forwarders 查詢
**設定 forwarders 主機

!!圖形介面管理 DNS 伺服器
@@color:blue;font-size:1.4em;http://www.webmin.net@@
*下載套件
*先在 /etc/resolv.conf  改回正確的 DNS server 位址
*刪除 /var/named/chroot/etc 下自行設定的 conf 檔、zone file
*停用 named 服務
!變數
*變數不需宣告類型,預設為字串
*變數名稱第一碼:[a-zA-Z_][a-zA-Z0-9_]*
**長度不超過 256 個字元
*變數命名慣例:
**變數全大寫:環境變數 (全域變數)
**a=1
***『 = 』左右不能有空格
*取值要加『 $ 』
**echo $USER
*<<slider env env env "">>
*<<slider set set set "">>
*<<slider unset unset unset "">>

!!自訂變數生命週期
*echo $SHLVL 顯示目前 shell level
**再執行一個 bash 就會再往上一層 shell
**輸入 exit 或是 ctrl+d 則退回下一層
*自訂變數僅存在在該 shell level,當脫掉某一層 shell,則該層的自訂變數將不再存在
*因此 shell script 執行中的變數一但執行完就結束其生命週期

!Shell script
<<slider [[第一隻 shell script]] [[第一隻 shell script]] [[第一隻 shell script]] "">>
!!執行 shell script 程式
#sh sh01.sh
# ./sh01.sh
**需給予 u+x 權限
#放在 $PATH 中
**root 的在 /root/bin/ (自行 mkdir)
**一般使用者在 /home/$USER/bin
#@@color:red;font-size:1.3em;source sh01.sh@@
**注意 $SHLVL 在原來的 shell level 執行,請小心使用

!參數
<<slider sh02.sh sh02.sh sh02.sh "">>
*$0 ~ $9: $0 表示 shell script 本身
*$10 起,表示 $1 加上一個 0 字元
*$* 列出所有參數
*$# 列出參數個數
*@@color:red;$! 傳回最後一道背景執行程式的 PID@@

!!變數置換
*若輸出有空格且有變數置換的需求時,使用『 " " 』
**效能會略減
*若輸出入只是單純的字串則建議使用『 ' ' 』
*若變數置換與字串直接連接,則使用 『 { } 』包裹變數名稱
**例如 ${MyWeight}Kg
***注意:與 php 不同,php 為 {$MyWeight}Kg

!!互動輸入變數
*read {//變數名稱//}

!!數值計算
*<<slider expr expr expr "">>
**運算元左右有空格
**乘法需加上跳脫字元 \
*<<slider 雙小括號 雙小括號 雙小括號 "">>
*<<slider 中括號 中括號 中括號 "">>

!!echo 與 printf
*echo:輸出結果並換行
*printf:只輸出結果不換行
**換行:『 \n 』

!!$RANDOM
*範圍: 0 ~ 32767
*取出 1 ~ 49 其中一個數字:
**echo $[$RANDOM%49+1]

#/etc/profile
#~/.bash_profile
**不存在則執行 ~/.bash_login
***不存在則執行 ~/.profile
pstree、runlevel、init
!Run Level
0. halt 關機
1. Single user mode
2. 
3. Full multiuser mode
4. unused → 提供自訂 Run level (CentOS 在 Run Level 中已有一套組態設定)
5. X11:多人多工圖形化介面
6. Reboot

*vi /etc/inittab
**檢視預設 run level,及 system initial 載入的組態設定
***CentOS 預設啟動 Run level 5,並載入 /etc/rc.d/rc.sysinit

!GRUB 開機選單
*存放位置
<<slider /boot/grub/grub.conf /boot/grub/grub.conf /boot/grub/grub.conf "">>
!Apache 伺服器
*套件名稱:httpd
*服務名稱:httpd
*主要組態: /etc/httpd/conf/httpd.conf
**1.3:/etc/httpd/httpd.conf
*預設不啟動
**service httpd start

!組態檔
|key|value|
or
{{{
<tag>
        key  value
</tag>
}}}

!!重要 Key 值
#DocumentRoot:對外營業的根目錄
**http:/ /主機名稱/ → /var/www/html
***URL → 通訊協定:/ /主機名稱或IP:連接埠/資源檔(含目錄)#錨點?參數
#ServerRoot:伺服器的根目錄 → /etc/httpd
#Include:其他組態檔 → conf.d/*.conf (相對路徑)
#DirectoryIndex:目錄索引,原則上無限制索引檔數量,規則請參閱 Brad 名言 4.
**根據 Apache 手冊:強烈建議只輸入需要的檔案,因 Apache 搜尋的特性,會減低效能
#UserDirl:是否啟用使用者個人網站,例如:http://www.flatfish.net/~flatfish
**disable → 停用
**{//目錄名稱//} → 啟用
**{// /home/username//} → @@color:red;chmod 711@@
**{// /home/username/public_html//} → @@color:purple;chmod 755@@
#權限:預設 {{{apache:x:48:48:Apache:/var/www:/sbin/nologin}}}
**User
**Group
***網頁上的檔案權限設定建議
{{{
chown flatfish.apach
chmod 640 網頁檔案
}}}
#Timeout:收到與回應一個要求的最長時間,當系統忙碌時要調大
#KeepAlive:是否要保持 TCP 連線,建議開啟提高效能
#MaxKeepAliveRequests:100 個人使用足夠了
#KeepAliveTimeout:一個要求到下一個要求的 Timeout,個人網頁 40 ~ 60,視網站特質,若像是論壇性質,client 點選連結很頻繁時可調小,若像是 www.brad.tw 知識性質,一篇文章可能會看很久的時候調大


!LAMP → Linux + Apache + MySQL + PHP
*PHP
**套件名稱:php
**主要組態:<<slider /etc/httpd/conf.d/php.conf /etc/httpd/conf.d/php.conf /etc/httpd/conf.d/php.conf "">>
*MySQL
**套件名稱:mysql
**服務名稱:mysqld
**連接埠:3306
**圖形介面:[[下載 PhpMyAdmin|http://www.phpmyadmin.net/home_page/downloads.php]]
***解壓縮複製到 /var/www/html 下,一個容易識別的目錄
***使用 web 瀏覽器
**安裝 php-mysql 連結:''yum install php-mysql''
{{{
phpMyAdmin - 錯誤

無法讀取 mysql 模組,
請檢查 PHP 設定 - 說明文件
}}}

!!LAMP 故障排除
#MySQL server 是否啟動
#httpd server 是否啟動
#php 是否已 Include
#SELinux 是否啟動 → disable

!!修改 skel 樣品屋
*目的:建立使用者不用再建立 public_html 目錄
**/etc/skel → 建立 public_html 

!!建立無『 ~ 』符號連結的使用者目錄名稱
*利用 ln -s 建立符號連結
{{{
[root@localhost html]# pwd
/var/www/html
[root@localhost html]# ln -s /home/flatfish/public_html/ flatfish
}}}

!有認證權限的目錄
{{{
<Directory /var/www/html/company/staff>
        AuthName        'BBB'
        AuthType        Basic
        AuthUserFile    /var/www/staff.passwd
        require         valid-user
</Directory>
}}}
<<slider htpasswd htpasswd htpasswd "">>
or
{{{
AllowOverride AuthConfig
}}}
{{{
cd /var/www/html/pics/
vi .htaccess
編輯以下項目
        AuthName        'BBB'
        AuthType        Basic
        AuthUserFile    /var/www/staff.passwd
        require         valid-user
}}}
*AccessFileName .htaccess
**認證權限

!!Options
*Indexes:提供目錄索引
*FollowSymLinks:跟隨符號連結
*Order
{{{
Order allow,deny
allow from all
deny from 192.168.1
}}}

!虛擬網站主機架設
*VirtualHost
##name-based:主機名稱不同
###NameVirtualHost www.flatfish.net:@@color:red;80@@ ← 埠號一定要
##ip-based:IP 不同

!!其他 httpd.conf 調教
{{{
    100 <IfModule prefork.c>
    101 StartServers       8		# 8個 httpd 子程序
    102 MinSpareServers    5
    103 MaxSpareServers   20		# 子程序超過 20 個時,會開始清除子程序
    104 ServerLimit      256		# 最多 256 個子程序
    105 MaxClients       256		# 最多接受 256 個 client
    106 MaxRequestsPerChild  4000	# 每個子程序最多接受的要求
    107 </IfModule>
}}}
*Listen 一定包括 Port number
*LoadModule:載入模組
*php 強化模組:eaccelerator
{{{
Caching Enabled:true
Optimized Enabled:true
}}}
*&&:and
**敘述 A && 敘述 B
***若 A 執行完 $?=0 則執行 B
***若 A 執行完 $?!=0 則不執行 B,結果為 false
ls / && echo ok
ls /dahfsdfg && echo ok
*{{{||}}}:or
**敘述 A || 敘述 B
***若 A 執行完 $?=0 則不執行 B
***若 A 執行完 $?!=0 則執行 B
ls / || echo ok
ls /hgjsfhg || echo ok
*test {//條件式//}
> <<slider test test [[test 說明]] "">>
*<<slider dirname dirname dirname "">> 與 <<slider basename basename basename "">>
*<<slider sh08.sh sh08.sh sh08.sh "">>


<<slider if if if "">>
<<slider case case case "">>
<<slider sh10.sh sh10.sh sh10.sh "">>
|一般模式|←→|編輯模式|
|~|←→|指令列模式|

|a|游標右邊開始輸入編輯內容|
|i|游標左邊開始輸入編輯內容|
|A|行尾開始輸入編輯內容|
|I|行首開始輸入編輯內容|
|o|頁尾開始輸入編輯內容|
|O|頁首開始編輯輸入內容|
|R|進入取代編輯模式|
*r: 取代一個字元

|>|>|>|>|>|>|>| O |
|I|@#$%^|i|游標位置|a|@#$%|A|
|>|>|>|>|>|>|>| o |

!一般模式下遊標移動
| h | 向左一格 | ← |
| j | 向下一格 | ↓ |
| k | 向上一格 | ↑ |
| l | 向右一格| →|
| 0 | 移動至行首 | Home |
| $ | 移動至行尾 | End |
| d0 | 刪除至行首 ||
| d$ | 刪除至行末 ||
| x | 向右刪除一個字元 | Del |
| X | 向左刪除一個字元 | Backspace |
| H | 移動至畫面最上 ||
| M | 移動至畫面中間 ||
| L | 移動至畫面最末 ||
| y | 複製 ||
| p | 向下貼上 ||
| P | 向上貼上 ||
| . | 重覆上一個動作 ||
| Pg Up | 上一頁 | Ctrl+F |
| Pg Dn | 下一頁 | Ctrl+B |
| 數字+Enter | 跳到下面第 n 行 ||
| G | 直接跳到頁尾 | Ctrl+End |
| 數字+G | 直接跳到第 n 行 ||
| gg | 直接跳到頁首 | Ctrl+Home |
d1G、dG、dnG、dd、ndd


!命令列模式
|:set nu|顯示列號|
|:set nonu|不顯示列號|
|:w|存檔|
|:q|離開|
|:q!|強制離開|
|:wq|存檔後離開|
|ZZ|有修改則存檔後離開,沒修改則直接離開|

*/ //{keyword}// 由上而下搜尋
*? //{keyword}// 由下而上搜尋
n: 正向
N: 反向

{{{
for  ((i=0;i<=9;i++))
do
     :
     :
done
}}}
<<slider sh11.sh sh11.sh sh11.sh "">>
<<slider sh13.sh sh13.sh [[sh13.sh 九九乘法表]] "">>

!!大量建置帳號九九乘法表
*先預先建立群組 staff
>//{{{group add staff}}}//
*<<slider sh14.sh sh14.sh [[sh14.sh]] "">>

{{{
for	變數	in	範圍
do
	:
	:
done
}}}
<<slider sh15.sh sh15.sh sh15.sh "">>
*空白、換列、Tab 都會被拆開
*每一個帳號至少有一個所屬的群組

!群組管理
*群組中不會有其他群組,只會有帳號
**分為 私有 及 共用 群組
{{{
/etc/group
/etc/gshadow
}}}
cat /etc/group
man 5 group
#群組名稱
#密碼
**x:使用 shadow (遮蔽式)密碼,須參照 /etc/gshadow
#gid
#成員

id //{accountname}//

cat /etc/gshadow
#群組名稱
#加密後的密碼
#
#

groupadd


!帳號管理
*帳號名稱最長 256 字元
{{{
/etc/paswd
/etc/shadow
/etc/group
/etc/gshadow
/home/*
/var/mail/ (mail box_
}}}
useradd、usermod、userdel

*UID
**0: Super user (通常為 root)
**1 ~ 499(預設): System user
**500(預設) ~ ? : Normal user
***Kernel 2.4-: 2^^16^^ → 0 ~ 65535
***Kernel 2.6+: 2^^32^^ → 0 ~ 43億

*Primary group
**主要群組


*nologin / false / 無 shell 資訊 : 皆無法登入

!!shadow
#login name
#加密後的密碼
#密碼上次修改的時間 (自 1970 年 1 月 1 日算起的天數)
#到下次可修改密碼的天數
#到下次必須修改密碼剩餘的天數
#在下次必須修改密碼的天數前提醒使用者
#帳號可使用剩餘天數
#帳號過期日期 (自1970 年 1 月 1 日算起)
#保留區

!!手動建立帳號
#/etc/passwd
#/etc/shadow
#/home/
#chown
!Telnet
*CentOS 預設安裝 telnet client,但不安裝 telnet server
*server 套件名稱:telnet-server
**yum -y install telnet-server
*服務名稱:in.telnetd

*註:伺服器類型
##standalone 獨立伺服器:頻繁被使用的服務,例如 apache
##inetd (xinetd) 短暫伺服器:
{{{
Xinetd 取代了網際網路服務系統程式 inetd,但更為安全。Xinetd 能根據遠端連
入的位址與(或)存取次數(以避免阻斷服務式的攻擊),為所有服務提供存取控制
。Xinetd 提供多種日誌服務,對伺服器參數的數目沒有設限,也能讓您在電腦上,
將特定服務與特定 IP 位址相對應。每個服務都有其獨特的 Xinetd 設定檔;這些
檔案都位於 /etc/xinetd.d 目錄中。
}}}
**/etc/xinetd.d/
{{{
service 服務名稱
{
	key	=	value

}
}}}
<<slider /etc/xinetd.d/telnet /etc/xinetd.d/telnet /etc/xinetd.d/telnet "">>

!TCP WRAPPERS 
<<slider [[TCP Wrapper 安全設定]] [[TCP Wrapper 安全設定]] [[TCP Wrapper 安全設定]] "">>

!SSH 伺服器
*SSH client 自與 SSH server 連線後會產生 /home/username/.ssh 目錄,存放建立的 private key,往後藉有此把 p-key 將傳送的資料加密,server 透過在 server 身上的 public key 解密
*預設 standalone
*套件名稱:openssh-server
*服務名稱:sshd
*組態檔:<<slider /etc/ssh/sshd_config /etc/ssh/sshd_config /etc/ssh/sshd_config "">>
*sshd 提供的三大服務:
**<<slider ssh ssh ssh "">>
**<<slider scp scp scp "">>
**<<slider sftp sftp sftp "">>

!!將 SSH 伺服器加入 xinetd 短暫伺服器
{{{
cp /etc/xinetd.d/telnet /etc/xinetd.d/ssh
}}}
*停用 sshd,在 /etc/xinetd.d/ 建立 ssh 檔案,參考 telnet
*重新啟動 xinetd

!利用 scp 設置免密碼自動登入 (必考)
#先在 @@color:red;client@@ 製作 public / private key
**利用 <<slider ssh-keygen ssh-keygen [[ssh-keygen -t rsa]] "">>
#將 public key 傳送至 server
**{{{scp id_rsa.pub root@192.168.33.154:/root/.ssh/id_rsa.pub.flatfish}}}
#在 server 整理 public key
**{{{cat id_rsa.pub.flatfish >> authorized_keys}}}

!禁止特定對象連線
/etc/nologin
*與 if 相同
{{{
while 判斷式
do
     :
     :
done
}}}

*httpd 啟動才停止
{{{
http=''

while [ -z "$http" ]
do
	http=`netstat -tlnp | grep ':80 '`
done
}}}

*高斯運算:算出 1 + 2 + 3 + ... + n 的總和
{{{
n=$1
i=1
sum=0
while [ $i -le $n ]
do
        sum=$[$sum+$i]
        i=$[$i+1]
done

echo $sum
}}}
| 權限 | r w x | r w x | r w x |
| 身分 | Owner | Group | Others |
| 優先權 | 1 | 2 | 3 |

*rwx 控制檔案『內容』權限與目錄『內容?』權限,與檔案屬性無關

<<slider chmod chmod chmod "">>

| 權限 | r | w | x |
| 檔案 | 讀取檔案內容 | 寫入修改檔案內容 | 執行檔案 |
| 目錄 | 讀取目錄下檔名 | 刪除/新增/改名 目錄下檔案 | 顯示目錄內檔案詳細資料 |

!預設權限
| 檔案<br>安全考量最大 666 | 一般 user<br>root | 6 6 4<br>6 4 4 |
| 目錄<br>最大 777 | 一般 user<br>root | 7 7 5<br>7 5 5 |
| umask | 一般 user<br>root | 0 0 0 2<br>0 0 2 2 |

!特殊權限
*4755 - SetUID: 執行時期,有 Owner 之權限 (SUID)
**例如 /etc/passwd 即具有此特性
*2755 - SetGID: 執行時期,有 Group 之權限 (SGID)
*1755 - Sticky bit: 主要應用在目錄身上,在該目錄中僅有檔案的 Owner 可以刪除修改檔案,可建立自己的檔案,修改自己的檔案
**例如 /tmp/ 目錄
@@color:blue;font-size:2.0em;比目魚強力推薦 rsync 異地備份套件@@
*原始網址 http://samba.anu.edu.au/rsync/
*詳細與進階使用方法請參閱以下三篇補充資料
**[[Rsync + SSH -- 讓 Server 自動異地備援也加密]]
**[[[Linux] cwRsync [rsync for windows] SSH 加密異地備份]]
**[[用rsync對網站進行鏡像備份]] 

!rsync 伺服器建置
*套件名稱:rsync
*連接埠:873
*也是一個短暫伺服器應用,透過 xinetd
*備份伺服器的服務名稱:rsyncd
{{{
Rsync 使用一套可靠的演算法則,快速地把遠端與本機的檔案做同步。Rsync 只會透
過網路,發送檔案間的差異部份,而非整個檔案,所以速度飛快。Rsync 常常用來當
作強大的鏡射工具,或用來取代 rcp 指令。本套件也包括一份技術報告,描述 rsync
所使用的演算法則。
}}}
*<<slider /etc/xinetd.d/rsync /etc/xinetd.d/rsync /etc/xinetd.d/rsync "">>
*主要組態檔:<<slider /etc/rsyncd.conf /etc/rsyncd.conf /etc/rsyncd.conf "">>
*設置密碼檔:<<slider rsyncd.passwd rsyncd.passwd 密碼檔範本 "">>
**chmod 600 rsyncd.passwd


!rsync 前端操作
*指令:rsync
{{{
rsync [OPTION] src dst
}}}

!!建議流程
*先寫好密碼檔:rsync.passwd
**內容僅有密碼
**''權限設為 600''
{{{
tar zcvf /home/flatfish flatfish.tar.tgz
rsync -vlHpogt --password-file rsync.passwd flatfish.tar.tgz bkuser@192.168.33.50::bk1
}}}
*Unix like 之間的網芳
*套件名稱:nfs-utils
*組態檔:/etc/export@@color:red;s@@/



!伺服器設置
*<<slider /etc/exports /etc/exports /etc/exports "">>

!客戶端設置
#mkdir /mnt/brad
#mount 192.168.33.50:/tmp /mnt/brad
#df -h

!自動掛卸
*套件名稱:autofs
{{{
autofs 是一個常駐程式,當你用到的時候,自動的掛載檔案系統
,當你不用的時候卸載它們。包括網路檔案系統、光碟機、軟碟機
等等的,
}}}
*組態檔:<<slider /etc/auto.master /etc/auto.master /etc/auto.master "">>
*五分鐘後自動卸載
**/etc/sysconfig/autofs 中設定
*應用程式安裝必須注意權限 (mode) 只能為 root
#直接安裝
**binary
#RPM:Red-hat Package Management
**binary
**source → 須先編譯 (compiler) 再安裝
#tarball:壓縮打包檔 → 先解壓縮
**解壓縮完就能執行
**source → 須先編譯 (compiler) 再安裝

!壓縮 與 解壓縮
*壓縮目的:節省空間,例如 .jpeg 即利用了失真壓縮 (不可逆)
##至今仍然沒有任何演算法能保證所壓縮的檔案能越壓越小
##壓縮是針對單一檔案,.zip、.rar 則是壓縮後的打包檔
*壓縮類型:
|類型|套件: Package|壓縮命令|文字瀏覽工具|
|.Z|ncompress|compress|less、zcat|
|.gz|gzip|gzip|less、zcat|
|.bz2|bzip2|bzip2|less、bzcat、bzless|
|.rar|rar|rar||
|.zip|zip|zip||

!打包 與 解包
*請參考<<slider tar tar [[tar 指令說明]] "">>

!!檔案搜尋
*搜尋指令
*搜尋指令相關
*搜尋檔案 locate
**透過資料庫 ''/var/lib/mlocate/mlocate.db'' 維護檔案
**定期更新 (透過 cron),CentOS 預設一天執行一次
**''/etc/updatedb.conf'' 紀錄不列入資料庫中的類型、目錄

| App |
| kernel |
| Hardware |
*Linux 核心是高度的模組化
**因此不易因為某一塊模組出現錯誤而影響整個核心運作

!重編核心
*為什麼要重編核心
##有需要的新功能、支援能力
##針對原來的核心減肥,有些不需要的功能可以藉由重編核心來釋放空間
*步驟:編譯 → 安裝
**過程中出現錯誤則無法繼續下一步
!!重編核心步驟
#核心原始碼 → 解壓縮 → @@color:red;/usr/src@@
#進入 /usr/src/linux-2.6.26.2
#執行make config(互動式設定) / make menuconfig(選單式設定) / make xconfig(Xwindows 內操作)
**確認沒有 .config 設定檔 (已編完且安裝好的 config 會出現在 /boot/ 內,通常檔名為 config-版本數
**Y: 表示將此功能包進核心
**M: 將此功能模組化
**N: 不使用此功能
**圖形介面下:圈圈是模組化,打勾是 build-int
#編譯原始檔:
**核心版本 2.6✞ 直接執行 make all
***make all 包含三個動作:
****make dep:相依檔案
****make bzImage:核心
****make modules:模組
#make modules_install
# ?
#cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.26.2
#mkinitrd /boot/initrd-2.6.26.2.img 2.6.26.2
#以下為選擇性
**cp System.map /boot/System.map-2.6.26.2
**cp .config /boot/config-2.6.26.2
#進入 /boot/grub 編輯 menu.lst 建立新的開機選項
#此時可以清除 /usr/src/linux-2.6.26.2

!!核心
*版本:主版本.次版本.patch
**ex: 2.6.26.2
***2 為主版本
***6 為次版本,偶數表示穩定版本,奇數表示開發中版本
*核心原始檔目錄:
**arch:與硬體相關
**block:儲存裝置
**crypto:加密解密
**drivers:驅動程式
**net:網路相關,例如 IPv6
**fs:檔案系統相關
**mm:記憶體管理
**sound:音效系統,非音效卡驅動程式
**kernel:核心
*目前及編譯完的核心
**/lib/modules/核心版本數
***cd /lib/modules/`uname -r`
**相依:<<slider modules.dep modules.dep modules.dep "">>

!模組
*lsmod
*modinfo
*insmod
*rmmod
**模組檔 2.6+ 為 .ko 檔,2.4- 為 .o
!需求
*NetBIOS ~~over~~ TCP / IP
*電腦名稱
*工作群組

!SAMBA 伺服器
*套件名稱:samba
*主要組態檔:/etc/samba/smb.conf
*服務名稱:
**smbd
**nmbd

!SAMBA 客戶端
*smbclient - L / /192.168.33.128
*smbclient / /192.168.33.128/s
*mount / /192.168.33.128/s /mnt/win

!!share 模式之身份與權限
*預設:nobody / 0744 / 0755
*guest account = xxxx (可指定為 Linux 某個帳號)

*<<slider testparm testparm testparm "">>
*捷徑 - shortcut
*參考指令 <<slider ln ln ln "">>
*hard link (硬式連結)
**適合同步
**原理:檔案建立時,透過 inode 編號(index node, 索引節點)對應到實體硬碟位址,建立 hard links 即是建立檔案時,複製 inode
***透過 ls -i 參數可檢視 inode 編號
***cp 是複製檔案內容
**@@color:red;hard links 無法複製到不同的分割區@@,因為 inode 在不同分割區是獨立的
**@@color:red;不可用於目錄連結@@,僅限用於檔案
**''ls -l'' 在檔案權限後面的數字表示該 inode 的 hard links 數量
**屬性也是連結著
*symblic links(符號連結)
**<<slider ln ln [[ln -s]] "">>
**類型欄位為 『 l 』,硬式連結數不會增加,mode 為 777
***實際仍受限於來源檔案的權限
**符號連結檔案內容為__來源檔案名稱__
**跨目錄建立符號連結必須使用__絕對表示法__
**亦可建立目錄連結
*硬式連結時,檔案移動在同一個硬碟分割區不影響,但無法移動至不同分割區;符號連結可移動到不同分割區,但須使用絕對表示法
*硬式連結不佔空間;一個符號連結消耗一個 Block(4K by default)
!!封包擷取程式
*Wireshark
**yum -y install wireshark-gnome

!!Linux 防火牆概念
*透過 Netfilter 防火牆模組,http://www.netfilter.org
**核心不包含防火牆
*核心 2.0.x 使用 ipfwadm
*核心 2.2.x ~ 2.4.x 使用 ipchains
*核心 2.6.x ~ 使用 iptables
*模組:/lib/modules/2.6.26.2/kernel/net/ipv4/netfilter/

!iptable
*iptable 的『表』:
**filter:封包過濾,『過』與『不過』
**nat:NAT 網路位址轉換
**mangle:針對封包內容修改
**raw:與穿越防火牆有關,與效能有關

!NAT
*/proc/sys/net/ipv4/ip_forward
**0:不允許 forward
**1:允許 forward

!!若 iptables 顯示無此表
*modprobe x_tables ip_tables iptable_filter ip_table_nat
*運作原理:
**一群 Client 向 Proxy Server 送出 http:/ /tw.yahoo.com 的要求,由 Proxy Server 向 Internet 抓取資料,並儲存在自己的 Cache
*Linux Proxy 預設使用 3128 提供服務
**Windows 預設使用 8080,但與 Tomcat 使用相同 Port
*Clients 需擁有類似的上網行為
*Proxy server 可設定 parent (父子)、sibling(同輩) 關係
**Proxy server 會發出 ICP 封包詢問其 parent 與 sibling 是否有該台 proxy 所需要的資料,當有其他 proxy server 回應有的時候 (HIT),送出請求的 Proxy server 會向第一台要求所需要的資料
**當同輩 (sibling) 有所需要的資料時,client 會直接向同輩的 Proxy server 抓取資料,且並不存放於原來的 Proxy server cache 中

!架設 Proxy Server
*套件名稱:squid
*連接埠使用:3128
*主要組態檔:<<slider /etc/squid/squid.conf /etc/squid/squid.conf /etc/squid/squid.conf "">>
*啟動 proxy server 之前需先格式化 cache 目錄 <<slider squid squid [[squid -z]] "">>
*squid 啟動後,若再次修改組態檔後,強烈不建議重新啟動 squid,改由 squid -k reconfigure 重新載入組態檔 

!ACL:Access Control List
*/etc/squid/squid.conf 中搜尋  ''ACCESS CONTROLS''
#先作定義:acl {//自訂名稱//} {//類型//} {//關鍵字//} <<slider ACL範例 ACL範例 ACL範例 "">>
#存取限制:http_acces [allow, deny] {//自訂名稱//}
!Boot Loader
*LILO
**組態檔:/etc/lilo.conf
***修改完組態檔後,需執行 lilo 才會生效
{{{
boot=/dev/hda 
delay=40 # 單位為 1/10 秒
image=/xxx.img # 指定核心映像檔
label=選項文字
}}}
*Grub
**組態檔:<<slider /boot/grub/grub.conf /boot/grub/grub.conf /boot/grub/grub.conf "">>

!Process 程序
*查詢階層式程序清單 <<slider pstree pstree pstree "">> 
*每個程序擁有獨立的 Process ID (PID, unique) ,程序結束其 PID 也不會被其他程序使用
*Parent ID → PPID
*查詢目前程序 <<slider ps ps ps "">>
*列出目前程序的資源消耗量 <<slider top top top "">>
*可插斷 / 不可插斷 的休眠狀態
**可插斷的休眠狀態可藉由送出插斷訊號結束或暫停該程序

!工作任務優先權
*PR (PRI):優先權
**值越小,權力越高
**無法@@color:red;直接修改@@
*NI
**Brad:好人指令 (nice),懂得謙讓
**透過直接修改 NI,來達到修改 PR 的目的 <<slider nice nice nice "">> <<slider renice renice renice "">>
{{{
$命令列 (0)
$nice 命令列 (10)
}}}
*PR~~new~~ = PR~~old~~ - NI~~old~~ + NI~~new~~
**若 NI~~old~~ = 0,則公式算出不一定準,因初始 PR 值由 CPU 決定

!工作任務前/背景
*$命令列 → 前景 → Ctrl+Z(暫停) → fg → 回到前景作業
*$命令列 & → 背景

!工作任務週期執行
|預約執行一次|@@color:red;atd@@|→|背景服務程式(daemon)|以分為單位|
|定期執行|@@color:red;crond@@|~|下任務||
*<<slider at at [[at 指令說明]] "">>
**at 預約工作存放於 ''/var/spool/at'' ,此乃一重要系統轉移時的備分區
*<<slider crontab crontab [[crontab 指令說明]] "">> 
**cron 排程工作存放於 ''/var/spool/cron''
**@@color:red;root 專用@@ 存放於 ''/etc/crontab''

!!at / cron 權限
# /etc/at(cron).allow (白名單)
# /etc/at(cron).deny (黑名單)
**預設存在黑名單,一列一帳號
*若存在白名單,則黑名單無效
#所有帳號允許:無白名單,有黑名單,但內容空白
#部分帳號允許:有白名單,允許帳號填入
#部分帳號禁止:無白名單,有黑名單,禁止帳號填入
#全部帳號禁止 (root 帳號例外):
##黑、白名單皆無
##有白名單,但內容空白
!邏輯磁碟管理
*類似微軟視窗下的動態硬碟
*多顆實體硬碟上不連續的分割區 (Physical Volume, PV),藉由 LVM 合成一個 Volume Group (VG),在切割為一個一個單獨的 Logical Volume


將準備要置入 VG 內的磁碟分割區設定格式為 8e - Linux LVM
*fdisk
*pvcreate
*pvdisplay / pvscan
*vgcreate
*vgdisplay / vgscan
*lvcreate
*lvdisplay / lvscan
*格式化
*mount

在已建立的 VG 中擴充 PV 空間
*pvcreate
*vgextend


*lvextend
*resize2fs

*lvreduce
!!送信 (SMTP)
#用戶端透過軟體 (ex:Thunderbird)送信至指定的 SMTP server
#SMTP server 透過 轉信(relay) 送至另外一部 SMTP server,最後送至目的端的 SMTP server
!!收信 (POP3、IMAP)
#用戶端透過軟體 (POP3: Thunderbird、Outlook;IMAP:Web)至伺服器取信

!收信 (POP3、IMAP)
*套件名稱:dovecot 自己玩
**dovecot 為獨立伺服器
*套件名稱:imap
**相依套件:openssl
*imap 為 短暫伺服器,透過 ixnetd 維護

!!透過 telnet 進入 POP3 收信
*telnet localhost 110
*指令
{{{
user flatfish
pass 123456
list 
retr #
dele #
quit
}}}
*POP3 必須離線閱讀
*訊息:+OK、+ERR

!Sendmail
##Postfix (推)
##Qmail
*套件名稱:sendmail
*組態檔目錄:/etc/mail/
**主要組態檔:sendmail.cf、sendmail.mc
***透過 sendmail.mc 維護 sendmail.cf (利用 m4)
<<slider /etc/mail/sendmail.cf /etc/mail/sendmail.cf /etc/mail/sendmail.cf "">>
<<slider /etc/mail/sendmail.mc /etc/mail/sendmail.mc /etc/mail/sendmail.mc "">>

!!透過 telnet 進入 SMTP 寄信
*telnet 127.0.0.1 25
*指令
{{{
helo 127.0.0.1
mail from:<bearflatfish@gmail.com>
rcpt to:<bearflatfish@gmail.com>
data
Subject: Test from flatfish 1
8:8
gogogo
.
}}}

!!存取表
*<<slider /etc/mail/access /etc/mail/access /etc/mail/access "">>
*makemap hash access.db <access

!!別名信件(群組)
*<<slider /etc/aliases /etc/aliases /etc/aliases "">>

!!個人轉信
* ~
* ~/.forward
*chmod 644 ~/.forward
**group 不可有寫入權限

!寄往 Domain 的信件
*先搞定 MX 紀錄
**當 MX 紀錄不存在,則會由對方寄信的 SMTP 決定是否採用 A 紀錄來寄信
*hostname 改為網路上獨一無二的名稱
**ex: ms1.flatfish.net.tw
**<<slider hostname hostname hostname "">>
**修改 /etc/sysconfig/network 的 HOSTNAME
** /etc/mail/local-host-names 中增加__收信的網域__
*寄信端 DNS server 位址改變需重新啟動 sendmail 服務,不然不能套用新的 DNS server 來解析名稱
fdisk
mkfs
mke2fs
mount

!!啟動 (BOOT) 時期自動掛載的掛載表
*修改 ''/etc/fstab''
{{{
[root@localhost mnt]# cat /etc/fstab
LABEL=/                 /                       ext3    defaults        1 1
LABEL=/home             /home                   ext3    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
LABEL=SWAP-sda3         swap                    swap    defaults        0 0
# Beginning of the block added by the VMware software
.host:/                 /mnt/hgfs               vmhgfs  defaults,ttl=5     0 0
# End of the block added by the VMware software
}}}
#裝置
##裝置檔名:/dev/sda2
##Label:LABEL=
#掛載點
#檔案系統
#掛載選項
#備份(dump):需 ext2↑
**0: 不可
**1: 可
#fsck:相當於 FAT 之 scandisk,需 ext2↑
**0: 不可
**1: 優先執行 fsck (建議使用)
**2: 較後執行 fsck

!!開機後的掛載表
*存放於 ''/etc/mtab''
*套件名稱:dhcp
*主要組態檔:<<slider /etc/dhcpd.conf /etc/dhcpd.conf /etc/dhcpd.conf "">>
**<<slider /usr/share/doc/dhcp*/dhcpd.conf.sample /usr/share/doc/dhcp*/dhcpd.conf.sample /usr/share/doc/dhcp*/dhcpd.conf.sample範本 "">>
!概念
#以分割區為對象
#可針對 __''使用者''__ 或 ''群組'' 設定不同的配額
#管制項目:
**__block 空間__
**inode 檔案數

*確定已安裝 quota 套件

!初始設定
#設定分割區支援使用 Quota → 寫入 ''/etc/fstab'' 中
**@@color:red;usrquota@@
**@@color:red;grpquota@@

!!計算並產生 Quota 統計檔
<<slider quotacheck quotacheck quotacheck "">>
<<slider repquota repquota repquota "">>
<<slider edquota edquota edquota "">>

*軟限制 (soft):當使用者檔案超過軟限制配額,會提示使用者超過配額的警告,並且開始寬容期 (grace time) 的計時,在寬容期倒數結束前,使用者仍然可以新增檔案,但一旦寬容期歸零時 (repquota 會顯示 NONE),使用者將無法在新增檔案,除非使用者刪除已存在的檔案,並在軟限制配額以內才能再次新增
*軟限制 (hard):使用者無論如何都不能超過硬限制配額,如果使用者想新增一個檔案,且該檔案超過已剩下的硬限制配額空間時,系統依然會新增,但是該檔案將存入不完全 (存到硬限制內),造成檔案毀損
*Quota 配額應用:
##家目錄
##mail (/var/spool/mail)


!ACL (Access Control List )概念
*針對磁碟分割區
*早期作業系統需在 ''/etc/fstab'' 中要做 ACL 的磁碟分割掛載選項加上 '',acl''
*wn-ftpd
*proftpd:組態檔極為簡單,Brad 推薦
*vsftpd:CentOS
*pureftpd

!!FTP 原理
*

!vsftpd
*Very Secure FTP
*套件名稱:vsftpd
*組態檔:/etc/vsftpd/vsftpd.conf
*預設獨立伺服器
*/etc/vsftpd/ftpusers:禁止登入的使用者黑名單

!!登入方式
*匿名,anonymous
**/var/ftp,匿名者登入後的根目錄
*帳號
**登入後進入個人的家目錄
*來賓

!將 vsftpd 予 xinetd 託管
*service vsftpd stop
*vsftpd.conf 中 listen=YES 改為 NO
*確認執行檔所在與檔名 /usr/sbin/vsftpd 
*進入 /etc/xinetd.d/,執行 cp telnet vsftp
*修改 vsftp 中 service 名稱與 server 指定至執行檔
*重新啟動 xinetd
!Client 推雷鳥

!新聞伺服器
*套件名稱:inn
*組態檔:一堆...... /etc/news
**主要組態檔:/etc/news/inn.conf
*主從式架構
**Server:
***建立不同 Newsgroup 新聞群組
***管理文章 (Article) 透過貼文 (Post)
***不同的 News Server 間,可藉由上游餵信 (Feeding) 給下游伺服器,或是透過相互傳送
****NNTP 通訊協定

!! News server 架設步驟
*為 news 帳號設定密碼
*以 news 身份登入
*inncheck -v 檢查
*/etc/news/inn.conf
*以 root 啟動服務
*文章過期檔 /etc/news/expire.ctl
*閱啟動服務讀者相關設定 /etc/news/readers.conf
*目前群組:/var/lib/news/active
*ctlinnd newgroup {//new_group_name//}
!有''人''幫你寫日誌
*Who?
*ps aux → ?
**背景服務:/sbin/syslogd
**安裝套件:''sysklogd''
**核心記錄器:/sbin/klogd
**組態檔:@@color:red;/etc/syslog.conf@@

!日誌檔組態設定
<<slider /etc/syslog.conf /etc/syslog.conf [[syslog.conf 範例]] "">>
{{{
服務名稱.優先等級							目的地:	1. 本地檔案
服務名稱,服務名稱,服務名稱.優先等級						2. 裝置 (印表機)
服務名稱.優先等級;服務名稱.優先等級						3. 遠端伺服器 (syslog server)
										4. 帳號
}}}
*服務名稱:auth, authpriv, cron, daemon, kern, lpr(線性印表機), mail, mark(自訂提供內部使用), news(新聞伺服器), security, syslog, user(提供使用者, uucp(unis-unis copy), local0 ~ local7(自訂)

*優先等級
{{{
                       (warn)        (error)                           (panic)
 info       notice     warning        err        crit       alert       emerg
─┴─────┴─────┴─────┴─────┴─────┴─────┴─→
}}}
**服務名稱.''優先等級'',設定的 ''優先等級'' 以上的訊息皆會紀錄
*修改 syslog.conf 記得執行 ''service syslog restart'' 重新起動服務
*套件:
**yp-tools :提供 NIS 相關的查尋指令功能
**ypbind   :提供 NIS Client 端的設定套件
**ypserv   :提供 NIS Server 端的設定套件
**portmap  :就是 RPC 一定需要的資料啊! 

*/etc/sysconfig/network 中加入以下內容
**NISDOMAIN={//自訂的 NIS Domain name//}
***類似微軟的 AD 網域名稱
*設定主要組態檔:/etc/ypserv.conf
*/etc/hosts
**加入自己的網域名稱
*視情況可能需要重新啟動網路服務
*設定信任群組 /etc/netgroup
**若無則 touch 出來
*啟動 ypserv 及 yppasswdd 服務
*檢測
*製作資料庫
**/usr/lib/yp/ypinit -m
*/etc/yp.conf
**ypserver flatfish


!Client
*加入網域名稱
**/etc/sysconfig/network 加入 NISDOMAIN
**
*/etc/yp.conf
**domain flatfishnis broadcast
**ypserver brad
*
*/etc/nsswitch.conf
**passwd:    files nis
**shadow:  files nis
**group: files nis
**hosts: files nis dns
*/etc/sysconfig/authconfig 將 UENIS=no 改為 yes
*/etc/pam.d/system-auth 在 password sufficient pam_unix.so .... 這行最後加上 nis
*service ypbind start
!概念
#grep → 列過濾搜尋
**grep 'RE' {//filename//}
#暴力搜尋法

!RE 正規表示法
* @@color:blue;^:指定起始字串,『 ^flatfish 』@@
* @@color:blue;$:指定節尾字串 ,『 flatfish$ 』@@
** '^$':頭尾沒有字串 → 空白列
**尋找 Home 目錄下有家的使用者
{{{
ls -l | grep '^d' | grep -v 'lost+found$'
}}}
**列出組態檔中的設定
***不顯示註解及空白列
{{{
grep -v '^#' /etc/syslog.conf | grep -v '^$'
}}}
* @@color:blue;[ ]:字元集合中取一個字元@@
**列出開頭為 a ~ m 的帳號
{{{
grep '^[a-m]' /etc/passwd
}}}
** [^ ]:此字元集合的反集合
***列出開頭''不''為 a ~ m 的帳號
{{{
grep '^[^a-m]' /etc/passwd
}}}
**列出組態檔中的設定 → 解2
***不顯示註解及空白列
{{{
grep '^[a-zA-Z*]' /etc/syslog.conf
}}}
* @@color:blue;\<  \>:篩選一個特定字 (word)@@
**找出 /var/log/messages 中,關於 ''Linux'' 的資料
**SELinux 即不符合此條件
{{{
grep '\<Linux\>' /var/log/messages
}}}
* @@color:blue;『 . 』:表示任何『 1 』個字元@@
* @@color:blue;『 * 』:表 0 或多個@@
* @@color:blue;『 \{ m, n \} 』:前面的 RE 出現 m ~ n 次@@
** { m }:出現 m 次
** { m, }:出現 m 次以上
*** [0-9]{1,3}:0 ~ 999
Background: #fff
Foreground: #000
PrimaryPale: #fc8
PrimaryLight: #ccf
PrimaryMid: #03c
PrimaryDark: #55f
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/***
|''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:''|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");

}
//}}}
/***
|Name|DisableWikiLinksPlugin|
|Source|http://www.TiddlyTools.com/#DisableWikiLinksPlugin|
|Version|1.5.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|Tiddler.prototype.autoLinkWikiWords, 'wikiLink' formatter|
|Options|##Configuration|
|Description|selectively disable TiddlyWiki's automatic ~WikiWord linking behavior|
This plugin allows you to disable TiddlyWiki's automatic ~WikiWord linking behavior, so that WikiWords embedded in tiddler content will be rendered as regular text, instead of being automatically converted to tiddler links.  To create a tiddler link when automatic linking is disabled, you must enclose the link text within {{{[[...]]}}}.
!!!!!Usage
<<<
You can block automatic WikiWord linking behavior for any specific tiddler by ''tagging it with<<tag excludeWikiWords>>'' (see configuration below) or, check a plugin option to disable automatic WikiWord links to non-existing tiddler titles, while still linking WikiWords that correspond to existing tiddlers titles or shadow tiddler titles.  You can also block specific selected WikiWords from being automatically linked by listing them in [[DisableWikiLinksList]] (see configuration below), separated by whitespace.  This tiddler is optional and, when present, causes the listed words to always be excluded, even if automatic linking of other WikiWords is being permitted.  

Note: WikiWords contained in default ''shadow'' tiddlers will be automatically linked unless you select an additional checkbox option lets you disable these automatic links as well, though this is not recommended, since it can make it more difficult to access some TiddlyWiki standard default content (such as AdvancedOptions or SideBarTabs)
<<<
!!!!!Configuration
<<<
<<option chkDisableWikiLinks>> Disable ALL automatic WikiWord tiddler links
<<option chkAllowLinksFromShadowTiddlers>> ... except for WikiWords //contained in// shadow tiddlers
<<option chkDisableNonExistingWikiLinks>> Disable automatic WikiWord links for non-existing tiddlers
Disable automatic WikiWord links for words listed in: <<option txtDisableWikiLinksList>>
Disable automatic WikiWord links for tiddlers tagged with: <<option txtDisableWikiLinksTag>>
<<<
!!!!!Revisions
<<<
2006.06.09 [1.5.0] added configurable txtDisableWikiLinksTag (default value: "excludeWikiWords") to allows selective disabling of automatic WikiWord links for any tiddler tagged with that value.
2006.12.31 [1.4.0] in formatter, test for chkDisableNonExistingWikiLinks
2006.12.09 [1.3.0] in formatter, test for excluded wiki words specified in DisableWikiLinksList
2006.12.09 [1.2.2] fix logic in autoLinkWikiWords() (was allowing links TO shadow tiddlers, even when chkDisableWikiLinks is TRUE).  
2006.12.09 [1.2.1] revised logic for handling links in shadow content
2006.12.08 [1.2.0] added hijack of Tiddler.prototype.autoLinkWikiWords so regular (non-bracketed) WikiWords won't be added to the missing list
2006.05.24 [1.1.0] added option to NOT bypass automatic wikiword links when displaying default shadow content (default is to auto-link shadow content)
2006.02.05 [1.0.1] wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.09 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.disableWikiLinks= {major: 1, minor: 5, revision: 0, date: new Date(2007,6,9)};

if (config.options.chkDisableNonExistingWikiLinks==undefined) config.options.chkDisableNonExistingWikiLinks= false;
if (config.options.chkDisableWikiLinks==undefined) config.options.chkDisableWikiLinks=false;
if (config.options.txtDisableWikiLinksList==undefined) config.options.txtDisableWikiLinksList="DisableWikiLinksList";
if (config.options.chkAllowLinksFromShadowTiddlers==undefined) config.options.chkAllowLinksFromShadowTiddlers=true;
if (config.options.txtDisableWikiLinksTag==undefined) config.options.txtDisableWikiLinksTag="excludeWikiWords";

// find the formatter for wikiLink and replace handler with 'pass-thru' rendering
initDisableWikiLinksFormatter();
function initDisableWikiLinksFormatter() {
	for (var i=0; i<config.formatters.length && config.formatters[i].name!="wikiLink"; i++);
	config.formatters[i].coreHandler=config.formatters[i].handler;
	config.formatters[i].handler=function(w) {
		// supress any leading "~" (if present)
		var skip=(w.matchText.substr(0,1)==config.textPrimitives.unWikiLink)?1:0;
		var title=w.matchText.substr(skip);
		var exists=store.tiddlerExists(title);
		var inShadow=w.tiddler && store.isShadowTiddler(w.tiddler.title);

		// check for excluded Tiddler
		if (w.tiddler && w.tiddler.isTagged(config.options.txtDisableWikiLinksTag))
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
		
		// check for specific excluded wiki words
		var t=store.getTiddlerText(config.options.txtDisableWikiLinksList)
		if (t && t.length && t.indexOf(w.matchText)!=-1)
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }

		// if not disabling links from shadows (default setting)
		if (config.options.chkAllowLinksFromShadowTiddlers && inShadow)
			return this.coreHandler(w);

		// check for non-existing non-shadow tiddler
		if (config.options.chkDisableNonExistingWikiLinks && !exists)
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }

		// if not enabled, just do standard WikiWord link formatting
		if (!config.options.chkDisableWikiLinks)
			return this.coreHandler(w);

		// just return text without linking
		w.outputText(w.output,w.matchStart+skip,w.nextMatch)
	}
}

Tiddler.prototype.coreAutoLinkWikiWords = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function()
{
	// DEBUG alert("processing: "+this.title);
	// if all automatic links are not disabled, just return results from core function
	if (!config.options.chkDisableWikiLinks)
		return this.coreAutoLinkWikiWords.apply(this,arguments);
	return false;
}
//}}}
論壇 架站機
/*{{{*/
 
/*}}}*/
/*{{{*/
a {color:#0044BB;font-weight:bold}
/*}}}*/
<!--{{{-->
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='easyEdit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
/***
|''Name:''|FieldsEditorPlugin|
|''Description:''|//create//, //edit//, //view// and //delete// commands in toolbar <<toolbar fields>>.|
|''Version:''|1.0.2|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.2.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Demo:
On [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], see [[FieldEditor example]]
!Installation:
*import this tiddler from [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] (tagged as systemConfig)
*save and reload
*optionnaly : add the following css text in your StyleSheet : {{{#popup tr.fieldTableRow td {padding:1px 3px 1px 3px;}}}}
!Code
***/

//{{{

config.commands.fields.handlePopup = function(popup,title) {
	var tiddler = store.fetchTiddler(title);
	if(!tiddler)
		return;
	var fields = {};
	store.forEachField(tiddler,function(tiddler,fieldName,value) {fields[fieldName] = value;},true);
	var items = [];
	for(var t in fields) {
		var editCommand = "<<untiddledCall editFieldDialog "+escape(title)+" "+escape(t)+">>";
		var deleteCommand = "<<untiddledCall deleteField "+escape(title)+" "+escape(t)+">>";
		var renameCommand = "<<untiddledCall renameField "+escape(title)+" "+escape(t)+">>";
		items.push({field: t,value: fields[t], actions: editCommand+renameCommand+deleteCommand});
	}
	items.sort(function(a,b) {return a.field < b.field ? -1 : (a.field == b.field ? 0 : +1);});
	var createNewCommand = "<<untiddledCall createField "+escape(title)+">>";
	items.push({field : "", value : "", actions:createNewCommand });
	if(items.length > 0)
		ListView.create(popup,items,this.listViewTemplate);
	else
		createTiddlyElement(popup,"div",null,null,this.emptyText);
}

config.commands.fields.listViewTemplate = {
	columns: [
		{name: 'Field', field: 'field', title: "Field", type: 'String'},
		{name: 'Actions', field: 'actions', title: "Actions", type: 'WikiText'},
		{name: 'Value', field: 'value', title: "Value", type: 'WikiText'}
	],
	rowClasses: [
			{className: 'fieldTableRow', field: 'actions'}
	],
	buttons: [	//can't use button for selected then delete, because click on checkbox will hide the popup
	]
}

config.macros.untiddledCall = {  // when called from listview, tiddler is unset, so we need to pass tiddler as parameter
	handler : function(place,macroName,params,wikifier,paramString) {
		var macroName = params.shift();
		if (macroName) var macro = config.macros[macroName];
		var title = params.shift();
		if (title) var tiddler = store.getTiddler(unescape(title));
		if (macro) macro.handler(place,macroName,params,wikifier,paramString,tiddler);		
	}
}

config.macros.deleteField = {
	handler : function(place,macroName,params,wikifier,paramString,tiddler) {
		if(!readOnly && params[0]) {
			fieldName = unescape(params[0]);
			var btn = createTiddlyButton(place,"delete", "delete "+fieldName,this.onClickDeleteField);
			btn.setAttribute("title",tiddler.title);
			btn.setAttribute("fieldName", fieldName);
		}
	},
	onClickDeleteField : function() {
		var title=this.getAttribute("title");
		var fieldName=this.getAttribute("fieldName");
		var tiddler = store.getTiddler(title);
		if (tiddler && fieldName && confirm("delete field " + fieldName+" from " + title +" tiddler ?")) {
			delete tiddler.fields[fieldName];
			store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
			story.refreshTiddler(title,"ViewTemplate",true);
		}
		return false;
	}
}

config.macros.createField = {
	handler : function(place,macroName,params,wikifier,paramString,tiddler) {
		if(!readOnly) {
			var btn = createTiddlyButton(place,"create new", "create a new field",this.onClickCreateField);
			btn.setAttribute("title",tiddler.title);
		}
	},
	onClickCreateField : function() {
		var title=this.getAttribute("title");
		var tiddler = store.getTiddler(title);
		if (tiddler) {
			var fieldName = prompt("Field name","");
			if (store.getValue(tiddler,fieldName)) {
				window.alert("This field already exists.");
			}
			else if (fieldName) {
				var v = prompt("Field value","");
				tiddler.fields[fieldName]=v;
				store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
				story.refreshTiddler(title,"ViewTemplate",true);
			}
		}
		return false;
	}
}

config.macros.editFieldDialog = {
	handler : function(place,macroName,params,wikifier,paramString,tiddler) {
		if(!readOnly && params[0]) {
			fieldName = unescape(params[0]);
			var btn = createTiddlyButton(place,"edit", "edit this field",this.onClickEditFieldDialog);
			btn.setAttribute("title",tiddler.title);
			btn.setAttribute("fieldName", fieldName);
		}
	},
	onClickEditFieldDialog : function() {
		var title=this.getAttribute("title");
		var tiddler = store.getTiddler(title);
		var fieldName=this.getAttribute("fieldName");
		if (tiddler && fieldName) {
			var value = tiddler.fields[fieldName];
			value = value ? value : "";
			var lines = value.match(/\n/mg);
			lines = lines ? true : false;
			if (!lines || confirm("This field contains more than one line. Only the first line will be kept if you edit it here. Proceed ?")) {
				var v = prompt("Field value",value);
				tiddler.fields[fieldName]=v;
				store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
				story.refreshTiddler(title,"ViewTemplate",true);
			}
		}
		return false;
	}
}

config.macros.renameField = {
	handler : function(place,macroName,params,wikifier,paramString,tiddler) {
		if(!readOnly && params[0]) {
			fieldName = unescape(params[0]);
			var btn = createTiddlyButton(place,"rename", "rename "+fieldName,this.onClickRenameField);
			btn.setAttribute("title",tiddler.title);
			btn.setAttribute("fieldName", fieldName);
		}
	},
	onClickRenameField : function() {
		var title=this.getAttribute("title");
		var fieldName=this.getAttribute("fieldName");
		var tiddler = store.getTiddler(title);
		if (tiddler && fieldName) {
			var newName = prompt("Rename " + fieldName + " as ?", fieldName);
			if (newName) {
				tiddler.fields[newName]=tiddler.fields[fieldName];
				delete tiddler.fields[fieldName];
				store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
				story.refreshTiddler(title,"ViewTemplate",true);
			}
		}
		return false;
	}
}

config.shadowTiddlers.StyleSheetFieldsEditor = "/*{{{*/\n";
config.shadowTiddlers.StyleSheetFieldsEditor += ".fieldTableRow td {padding : 1px 3px}\n";
config.shadowTiddlers.StyleSheetFieldsEditor += ".fieldTableRow .button {border:0; padding : 0 0.2em}\n";
config.shadowTiddlers.StyleSheetFieldsEditor +="/*}}}*/";
store.addNotification("StyleSheetFieldsEditor", refreshStyles);

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

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

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

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

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

!Code
***/
//{{{

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Parse the "toFile" option
	var filename = null;
	var lineSeparator = undefined;
	if ((p < parameter.length) && parameter[p] == "toFile") {
		p++;
		if (p >= parameter.length) {
			this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");
			return;
		}
		
		filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));
		p++;
		if ((p < parameter.length) && parameter[p] == "withLineSeparator") {
			p++;
			if (p >= parameter.length) {
				this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");
				return;
			}
			lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);
			p++;
		}
	}
	
	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);
		return;
	}

	// Perform the action.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);
	var count = tiddlers.length;
	var text = "";
	if (count > 0 && beginExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);
	
	for (var i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		text += func(tiddler, context, count, i);
	}
	
	if (count > 0 && endExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);

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

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


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

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

// Internal.
//
// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of 
// the given path.
//
config.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {
	if (!idPrefix) {
		idPrefix = "store";
	}
	var lenPrefix = idPrefix.length;
	
	// Read the content of the given file
	var content = loadFile(this.getLocalPath(path));
	if(content === null) {
		throw "TiddlyWiki '"+path+"' not found.";
	}
	
	var tiddlyWiki = new TiddlyWiki();

	// Starting with TW 2.2 there is a helper function to import the tiddlers
	if (tiddlyWiki.importTiddlyWiki) {
		if (!tiddlyWiki.importTiddlyWiki(content))
			throw "File '"+path+"' is not a TiddlyWiki.";
		tiddlyWiki.dirty = false;
		return tiddlyWiki;
	}
	
	// The legacy code, for TW < 2.2
	
	// Locate the storeArea div's
	var posOpeningDiv = content.indexOf(startSaveArea);
	var posClosingDiv = content.lastIndexOf(endSaveArea);
	if((posOpeningDiv == -1) || (posClosingDiv == -1)) {
		throw "File '"+path+"' is not a TiddlyWiki.";
	}
	var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);
	
	// Create a "div" element that contains the storage text
	var myStorageDiv = document.createElement("div");
	myStorageDiv.innerHTML = storageText;
	myStorageDiv.normalize();
	
	// Create all tiddlers in a new TiddlyWiki
	// (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)
	var store = myStorageDiv.childNodes;
	for(var t = 0; t < store.length; t++) {
		var e = store[t];
		var title = null;
		if(e.getAttribute)
			title = e.getAttribute("tiddler");
		if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
			title = e.id.substr(lenPrefix);
		if(title && title !== "") {
			var tiddler = tiddlyWiki.createTiddler(title);
			tiddler.loadFromDiv(e,title);
		}
	}
	tiddlyWiki.dirty = false;

	return tiddlyWiki;
};


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

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

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

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

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

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

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

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


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

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


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

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

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

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

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

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


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



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


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

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

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

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


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


} // of "install only once"

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


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

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

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

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

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

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/
相簿 架站機
使用此 TiddlyWiki 的空白範本之前,請先修改以下預設文章:
* SiteTitle 及 SiteSubtitle:網站的標題和副標題,顯示於頁面上方<br />(在儲存變更後,將顯示於瀏覽器視窗的標題列)。
* MainMenu:主選單(通常在頁面左側)。
* DefaultTiddlers:內含一些文章的標題,可於載入TiddlyWiki 後的預設開啟。
請輸入您的大名,作為所建立/ 編輯的文章署名:<<option txtUserName>>
<!--{{{-->
<div class='toolbar' macro='toolbar +saveTiddler  -cancelTiddler deleteTiddler'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='easyEdit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
/***
|Name|HTMLFormattingPlugin|
|Source|http://www.TiddlyTools.com/#HTMLFormattingPlugin|
|Documentation|http://www.TiddlyTools.com/#HTMLFormattingPluginInfo|
|Version|2.1.5|
|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|'HTML' formatter|
|Description|embed wiki syntax formatting inside of HTML content|
The shorthand Wiki-style formatting syntax of ~TiddlyWiki is very convenient and enables most content to be reasonably well presented. However, there are times when tried-and-true HTML formatting syntax allows more more precise control of the content display.  When HTML formatting syntax is embedded within a tiddler (in between {{{<}}}{{{html>}}} and {{{<}}}{{{/html>}}} markers) TiddlyWiki passes this content to the browser for processing as 'native' HTML.  However, TiddlyWiki does not also process the HTML source content for any embedded wiki-formatting syntax it may contain.  This means that while you can use HTML formatted content, you cannot mix wiki-formatted content within the HTML formatting.

The ~HTMLFormatting plugin allows you to freely ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.
!!!!!Documentation
>see [[HTMLFormattingPluginInfo]]
!!!!!Revisions
<<<
2008.01.08 [*.*.*] plugin size reduction: documentation moved to HTMLFormattingInfo
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.06.14 [2.1.5] in formatter, removed call to e.normalize().  Creates an INFINITE RECURSION error in Safari!!!!
2006.09.10 [2.1.4] update formatter for 2.1 compatibility (use this.lookaheadRegExp instead of temp variable)
2006.05.28 [2.1.3] in wikifyTextNodes(), decode the *value* of TEXTAREA nodes, but don't wikify() its children.  (thanks to "ayj" for bug report)
2006.02.19 [2.1.2] in wikifyTextNodes(), put SPAN element into tiddler DOM (replacing text node), BEFORE wikifying the text content.  This ensures that the 'place' passed to any macros is correctly defined when the macro is evaluated, so that calls to story.findContainingTiddler(place) will work as expected. (Thanks for bug report from GeoffSlocock)
2006.02.05 [2.1.1] wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.01 [2.1.0] don't wikify #TEXT nodes inside SELECT and TEXTAREA elements
2005.11.06 [2.0.1] code cleanup
2005.10.31 [2.0.0] replaced hijack wikify() with hijack config.formatters["html"] and simplified recursive WikifyTextNodes() code
2005.10.09 [1.0.2] combined documentation and code into a single tiddler
2005.08.05 [1.0.1] moved HTML and CSS definitions into plugin code instead of using separate tiddlers
2005.07.26 [1.0.1] Re-released as a plugin. Added <{{{html}}}>...</{{{nohtml}}}> and <{{{hide newlines}}}> handling
2005.06.26 [1.0.0] Initial Release (as code adaptation - pre-dates TiddlyWiki plugin architecture!!)
<<<
!!!!!Code
***/
//{{{
version.extensions.HTMLFormatting = {major: 2, minor: 1, revision: 5, date: new Date(2007,6,14)};

// find the formatter for HTML and replace the handler
initHTMLFormatter();
function initHTMLFormatter()
{
	for (var i=0; i<config.formatters.length && config.formatters[i].name!="html"; i++);
	if (i<config.formatters.length)	config.formatters[i].handler=function(w) {
		if (!this.lookaheadRegExp)  // fixup for TW2.0.x
			this.lookaheadRegExp = new RegExp(this.lookahead,"mg");
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var html=lookaheadMatch[1];
			// optionally suppress wiki-style literal handling of newlines
			// strip any carriage returns added by Internet Explorer's textarea edit field
			// encode newlines as \n so Internet Explorer's HTML parser won't eat them
			// encode macro brackets (<< and >>) so HTML parser won't eat them
			if (html.indexOf('<hide linebreaks>')!=-1) html=html.replace(/\n/g,' ');
			html=html.replace(/\r/g,'');
			html=html.replace(/\n/g,'\\n');
			html=html.replace(/<</g,'%%(').replace(/>>/g,')%%');
			// create span to hold HTML
			// parse HTML and normalize the results
			// walk node tree and call wikify() on each text node
			var e = createTiddlyElement(w.output,"span");
			e.innerHTML=html;
			// REMOVED: e.normalize();  // THIS CAUSED INFINITE RECURSION IN SAFARI
			wikifyTextNodes(e);
			// advance to next parse position
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
}

// wikify text nodes remaining after HTML content is processed (pre-order recursion)
function wikifyTextNodes(theNode)
{
	// textarea node doesn't get wikified, just decoded... 
	if (theNode.nodeName.toLowerCase()=='textarea')
		theNode.value=theNode.value.replace(/\%%\(/g,'<<').replace(/\)\%%/g,'>>').replace(/\\n/g,'\n');
	else for (var i=0;i<theNode.childNodes.length;i++) {
		var theChild=theNode.childNodes.item(i);
		if (theChild.nodeName.toLowerCase()=='option') continue;
		if (theChild.nodeName.toLowerCase()=='select') continue;
		wikifyTextNodes(theChild);
		if (theChild.nodeName=='#text') {
			var txt=theChild.nodeValue;
			// decode macro brackets and newlines
			txt=txt.replace(/\%%\(/g,'<<').replace(/\)\%%/g,'>>').replace(/\\n/g,'\n');
			// replace text node with wikified() span
			var newNode=createTiddlyElement(null,"span");
			theNode.replaceChild(newNode,theChild);
			wikify(txt,newNode);
		}
	}
}
//}}}
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +easyEdit > fields syncing permalink references jump'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>

<!--
<div class='tagging' macro='tagging'></div>
-->
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
*atrun
*anacron
*repquota 單位??
**Kilobytes
*網路環境換的時候的 shell script
**mynet
<<importTiddlers inline>>
/***
|Name|ImportTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ImportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ImportTiddlersPluginInfo|
|Version|4.3.1|
|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|config.macros.importTiddlers.handler|
|Options|##Configuration|
|Description|interactive controls for import/export with filtering.|
This plugin lets you selectively combine tiddlers from any two TiddlyWiki documents.  An interactive control panel lets you pick a document to import from, and then select which tiddlers to import, with prompting for skip, rename, merge or replace actions when importing tiddlers that match existing titles.  Automatically add tags to imported tiddlers so they are easy to find later on.  Generates a detailed report of import 'history' in ImportedTiddlers.
!!!!!Documentation
<<<
see [[ImportTiddlersPluginInfo]] for details
<<<
!!!!!interactive control panel:
<<<
<<tiddler ImportTiddlers>>
^^(see [[ImportTiddlers]] shadow tiddler)^^
<<<
!!!!!Installation Notes
<<<
* As of 6/27/2007, "patch" functions that provide backward-compatibility with TW2.1.x and earlier have been split into a separate [[ImportTiddlersPluginPatch]] tiddler to reduce installation overhead for //this// plugin.  You only need to install the additional plugin tiddler when using ImportTiddlersPlugin in documents using TW2.1.x or earlier.
* As of 3/21/2007, the interactive {{{<<importTiddlers>>}}} and non-interactive {{{<<loadTiddlers>>}}} macro definitions and related code have been split into separate [[ImportTiddlersPlugin]] and [[LoadTiddlersPlugin]] to permit selective installation of either the interactive and/or non-interactive macro functions.
* Quick Installation Tip: If you are using an unmodified version of TiddlyWiki (core release version <<version>>), you can get a new, empty TiddlyWiki with the Import Tiddlers plugin pre-installed (''[[download from here|TW+ImportExport.html]]''), and then simply import all your content from your old document into this new, empty document.
<<<
!!!!!Revisions
<<<
2008.06.29 [4.3.1] More layout/animation work for simpler sequential interaction.  Code reduction/cleanup
|please see [[ImportTiddlersPluginInfo]] for additional revision details|
2005.07.20 [1.0.0] Initial Release
<<<
!!!!!Code
***/
// // ''MACRO DEFINITION''
//{{{
// Version
version.extensions.importTiddlers = {major: 4, minor: 3, revision: 0, date: new Date(2008,6,28)};

// add ImportTiddlerPlugin controls to built-in backstage import task
if (config.tasks) { // TW2.2 or above
	config.tasks.importTask.content="Use ~TiddlyWiki built-in importer (below) or, ";
	config.tasks.importTask.content+="<<importTiddlers link 'Use ImportTiddlersPlugin control panel...'>>\n";
	config.tasks.importTask.content+="<<importTiddlers core>>"
}

// IE needs explicit global scoping for functions/vars called from browser events
window.onClickImportButton=onClickImportButton;
window.refreshImportList=refreshImportList;

// default cookie/option values
if (!config.options.chkImportReport) config.options.chkImportReport=true;

// default shadow definition
config.shadowTiddlers.ImportTiddlers="<<importTiddlers inline>>";

merge(config.macros.importTiddlers,{
	label: "import tiddlers",
	prompt: "Copy tiddlers from another document",
	openMsg: "Opening %0",
	openErrMsg: "Could not open %0 - error=%1",
	readMsg: "Read %0 bytes from %1",
	foundMsg: "Found %0 tiddlers in %1",
	filterMsg: "Filtered %0 tiddlers matching '%1'",
	summaryMsg: "%0 tiddler%1 in the list",
	summaryFilteredMsg: "%0 of %1 tiddler%2 in the list",
	plural: "s are",
	single: " is",
	countMsg: "%0 tiddlers selected for import",
	processedMsg: "Processed %0 tiddlers",
	importedMsg: "Imported %0 of %1 tiddlers from %2",
	loadText: "please load a document...",
	closeText: "close",	// text for close button when file is loaded
	doneText: "done",	// text for close button when file is not loaded
	startText: "import",	// text for import button
	stopText: "stop",	// text for import button while importing
	local: true,		// default to import from local file
	src: "",		// path/filename or URL of document to import (retrieved from SiteUrl tiddler)
	proxy: "",		// URL for remote proxy script (retrieved from SiteProxy tiddler)
	useProxy: false,	// use specific proxy script in front of remote URL
	inbound: null,		// hash-indexed array of tiddlers from other document
	newTags: "",		// text of tags added to imported tiddlers
	addTags: true,		// add new tags to imported tiddlers
	listsize: 10,		// # of lines to show in imported tiddler list
	importTags: true,	// include tags from remote source document when importing a tiddler
	keepTags: true,		// retain existing tags when replacing a tiddler
	sync: false,		// add 'server' fields to imported tiddlers (for sync function)
	lastFilter: "",		// most recent filter (URL hash) applied
	lastAction: null,	// most recent collision button performed
	index: 0,		// current processing index in import list
	sort: ""		// sort order for imported tiddler listbox
});

if (config.macros.importTiddlers.coreHandler==undefined)
	config.macros.importTiddlers.coreHandler=config.macros.importTiddlers.handler; // save built-in handler
config.macros.importTiddlers.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	if (!params[0] || params[0].toLowerCase()=='core') { // default to built in
		if (config.macros.importTiddlers.coreHandler)
			config.macros.importTiddlers.coreHandler.apply(this,arguments);
		else 
			createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);
	} else if (params[0]=='link') { // show link to floating panel
		createTiddlyButton(place,params[1]||this.label,params[2]||this.prompt,onClickImportMenu);
	} else if (params[0]=='inline') {// show panel as INLINE tiddler content
		createImportPanel(place);
		document.getElementById("importPanel").style.position="static";
		document.getElementById("importPanel").style.display="block";
	} else if (config.macros.loadTiddlers)
		config.macros.loadTiddlers.handler(place,macroName,params); // any other params: loadtiddlers
}

// // ''INTERFACE DEFINITION''
// // Handle link click to create/show/hide control panel
//{{{
function onClickImportMenu(e)
{
	if (!e) var e = window.event;
	var parent=resolveTarget(e).parentNode;
	var panel = document.getElementById("importPanel");
	if (panel==undefined || panel.parentNode!=parent)
		panel=createImportPanel(parent);
	var isOpen = panel.style.display=="block";
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		panel.style.display = isOpen ? "none" : "block" ;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}
//}}}

// // Create control panel: HTML, CSS
//{{{
function createImportPanel(place) {
	var cmi=config.macros.importTiddlers; // abbreviation
	var panel=document.getElementById("importPanel");
	if (panel) { panel.parentNode.removeChild(panel); }
	setStylesheet(cmi.css,"importTiddlers");
	panel=createTiddlyElement(place,"span","importPanel",null,null)
	panel.innerHTML=cmi.html;
	refreshImportList();
	var siteURL=store.getTiddlerText("SiteUrl"); if (!siteURL) siteURL="";
	document.getElementById("importSourceURL").value=siteURL;
	cmi.src=siteURL;
	var siteProxy=store.getTiddlerText("SiteProxy"); if (!siteProxy) siteProxy="SiteProxy";
	document.getElementById("importSiteProxy").value=siteProxy;
	cmi.proxy=siteProxy;
	if (config.browser.isGecko) { // FF3 FIXUP
		document.getElementById("fileImportSource").style.display="none";
		document.getElementById("importLocalPanelFix").style.display="block";
	}
	return panel;
}
//}}}

// // CSS
//{{{
config.macros.importTiddlers.css = '\
#importPanel {\
	display: none; position:absolute; z-index:11; width:35em; right:105%; top:3em;\
	background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
	border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
	padding: 0.5em; margin:0em; -moz-border-radius:1em;\
}\
#importPanel a, #importPanel td a { color:#009; display:inline; margin:0px; padding:1px; }\
#importPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }\
#importPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }\
#importPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }\
#importPanel select { width:100%;margin:0px;font-size:8pt;line-height:110%;}\
#importPanel input  { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\
#importPanel .box { border:1px solid #000; background-color:#eee; padding:3px 5px; margin-bottom:5px; -moz-border-radius:5px;}\
#importPanel .topline { border-top:1px solid #999; padding-top:2px; margin-top:2px; }\
#importPanel .rad { width:auto; }\
#importPanel .chk { width:auto; margin:1px;border:0; }\
#importPanel .btn { width:auto; }\
#importPanel .btn1 { width:98%; }\
#importPanel .btn2 { width:48%; }\
#importPanel .btn3 { width:32%; }\
#importPanel .btn4 { width:23%; }\
#importPanel .btn5 { width:19%; }\
#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }\
#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; display:inline }\
#importCollisionPanel { display:none; margin:0.5em 0em 0em 0em; }\
#backstagePanel #importPanel { left:10%; right:auto; }\
';
//}}}

// // HTML 
//{{{
config.macros.importTiddlers.html = '\
<!-- source and report -->\
<table><tr><td align=left>\
	import from\
	<input type="radio" class="rad" name="importFrom" id="importFromFile" value="file" CHECKED\
		onclick="onClickImportButton(this,event)" title="show file controls"> local file\
	<input type="radio" class="rad" name="importFrom" id="importFromWeb"  value="http"\
		onclick="onClickImportButton(this,event)" title="show web controls"> web server\
</td><td align=right>\
	<input type=checkbox class="chk" id="chkImportReport" checked\
		onClick="config.options[\'chkImportReport\']=this.checked;"> create report\
</td></tr></table>\
\
<div class="box" id="importSourcePanel" style="margin:.5em">\
<div id="importLocalPanel" style="display:block;margin-bottom:2px;"><!-- import from local file  -->\
enter or browse for source path/filename<br>\
<input type="file" id="fileImportSource" size=57 style="width:100%"\
	onKeyUp="config.macros.importTiddlers.src=this.value"\
	onChange="config.macros.importTiddlers.src=this.value;document.getElementById(\'importLoad\').onclick()">\
<div id="importLocalPanelFix" style="display:none"><!-- FF3 FIXUP -->\
	<input type="text" id="fileImportSourceFix" style="width:90%"\
		title="Enter a path/file to import"\
		onKeyUp="config.macros.importTiddlers.src=this.value"\
		onChange="config.macros.importTiddlers.src=this.value; document.getElementById(\'importLoad\').onclick()">\
	<input type="button" id="fileImportSourceFixButton" style="width:7%" value="..."\
		title="Select a path/file to import"\
		onClick="var r=config.macros.importTiddlers.askForFilename(this); if (!r||!r.length) return;\
			document.getElementById(\'fileImportSourceFix\').value=r;\
			config.macros.importTiddlers.src=r;\
			document.getElementById(\'importLoad\').onclick()">\
</div><!--end FF3 FIXUP-->\
</div><!--end local-->\
<div id="importHTTPPanel" style="display:none;margin-bottom:2px;"><!-- import from http server -->\
<table><tr><td align=left>\
	enter a URL or <a href="javascript:;" id="importSelectFeed"\
		onclick="onClickImportButton(this,event)" title="select a pre-defined \'systemServer\' URL">\
		select a server</a><br>\
</td><td align=right>\
	<input type="checkbox" class="chk" id="importUsePassword"\
		onClick="config.macros.importTiddlers.usePassword=this.checked;\
			config.macros.importTiddlers.showPanel(\'importIDPWPanel\',this.checked);">password\
	<input type="checkbox" class="chk" id="importUseProxy"\
		onClick="config.macros.importTiddlers.useProxy=this.checked;\
			config.macros.importTiddlers.showPanel(\'importSiteProxy\',this.checked);">proxy\
</td></tr></table>\
<input type="text" id="importSiteProxy" style="display:none;margin-bottom:1px" onfocus="this.select()" value="SiteProxy"\
	onKeyUp="config.macros.importTiddlers.proxy=this.value"\
	onChange="config.macros.importTiddlers.proxy=this.value;">\
<input type="text" id="importSourceURL" onfocus="this.select()" value="SiteUrl"\
	onKeyUp="config.macros.importTiddlers.src=this.value"\
	onChange="config.macros.importTiddlers.src=this.value;">\
<div id="importIDPWPanel" style="text-align:center;margin-top:2px;display:none";>\
username: <input type=text id="txtImportID" style="width:25%" \
	onChange="config.options.txtRemoteUsername=this.value;">\
 password: <input type=password id="txtImportPW" style="width:25%" \
	onChange="config.options.txtRemotePassword=this.value;">\
</div><!--end idpw-->\
</div><!--end http-->\
</div><!--end source-->\
\
<div class="box" id="importSelectPanel" style="display:none;margin:.5em;">\
<table><tr><td align=left>\
select:\
<a href="javascript:;" id="importSelectAll"\
	onclick="onClickImportButton(this);return false;" title="SELECT all tiddlers">\
	all</a>\
&nbsp;<a href="javascript:;" id="importSelectNew"\
	onclick="onClickImportButton(this);return false;" title="SELECT tiddlers not already in destination document">\
	added</a>\
&nbsp;<a href="javascript:;" id="importSelectChanges"\
	onclick="onClickImportButton(this);return false;" title="SELECT tiddlers that have been updated in source document">\
	changes</a>\
&nbsp;<a href="javascript:;" id="importSelectDifferences"\
	onclick="onClickImportButton(this);return false;" title="SELECT tiddlers that have been added or are different from existing tiddlers">\
	differences</a>\
</td><td align=right>\
<a href="javascript:;" id="importListSmaller"\
	onclick="onClickImportButton(this);return false;" title="SHRINK list size">\
	&nbsp;&#150;&nbsp;</a>\
<a href="javascript:;" id="importListLarger"\
	onclick="onClickImportButton(this);return false;" title="GROW list size">\
	&nbsp;+&nbsp;</a>\
<a href="javascript:;" id="importListMaximize"\
	onclick="onClickImportButton(this);return false;" title="MAXIMIZE/RESTORE list size">\
	&nbsp;=&nbsp;</a>\
</td></tr></table>\
<select id="importList" size=8 multiple\
	onchange="setTimeout(\'refreshImportList(\'+this.selectedIndex+\')\',1)">\
	<!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->\
</select>\
<div style="text-align:center">\
	<a href="javascript:;"\
		title="click for help using filters..."\
		onclick="alert(\'A filter consists of one or more space-separated combinations of:\\n\\ntiddler titles\\ntag:[[tagvalue]]\\ntag:[[tag expression]] (requires MatchTagsPlugin)\\nstory:[[TiddlerName]]\\nsearch:[[searchtext]]\\n\\nUse a blank filter for all tiddlers.\')"\
	>filter</a>\
	<input type="text" id="importLastFilter" style="margin-bottom:1px; width:65%"\
		title="Enter a combination of one or more filters. Use a blank filter for all tiddlers."\
		onfocus="this.select()" value=""\
		onKeyUp="config.macros.importTiddlers.lastFilter=this.value"\
		onChange="config.macros.importTiddlers.lastFilter=this.value;">\
	<input type="button" id="importApplyFilter" style="width:20%" value="apply"\
		title="filter list of tiddlers to include only those that match certain criteria"\
		onclick="onClickImportButton(this)">\
	</div>\
</div><!--end select-->\
\
<div class="box" id="importOptionsPanel" style="text-align:center;margin:.5em;display:none;">\
	apply tags: <input type=checkbox class="chk" id="chkImportTags" checked\
		onClick="config.macros.importTiddlers.importTags=this.checked;">from source&nbsp;\
	<input type=checkbox class="chk" id="chkKeepTags" checked\
		onClick="config.macros.importTiddlers.keepTags=this.checked;">keep existing&nbsp;\
	<input type=checkbox class="chk" id="chkAddTags" \
		onClick="config.macros.importTiddlers.addTags=this.checked;\
		if (this.checked) document.getElementById(\'txtNewTags\').focus();">add new<br>\
	<input type=text id="txtNewTags" style="margin-top:4px;" size=15\ onfocus="this.select()" \
		title="enter tags to be added to imported tiddlers" \
		onKeyUp="config.macros.importTiddlers.newTags=this.value;\
		document.getElementById(\'chkAddTags\').checked=this.value.length>0;" autocomplete=off>\
	<nobr><input type=checkbox class="chk" id="chkSync" \
		onClick="config.macros.importTiddlers.sync=this.checked;">\
		link imported tiddlers to source document (for sync later)</nobr>\
</div><!--end options-->\
\
<div id="importButtonPanel" style="text-align:center">\
	<input type=button id="importLoad"	class="importButton btn3" value="open"\
		title="load listbox with tiddlers from source document"\
		onclick="onClickImportButton(this)">\
	<input type=button id="importOptions"	class="importButton btn3" value="options..."\
		title="set options for tags, sync, etc."\
		onclick="onClickImportButton(this)">\
	<input type=button id="importStart"	class="importButton btn3" value="import"\
		title="start/stop import of selected source tiddlers into current document"\
		onclick="onClickImportButton(this)">\
	<input type=button id="importClose"	class="importButton btn3" value="done"\
		title="clear listbox or hide control panel"\
		onclick="onClickImportButton(this)">\
</div>\
\
<div class="none" id="importCollisionPanel" style="text-align:left;margin:0 0 0 .5em">\
	<table><tr><td style="width:65%" align="left">\
		<table><tr>\
		<td align=left>\
			tiddler already exists:\
		</td><td align=right>\
			<input type=checkbox class="chk" id="importApplyToAll" \
			onclick="document.getElementById(\'importRename\').disabled=this.checked;"\
			checked>apply to all\
		</td></tr></table>\
		<input type=text id="importNewTitle" size=15 autocomplete=off">\
	</td><td style="width:34%" align="center">\
		<input type=button id="importMerge"\
			class="importButton" style="width:47%" value="merge"\
			title="append the incoming tiddler to the existing tiddler"\
			onclick="onClickImportButton(this)"><!--\
		--><input type=button id="importSkip"\
			class="importButton" style="width:47%" value="skip"\
			title="do not import this tiddler"\
			onclick="onClickImportButton(this)"><!--\
		--><br><input type=button id="importRename"\
			class="importButton" style="width:47%" value="rename"\
			title="rename the incoming tiddler"\
			onclick="onClickImportButton(this)"><!--\
		--><input type=button id="importReplace"\
			class="importButton" style="width:47%" value="replace"\
			title="discard the existing tiddler"\
			onclick="onClickImportButton(this)">\
	</td></tr></table>\
</div><!--end collision-->\
';
//}}}

// // Control interactions
//{{{
function onClickImportButton(which,event)
{
	var cmi=config.macros.importTiddlers; // abbreviation

	var list = document.getElementById('importList');
	if (!list) return;
	var thePanel = document.getElementById('importPanel');
	var theCollisionPanel = document.getElementById('importCollisionPanel');
	var theNewTitle = document.getElementById('importNewTitle');
	var count=0;
	switch (which.id)
		{
		case 'importFromFile':	// show local panel
		case 'importFromWeb':	// show HTTP panel
			cmi.local=(which.id=='importFromFile');
			cmi.showPanel('importLocalPanel',cmi.local);
			cmi.showPanel('importHTTPPanel',!cmi.local);
			break;
		case 'importOptions':	// show/hide options panel
			cmi.showPanel('importOptionsPanel',document.getElementById('importOptionsPanel').style.display=='none');
			break;
		case 'fileImportSource':
		case 'importLoad':		// load import source into hidden frame
			importReport();		// if an import was in progress, generate a report
			cmi.inbound=null;	// clear the imported tiddler buffer
			refreshImportList();	// reset/resize the listbox
			if (cmi.src=="") break;
			// Load document, read it's DOM and fill the list
			cmi.loadRemoteFile(cmi.src,cmi.filterTiddlerList);
			break;
		case 'importSelectFeed':	// select a pre-defined systemServer feed URL
			var p=Popup.create(which); if (!p) return;
			var tids=store.getTaggedTiddlers('systemServer');
			if (!tids.length)
				createTiddlyText(createTiddlyElement(p,'li'),'no pre-defined server feeds');
			for (var t=0; t<tids.length; t++) {
				var u=store.getTiddlerSlice(tids[t].title,"URL");
				var d=store.getTiddlerSlice(tids[t].title,"Description");
				if (!d||!d.length) d=store.getTiddlerSlice(tids[t].title,"description");
				if (!d||!d.length) d=u;
				createTiddlyButton(createTiddlyElement(p,'li'),tids[t].title,d,
					function(){
						var u=this.getAttribute('url');
						document.getElementById('importSourceURL').value=u;
						config.macros.importTiddlers.src=u;
						document.getElementById('importLoad').onclick();
					},
					null,null,null,{url:u});
			}
			Popup.show(p,false);
			event.cancelBubble = true;
			if (event.stopPropagation) event.stopPropagation();
			return(false);
			// create popup with feed list
			// onselect, insert feed URL into input field.
			break;
		case 'importSelectAll':		// select all tiddler list items (i.e., not headings)
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				if (list.options[t].value=="") continue;
				list.options[t].selected=true;
				count++;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			document.getElementById('importStart').disabled=!count;
			document.getElementById('importStart').style.visibility=count?"visible":"hidden";
			break;
		case 'importSelectNew':		// select tiddlers not in current document
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value=="") continue;
				list.options[t].selected=!store.tiddlerExists(list.options[t].value);
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			document.getElementById('importStart').disabled=!count;
			document.getElementById('importStart').style.visibility=count?"visible":"hidden";
			break;
		case 'importSelectChanges':		// select tiddlers that are updated from existing tiddlers
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value==""||!store.tiddlerExists(list.options[t].value)) continue;
				for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
					{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
				list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified>0); // updated tiddler
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			document.getElementById('importStart').disabled=!count;
			document.getElementById('importStart').style.visibility=count?"visible":"hidden";
			break;
		case 'importSelectDifferences':		// select tiddlers that are new or different from existing tiddlers
			importReport();		// if an import was in progress, generate a report
			for (var t=0,count=0; t < list.options.length; t++) {
				list.options[t].selected=false;
				if (list.options[t].value=="") continue;
				if (!store.tiddlerExists(list.options[t].value)) { list.options[t].selected=true; count++; continue; }
				for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
					{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
				list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified!=0); // changed tiddler
				count+=list.options[t].selected?1:0;
			}
			clearMessage(); displayMessage(cmi.countMsg.format([count]));
			document.getElementById('importStart').disabled=!count;
			document.getElementById('importStart').style.visibility=count?"visible":"hidden";
			break;
		case 'importApplyFilter':	// filter list to include only matching tiddlers
			importReport();		// if an import was in progress, generate a report
			clearMessage();
			if (!cmi.all) // no tiddlers loaded = "0 selected"
				{ displayMessage(cmi.countMsg.format([0])); return false; }
			var hash=document.getElementById('importLastFilter').value;
			cmi.inbound=cmi.filterByHash("#"+hash,cmi.all);
			refreshImportList();	// reset/resize the listbox
			break;
		case 'importStart':		// initiate the import processing
			importReport();		// if an import was in progress, generate a report
			document.getElementById('importApplyToAll').checked=false;
			document.getElementById('importStart').value=cmi.stopText;
			if (cmi.index>0) cmi.index=-1; // stop processing
			else cmi.index=importTiddlers(0); // or begin processing
			importStopped();
			break;
		case 'importClose':		// unload imported tiddlers or hide the import control panel
			// if imported tiddlers not loaded, close the import control panel
			if (!cmi.inbound) { thePanel.style.display='none'; break; }
			importReport();		// if an import was in progress, generate a report
			cmi.inbound=null;	// clear the imported tiddler buffer
			refreshImportList();	// reset/resize the listbox
			break;
		case 'importSkip':	// don't import the tiddler
			cmi.lastAction=which;
			var theItem	= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported = cmi.inbound[j];
			theImported.status='skipped after asking';			// mark item as skipped
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index+1);	// resume with NEXT item
			importStopped();
			break;
		case 'importRename':		// change name of imported tiddler
			cmi.lastAction=which;
			var theItem		= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported		= cmi.inbound[j];
			theImported.status	= 'renamed from '+theImported.title;	// mark item as renamed
			theImported.set(theNewTitle.value,null,null,null,null);		// change the tiddler title
			theItem.value		= theNewTitle.value;			// change the listbox item text
			theItem.text		= theNewTitle.value;			// change the listbox item text
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with THIS item
			importStopped();
			break;
		case 'importMerge':	// join existing and imported tiddler content
			cmi.lastAction=which;
			var theItem	= list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported	= cmi.inbound[j];
			var theExisting	= store.getTiddler(theItem.value);
			var theText	= theExisting.text+'\n----\n^^merged from: ';
			theText		+='[['+cmi.src+'#'+theItem.value+'|'+cmi.src+'#'+theItem.value+']]^^\n';
			theText		+='^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\n'+theImported.text;
			var theDate	= new Date();
			var theTags	= theExisting.getTags()+' '+theImported.getTags();
			theImported.set(null,theText,null,theDate,theTags);
			theImported.status   = 'merged with '+theExisting.title;	// mark item as merged
			theImported.status  += ' - '+theExisting.modified.formatString("MM/DD/YYYY 0hh:0mm:0ss");
			theImported.status  += ' by '+theExisting.modifier;
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with this item
			importStopped();
			break;
		case 'importReplace':		// substitute imported tiddler for existing tiddler
			cmi.lastAction=which;
			var theItem		  = list.options[cmi.index];
			for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==theItem.value) break;
			var theImported     = cmi.inbound[j];
			var theExisting	  = store.getTiddler(theItem.value);
			theImported.status  = 'replaces '+theExisting.title;		// mark item for replace
			theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY 0hh:0mm:0ss");
			theImported.status += ' by '+theExisting.modifier;
			theCollisionPanel.style.display='none';
			cmi.index=importTiddlers(cmi.index);	// resume with THIS item
			importStopped();
			break;
		case 'importListSmaller':		// decrease current listbox size, minimum=5
			if (list.options.length==1) break;
			list.size-=(list.size>5)?1:0;
			cmi.listsize=list.size;
			break;
		case 'importListLarger':		// increase current listbox size, maximum=number of items in list
			if (list.options.length==1) break;
			list.size+=(list.size<list.options.length)?1:0;
			cmi.listsize=list.size;
			break;
		case 'importListMaximize':	// toggle listbox size between current and maximum
			if (list.options.length==1) break;
			list.size=(list.size==list.options.length)?cmi.listsize:list.options.length;
			break;
		}
}
//}}}

// // toggle panel
//{{{
config.macros.importTiddlers.showPanel=function(place,show) {
	if (typeof place == "string") var place=document.getElementById(place);
	if (!place||!place.style) return;
	if(anim && config.options.chkAnimate) anim.startAnimating(new Slider(place,show,false,"none"));
	else place.style.display=show?"block":"none";
}
//}}}

// // refresh listbox
//{{{
function refreshImportList(selectedIndex)
{
	var cmi=config.macros.importTiddlers; // abbreviation

	var list  = document.getElementById("importList");
	if (!list) return;
	// if nothing to show, reset list content and size
	if (!cmi.inbound) 
	{
		while (list.length > 0) { list.options[0] = null; }
		list.options[0]=new Option(cmi.loadText,"",false,false);
		list.size=cmi.listsize;

		// toggle buttons and panels
		document.getElementById('importLoad').disabled=false;
		document.getElementById('importLoad').style.display='inline';
		document.getElementById('importStart').disabled=true;
		document.getElementById('importStart').style.visibility="hidden";
		document.getElementById('importOptions').disabled=true;
		document.getElementById('importOptions').style.display='none';
		document.getElementById('fileImportSource').disabled=false;
		document.getElementById('importFromFile').disabled=false;
		document.getElementById('importFromWeb').disabled=false;
		document.getElementById('importStart').value=cmi.startText;
		document.getElementById('importClose').value=cmi.doneText;
		document.getElementById('importSelectPanel').style.display='none';
		document.getElementById('importOptionsPanel').style.display='none';
		return;
	}
	// there are inbound tiddlers loaded...
	// toggle buttons and panels
	document.getElementById('importLoad').disabled=true;
	document.getElementById('importLoad').style.display='none';
	document.getElementById('importStart').style.visibility='visible';
	document.getElementById('importOptions').style.display='inline';
	document.getElementById('importOptions').disabled=false;
	document.getElementById('fileImportSource').disabled=true;
	document.getElementById('importFromFile').disabled=true;
	document.getElementById('importFromWeb').disabled=true;
	document.getElementById('importClose').value=cmi.closeText;
	if (document.getElementById('importSelectPanel').style.display=='none')
		cmi.showPanel('importSelectPanel',true);

	// get the sort order
	if (!selectedIndex)   selectedIndex=0;
	if (selectedIndex==0) cmi.sort='title';		// heading
	if (selectedIndex==1) cmi.sort='title';
	if (selectedIndex==2) cmi.sort='modified';
	if (selectedIndex==3) cmi.sort='tags';
	if (selectedIndex>3) {
		// display selected tiddler count
		for (var t=0,count=0; t < list.options.length; t++) {
			if (!list.options[t].selected) continue;
			if (list.options[t].value!="")
				count+=1;
			else { // if heading is selected, deselect it, and then select and count all in section
				list.options[t].selected=false;
				for ( t++; t<list.options.length && list.options[t].value!=""; t++) {
					list.options[t].selected=true;
					count++;
				}
			}
		}
		clearMessage(); displayMessage(cmi.countMsg.format([count]));
	}
	document.getElementById('importStart').disabled=!count;
	if (selectedIndex>3) return; // no refresh needed

	// get the alphasorted list of tiddlers
	var tiddlers=cmi.inbound;
	tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });
	// clear current list contents
	while (list.length > 0) { list.options[0] = null; }
	// add heading and control items to list
	var i=0;
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	if (cmi.all.length==tiddlers.length)
		var summary=cmi.summaryMsg.format([tiddlers.length,(tiddlers.length!=1)?cmi.plural:cmi.single]);
	else
		var summary=cmi.summaryFilteredMsg.format([tiddlers.length,cmi.all.length,(cmi.all.length!=1)?cmi.plural:cmi.single]);
	list.options[i++]=new Option(summary,"",false,false);
	list.options[i++]=new Option(((cmi.sort=="title"   )?">":indent)+' [by title]',"",false,false);
	list.options[i++]=new Option(((cmi.sort=="modified")?">":indent)+' [by date]',"",false,false);
	list.options[i++]=new Option(((cmi.sort=="tags")?">":indent)+' [by tags]',"",false,false);
	// output the tiddler list
	switch(cmi.sort) {
		case "title":
			for(var t = 0; t < tiddlers.length; t++)
				list.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);
			break;
		case "modified":
			// sort descending for newest date first
			tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });
			var lastSection = "";
			for(var t = 0; t < tiddlers.length; t++) {
				var tiddler = tiddlers[t];
				var theSection = tiddler.modified.toLocaleDateString();
				if (theSection != lastSection) {
					list.options[i++] = new Option(theSection,"",false,false);
					lastSection = theSection;
				}
				list.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);
			}
			break;
		case "tags":
			var theTitles = {}; // all tiddler titles, hash indexed by tag value
			var theTags = new Array();
			for(var t=0; t<tiddlers.length; t++) {
				var title=tiddlers[t].title;
				var tags=tiddlers[t].tags;
				if (!tags || !tags.length) {
					if (theTitles["untagged"]==undefined) { theTags.push("untagged"); theTitles["untagged"]=new Array(); }
					theTitles["untagged"].push(title);
				}
				else for(var s=0; s<tags.length; s++) {
					if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }
					theTitles[tags[s]].push(title);
				}
			}
			theTags.sort();
			for(var tagindex=0; tagindex<theTags.length; tagindex++) {
				var theTag=theTags[tagindex];
				list.options[i++]=new Option(theTag,"",false,false);
				for(var t=0; t<theTitles[theTag].length; t++)
					list.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);
			}
			break;
		}
	list.selectedIndex=selectedIndex;		  // select current control item
	if (list.size<cmi.listsize) list.size=cmi.listsize;
	if (list.size>list.options.length) list.size=list.options.length;
}

config.macros.importTiddlers.filterTiddlerList=function(success,params,txt,src,xhr) {
	var cmi=config.macros.importTiddlers; // abbreviation
	var src=src.replace(/%20/g," ");
	if (!success) { displayMessage(cmi.openErrMsg.format([src,xhr.status])); return; }
	cmi.all = cmi.readTiddlersFromHTML(txt);
	var count=cmi.all?cmi.all.length:0;
	var querypos=src.lastIndexOf("?"); if (querypos!=-1) src=src.substr(0,querypos);
	displayMessage(cmi.foundMsg.format([count,src]));
	cmi.inbound=cmi.filterByHash(params,cmi.all); // use full URL including hash (if any)
	document.getElementById("importLastFilter").value=cmi.lastFilter;
	window.refreshImportList(0);
}

config.macros.importTiddlers.filterByHash=function(src,tiddlers)
{
	var hashpos=src.lastIndexOf("#"); if (hashpos==-1) return tiddlers;
	var hash=src.substr(hashpos+1); if (!hash.length) return tiddlers;
	var tids=[];
	var params=hash.parseParams("anon",null,true,false,false);
	for (var p=1; p<params.length; p++) {
		switch (params[p].name) {
			case "anon":
			case "open":
				tids.pushUnique(params[p].value);
				break;
			case "tag":
				if (store.getMatchingTiddlers) { // for boolean expressions - see MatchTagsPlugin
					var r=store.getMatchingTiddlers(params[p].value,null,tiddlers);
					for (var t=0; t<r.length; t++) tids.pushUnique(r[t].title);
				} else for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].isTagged(params[p].value))
						tids.pushUnique(tiddlers[t].title);
				break;
			case "story":
				for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].title==params[p].value) {
						tiddlers[t].changed();
						for (var s=0; s<tiddlers[t].links.length; s++)
							tids.pushUnique(tiddlers[t].links[s]);
						break;
					}
				break;
			case "search":
				for (var t=0; t<tiddlers.length; t++)
					if (tiddlers[t].text.indexOf(params[p].value)!=-1)
						tids.pushUnique(tiddlers[t].title);
				break;
		}
	}
	var matches=[];
	for (var t=0; t<tiddlers.length; t++)
		if (tids.contains(tiddlers[t].title))
			matches.push(tiddlers[t]);
	displayMessage(config.macros.importTiddlers.filterMsg.format([matches.length,hash]));
	config.macros.importTiddlers.lastFilter=hash;
	return matches;
}
//}}}

// // re-entrant processing for handling import with interactive collision prompting
//{{{
function importTiddlers(startIndex)
{
	var cmi=config.macros.importTiddlers; // abbreviation

	if (!cmi.inbound) return -1;

	var list = document.getElementById('importList');
	if (!list) return;
	var t;
	// if starting new import, reset import status flags
	if (startIndex==0)
		for (var t=0;t<cmi.inbound.length;t++)
			cmi.inbound[t].status="";
	for (var i=startIndex; i<list.options.length; i++)
		{
		// if list item is not selected or is a heading (i.e., has no value), skip it
		if ((!list.options[i].selected) || ((t=list.options[i].value)==""))
			continue;
		for (var j=0;j<cmi.inbound.length;j++)
			if (cmi.inbound[j].title==t) break;
		var inbound = cmi.inbound[j];
		var theExisting = store.getTiddler(inbound.title);
		// avoid redundant import for tiddlers that are listed multiple times (when 'by tags')
		if (inbound.status=="added")
			continue;
		// don't import the "ImportedTiddlers" history from the other document...
		if (inbound.title=='ImportedTiddlers')
			continue;
		// if tiddler exists and import not marked for replace or merge, stop importing
		if (theExisting && (inbound.status.substr(0,7)!="replace") && (inbound.status.substr(0,5)!="merge"))
			return i;
		// assemble tags (remote + existing + added)
		var newTags = "";
		if (cmi.importTags)
			newTags+=inbound.getTags()	// import remote tags
		if (cmi.keepTags && theExisting)
			newTags+=" "+theExisting.getTags(); // keep existing tags
		if (cmi.addTags && cmi.newTags.trim().length)
			newTags+=" "+cmi.newTags; // add new tags
		inbound.set(null,null,null,null,newTags.trim());
		// set the status to 'added' (if not already set by the 'ask the user' UI)
		inbound.status=(inbound.status=="")?'added':inbound.status;
		// set sync fields
		if (cmi.sync) {
			if (!inbound.fields) inbound.fields={}; // for TW2.1.x backward-compatibility
			inbound.fields["server.page.revision"]=inbound.modified.convertToYYYYMMDDHHMM();
			inbound.fields["server.type"]="file";
			inbound.fields["server.host"]=(cmi.local?"file://":"")+cmi.src;
		}
		// do the import!
		store.suspendNotifications();
		store.saveTiddler(inbound.title, inbound.title, inbound.text, inbound.modifier, inbound.modified, inbound.tags, inbound.fields, true, inbound.created);
                store.fetchTiddler(inbound.title).created = inbound.created; // force creation date to imported value (needed for TW2.1.x and earlier)
		store.resumeNotifications();
		}
	return(-1);	// signals that we really finished the entire list
}
//}}}

//{{{
function importStopped()
{
	var cmi=config.macros.importTiddlers; // abbreviation
	var list = document.getElementById('importList');
	var theNewTitle = document.getElementById('importNewTitle');
	if (!list) return;
	if (cmi.index==-1){ 
		document.getElementById('importStart').value=cmi.startText;
		importReport();		// import finished... generate the report
	} else {
		// import collision...
		// show the collision panel and set the title edit field
		document.getElementById('importStart').value=cmi.stopText;
		cmi.showPanel('importCollisionPanel',true);
		theNewTitle.value=list.options[cmi.index].value;
		if (document.getElementById('importApplyToAll').checked
			&& cmi.lastAction
			&& cmi.lastAction.id!="importRename") {
			onClickImportButton(cmi.lastAction);
		}
	}
}
//}}}

// // ''REPORT GENERATOR''
//{{{
function importReport()
{
	var cmi=config.macros.importTiddlers; // abbreviation
	if (!cmi.inbound) return;

	// if import was not completed, the collision panel will still be open... close it now.
	var panel=document.getElementById('importCollisionPanel'); if (panel) panel.style.display='none';

	// get the alphasorted list of tiddlers
	var tiddlers = cmi.inbound;
	// gather the statistics
	var count=0; var total=0;
	for (var t=0; t<tiddlers.length; t++) {
		if (!tiddlers[t].status || !tiddlers[t].status.trim().length) continue;
		if (tiddlers[t].status.substr(0,7)!="skipped") count++;
		total++;
	}
	// generate a report
	if (total) displayMessage(cmi.processedMsg.format([total]));
	if (count && config.options.chkImportReport) {
		// get/create the report tiddler
		var theReport = store.getTiddler('ImportedTiddlers');
		if (!theReport) { theReport= new Tiddler(); theReport.title = 'ImportedTiddlers'; theReport.text  = ""; }
		// format the report content
		var now = new Date();
		var newText = "On "+now.toLocaleString()+", "+config.options.txtUserName
		newText +=" imported "+count+" tiddler"+(count==1?"":"s")+" from\n[["+cmi.src+"|"+cmi.src+"]]:\n";
		if (cmi.addTags && cmi.newTags.trim().length)
			newText += "imported tiddlers were tagged with: \""+cmi.newTags+"\"\n";
		newText += "<<<\n";
		for (var t=0; t<tiddlers.length; t++) if (tiddlers[t].status) newText += "#[["+tiddlers[t].title+"]] - "+tiddlers[t].status+"\n";
		newText += "<<<\n";
		// update the ImportedTiddlers content and show the tiddler
		theReport.text	 = newText+((theReport.text!="")?'\n----\n':"")+theReport.text;
		theReport.modifier = config.options.txtUserName;
		theReport.modified = new Date();
                store.saveTiddler(theReport.title, theReport.title, theReport.text, theReport.modifier, theReport.modified, theReport.tags, theReport.fields);
		story.displayTiddler(null,theReport.title,1,null,null,false);
		story.refreshTiddler(theReport.title,1,true);
	}

	// reset status flags
	for (var t=0; t<cmi.inbound.length; t++) cmi.inbound[t].status="";

	// mark document as dirty and let display update as needed
	if (count) { store.setDirty(true); store.notifyAll(); }

	// always show final message when tiddlers were actually loaded
	if (count) displayMessage(cmi.importedMsg.format([count,tiddlers.length,cmi.src.replace(/%20/g," ")]));
}
//}}}

// // File and XMLHttpRequest I/O
//{{{
config.macros.importTiddlers.askForFilename=function(here) {
	var msg=here.title; // use tooltip as dialog box message
	var path=getLocalPath(document.location.href);
	var slashpos=path.lastIndexOf("/"); if (slashpos==-1) slashpos=path.lastIndexOf("\\"); 
	if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash
	var file="";
	var result="";
	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.modeOpen);
			var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
			thispath.initWithPath(path);
			picker.displayDirectory=thispath;
			picker.defaultExtension='html';
			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 { // XPSP2 IE only
			var s = new ActiveXObject('UserAccounts.CommonDialog');
			s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
			s.FilterIndex=3; // default to HTML files;
			s.InitialDir=path;
			s.FileName=file;
			if (s.showOpen()) var result=s.FileName;
		}
		catch(e) {  // fallback
			var result=prompt(msg,path+file);
		}
	}
	return result;
}

config.macros.importTiddlers.fileExists=function(theFile) {
	var found=false;
	if(window.Components) {
		try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
		catch(e) { return false; } // security access denied
		var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
		try { file.initWithPath(theFile); }
		catch(e) { return false; } // invalid directory
		found = file.exists();
	}
	else { // use ActiveX FSO object for MSIE 
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		found = fso.FileExists(theFile)
	}
	return found;
}

config.macros.importTiddlers.loadRemoteFile = function(src,callback) {
	if (src==undefined || !src.length) return null; // filename is required
	var original=src; // URL as specified
	var hashpos=src.indexOf("#"); if (hashpos!=-1) src=src.substr(0,hashpos); // URL with #... suffix removed (needed for IE)
	clearMessage();
	displayMessage(this.openMsg.format([src.replace(/%20/g," ")]));
	if (src.substr(0,5)!="http:" && src.substr(0,5)!="file:") { // if src is relative (i.e., not a URL)
		if (!this.fileExists(src)) { // if file cannot be found, might be relative path.. try fixup
			var pathPrefix=document.location.href;  // get current document path and trim off filename
			var slashpos=pathPrefix.lastIndexOf("/"); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf("\\"); 
			if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
			src=pathPrefix+src;
			if (pathPrefix.substr(0,5)!="http:") src=getLocalPath(src);
		}
	}
	if (src.substr(0,5)!="http:" && src.substr(0,5)!="file:") { // if not remote URL, read from local filesystem
		var txt=loadFile(src);
		if ((txt==null)||(txt==false)) // file didn't load
			{ displayMessage(config.macros.importTiddlers.openErrMsg.format([src.replace(/%20/g," "),"(filesystem error)"])); }
		else {
			displayMessage(config.macros.importTiddlers.readMsg.format([txt.length,src.replace(/%20/g," ")]));
			if (callback) callback(true,original,convertUTF8ToUnicode(txt),src,null);
		}
	}
	else {
		var name=config.options.txtRemoteUsername; var pass=config.options.txtRemotePassword;
		var xhr=doHttp("GET",src,null,null,name,pass,callback,original,null)
		if (!xhr) displayMessage(config.macros.importTiddlers.openErrMsg.format([src,"(XMLHTTPRequest error)"]));
	}
}

config.macros.importTiddlers.readTiddlersFromHTML=function(html)
{
	var remoteStore=new TiddlyWiki();
	remoteStore.importTiddlyWiki(html);
	return remoteStore.getTiddlers("title");	
}
//}}}
On 2008年7月13日 下午 01:25:47, 比目魚 imported 1 tiddler from
[[D:\MCSE2008\toBalaKMKNotepad-SESE-01XP-200806.html|D:\MCSE2008\toBalaKMKNotepad-SESE-01XP-200806.html]]:
<<<
#[[如何把ubuntu 7.04(完整Linux系統,非Live CD)裝入隨身碟中(傻瓜必勝版)]] - added
<<<
/***
|''Name:''|IntelliTaggerPlugin|
|''Version:''|1.0.2 (2007-07-25)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[IntelliTaggerPlugin Documentation]]|
|''~SourceCode:''|[[IntelliTaggerPlugin SourceCode]]|
|''Licence:''|[[BSD open source license (abego Software)]]|
|''~CoreVersion:''|2.0.8|
|''Browser:''|Firefox 1.5.0.2 or better|
***/
/***
!Version History
* 1.0.2 (2007-07-25): 
** Feature: "Return" key may be used to accept first tag suggestion (beside "Alt-1")
** Bugfix: Keyboard shortcuts (Alt+3 etc.) shifted
* 1.0.1 (2007-05-18): Improvement: Speedup when using TiddlyWikis with many tags
* 1.0.0 (2006-04-26): Initial release

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

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

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

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

if (config.commands.intelliTagsEdit) 
    return;

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

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

})();
//}}}
!BIOS
*三大 BIOS 掌握的資源:
**I/O: I/O address,cat /proc/ioports
**IRQ:插斷位址,cat /proc/interrupts
|IRQ|4|com1|ttyS0|
||3|com2|ttyS1|
||4|com3|ttyS2|
||3|com4|ttyS3|
||7|LPT1|lp0|
**DMA:記憶體直接存取的通道,cat /proc/dma
*cat /proc/pci,若無則使用 lspci

!!數據機與音效卡
*確定設備是否符合相容性要求
**modem 不是 win-modem
*數據機使用 wvdial 撥號
*設定序列埠速率

!!非 IDE 介面
*SCSI ID
*/proc/scsi
*scsi_info (未安裝)
**scsiutils 套件 http://www.rpmfind.net 搜尋

!!USB
*uhci
*ohci
!!!以上為 USB1.1 使用的模組
*ehci:USB2.0 → 480 Mbps

!!印表機
*http:/ /localhost:631
*主要組態檔:/etc/printcap
{{{
名稱|別名:key=value:......
VMware_Virtual_Printer|VMware_Virtual_Printer:rm=ms1.i129.com:rp=VMware_Virtual_Printer:
}}}
**語系不同、需列印非純文字文件時才需要驅動程式
*<<slider lpr lpr lpr "">>

!!X windows
*主要組態檔存放在 /etc/X11
*starx → xinit → X
*測試環境 Ubuntu 8.04
{{{
sudo apt-get install chmsee

cd /var/lib
sudo ln -s xulrunner-1.9.0.2/libxul.so libxul.so
sudo ln -s xulrunner-1.9.0.2/libxpcom.so libxpcom.so
sudo ln -s xulrunner-1.9.0.2/libsqlite3.so libsqlite3.so
sudo ln -s xulrunner-1.9.0.2/libmozjs.so libmozjs.so
}}}
*請自行將 xulrunner 版本數置換
*LPIC:選擇填充,中立版本,101、102
**http://www.lpi.org
*RHCE:實作、實機、搭配部份測驗題(一小時),考試一整天,上午疑難排解、測驗,下午佈署安裝
*NCLP:Novell SuSE,實作、非實機,遠端連線考試,沒有 tab,有 man
{{{
mount -t iso9660 xxx.iso /media/iso -o loop, utf8
}}}
<<tagsTree system "" 1 4 index label>>
<<tagsTree net "" 1 4 index label>>
<<tagsTree pb "" 1 4 index label>>
<<tagsTree kl "" 2 4 index label>>
<<tagsTree supplement "" 1 4 index label>>
<<tagsTree twcms "" 1 4 index label>>
<<tagsTree KMKConfig "" 1 4 index label>>
<<tabs txtMainTab "最近更新" "依更新日期排序" TabTimeline "分類" "所有標籤" TabTags "設定文章" "說所有設定文章" TabMoreShadowed>>

<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
<!--}}}-->

<!--{{{-->
<style type="text/css">
#contentWrapper {display:none;}
</style>

<div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;">
<b>Sky of flatfish</b><br><br><img src="loader.gif"><br>
<span style="font-size: 14px; color:red;">Requires Javascript.</span>
</div>
<!--}}}-->
!網路上找到的最速安裝法
#下載 skype for CentOS 版本
#執行 rpm -ivh skype-2.0.0.72-centos.i586.rpm 會出現要使用的四個檔案找不到
#使用 yum install 加上缺少的四個檔案
#再次執行 rpm -ivh skype-2.0.0.72-centos.i586.rpm 即可安裝完成

!災難篇
*安裝了 Qt 4.3.4,結果執行 rpm -ivh skype-2.0.0.72-centos.i586.rpm 依然提示要求要 Qt >= 4.2
**解決法:
{{{
wget  http://gd.tuwien.ac.at/infosys/phone/skype/rpm-public-key.asc
rpm --import rpm-public-key.asc
yum -y install skype-2.0.0.72-centos.i586.rpm
}}}
*中文版 Skype 在 CentOS 中文版顯示亂碼
**解決方法:複製以下命令,編輯 Skype 命令取代原來僅有的 skype
{{{
env LC_ALL=en_US.UTF-8 skype
}}}
!給吸準備
*下載以下檔案備用
**[[VLC 主程式|http://dag.wieers.com/rpm/packages/vlc/vlc-0.8.6d-1.el5.rf.i386.rpm]]   
**[[Debian's Advanced Packaging Tool with RPM support. |http://dag.wieers.com/rpm/packages/apt/apt-0.5.15lorg3.2-1.el5.rf.i386.rpm]]  
**[[RPMforge release file and package configuration. |http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.i386.rpm]]  

!安裝
{{{
rpm -ivh apt-0.5.15lorg3.2-1.el5.rf.i386.rpm
rpm -ivh rpmforge-release-0.3.6-1.el5.rf.i386.rpm
yum -y install vlc-0.8.6d-1.el5.rf.i386.rpm
}}}
在 /etc/dhcp3/dhclient.conf 最後面新增下面一行
{{{
prepend domain-name-servers  168.95.1.1;
}}}
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryDark]]'>
<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='toolBar' refresh='content' force='true' tiddler='ToolBar'></div>
<div id='mainMenu' refresh='content' force='true' tiddler='MainMenu'></div>

<!--
<div id='sidebar'>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
-->

<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
//{{{
//============================================================================
//                           PartTiddlerPlugin

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

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

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

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

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


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

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

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

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

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

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

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

	// Parse the start tag parameters
	var arguments = parseStartTagParams(tagMatch[3]);
	if (!arguments) return false;
	
	// Continue processing
	var startTagEndIndex = skipEmptyEndOfLine(w.source, tagMatch.index + tagMatch[0].length);
	var endMatch = findNextPartEndOrStartTagMatch(w.source, startTagEndIndex);
	if (endMatch && endMatch[1]) {
		if (!arguments.isHidden) {
			w.nextMatch = startTagEndIndex;
			w.subWikify(w.output,partEndTagREString);
		}
		w.nextMatch = skipEmptyEndOfLine(w.source, endMatch.index + endMatch[0].length);
		
		return true;
	}
	return false;
}

config.formatters.push( {
    name: "part",
    match: "<part\\s+[^>]+>",
	
	handler: function(w) {
		if (!handlePartSection(w)) {
			w.outputText(w.output,w.matchStart,w.matchStart+w.matchLength);
		}
	}
} )

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

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

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

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

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

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

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

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




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

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

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

	return this.abegoIsPartTiddler;
}

config.commands.editTiddler.handler = 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;
		}
	};
})();

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

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

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

} // of "install only once"
//}}}
{{{
Rsync + SSH -- 讓 Server 自動異地備援也加密
一.前言
自從911事件之後...異地備援這個名稱就常聽人提起...不過就是滿少看到大家在討論...剛好這次因為有需要...不得不研究這個東西...順便看看大家都是怎樣實作異地備援的...底下是個人的一點點心得...
這次主要分成三個部份...單向 Trusted SSH Authorized...Rsync...Crontab....姑且不論傳輸速度為何...以及無時差的異地備援...相信這樣的Solutions應該可以滿足一般人的需求吧

二.準備
測試系統: Red Hat Linux 7.3 to Red Hat 7.3 ...
Local 端需要啟動 Rsync...套件 openssh-3.4p1-1

** 假設: A (10.0.0.1) 要對 B (192.168.0.1) 做異地備援
PS:角色定位要明確...當然您要巔倒的來做也行...

參考網站 : http://www.fanqiang.com/a6/b7/20010908/1305001258_b.html

三.開始實作

1.完成單向Trusted SSH Authorized﹕
我要 A (10.0.0.1) 要對 B (192.168.0.1) 做異地備援 ...所以我針對 A 讓它使用SSH連到 B 時...不需要輸入密碼...User 是 Root...SSH Version2的版本..首先要先在A(10.0.0.1)產生public/private dsa key pair..

[root@mondeo home]# cd /root/.ssh/
[root@mondeo .ssh]# ssh-keygen -d
Generating public/private dsa key pair.
Enter file in which to save the key (/root/.ssh/id_dsa):
Enter passphrase (empty for no passphrase): <-- 此處不打passphrase..下次才不會詢問password
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
The key fingerprint is:
11:22:33:44:55:66:77:88:99:00:11:22:33:44:55:66 root@mondeo.adj.idv.tw
[root@mondeo .ssh]#

這時會在系統下看到兩個檔案...id_dsa與id_dsa.pub 現在要把id_dsa.pub丟到192.168.0.1 並且更名為 authorized_keys2

[root@mondeo .ssh]# scp id_dsa.pub 192.168.0.1:/root/.ssh/authorized_keys2
root@192.168.0.1's password:
id_dsa.pub 100% |***************************************************************************| 612 00:00
[root@mondeo .ssh]#


現在您可以執行ssh 192.168.0.1 看看能否登入而不需要輸入密碼...

2.使用rsync 做Remote sync﹕
rsync特性簡介 :
rsync是unix-like系統下的數據鏡像備份工具,從命名上就可以看出來了remote sync。它的特性如下:
1、可以鏡像保存整個目錄樹和文件系統。
2、可以很容易做到保持原來文件的權限、時間等等。
3、無須特殊權限即可安裝。
4、優化的流程,文件傳輸效率高。
5、可以使用rcp、ssh等方式來傳輸文件,當然也可以通過直接的socket連接。
6、支持匿名傳輸。

首先要先對B(192.168.0.1)把Rsync的Server on起來...
[root@linux /]#chkconfig --list rsync
rsync off
[root@linux /]#chkconfig rsync on

現在我先在A(10.0.0.1)上建一個 Backup directory...然後對B(192.168.0.1)的mysql跟html的目錄做異地備援...偶寫一個簡單的script如下:

[root@mondeo /]# mkdir backup
[root@mondeo backup]#vi sync

rsync -avlR --delete -e ssh 192.168.0.1:/var/lib/mysql /backup/
rsync -avlR --delete -e ssh 192.168.0.1:/var/www/html /backup/
[root@mondeo backup]#chmod 700 sync

參數意義如下﹕
-a, --archive
It is a quick way of saying you want recursion and want to preserve almost everything.
-v, --verbose
This option increases the amount of information you are given during the transfer.
-l, --links
When symlinks are encountered, recreate the symlink on the destination.
-R, --relative
Use relative paths. 保留相對路徑...才不會讓子目錄跟 parent 擠在同一層...
--delete
是指如果Server端刪除了一文件,那客戶端也相應把這一文件刪除,保持真正的一致。
-e ssh
建立起加密的連接。
參數的使用因人而異...您可以man rsync來使用更多的參數...

測試看看:
[root@mondeo backup]# ./sync
receiving file list ... done
.
.
.
done
wrote 16 bytes  read 107 bytes  82.00 bytes/sec
total size is 0  speedup is 0.00
receiving file list ... done
.
.
.
done
wrote 16 bytes  read 921 bytes  624.67 bytes/sec
total size is 308331  speedup is 329.06
[root@mondeo backup]#
看到沒詢問密碼....以及有把檔案copy過來就沒問題囉....當然你可以把遠端的資料做個變動...看是否真有同步啦....

3.使用crontab 來做自動排程﹕

現在設好之後...我希望每天的0點0分...夜深人靜的時後再來幫我做sync....當然您想要多久做 sync 看個人需求囉...
[root@mondeo backup]# crontab -e0 0 * * * /backup/sync

如此一來..算是大功告成了...原則上您已具備自動加密異地備援囉....趕緊找兩台機器來試試吧...
以上只是個人測試結果...如有錯誤...煩請指教!!!
}}}

轉錄自 http://dz.adj.idv.tw/thread-48-1-4.html
{{{
Subject: □ Unix 的批次檔 - Shell Script□


       台大計算機中心網路推廣協會
              網路課程講義

課程名稱:UNIX的批次檔 ── Shell Script
上課日期:82年11月16日
講師:蔡孟光
───────────────────────────
<<<版權聲明>>>
本著作物版權屬於國立台灣大學電子計算機中心。為了推廣網路的使用,除了下列的限
制之外,任何人均可以任何型式複製或修改這份講義。
一、不得有任何的商業行為
二、複製或修改這份講義時,必須將本版權聲明列入,並註明之
三、國立台灣大學電子計算機中心不對修改過後的內容負任何的責任
───────────────────────────
<<<目錄>>>
□前言
□將文字檔設為可執行的Shell Script
□Script的基本結構及觀念
□Bourne Shell
  一、變數
  二、執行命令
  三、流程控制
□C Shell
  一、變數
  二、執行命令
  三、流程控制

□附錄A    expr命令
□附錄B    test命令



□前言

    在DOS 中,你可能會從事一些例行的重覆性工作,此時你會將這些重覆性的命令寫
成批次檔,只要執行這個批次檔就等於執行這些命令。大家會問在UNIX中是否有批次處
理這個東東,答案是有的。在UNIX中不只有如DOS 的批次處理,它的功能比起DOS 更強
大,相對地也較複雜,已經和一般的高階語言不相上下。在UNIX中大家都不叫做批次檔
,而叫做Shell Script。
    一般而言,Shell Script的地位和其它的可執行檔(或命令)是完全相同的,只不
過Shell Script是以文字檔的方式儲存,而非二進位檔。而執行Shell Script時,必須
有一個程式將其內容轉成一道道的命令執行,而這個程式其實就是Shell ,這也就是為
什麼我們叫做Shell Script的原因(往後我們稱為Script)。不同Shell 的Script基本
上會有一些差異,所以我們不能將寫給A shell 的Script用B shell 執行。而在UNIX中
大家最常使用Bourne Shell以及C Shell ,所以這堂課就介紹這兩種Script的寫法。


□將文字檔設為可執行的Shell Script

    如果我們已經寫好Script,如何將其設成可執行檔呢?因為Script其實是一個可執
行檔,所以必須將其存取權設定成可執行。我們可以使用下列命令更改存取權:

        chmod u+x filename      只有自己可以執行,其它人不能執行
        chmod ug+x filename     只有自己以及同一群可以執行,其它人不能執行
        chmod +x filename       所有人都可以執行

    而我們如何指定使用那一個Shell 來解釋所寫的Script呢?幾種基本的指定方式如
下所述:
1. 如果Script的第一個非空白字元不是"#",則它會使用Bourne Shell。
2. 如果Script的第一個非空白字元是"#"時,但不以"#!"開頭時,則它會使用C Shell。
3. 如果Script以"#!"開頭,則"#!"後面所寫的就是所使用的Shell,而且要將整個路徑
    名稱指出來。
這裡建議使用第三種方式指定Shell ,以確保所執行的就是所要的。Bourne Shell的路
徑名稱為/bin/sh ,而C Shell 則為/bin/csh。

    <eg>
        1. 使用Bourne Shell
            ┌──────────┐    ┌──────────┐
            │echo enter filename │    │#!/bin/sh           │
            │      .             │ or │      .             │
            │      .             │    │      .             │
            │      .             │    │      .             │
            └──────────┘    └──────────┘

        2. 使用C Shell
            ┌──────────┐    ┌──────────┐
            │# C Shell Script    │    │#!/bin/csh          │
            │      .             │    │      .             │
            │      .             │    │      .             │
            │      .             │    │      .             │
            └──────────┘    └──────────┘

        3. 使用/etc/perl
            ┌──────────┐
            │#! /etc/perl        │
            │      .             │
            │      .             │
            │      .             │
            └──────────┘

    除了在Script內指定所使用的Shell 外,你也可以在命令列中強制指定。比如你要
用C Shell 執行某個Script,你可以下這個命令:

        csh filename

此時的Script的存取權就不一定要為可執行檔,其內部所指定的Shell 也會無效,詳細
的情形後面會討論。


□Script的基本結構及觀念

    Script是以行為單位,我們所寫的Script會被分解成一行一行來執行。而每一行可
以是命令、註解、或是流程控制指令等。如果某一行尚未完成,可以在行末加上"\" ,
這個時候下一行的內容就會接到這一行的後面,成為同一行,如下
        ┌───────────┐
        │echo The message is \ │
        │too long so we have \ │
        │to split it into \    │
        │several lines         │
        └───────────┘
    當Script中出現"#" 時,再它後面的同一行文字即為註解,Shell 不會對其翻譯。
    在Script中要執行一個命令的方法和在命令列中一樣,你可以前景或背景執行,執
行命令時也會需要設定一些環境變數。
    Script的流程控制和一般高階語言的流程控制沒有什麼兩樣,也和高階語言一樣有
副程式。這些使得Script的功能更加強大。
    為了達到與高階語言相同的效果,我們也可以在Script中設定變數,如此使Script
成為一個名付其實的高階語言。


□Bourne Shell

一、變數

    Bourne Shell的變數型態只有字串變數,所以要使用數值運算則必須靠外部命令達
    成目的。而其變數種類有下列幾種:

    1. 使用者變數
        這是最常使用的變數,我們可以任何不包含空白字元的字串來當做變數名稱。
        設定變數值時則用下列方式:

            var=string

        取用變數時則在變數名稱前加上一"$" 號。

        <eg>
            ┌───────┐
            │name=Tom      │
            │echo name     │
            │echo $name    │
            └───────┘
            結果如下:
            name
            Tom

    2. 系統變數(環境變數)
        和使用者變數相似,只不過此種變數會將其值傳給其所執行的命令。要將一使
        用者變數設定為系統變數,只要加上:

            export var

        <eg>
            ┌───────┐
            │name=Tom      │
            │export name   │
            └───────┘

        以下是使用者一進入系統之後就已設定好的系統變數:

            $HOME       使用者自己的目錄
            $PATH       執行命令時所搜尋的目錄
            $TZ         時區
            $MAILCHECK  每隔多少秒檢查是否有新的信件
            $PS1        在命令列時的提示號
            $PS2        當命令尚未打完時,Shell 要求再輸入時的提示號
            $MANPATH    man 指令的搜尋路徑

    3. 唯讀的使用者變數
        和使用者變數相似,只不過這些變數不能被改變。要將使用者變數設成唯讀的
        ,只要加上:

            readonly var

        而若只打readonly則會列出所有唯讀的變數。還有一點,系統變數不可以設定
        成唯讀的。

        <eg>
            ┌───────┐
            │name=Tom      │
            │readonly name │
            │echo $name    │
            │name=John     │
            │readonly      │
            └───────┘
            結果如下:
            Tom
            name: is read only
            readonly name
            readonly ......

    4. 特殊變數
        有些變數是一開始執行Script時就會設定,並且不以加以修改,但我們不叫它
        唯讀的系統變數,而叫它特殊變數(有些書會叫它唯讀的系統變數),因為這
        些變數是一執行程式時就有了,況且使用者無法將一般的系統變數設定成唯讀
        的。以下是一些等殊變數:

            $0      這個程式的執行名字
            $n      這個程式的第n個參數值,n=1..9
            $*      這個程式的所有參數
            $#      這個程式的參數個數
            $$      這個程式的PID
            $!      執行上一個背景指令的PID
            $?      執行上一個指令的返回值

        當你執行這個程式時的參數數目超過9 個時,我們可以使用shift 命令將參數
        往前移一格,如此即可使用第10個以後的參數。除此之外,吾人可以用set 命
        令改變$n及$*,方法如下:

            set string

        如此$*的值即為string,而分解後則會放入$n。如果set 命令後面沒有參數,
        則會列出所有已經設定的變數以及其值。

        <eg>
            檔名:ex1  參數:this is a test
            ┌───────────┐
            │echo Filename: $0     │
            │echo Arguments: $*    │
            │echo No. of args.: $# │
            │echo 2nd arg.: $2     │
            │shift                 │
            │echo No. of args.: $# │
            │echo 2nd arg.: $2     │
            │set hello, everyone   │
            │echo Arguments: $*    │
            │echo 2nd arg.: $2     │
            └───────────┘
            結果如下:
            Filename: ex1
            Arguments: this is a test
            No. of args.: 4
            2nd arg.: is
            No. of args.: 3
            2nd arg.: a
            Arguments: hello, everyone
            2nd arg.: everyone

    值得一提的是,當你想從鍵盤輸入一變數值時,你可以使用下面的命令:

        read var1 var2.....

    這時read會將一個字分給一個變數。如果輸入的字比變數還多,最後一個變數會將
    剩下的字當成其值。如果輸入的字比變數還少,則後面的變數會設成空字串。
        如果需要處理數值運算,我們可以使用expr命令。其參數及輸出列於附錄A。


二、執行命令

    在Bourne Shell中有五種方法執行一個命令,而這五種方式所產生的果有些許的不
    同。
    1. 直接下命令
        這個方式和在命令列中直接下命令的效果一樣。
    2. 使用sh命令

            sh command

        這個檔案必須是Bourne Shell的Script,但這個檔案並不一定要設成可執行。
        除此之外和直接下命令的方式一樣。
    3. 使用"."命令

            . command

        這時和使用sh命令相似,只不過它不像sh一般會產生新的process ,相反地,
        它會在原有的process 下完成工作。
    4. 使用exec命令

            exec command

        此時這個Script將會被所執行的命令所取代。當這個命令執行完畢之後,這個
        Script也會隨之結束。
    5. 使用命令替換
        這是一個相當有用的方法。如果想要使某個命令的輸出成為另一個命令的參數
        時,就一定要使用這個方法。我們將命令列於兩個"`" 號之間,而Shell 會以
        這個命令執行後的輸出結果代替這個命令以及兩個"`" 符號。

        <eg>
            str='Current directory is '`pwd`
            echo $str
            結果如下:
            Current directory is /users/cc/mgtsai
            這個意思是pwd 這個命令輸出"/users/cc/mgtsai",而後整個字串代替原
            來的`pwd` 設定str 變數,所以str 變數的內容則會有pwd 命令的輸出。

        <eg>
            number=`expr $number + 1`
            這就是先前所提要作數值運算的方法,基本上expr命令只將運算式解,而
            後輸出到標準輸出上。如果要將某變數設定成其值,非得靠命令替換的方
            式不可。這個例子是將number變數的值加1 後再存回number變數。


三、流程控制

    在介紹流程控制之前,我們先來看看test命令。test命令的參數是條件判斷式,當
    條件為真時則傳回非零值,而條件為偽時則傳回零。在所有的流程控制都必須用到
    test命令來判斷真偽。而test命令的使用方法則列於附錄B。

    <eg>
        test $# = 0
        如果執行這個程式沒有參數時,會傳回非零值代表"$# = 0"這個條件成立。反
        之則會傳回零。

    以下介紹各種流程控制:

    1. if then
        語法以及流程圖如下
                                             │      FALSE
            if (condition)              <condition>─┐
              then                           │TRUE    │
                then-commands           then-commands  │
            fi                               ├────┘
                                             │

        condition 是一個test命令。往後所介紹的各種流程中的condition 都是test
        命令。

        <eg>
            檔名:chkarg
            ┌───────────┐
            │if (test $# != 0)     │
            │  then                │
            │    echo Arg1: $1     │
            │fi                    │
            └───────────┘
            $ chkarg Hello
            Arg1: Hello
            $ chkarg
            $

    2. if then else
        語法以及流程圖如下
                                             │       FALSE
            if (condition)              <condition>─────┐
              then                           │TRUE            │
                then-commands           then-commands    else-commands
              else                           ├────────┘
                else-commands                │
            fi

    3. if then elif
        語法以及流程圖如下
                                            │       FALSE
            if (condition1)             <condition1>─┐
              then                          │TRUE      │      FALSE
                commands1              commands1  <condition2>─┐
            elif (condition2)               │          │TRUE    │
              then                          │     commands2   commands3
                commands2                   ├─────┴────┘
              else                          │
                commands3
            fi

        <eg>
            echo 'word 1: \c'
            read word1
            echo 'word 2: \c'
            read word2
            echo 'word 3: \c'
            read word3
            if (test "$word1" = "$word2" -a "$word2" = "$word3")
              then
                echo 'Match: words 1, 2, & 3'
            elif (test "$word1" = "$word2")
              then
                echo 'Match: words 1 & 2'
            elif (test "$word1" = "$word3")
              then
                echo 'Match: words 1 & 3'
            elif (test "$word2" = "$word3")
              then
                echo 'Match: words 2 & 3'
            else
                echo 'No match'
            fi

    4. for in
        語法以及流程圖如下
                                                  │            FALSE
            for var in arg-list     ┌─<arg-list還有東西嗎?>─┐
              do                    │            │TRUE          │
                commands            │     從arg-list取得一項     │
            done                    │     放到變數var            │
                                    │            │              │
                                    │          commands          │
        <eg>                        └──────┘              │
            ┌───────────┐            ┌───────┘
            │for a in xx yy zz     │            │
            │  do                  │
            │    echo $a           │
            │done                  │
            └───────────┘
            結果如下:
            xx
            yy
            zz

    5. for
        語法以及流程圖如下
                                                  │            FALSE
            for var                   ┌─<參數中還有東西嗎?>─┐
              do                      │          │TRUE          │
                commands              │     從參數中取得一項     │
            done                      │     放到變數var          │
                                      │          │              │
                                      │        commands          │
        <eg>                          └─────┘              │
            檔名:lstarg                          ┌───────┘
            ┌───────────┐            │
            │for a                 │
            │  do                  │
            │    echo $a           │
            │done                  │
            └───────────┘
            $lstarg xx yy zz
            xx
            yy
            zz

    6. while
        語法以及流程圖如下
                                              │     FALSE
            while (condition)       ┌─<condition>─┐
              do                    │        │TRUE   │
                commands            │     commands    │
            done                    └────┘       │
                                             ┌────┘
                                             │
        <eg>
            ┌───────────────┐
            │number=0                      │
            │while (test $number -lt 10)   │
            │  do                          │
            │    echo "$number\c"          │
            │    number=`expr $number + 1` │
            │done                          │
            │echo                          │
            └───────────────┘
            結果如下:
            0123456789

    7. until
        語法以及流程圖如下
                                              │     TRUE
            until (condition)       ┌─<condition>─┐
              do                    │        │FALSE  │
                commands            │     commands    │
            done                    └────┘       │
                                             ┌────┘
                                             │
        它和while 的不同只在於while 是在條件為真時執行迴圈,而until 是在條件
        為假時執行迴圈。

    8. break及continue
        這兩者是用於for, while, until 等迴圈控制下。break 會跳至done後方執行
        ,而continue會跳至done執行,繼續執行迴圈。

    9. case
        語法以及流程圖如下
                                         │       TRUE
            case str in             <str=pat1>────commands1─┐
              pat1) commands1;;          │FALSE  TRUE             │
              pat2) commands2;;     <str=pat2>────commands2─┤
              pat3) commands3;;          │FALSE  TRUE             │
            esac                    <str=pat3>────commands3─┤
                                         │FALSE                   │
                                         ├────────────┘
                                         │
        而pat 除了可以指定一些確定的字串,也可以指定字串的集合,如下

            *       任意字串
            ?       任意字元
            [abc]   a, b, 或c三字元其中之一
            [a-n]   從a到n的任一字元
            |       多重選擇

        <eg>
            ┌───────────────┐
            │echo 'Enter A, B, or C: \c'   │
            │read letter                   │
            │case $letter in               │
            │  A|a) echo 'You entered A.';;│
            │  B|b) echo 'You entered B.';;│
            │  C|c) echo 'You entered C.';;│
            │  *) echo 'Not A, B, or C';;  │
            │esac                          │
            └───────────────┘

    10. 函數
        格式如下

        function-name()
        {
            commands
        }

        而要呼叫此函數,就像在命令列下直接下命令一般。


□C Shell

    C Shell 有些特性和Bourne Shell一樣,但有些不相同。這裡介紹與Bourne Shell
不相同的地方。


一、變數

    1. 字串變數
        這個部分和Bourne Shell的變數一樣,只不過在設定變數值時不能使用Bourne
        Shell的方式,而必須打:

            set var=value

    2. 數字運算
        基本上C Shell 沒有數字變數,但C Shell 卻有簡單的方法處理數字運算:

            @ var operator expression

        operator可以是C 語言中的=, +=, -=,......,而expression則是運算式。運
        算式的運算子如下:

            A. ()   改變計算的順序
~@
            B. ~    位元NOT運算
@~~
               !    邏輯否定
            C. %    取餘數
               /    除
               *    乘
               -    減
               +    加
            D. >>   右移
               <<   左移
            E. >    大於
               <    小於
               >=   大於等於
               <=   小於等於
               !=   不等於
               ==   等於
            F. &    位元AND運算
               ^    位元XOR運算
               |    位元OR 運算
            G. &&   邏輯AND
               ||   邏輯OR

        除此之外,我們也可以檢驗一個檔案的狀態,如下

            -n filename

        而-n可為下列之一

            -d  檔案是一個目錄檔案
            -e  檔案存在
            -f  檔案為一般的檔案
            -o  使用者擁有這個檔案
            -r  使用者可以讀取這個檔案
            -w  使用者可以寫入這個檔案
            -x  使用者可以執行這個檔案
            -z  檔案長度為0

        <eg>
            @ count = count + 1
            @ flag = -e /users/cc/mgtsai/mail && -e /usr/spool/mail

    3. 陣列
        在C Shell 中,我們可以宣告陣列變數,方式如下

            set var=(val1 val2 ......)

        而var[1]之值為val1,var[2]之值為val2......。而$var代表整個陣列。我們
        可以用$#var 來計算陣列個數,也可以用$?var 來檢查某個變數是否已宣告。

    4. 特殊變數
        $argv       和Bourne Shell的$*相似,只不過這是一個陣列。
        $argv[n]    和Bourne Shell的$n相同,但不受個數限制。
        $#argv      和Bourne Shell的$#相同
        $home       和Bourne Shell的$HOME相同
        $path       和Bourne Shell的$PATH相似,只不過這是一個陣列
        $prompt     和Bourne Shell的$PS1相同
        $shell      Shell的路徑名稱
        $status     和Bourne Shell的$?相同
        $$          和Bourne Shell的$$相同
        $<          鍵盤輸入


二、執行命令

    基本上和Bourne Shell相同,只有一點在Bourne Shell中的"." 命令在C Shell 中
    則為"source"命令。


三、流程控制

    在C Shell 中流程控制不像Bourne Shell中一般需要使用test命令。相反地,它和
    C 語言類似只要在條件中寫出運萛式即可。當運算結果不為零時,其值為真,為零
    時其值為偽。以下是C Shell的流程控制
    1. if
        語法如下

        if (expression) simple-command

    2. goto
        語法如下

        goto label

        這時程式會跳至以l"label:"開頭的那一行執行

        <eg>
            if ($#argv == 2) goto goodargs
            echo 'Please use two arguments.'
            exit
            goodrags:
            ...

    3. if then else
        這和Bourne Shell的if then, if then else, if then elif 相似。語法如下

        A.  if (expression) then
                commands
            endif

        B.  if (expression) then
                commands
            else
                commands
            endif

        C.  if (expression) then
                commands
            else if (expression) then
                commands
            else
                commands
            endif

    4. foreach
        這和Bourne Shell的for in相似。語法如下

            foreach var (arg-list)
                commands
            end

    5. while
        這和Bourne Shell的while相似。語法如下

            while (expression)
                commands
            end

    6. break及continue
        這和Bourne Shell的break 及continue相似,是用來中斷foreach 及while 迴
        圈。

    7. switch
        這和Bourne Shell的case相似。語法如下

            switch (string)
              case pat1:
                commands1
              breaksw
              case pat2:
                commands2
              breaksw
              case pat3:
                commands3
              breaksw
            endsw


□附錄A    expr命令


命令格式

    expr expression

敘述

    expression是由字串以及運算子所組成,每個字串或是運算子之間必須用空白隔開
    。下表是運算子的種類及功能,而優先順序則以先後次序排列,我們可以利用小括
    號來改變運算的優先次序。其運算結果則輸出至標準輸出上。

        :   字串比較。比較的方式是以兩字串的第一個字母開始,而以第二個字串的
            字母結束。如果相同時,則輸出第二個字串的字母個數,如果不同時則傳
            回0 。
        *   乘法
        /   除法
        %   取餘數
        +   加法
        -   減法
        <   小於
        <=  小於等於
        =   等於
        !=  不等於
        >=  大於等於
        >   大於
        &   AND運算
        |   OR運算

    當expression中含有"*", "(", ")" 等符號時,必須在其前面加上"\" ,以免被
    Shell 解釋成其它意義。

    <eg>    expr 2 \* \( 3 + 4 \)       其輸出為14


□附錄B    test命令


命令格式

    test expression

敘述

    expression中包含一個以上的判斷準則以作為test評詁的標準。兩準則間用"-a"代
    表邏輯AND 運算,"-o"代表邏輯OR運算,而在準則前放置一"!" 代表NOT 運算。如
    果沒有括號,則優先權則為"!" > "-a" > "-o" 。和expr命令相同,相使用左右括
    號時,必須在其前面加上"\" 。以下是有關準則的敘述(合敘述時傳回真,否則傳
    回偽):

        string              string不為空白字串
        -n string           string的長度大於0
        -z string           string的長度等於0
        string1=string2     string1等於string2
        string1!=string2    string1不等於string2
        int1 -gt int2       int1大於int2
        int1 -ge int2       int1大於等於int2
        int1 -eq int2       int1等於int2
        int1 -ne int2       int1不等於int2
        int1 -le int2       int1小於等於int2
        int1 -lt int2       int1小於int2
        -r filename         檔案可讀取
        -w filename         檔案可寫入
        -x filename         檔案可執行
        -f filename         檔案為一般檔
        -d filename         檔案為目錄
        -s filename         檔案為非空的一般檔

    <eg>     test -r "$filename" -a -s "$filename"


   ╭─────────────────────────────────╮
   │ ☆  ㄙ  ┼  〨┼ ┌┼╮ ☆     bbs.ntu.edu.tw      │
   │ ☆  O  Λ  Ο│ ╰┼╯ ☆    < 140.112.8.19 >     │
   ╰─────────────────────────────────╯
 


}}}
http://163.23.79.65/html/techdoc/shell.txt
<<tabs txtMainTab "最近更新" "依更新日期排序" TabTimeline "分類" "所有標籤" TabTags "設定文章" "說所有設定文章" TabMoreShadowed>>
<<showUpdates excludeTag:excludeLists write:'(index < 10) ? ""+""+ tiddler.modified.formatString("YYYY年0MM月0DD日")+ "\n&nbsp;&nbsp;&nbsp;&nbsp;[["  +tiddler.title+"]]"+"\n" : ""'>>
''flatfish''@2008 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;powered by TWtBala - TiddlyWiki 2.3.0
比目魚的天空 - Linux 也藍藍的!!!
/***
|''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);
	}
};


}
//}}}
/***

''Inspired by [[TiddlyPom|http://www.warwick.ac.uk/~tuspam/tiddlypom.html]]''

|Name|SplashScreenPlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#SplashScreenPlugin|
|Version|0.21 |
|Requires|~TW2.08+|
!Description:
Provides a simple splash screen that is visible while the TW is loading.

!Installation
Copy the source text of this tiddler to your TW in a new tiddler, tag it with systemConfig and save and reload. The SplashScreen will now be installed and will be visible the next time you reload your TW.

!Customizing
Once the SplashScreen has been installed and you have reloaded your TW, the splash screen html will be present in the MarkupPreHead tiddler. You can edit it and customize to your needs.

!History
* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.
* 26-06-06 : version 0.2, first release

!Code
***/
//{{{
var old_lewcid_splash_restart=restart;

restart = function()
{   if (document.getElementById("SplashScreen"))
        document.getElementById("SplashScreen").style.display = "none";
      if (document.getElementById("contentWrapper"))
        document.getElementById("contentWrapper").style.display = "block";
    
    old_lewcid_splash_restart();
   
    if (splashScreenInstall)
       {if(config.options.chkAutoSave)
			{saveChanges();}
        displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");
        }
}


var oldText = store.getTiddlerText("MarkupPreHead");
if (oldText.indexOf("SplashScreen")==-1)
   {var siteTitle = store.getTiddlerText("SiteTitle");
   var splasher='\n\n<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>'+siteTitle +'</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>';
   if (! store.tiddlerExists("MarkupPreHead"))
       {var myTiddler = store.createTiddler("MarkupPreHead");}
   else
      {var myTiddler = store.getTiddler("MarkupPreHead");}
      myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);
      store.setDirty(true);
      var splashScreenInstall = true;
}
//}}}
/*{{{*/

/* 主要項目樣式 

    在 Tiddler 中的使用格式如下 :
    {{item1{Item description}}}

*/
.item1{
 line-height:28px;
 font-weight:bold;
 font-size:14px;
 border-left: 10px solid blue;
 margin: 0px 0px 0px 20px;
 padding: 0px 0px 0px 3px;
 background-color:transparent;
}

/* 實作項目樣式 

    在 Tiddler 中的使用格式如下 :
    {{op1{operation description}}}

*/
.op1{
 line-height:28px;
 font-weight:bold; 
 font-size:14px;
 margin:0px 0px 0px 0px;
 padding: 0px 0px 0px 0px;
 background-color:transparent;
}


/*
Making preformated <pre> text wrap in CSS3, Mozilla, Opera and IE

word-wrap: break-word; - 視窗邊界換行,僅 IE 支援。也可以用 word-brak: break-all; 但不會保持英文單字的完整性。
white-space: pre; - 對某標籤作預先格式化,所有標準瀏覽器皆支援。
white-space: -moz-pre-wrap; - 預先格式化,但在元素邊界換行,僅 Mozilla (Firefox) 支援。
white-space: pre-wrap; - 預先格式化,但在元素邊界換行,僅 Opera 支援。
*/
.viewer pre {
  font-size:12px;
  white-space: pre-wrap;       /* css-3 */
  white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
  white-space: -pre-wrap;      /* Opera 4-6 */
  white-space: -o-pre-wrap;    /* Opera 7 */
  word-wrap: break-word;       /* Internet Explorer 5.5+ */
}
.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}


/*
無框線表格樣式設定, 以下是使用範例:

|!Col1|!Col2|!Col3|
|r1c1| r1r2c2 |r1c3|
|r2c1|~|r2c3|
|borderless|k    // 使用格式

*/
.borderless, .borderless table, .borderless td, .borderless tr, .borderless th, .borderless tbody { 
   border:0 !important; margin:0 !important; padding:2px !important; 
   td.vertical-align:top !important;margin-left: auto !important; 
   margin-right: auto !important;
}

.externalLink {text-decoration:none}

#toolBar { 
 background-color: #eee; 
 color:#ccc;
 width: auto;
 text-align:left;
 padding: 0.4em 0.6em 0.4em 0.6em;
}

h1,h2,h3 {padding-bottom:1px; margin-top:0.1em;margin-bottom:0.1em;}
h4,h5,h6 {margin-top:0.1em;}
h1 {font-size:1.2em;}
h2 {font-size:1.0em;}
h3 {font-size:0.8em;}
h4 {font-size:0.6em;}
h5 {font-size:0.4em;}

.headerShadow {position:relative; padding:2.0em 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:2.0em 0em 1em 1em; left:0px; top:0px;}

#mainMenu {
position:absolute; left:0; width:15.5em; text-align:left; line-height:1.2em; 
padding:1.0em 0.5em 0.2em 0.5em; font-size:1em;
}

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

/*
 toBalaFile 巨集的 Style 設定
*/
.toBalaFile {background:#fff; border:0px solid #ccc; padding:1px 7px 1px 3px; margin:2px;}
.toBalaFileEdit {border:1px solid #841;padding:2px;margin:2px 5px 2px 5px;}
.toBalaFileCancel {border:1px solid #841;padding:2px;margin:2px 5px 2px 5px;}
.toBalaFileToolBar {background:#fff;border-bottom: 3px solid #841;padding:3px 0px 5px 0px;margin:5px 0px 0px 3px;}
.toBalaFileSave {border:1px solid #841;padding:2px;margin:2px 5px 2px 5px;}

/*}}}*/
/*{{{*/
/***** LAYOUT STYLES -  DO NOT EDIT! *****/
ul.suckerfish, ul.suckerfish ul {
	margin: 0;
	padding: 0;
	list-style: none;
	line-height:1.4em;
}

ul.suckerfish  li {
	display: inline-block; 
	display: block;
	float: left; 
}

ul.suckerfish li ul {
	position: absolute;
	left: -999em;
}

ul.suckerfish li:hover ul, ul.suckerfish li.sfhover ul {
	left: auto;
}

ul.suckerfish ul li {
	float: none;
	border-right: 0;
	border-left:0;
}

ul.suckerfish a, ul.suckerfish a:hover {
	display: block;
}

ul.suckerfish li a.tiddlyLink, ul.suckerfish li a, #mainMenu ul.suckerfish li a {font-weight:bold;}
/**** END LAYOUT STYLES *****/


/**** COLORS AND APPEARANCE - DEFAULT *****/
ul.suckerfish li a {
	padding: 0.5em 1.5em;
	color: #FFF;
	background: #0066aa;
	border-bottom: 0;
	font-weight:bold;
}

ul.suckerfish li:hover a, ul.suckerfish li.sfhover a{
	background: #00558F;
}

ul.suckerfish li:hover ul a, ul.suckerfish li.sfhover ul a{
	color: #000;
	background: #eff3fa;
	border-top:1px solid #FFF;
}

ul.suckerfish ul li a:hover {
	background: #e0e8f5;
}

ul.suckerfish li a{
	width:9em;
}

ul.suckerfish ul li a, ul.suckerfish ul li a:hover{
	display:inline-block;
	width:9em;
}

ul.suckerfish li {
	border-left: 1px solid #00558F;
}
/***** END COLORS AND APPEARANCE - DEFAULT *****/


/***** LAYOUT AND APPEARANCE: VERTICAL *****/
ul.suckerfish.vertical li{
	width:10em;
	border-left: 0px solid #00558f;
}

ul.suckerfish.vertical ul li, ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a {
	border-left: 0.8em solid #00558f;
}

ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a,  ul.suckerfish.vertical li.sfhover a:hover{
	width:8em;
}

ul.suckerfish.vertical {
	width:10em; text-align:left;
	float:left;
}

ul.suckerfish.vertical li a {
	padding: 0.5em 1em 0.5em 1em;
	border-top:1px solid  #fff;
}

ul.suckerfish.vertical, ul.suckerfish.vertical ul {
	line-height:1.4em;
}

ul.suckerfish.vertical li:hover ul, ul.suckerfish.vertical li.sfhover ul { 
	margin: -2.4em 0 0 10.9em;
}

ul.suckerfish.vertical li:hover ul li a, ul.suckerfish.vertical li.sfhover ul li a {
	border: 0px solid #FFF;
}

ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a{
	padding-right:1.1em;
}

ul.suckerfish.vertical li:hover ul li, ul.suckerfish.vertical li.sfhover ul li {
	border-bottom:1px solid  #fff;
}

/***** END LAYOUT AND APPEARANCE: VERTICAL *****/
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/etc/sysconfig/displaymanager
{{{
DISPLAYMANAGER_REMOTE_ACCESS="yes"
DISPLAYMANAGER_ROOT_LOGIN_REMOTE="yes" # optional
DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN="yes"
}}}
/etc/opt/gnome/gdm/gdm.conf
{{{
[xdmcp]
# Distributions: Ship with this off.  It is never a safe thing to leave
# out on the net.  Setting up /etc/hosts.allow and /etc/hosts.deny to only
# allow local access is another alternative but not the safest.
# Firewalling port 177 is the safest if you wish to have xdmcp on.
# Read the manual for more notes on the security of XDMCP.
Enable=true
}}}
/etc/X11/xdm/Xaccess
{{{
*                                       #any host can get a login window
}}}

/etc/X11/xdm/xdm-config
{{{
!DisplayManager.requestPort:    0
}}}

*啟動xfs
{{{
chkconfig --level 35 xfs on
}}}
*以下抄自 [[Brad 老師的講義|http://www.brad.tw/telnetxinetd]]
{{{
兩個主要的權限設定檔案

    * /etc/hosts.allow
          o 在 /etc/hosts.allow 中
            服務應用程式名稱:位址[:allow|deny]
            (預設為 allow )
          o in.telnetd:192.168.11.0/255.255.255.0
            sshd:192.168.11.147 192.168.11.61

    * /etc/hosts.deny
          o 在 /etc/hosts.deny 中
            服務應用程式名稱:位址[:allow|deny]
            預設為 deny
          o in.telnetd:192.168.11.0/255.255.255.0
            sshd:192.168.11.147 192.168.11.61
          o 最後再來一個
            ALL:ALL[:allow|deny]
    * 當檔案 /etc/hosts.allow 存在時, 則先以此檔案內之設定為準
      而在 /etc/hosts.allow 沒有規定到的部份, 則將在 /etc/hosts.deny 當中繼續檢查

      最簡單最安全的方式, 就是直接在 /etc/hosts.allow 中
      ALL:ALL:deny
      其他都不要 
}}}

*hosts.allow 範例
**應用程式名稱: 來源
{{{
in.telnetd: 192.168.33.0/255.255.255.0
}}}
<<tabs txtMoreTab "未完成" "內容空白的文章" TabMoreMissing "未引用" "未被引用的文章" TabMoreOrphans "預設文章" "已預設內容的隱藏文章" TabMoreShadowed>>
<<list shadowed>>
<<allTags excludeLists>>
<<timeline created 15>>
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|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|Story.prototype.chooseTemplateForTiddler()|
|Description|use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values|
The core function, "story.chooseTemplateForTiddler(title,template)" is essentially a "pass-thru" that returns the same template it was given, and is provided by the core so that plugins can customize the template selection logic to select alternative templates, based on whatever programmatic criteria is appropriate.  This tweak extends story.chooseTemplateForTiddler() so that ''whenever a tiddler is marked with a specific tag value, it can be viewed and/or edited using alternatives to the standard tiddler templates.'' 
!!!!!Usage
<<<
Each alternative template is associated with a specific tiddler tag value by using that tag value as a prefix added to the standard TiddlyWiki template titles, [[ViewTemplate]] and [[EditTemplate]].

For example, any tiddlers that are tagged with ''<<tag media>>'' will look for alternative templates named [[mediaViewTemplate]] and [[mediaEditTemplate]].  Additionally, in order to find templates that have proper WikiWord tiddler titles (e.g., [[MediaViewTemplate]] and [[MediaEditTemplate]]), the plugin will also attempt to use a capitalized form of the tag value (e.g., ''Media'') as a prefix.  //This capitalization is for comparison purposes only and will not alter the actual tag values that are stored in the tiddler.//

If no matching alternative template can be found by using //any// of the tiddler's tags (either "as-is" or capitalized), the tiddler defaults to using the appropriate standard [[ViewTemplate]] or [[EditTemplate]] definition.

''To add your own custom templates:''
>First, decide upon a suitable tag keyword to uniquely identify your custom templates and create custom view and/or edit templates using that keyword as a prefix (e.g., "KeywordViewTemplate" and "KeywordEditTemplate").  Then, simply create a tiddler and tag it with your chosen keyword... that's it!  As long as the tiddler is tagged with your keyword, it will be displayed using the corresponding alternative templates.  If you remove the tag or rename/delete the alternative templates, the tiddler will revert to using the standard viewing and editing templates.
<<<
!!!!!Examples
<<<
|Sample tiddler| tag | view template | edit template |
|[[MediaSample - QuickTime]]| <<tag media>> | [[MediaViewTemplate]] | [[MediaEditTemplate]] |
|[[MediaSample - Windows]]| <<tag media>> | [[MediaViewTemplate]] | [[MediaEditTemplate]] |
|[[CDSample]]| <<tag CD>> | [[CDViewTemplate]] | [[CDEditTemplate]] |
|<<newTiddler label:"create new task..." title:SampleTask tag:task text:"Type some text and then press DONE to view the task controls">> | <<tag task>> | [[TaskViewTemplate]] | [[EditTemplate]] |

//(note: if these samples are not present in your document, please visit// http://www.TiddlyTools.com/ //to view these sample tiddlers on-line)//
<<<
!!!!!Revisions
<<<
2007.06.23 [1.1.0] re-written to use automatic 'tag prefix' search instead of hard coded check for each tag.  Allows new custom tags to be used without requiring code changes to this plugin.
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.taggedTemplate= {major: 1, minor: 1, revision: 0, date: new Date(2007,6,18)};
Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
	// get default template from core
	var template=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);

	// if the tiddler to be rendered doesn't exist yet, just return core result
	var tiddler=store.getTiddler(title); if (!tiddler) return template;

	// look for template whose prefix matches a tag on this tiddler
	for (t=0; t<tiddler.tags.length; t++) {
		var tag=tiddler.tags[t];
		if (store.tiddlerExists(tag+template)) { template=tag+template; break; }
		// try capitalized tag (to match WikiWord template titles)
		var cap=tag.substr(0,1).toUpperCase()+tag.substr(1);
		if (store.tiddlerExists(cap+template)) { template=cap+template; break; }
	}

	return template;
}
//}}}
/***
|''Name:''|~TaggerPlugin|
|''Version:''|1.0.1 (2006-06-01)|
|''Source:''|http://tw.lewcid.org//#TaggerPlugin|
|''Author:''|SaqImtiaz|
|''Description:''|Provides a drop down listing current tiddler tags, and allowing toggling of tags.|
|''Documentation:''|[[TaggerPluginDocumentation]]|
|''Source Code:''|[[TaggerPluginSource]]|
|''~TiddlyWiki:''|Version 2.0.8 or better|
***/
// /%
config.tagger={defaults:{label:"Tags: ",tooltip:"Manage tiddler tags",taglist:"true",excludeTags:"",notags:"tiddler has no tags",aretags:"current tiddler tags:",toggletext:"add tags:"}};config.macros.tagger={};config.macros.tagger.arrow=(document.all?"▼":"▾");config.macros.tagger.handler=function(_1,_2,_3,_4,_5,_6){var _7=config.tagger.defaults;var _8=_5.parseParams("tagman",null,true);var _9=((_8[0].label)&&(_8[0].label[0])!=".")?_8[0].label[0]+this.arrow:_7.label+this.arrow;var _a=((_8[0].tooltip)&&(_8[0].tooltip[0])!=".")?_8[0].tooltip[0]:_7.tooltip;var _b=((_8[0].taglist)&&(_8[0].taglist[0])!=".")?_8[0].taglist[0]:_7.taglist;var _c=((_8[0].exclude)&&(_8[0].exclude[0])!=".")?(_8[0].exclude[0]).readBracketedList():_7.excludeTags.readBracketedList();if((_8[0].source)&&(_8[0].source[0])!="."){var _d=_8[0].source[0];}if(_d&&!store.getTiddler(_d)){return false;}var _e=function(e){if(!e){var e=window.event;}var _11=Popup.create(this);var _12=store.getTags();var _13=new Array();for(var i=0;i<_12.length;i++){_13.push(_12[i][0]);}if(_d){var _15=store.getTiddler(_d);_13=_15.tags.sort();}var _16=_6.tags.sort();var _17=function(_18,_19,_1a){var sp=createTiddlyElement(createTiddlyElement(_11,"li"),"span",null,"tagger");var _1c=createTiddlyButton(sp,_18,_1a+" '"+_19+"'",taggerOnToggle,"button","toggleButton");_1c.setAttribute("tiddler",_6.title);_1c.setAttribute("tag",_19);insertSpacer(sp);if(window.createTagButton_orig_mptw){createTagButton_orig_mptw(sp,_19)}else{createTagButton(sp,_19);}};createTiddlyElement(_11,"li",null,"listTitle",(_6.tags.length==0?_7.notags:_7.aretags));for(var t=0;t<_16.length;t++){_17("[x]",_16[t],"remove tag ");}createTiddlyElement(createTiddlyElement(_11,"li"),"hr");if(_b!="false"){createTiddlyElement(_11,"li",null,"listTitle",_7.toggletext);for(var i=0;i<_13.length;i++){if(!_6.tags.contains(_13[i])&&!_c.contains(_13[i])){_17("[ ]",_13[i],"add tag ");}}createTiddlyElement(createTiddlyElement(_11,"li"),"hr");}var _1f=createTiddlyButton(createTiddlyElement(_11,"li"),("Create new tag"),null,taggerOnToggle);_1f.setAttribute("tiddler",_6.title);if(_d){_1f.setAttribute("source",_d);}Popup.show(_11,false);e.cancelBubble=true;if(e.stopPropagation){e.stopPropagation();}return (false);};createTiddlyButton(_1,_9,_a,_e,"button","taggerDrpBtn");};window.taggerOnToggle=function(e){var tag=this.getAttribute("tag");var _22=this.getAttribute("tiddler");var _23=store.getTiddler(_22);if(!tag){var _24=prompt("Enter new tag:","");if(_24!=""&&_24!=null){var tag=_24;if(this.getAttribute("source")){var _26=store.getTiddler(this.getAttribute("source"));_26.tags.pushUnique(_24);}}else{return false;}}if(!_23||!_23.tags){store.saveTiddler(_22,_22,"",config.options.txtUserName,new Date(),tag);}else{if(_23.tags.find(tag)==null){_23.tags.push(tag);}else{if(!_24){_23.tags.splice(_23.tags.find(tag),1);}}store.saveTiddler(_23.title,_23.title,_23.text,_23.modifier,_23.modified,_23.tags);}story.refreshTiddler(_22,null,true);if(config.options.chkAutoSave){saveChanges();}return false;};setStylesheet(".tagger a.button {font-weight: bold;display:inline; padding:0px;}\n"+".tagger #toggleButton {padding-left:2px; padding-right:2px; margin-right:1px; font-size:110%;}\n"+"#nestedtagger {background:#2E5ADF; border: 1px solid #0331BF;}\n"+".popup .listTitle {color:#000;}\n"+"","TaggerStyles");window.lewcidTiddlerSwapTag=function(_27,_28,_29){for(var i=0;i<_27.tags.length;i++){if(_27.tags[i]==_28){_27.tags[i]=_29;return true;}}return false;};window.lewcidRenameTag=function(e){var tag=this.getAttribute("tag");var _2d=prompt("Rename tag '"+tag+"' to:",tag);if((_2d==tag)||(_2d==null)){return false;}if(store.tiddlerExists(_2d)){if(confirm(config.messages.overwriteWarning.format([_2d.toString()]))){story.closeTiddler(_2d,false,false);}else{return null;}}tagged=store.getTaggedTiddlers(tag);if(tagged.length!=0){for(var j=0;j<tagged.length;j++){lewcidTiddlerSwapTag(tagged[j],tag,_2d);}}if(store.tiddlerExists(tag)){store.saveTiddler(tag,_2d);}if(document.getElementById("tiddler"+tag)){var _2f=document.getElementById(story.idPrefix+tag);var _30=story.positionTiddler(_2f);var _31=document.getElementById(story.container);story.closeTiddler(tag,false,false);story.createTiddler(_31,_30,_2d,null);story.saveTiddler(_2d);}if(config.options.chkAutoSave){saveChanges();}return false;};window.onClickTag=function(e){if(!e){var e=window.event;}var _34=resolveTarget(e);var _35=(!isNested(_34));if((Popup.stack.length>1)&&(_35==true)){Popup.removeFrom(1);}else{if(Popup.stack.length>0&&_35==false){Popup.removeFrom(0);}}var _36=(_35==false)?"popup":"nestedtagger";var _37=createTiddlyElement(document.body,"ol",_36,"popup",null);Popup.stack.push({root:this,popup:_37});var tag=this.getAttribute("tag");var _39=this.getAttribute("tiddler");if(_37&&tag){var _3a=store.getTaggedTiddlers(tag);var _3b=[];var li,r;for(r=0;r<_3a.length;r++){if(_3a[r].title!=_39){_3b.push(_3a[r].title);}}var _3d=config.views.wikified.tag;if(_3b.length>0){var _3e=createTiddlyButton(createTiddlyElement(_37,"li"),_3d.openAllText.format([tag]),_3d.openAllTooltip,onClickTagOpenAll);_3e.setAttribute("tag",tag);createTiddlyElement(createTiddlyElement(_37,"li"),"hr");for(r=0;r<_3b.length;r++){createTiddlyLink(createTiddlyElement(_37,"li"),_3b[r],true);}}else{createTiddlyText(createTiddlyElement(_37,"li",null,"disabled"),_3d.popupNone.format([tag]));}createTiddlyElement(createTiddlyElement(_37,"li"),"hr");var h=createTiddlyLink(createTiddlyElement(_37,"li"),tag,false);createTiddlyText(h,_3d.openTag.format([tag]));createTiddlyElement(createTiddlyElement(_37,"li"),"hr");var _40=createTiddlyButton(createTiddlyElement(_37,"li"),("Rename tag '"+tag+"'"),null,lewcidRenameTag);_40.setAttribute("tag",tag);}Popup.show(_37,false);e.cancelBubble=true;if(e.stopPropagation){e.stopPropagation();}return (false);};if(!window.isNested){window.isNested=function(e){while(e!=null){var _42=document.getElementById("contentWrapper");if(_42==e){return true;}e=e.parentNode;}return false;};}config.shadowTiddlers.TaggerPluginDocumentation="The documentation is available [[here.|http://tw.lewcid.org/#TaggerPluginDocumentation]]";config.shadowTiddlers.TaggerPluginSource="The uncompressed source code is available [[here.|http://tw.lewcid.org/#TaggerPluginSource]]";
// %/
/***
|''Name:''|TagsTreePlugin|
|''Description:''|Displays tags hierachy as a tree of tagged tiddlers.<br>Can be used to create dynamic outline navigation.|
|''Version:''|1.0.1|
|''Date:''|Jan 04,2008|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0|
!Demo
On the plugin [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] :
*Try to tag some <<newTiddler>> with a tag displayed in the menu and edit MainMenu.
*Look at some tags like [[Plugins]] or [[menu]].
!Installation
#import the plugin,
#save and reload,
#optionally, edit TagsTreeStyleSheet.
! Usage
{{{<<tagsTree>>}}} macro accepts the following //optional// parameters.
|!#|!parameter|!description|!by default|
|1|{{{root}}}|Uses {{{root}}} tag as tree root|- In a //tiddler// content or template : uses the tiddler as root tag.<br>- In the //page// content or template (by ex MainMenu) : displays all untagged tags.|
|2|{{{excludeTag}}}|Excludes all such tagged tiddlers from the tree|Uses default excludeLists tag|
|3|{{{level}}}|Expands nodes until level {{{level}}}.<br>Value {{{0}}} hides expand/collapse buttons.|Nodes are collapsed on first level|
|4|{{{depth}}}|Hierachy depth|6 levels depth (H1 to H6 header styles)|
|5|{{{sortField}}}|Alternate sort field. By example : "index".|Sorts tags and tiddlers alphabetically (on their title)|
|6|{{{labelField}}}|Alertnate label field. By example : "label".|Displays tiddler's title|

!Useful addons
*[[FieldsEditorPlugin]] : //create//, //edit//, //view// and //delete// commands in toolbar <<toolbar fields>>.
*[[TaggerPlugin]] : Provides a drop down listing current tiddler tags, and allowing toggling of tags.
!Advanced Users
You can change the global defaults for TagsTreePlugin, like default {{{level}}} value or level styles, by editing or overriding the first config.macros.tagsTree attributes below.
!Code
***/
//{{{
config.macros.tagsTree = {
	expand : "+",
	collapse : "–",
	depth : 6,
	level : 1,
	sortField : "",	
	labelField : "",
	styles : ["h1","h2","h3","h4","h5","h6"],
	trees : {}
}

config.macros.tagsTree.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	var root = params[0] ? params[0] : (tiddler ? tiddler.title : null);
	var excludeTag = params[1] ? params[1] : "excludeTagsTree";
	var level = params[2] ? params[2] : config.macros.tagsTree.level;
	var depth = params[3] ? params[3] : config.macros.tagsTree.depth;
	var sortField = params[4] ? params[4] : config.macros.tagsTree.sortField;
	var labelField = params[5] ? params[5] : config.macros.tagsTree.labelField;
	var showButtons = (level>0);
	var id = config.macros.tagsTree.getId(place);
	if (config.macros.tagsTree.trees[id]==undefined) config.macros.tagsTree.trees[id]={};
	config.macros.tagsTree.createSubTree(place,id,root,excludeTag,[],level>0 ? level : 1,depth, sortField, labelField,showButtons);
}

config.macros.tagsTree.createSubTree = function(place, id, root, excludeTag, ancestors, level, depth, sortField, labelField,showButtons){
	var childNodes = root ? this.getChildNodes(root, ancestors) : this.getRootTags(excludeTag);
	var isOpen = (level>0) || (!showButtons);
	if (root && this.trees[id][root]!=undefined) isOpen = this.trees[id][root]; 
	if (root && ancestors.length) {
		var t = store.getTiddler(root);
		if (childNodes.length && depth>0) {
			var wrapper = createTiddlyElement(place , this.styles[Math.min(Math.max(ancestors.length,1),6)-1],null,"branch");
			if (showButtons) {
				b = createTiddlyButton(wrapper, isOpen ? config.macros.tagsTree.collapse : config.macros.tagsTree.expand, null, config.macros.tagsTree.onClick);
				b.setAttribute("treeId",id);
				b.setAttribute("tiddler",root);					
			}
			createTiddlyText(createTiddlyLink(wrapper, root),t&&labelField ? t.fields[labelField] ? t.fields[labelField] : root : root);
		}
		else 
			createTiddlyText(createTiddlyLink(place, root,false,"leaf"),t&&labelField ? t.fields[labelField] ? t.fields[labelField] : root : root);
	}
	if (childNodes.length && depth) {
		var d = createTiddlyElement(place,"div",null,"subtree");
		d.style.display= isOpen ? "block" : "none";
		if (sortField)
			childNodes.sort(function(a, b){
				var fa=a.fields[sortField];
				var fb=b.fields[sortField];
				return (fa==undefined && fb==undefined) ? a.title < b.title ? -1 : a.title > b.title ? 1 : 0 : (fa==undefined && fb!=undefined) ? 1 :(fa!=undefined && fb==undefined) ? -1 : fa < fb ? -1 : fa > fb ? 1 : 0;
			})
		for (var cpt=0; cpt<childNodes.length; cpt++)
			this.createSubTree(d, id, childNodes[cpt].title, excludeTag, ancestors.concat(root), level-1, depth-1, sortField, labelField, showButtons);	
	}	
}

config.macros.tagsTree.onClick = function(e){
	var id = this.getAttribute("treeId");
	var tiddler = this.getAttribute("tiddler");	
	var n = this.parentNode.nextSibling;
	var isOpen = n.style.display != "none";
	if(config.options.chkAnimate && anim && typeof Slider == "function")
		anim.startAnimating(new Slider(n,!isOpen,null,"none"));
	else
		n.style.display = isOpen ? "none" : "block";
	this.firstChild.nodeValue = isOpen ? config.macros.tagsTree.expand : config.macros.tagsTree.collapse;
	config.macros.tagsTree.trees[id][tiddler]=!isOpen;
	return false;
}

config.macros.tagsTree.getChildNodes = function(root ,ancestors){
	var childs = store.getTaggedTiddlers(root);
	var result = new Array();
	for (var cpt=0; cpt<childs.length; cpt++)
		if (childs[cpt].title!=root && ancestors.indexOf(childs[cpt].title)==-1) result.push(childs[cpt]);
	return result;
}

config.macros.tagsTree.getRootTags = function(excludeTag){
	var tags = store.getTags(excludeTag);
	tags.sort(function(a,b) {return a[0].toLowerCase() < b[0].toLowerCase() ? -1 : (a[0].toLowerCase() == b[0].toLowerCase() ? 0 : +1);});
	var result = new Array();
	for (var cpt=0; cpt<tags.length; cpt++) {
		var t = store.getTiddler(tags[cpt][0]);
		if (!t || t.tags.length==0) result.push(t ? t : {title:tags[cpt][0],fields:{}});
	}
	return result;
}

config.macros.tagsTree.getId = function(element){
	while (!element.id && element.parentNode) element=element.parentNode;
	return element.id ? element.id : "<html>";
}

config.shadowTiddlers.TagsTreeStyleSheet = "/*{{{*/\n";
config.shadowTiddlers.TagsTreeStyleSheet +=".leaf, .subtree {display:block; margin-left : 0.5em}\n";
config.shadowTiddlers.TagsTreeStyleSheet +=".subtree {margin-bottom:0.5em}\n";
config.shadowTiddlers.TagsTreeStyleSheet +="#mainMenu {text-align:left}\n";
config.shadowTiddlers.TagsTreeStyleSheet +=".branch .button {border:1px solid #DDD; color:#AAA;font-size:9px;padding:0 2px;margin-right:0.3em;vertical-align:middle;text-align:center;}\n";
config.shadowTiddlers.TagsTreeStyleSheet +="/*}}}*/";

store.addNotification("TagsTreeStyleSheet", refreshStyles); 

config.shadowTiddlers.MainMenu="<<tagsTree>>"

config.shadowTiddlers.PageTemplate = config.shadowTiddlers.PageTemplate.replace(/id='mainMenu' refresh='content' /,"id='mainMenu' refresh='content' force='true' ")

//}}}
/*{{{*/
.leaf, .subtree {display:block}

/* 設定 Tree 第一層的 left margin */ 
#mainMenu>.subtree {margin-left:0em}

.leaf {margin-left:0.2em; margin-bottom:0.2em; color:navy;}
.subtree {margin-left:0.8em;}

.branch .button {
   border:1px solid #DDD; color:#999;
   font-size:10px;padding:0 4px;
   margin-right:0.5em;
   vertical-align:middle;text-align:center;
}

/*}}}*/
/***
|''Name:''|TiddlersBarPlugin|
|''Description:''|A bar to switch between tiddlers through tabs (like browser tabs bar).|
|''Version:''|1.2.5|
|''Date:''|Jan 18,2008|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Demos
On [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], open several tiddlers to use the tabs bar.
!Installation
#import this tiddler from [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] (tagged as systemConfig)
#save and reload
#''if you're using a custom [[PageTemplate]]'', add {{{<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>}}} before {{{<div id='tiddlerDisplay'></div>}}}
#optionally, adjust StyleSheetTiddlersBar
!Tips
*Doubleclick on the tiddlers bar (where there is no tab) create a new tiddler.
*Tabs include a button to close {{{x}}} or save {{{!}}} their tiddler.
*By default, click on the current tab close all others tiddlers.
!Configuration options 
<<option chkDisableTabsBar>> Disable the tabs bar (to print, by example).
<<option chkHideTabsBarWhenSingleTab >> Automatically hide the tabs bar when only one tiddler is displayed. 
<<option txtSelectedTiddlerTabButton>> ''selected'' tab command button.
/<<option txtPreviousTabKey>> previous tab access key.
<<option txtNextTabKey>> next tab access key.
!Code
***/
//{{{
config.options.chkDisableTabsBar = config.options.chkDisableTabsBar ? config.options.chkDisableTabsBar : false;
config.options.chkHideTabsBarWhenSingleTab  = config.options.chkHideTabsBarWhenSingleTab  ? config.options.chkHideTabsBarWhenSingleTab  : false;
config.options.txtSelectedTiddlerTabButton = config.options.txtSelectedTiddlerTabButton ? config.options.txtSelectedTiddlerTabButton : "closeOthers";
config.options.txtPreviousTabKey = config.options.txtPreviousTabKey ? config.options.txtPreviousTabKey : "";
config.options.txtNextTabKey = config.options.txtNextTabKey ? config.options.txtNextTabKey : "";
config.macros.tiddlersBar = {
	tooltip : "see ",
	tooltipClose : "click here to close this tab",
	tooltipSave : "click here to save this tab",
	promptRename : "Enter tiddler new name",
	currentTiddler : "",
	previousState : false,
	previousKey : config.options.txtPreviousTabKey,
	nextKey : config.options.txtNextTabKey,	
	tabsAnimationSource : null, //use document.getElementById("tiddlerDisplay") if you need animation on tab switching.
	handler: function(place,macroName,params) {
		var previous = null;
		if (config.macros.tiddlersBar.isShown())
			story.forEachTiddler(function(title,e){
				if (title==config.macros.tiddlersBar.currentTiddler){
					var d = createTiddlyElement(null,"span",null,"tab tabSelected");
					config.macros.tiddlersBar.createActiveTabButton(d,title);
					if (previous && config.macros.tiddlersBar.previousKey) previous.setAttribute("accessKey",config.macros.tiddlersBar.nextKey);
					previous = "active";
				}
				else {
					var d = createTiddlyElement(place,"span",null,"tab tabUnselected");
					var btn = createTiddlyButton(d,title,config.macros.tiddlersBar.tooltip + title,config.macros.tiddlersBar.onSelectTab);
					btn.setAttribute("tiddler", title);
					if (previous=="active" && config.macros.tiddlersBar.nextKey) btn.setAttribute("accessKey",config.macros.tiddlersBar.previousKey);
					previous=btn;
				}
				var isDirty =story.isDirty(title);
				var c = createTiddlyButton(d,isDirty ?"!":"x",isDirty?config.macros.tiddlersBar.tooltipSave:config.macros.tiddlersBar.tooltipClose, isDirty ? config.macros.tiddlersBar.onTabSave : config.macros.tiddlersBar.onTabClose,"tabButton");
				c.setAttribute("tiddler", title);
				if (place.childNodes) {
					place.insertBefore(document.createTextNode(" "),place.firstChild); // to allow break line here when many tiddlers are open
					place.insertBefore(d,place.firstChild); 
				}
				else place.appendChild(d);
			})
	}, 
	refresh: function(place,params){
		removeChildren(place);
		config.macros.tiddlersBar.handler(place,"tiddlersBar",params);
		if (config.macros.tiddlersBar.previousState!=config.macros.tiddlersBar.isShown()) {
			story.refreshAllTiddlers();
			if (config.macros.tiddlersBar.previousState) story.forEachTiddler(function(t,e){e.style.display="";});
			config.macros.tiddlersBar.previousState = !config.macros.tiddlersBar.previousState;
		}
	},
	isShown : function(){
		if (config.options.chkDisableTabsBar) return false;
		if (!config.options.chkHideTabsBarWhenSingleTab) return true;
		var cpt=0;
		story.forEachTiddler(function(){cpt++});
		return (cpt>1);
	},
	selectNextTab : function(){  //used when the current tab is closed (to select another tab)
		var previous="";
		story.forEachTiddler(function(title){
			if (!config.macros.tiddlersBar.currentTiddler) {
				story.displayTiddler(null,title);
				return;
			}
			if (title==config.macros.tiddlersBar.currentTiddler) {
				if (previous) {
					story.displayTiddler(null,previous);
					return;
				}
				else config.macros.tiddlersBar.currentTiddler=""; 	// so next tab will be selected
			}
			else previous=title;
			});		
	},
	onSelectTab : function(e){
		var t = this.getAttribute("tiddler");
		if (t) story.displayTiddler(null,t);
		return false;
	},
	onTabClose : function(e){
		var t = this.getAttribute("tiddler");
		if (t) {
			if(story.hasChanges(t) && !readOnly) {
				if(!confirm(config.commands.cancelTiddler.warning.format([t])))
				return false;
			}
			story.closeTiddler(t);
		}
		return false;
	},
	onTabSave : function(e) {
		var t = this.getAttribute("tiddler");
		if (!e) e=window.event;
		if (t) config.commands.saveTiddler.handler(e,null,t);
		return false;
	},
	onSelectedTabButtonClick : function(event,src,title) {
		var t = this.getAttribute("tiddler");
		if (!event) event=window.event;
		if (t && config.options.txtSelectedTiddlerTabButton && config.commands[config.options.txtSelectedTiddlerTabButton])
			config.commands[config.options.txtSelectedTiddlerTabButton].handler(event, src, t);
		return false;
	},
	onTiddlersBarAction: function(event) {
		var source = event.target ? event.target.id : event.srcElement.id; // FF uses target and IE uses srcElement;
		if (source=="tiddlersBar") story.displayTiddler(null,'New Tiddler',DEFAULT_EDIT_TEMPLATE,false,null,null);
	},
	createActiveTabButton : function(place,title) {
		if (config.options.txtSelectedTiddlerTabButton && config.commands[config.options.txtSelectedTiddlerTabButton]) {
			var btn = createTiddlyButton(place, title, config.commands[config.options.txtSelectedTiddlerTabButton].tooltip ,config.macros.tiddlersBar.onSelectedTabButtonClick);
			btn.setAttribute("tiddler", title);
		}
		else
			createTiddlyText(place,title);
	}
}

story.coreCloseTiddler = story.coreCloseTiddler? story.coreCloseTiddler : story.closeTiddler;
story.coreDisplayTiddler = story.coreDisplayTiddler ? story.coreDisplayTiddler : story.displayTiddler;

story.closeTiddler = function(title,animate,unused) {
	if (title==config.macros.tiddlersBar.currentTiddler)
		config.macros.tiddlersBar.selectNextTab();
	story.coreCloseTiddler(title,false,unused); //disable animation to get it closed before calling tiddlersBar.refresh
	var e=document.getElementById("tiddlersBar");
	if (e) config.macros.tiddlersBar.refresh(e,null);
}

story.displayTiddler = function(srcElement,tiddler,template,animate,unused,customFields,toggle){
	story.coreDisplayTiddler(config.macros.tiddlersBar.tabsAnimationSource,tiddler,template,animate,unused,customFields,toggle);
	var title = (tiddler instanceof Tiddler)? tiddler.title : tiddler;  
	if (config.macros.tiddlersBar.isShown()) {
		story.forEachTiddler(function(t,e){
			if (t!=title) e.style.display="none";
			else e.style.display="";
		})
		config.macros.tiddlersBar.currentTiddler=title;
	}
	var e=document.getElementById("tiddlersBar");
	if (e) config.macros.tiddlersBar.refresh(e,null);
}

var coreRefreshPageTemplate = coreRefreshPageTemplate ? coreRefreshPageTemplate : refreshPageTemplate;
refreshPageTemplate = function(title) {
	coreRefreshPageTemplate(title);
	if (config.macros.tiddlersBar) config.macros.tiddlersBar.refresh(document.getElementById("tiddlersBar"));
}

//ensureVisible=function (e) {return 0} //disable bottom scrolling (not useful now)

config.shadowTiddlers.StyleSheetTiddlersBar = "/*{{{*/\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar .button {border:0}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar .tab {white-space:nowrap}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar {padding : 1em 0.5em 2px 0.5em}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += ".tabUnselected .tabButton, .tabSelected .tabButton {padding : 0 2px 0 2px; margin: 0 0 0 4px;}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += ".tiddler, .tabContents {border:1px [[ColorPalette::TertiaryPale]] solid;}\n";
config.shadowTiddlers.StyleSheetTiddlersBar +="/*}}}*/";
store.addNotification("StyleSheetTiddlersBar", refreshStyles);

config.refreshers.none = function(){return true;}
config.shadowTiddlers.PageTemplate=config.shadowTiddlers.PageTemplate.replace(/<div id='tiddlerDisplay'><\/div>/m,"<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>\n<div id='tiddlerDisplay'></div>");

//}}}
<<search>> | [[首頁]] | [[土芭樂 3.0 - 數位新思路|http://tbala.net/]]  |  [[鳥哥的 Linux 私房菜|http://linux.vbird.org/]]  |  <<newTiddler label:"新增文章">>  <<saveChanges>> 
{{{
先進入Ubuntu系統,然後切換到 VMware Workstation中的VM功能表,在下面選擇Install VMware Tools.這時候Ubuntu的桌面上會自動掛載一個VMwareTools的光碟機,按兩下進入,裡面有兩個安裝檔,一個是rpm格式,一個是 tar.gz格式。因為Ubuntu默認不支持rpm安裝,因此解壓tar.gz檔進行安裝。有一件事情要先提一下,因為VMware Tools的安裝一定要裝一個 C Header files,而且版本要和系統一樣(我也是裝到後來才知道,不然安裝時提示一個/linux/include什麼的資料夾找不到。)具體操作如下:
引用:
uname -r 
sudo apt-get install gcc make linux-headers-2.6.15-27-686(這裡用你們自己的版本替換) 


安裝完畢之後再進入到剛才解壓的資料夾中,用sudo ./vmware-install.pl安裝。最後一直用默認設置直到完成。
}}}

轉錄自 http://www.cnblogs.com/oomusou/archive/2008/05/27/1208517.html
{{{
1)編輯 /etc/profile 在最後一行加入底下語法:
Code:

NOW=`date +%Y%m%d:%H%M%S`
LAST=`last $USER -5`
echo "[$NOW]: From $HOSTNAME : this user $USER login..." > /tmp/userlogin.log
echo "$LAST" >> /tmp/userlogin.log
mail -s "Attention !! User Login~~" user1@test.com,user2@test.com < /tmp/userlogin.log
rm -f /tmp/userlogin.log


這樣的話可以把信寄給兩個user...當然要一個的話也可以囉...

(2)用這個方法只有root登入才能顯示完整訊息..如果是其它user要修改wtmp
Code:

chmod 644 /var/log/wtmp
}}}

轉錄自http://phorum.study-area.org/index.php/topic,8231.html
{{{
In order to run VMWare a few dependencies are needed to be installed:

sudo apt-get install linux-headers-`uname -r` build-essential xinetd

This will install all needed dependencies!
If there are still some problems install gcc-3.4.

sudo apt-get install gcc-3.4
}}}
*@@font-size:1.2em;若 VNC 連進 VMWare 下的 CentOS,安裝了 VMWare Tools 仍然滑鼠只會不停的往右上跑時,開啟終端機,執行 {{{su - root}}},並輸入 root 密碼,輸入 {{{cd /etc/X11}}} 切換目錄至 /etc/X11/ 下,執行 {{{vi xorg.conf}}} 修改組態設定檔,按一下 esc 鍵即可開始編輯,加入以下紅色部分的內容,編輯完成後按一下 esc 鍵,輸入 {{{:w}}} 按一下 enter 存檔,再按一下 esc,輸入兩個大寫的『 ZZ 』離開 vi 編輯器,重新開機即可@@

 # Xorg configuration created by system-config-display

Section "ServerLayout"
	Identifier     "single head configuration"
	Screen      0  "Screen0" 0 0
	InputDevice    "Keyboard0" "CoreKeyboard"
@@color:red;font-size:1.4em;	InputDevice    "VMMouse" "CorePointer"@@
EndSection

Section "ServerFlags"
	Option	    "NoAutoAddDevices"
EndSection

Section "InputDevice"
 # keyboard added by rhpxl
	Identifier  "Keyboard0"
	Driver      "kbd"
	Option	    "XkbModel" "pc105"
	Option	    "XkbLayout" "us"
EndSection

@@color:red;font-size:1.4em;Section "InputDevice"
	Identifier  "VMMouse"
	Driver      "vmmouse"
	Option	    "Device" "/dev/input/mice"
	Option	    "Emulate3Buttons" "yes"
       Option         "ZAxisMapping" "4 5"
       Option         "Buttons" "5" 
  	Option	    "Protocol" "IMPS/2"
EndSection@@

!!以下刪除...

[[參考資料|http://communities.vmware.com/thread/135414]]
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>

<!--
<div class='tagging' macro='tagging'></div>
-->
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
Blog 架站機
!!X-Window 相關

**-version: 版本資訊
{{{
[Linux] cwRsync [rsync for windows] SSH 加密異地備份

Dec 14th, 2006 by appleboy 參觀者:6,846Views 機器人:1,436Views

這個我找了好久~因為館內用的系統2003server跟前端系統linux,2個是不同的作業系統

但是我每天都有備份linux資料,我想同步到win的server上面,但是這樣就要在win的機器上面架設rsync伺服器跟rsync client套件

所以我找了很久 終於找到了 cwRsync 有client端 跟server端 跟ssh 加密 open ssh server

cwRsync - Rsync for Windows

請點選中間的 Download cwRsync Server

1

下載之後解壓縮,裡面會有一個執行檔,在安裝即可

安裝好之後,去程式集打開 cwrsync server -> 05. Start a Unix BASH Shell 會出現底下畫面

2

執行之後,會出現一個 cmd 視窗但字元卻是 $ 的。


請輸入下列指令 /bin/activate-user.sh

系統時會出現訊息:

    Do you want to activarte a (l)ocal or a (d)omain user [l/d]? 

此時請按 l (小寫L)

接著畫面最下方會出現:

    Enter a user account for activation: 

可輸入 Administrator 或是其他帳號。
然後,接下來出現的訊息都可直接按 Enter 跳過了。

然後再去開啟 系統的服務 OpenSSHD 跟 Rsync Server 這樣子就可以連上了

你可以設定 rsync.conf 檔案「windows」

    use chroot = false
    strict modes = false
    hosts allow = *
    log file = rsyncd.log
    pid file = rsyncd.pid

    # Module definitions
    # Remember cygwin naming conventions : c:\work becomes /cygwin/c/work
    #
    [backup_NAS]
    path = /cygdrive/d/backup
    read only = false
    transfer logging = yes
    read only = no
    secrets file = /cygdrive/d/backup/rsyncd.secrets

    [mv_001]
    path = /cygdrive/e/001
    read only = false
    transfer logging = yes
    read only = no
    secrets file = /cygdrive/d/backup/rsyncd.secrets

windows底下對應目錄方式如下

    # Module definitions
    # Remember cygwin naming conventions : c:\work becomes /cygwin/c/work
    #

這樣大致就設定成功了,現在來測試看看

底下我先用rsync server的方式 來測試速度

    rsync -avl --delete --progress --password-file=/etc/rsyncd.192.168.100.7 /backup01/www_data /backup01/mysql_db appleboy@192.168.100.7::backup_NAS

3

至少速度 都有3MB以上,速度相當不錯,半夜的時候還有衝到10MB左右

不過現在換用 ssh 加密傳輸 如下,不只速度慢,而且還要使用ssh密碼,比較麻煩,不過可以透過下面文章,來達到不必輸入密碼

Rsync + SSH 讓 Server 自動異地備援也加密

    rsync -avl --delete --progress /backup01/www_data /backup01/mysql_db Administrator@192.168.100.7:/cygdrive/d/backup

速度如下圖

4

真的差很多,不過終於搞定linux跟win備份的問題

其實寫script也可以,只不過懶 哈哈~

http://phorum.study-area.org/viewtopic.php?t=42960
}}}

轉錄自 http://blog.wu-boy.com/2006/12/14/53/
/***
|''Name:''|abego.IncludePlugin|
|''Version:''|1.0.0 (2007-02-08)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#IncludePlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[IncludePlugin Documentation|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]]|
|''Community:''|([[del.icio.us|http://del.icio.us/post?url=http://tiddlywiki.abego-software.de/index.html%23IncludePlugin]]) ([[Support|http://groups.google.com/group/TiddlyWiki]])|
|''Copyright:''|&copy; 2007 [[abego Software|http://www.abego-software.de]]|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''~CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.5.0.9 or better; Internet Explorer 6.0|
***/
//{{{

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

var invokeLater = function(func, delay, priority) {
	return abego.invokeLater ? abego.invokeLater(func, delay, priority) : setTimeout(func,delay);
};

// Asynchronously load the given (local or remote) file.
// 
// @param url 		either an URL or a local file path to a file
//					Examples:
//						* http://www.abego-software.de/index.html
//						* file:///C:/abegoWebSite-Copy/index.html
//						* C:\abegoWebSite-Copy\index.html    (for Windows machines)
//							(Notice: backslashes in JavaScript string constants must be escaped, 
//							 i.e. the last example must be written as: "C:\\abegoWebSite-Copy\\index.html"
//							 when "hardcoded" in JavaScript source code)
// 
// @param callback 
//					function(content,url,params,errorMessage) 
//					called at the end of the operation. 
//					On success content holds the content of the loaded file. 
//					On error content is undefined and errorMessage holds an error message. 
//					params is the params passed into abego.loadFile.
//
// @param params 	passed through to the callback function
// 
abego.loadFile = function(url,callback,params) {

	var onLoad = function(status,params,responseText,url,xhr) {
		return status 
				? callback(responseText, url, params)
				: callback(undefined, url, params, "Error loading %0".format([url]));
	};
	
	// Make sure the URL is a real URL, with protocol prefix etc.
	if (url.search(/^((http(s)?)|(file)):/) != 0) {
		
		// no protocol specified. 
		if (url.search(/^((.\:\\)|(\\\\)|(\/))/) == 0) {
			// "url" is an "absolute" path to a local file. Prefix it with file://
			url = "file://"+url;
			
		} else {
			// "url" is a "relative" URL. Make it absolute
			
			// prefix the url with the directory containing the current document
			// (This also includes the protocol prefix)
			var documentPath = document.location.toString();
			var i = documentPath.lastIndexOf("/");
			url = documentPath.substr(0,i+1)+url;
		}
		// replace every \ by a /, to cover Windows style pathes
		url = url.replace(/\\/mg,"/");
	}
	
	loadRemoteFile(url,onLoad,params);

};

// Asynchronously load the given (local or remote) TiddlyWiki store.
// 
// @param url 		either an URL or a local file path to a TiddlyWiki file (absolute or relative)
//					Examples:
//						* http://www.abego-software.de/index.html
//						* file:///C:/abegoWebSite-Copy/index.html
//						* include/beta.html
//						* C:\abegoWebSite-Copy\index.html    (for Windows machines)
//							(Notice: backslashes in JavaScript string constants must be escaped, 
//							 i.e. the last example must be written as: "C:\\abegoWebSite-Copy\\index.html"
//							 when "hardcoded" in JavaScript source code)
// 
// @param callbackWithStore 
//					function(theStore,url,params,errorMessage) 
//					called at the end of the operation. 
//					On success theStore holds the loaded store (a TiddlyWiki object). 
//					On error theStore is undefined and errorMessage holds an error message. 
//					params is the params passed into abego.loadTiddlyWikiStore
//
// @param params 	passed through to the callbackWithStore
//
// @progress		[optional] function(message, sender, state, url, params) called in various situations during the operation,
//								typically used to show "the progress" of the operation.
//								sender: the constant "abego.loadTiddlyWikiStore"
//								state: one of these: "Started", "Processing", "Done", "Failed"
//									"Processing" means the data has been received and in now processed.
// 
abego.loadTiddlyWikiStore = function(url,callbackWithStore,params,progress) {
	
	var sendProgress = function(message, state) {
		if (progress)
			progress(message,"abego.loadTiddlyWikiStore",state,url,params);
	};
	
	// Load contents of a TiddlyWiki from a string
	//# Returns null on success, an error message otherwise.
	//# based on code from TiddlyWiki 2.2 alpha
	var importTiddlyWiki = function(store,text)
	{
		// Crack out the content - will be refactored to share code with saveChanges()
		var posOpeningDiv = text.indexOf(startSaveArea);
		var limitClosingDiv = text.indexOf("<!--POST-BODY-END--"+">");
		var posClosingDiv = text.lastIndexOf(endSaveArea,limitClosingDiv == -1 ? text.length : limitClosingDiv);
		if((posOpeningDiv == -1) || (posClosingDiv == -1))
			return config.messages.invalidFileError.format([url]);
		var content = "<html><body>" + text.substring(posOpeningDiv,posClosingDiv + endSaveArea.length) + "</body></html>";
		// Create the iframe
		var iframe = document.createElement("iframe");
		iframe.style.display = "none";
		document.body.appendChild(iframe);
		var doc = iframe.document;
		if(iframe.contentDocument)
			doc = iframe.contentDocument; // For NS6
		else if(iframe.contentWindow)
			doc = iframe.contentWindow.document; // For IE5.5 and IE6
		// Put the content in the iframe
		doc.open();
		doc.writeln(content);
		doc.close();
		// Load the content into a TiddlyWiki() object
		var storeArea = doc.getElementById("storeArea");
		store.loadFromDiv(storeArea,"store");
		// Get rid of the iframe
		iframe.parentNode.removeChild(iframe);
		return null;
	};
	
	var sendError = function(message) {
		sendProgress("Error when loading %0".format([url]),"Failed");
		callbackWithStore(undefined, url,params, message);
		return message;
	};
	
	var sendStore = function(store) {
		sendProgress("Loaded %0".format([url]),"Done");
		callbackWithStore(store, url, params);
		return null;
	};
	
	
	var callback = function(content,theURL,params,errorMessage) {
		if (content === undefined) {
			sendError(errorMessage);
			return;
		}
		
		sendProgress("Processing %0".format([url]),"Processing");
		var orig_invalidFileError = config.messages.invalidFileError;
		config.messages.invalidFileError = "The file '%0' does not appear to be a valid TiddlyWiki file";
		try {
			// Load the content into a TiddlyWiki() object
			var importStore = new TiddlyWiki();
			var errorText = importTiddlyWiki(importStore,content);
			if (errorText)
				sendError(errorText);
			else
				sendStore(importStore);

		} catch (ex) {
			sendError(exceptionText(ex));
		} finally {
			config.messages.invalidFileError = orig_invalidFileError;
		}
	};
	
	sendProgress("Start loading %0".format([url]),"Started");
	abego.loadFile(url,callback,params);
};


//==============================================================================
// Include Plugin 

(function(){

// only install once
if (abego.TiddlyWikiIncluder) return;


// --------------------------------------------------
// Constants

var WAITING = "waiting";
var LOADING = "loading";

var ANI_DURATION_HIDE_STATE = 1000;

var REFRESH_PRIORITY = -200;
var ANIMATION_PRIORITY = -100;
var UPDATE_STATE_PRIORITY = -300;

// --------------------------------------------------
// Variables

var useInclude;
var includes = []; // [] of Strings. the urls of the stores to include, in the sequence of the calls.
var includedStores = {}; // url(String) -> TiddlyWiki or String; when not (yet) loaded a status or error string.
var pendingOnLoadURLs = []; // [] of String. a list of urls that should be passed with the next "notifyListeners".
var refreshTiddlyWikiTimerID; // for delayed refresh
var listeners = [];
var progress;

// --------------------------------------------------
// Helper functions

var isIncludeEnabled = function() {
	if (useInclude === undefined)
		useInclude = config.options.chkUseInclude === undefined || config.options.chkUseInclude;
	return useInclude;
};

var getMissingIncludeMsg = function(url) {
	return "No include specified for %0".format([url])
};

// Called after one or more included TiddlyWikis are loaded
//
var notifyListeners = function() {
	var urls = pendingOnLoadURLs;
	pendingOnLoadURLs = [];
	if (urls.length) {
		for (var i= 0; i < listeners.length; i++)
			listeners[i](urls);
	}
};

var idleCount; // Reset to 0 when the system is "not idle", incremented inside refreshTiddlyWiki

var refreshTiddlyWiki = function() {
	// To avoid to much refreshing/flickering don't refresh immediately 
	// but wait until the system was idle for a certain time.
	
	if (refreshTiddlyWikiTimerID !== undefined) clearInterval(refreshTiddlyWikiTimerID);
	
	idleCount = 0;
	
	var sendDone = function() {
		abego.TiddlyWikiIncluder.sendProgress("","","Done");
	};
	
	refreshTiddlyWikiTimerID = setInterval(function() {
		idleCount++;
		if (idleCount <= 10)
			return;
			
		clearInterval(refreshTiddlyWikiTimerID);
		refreshTiddlyWikiTimerID = undefined;
			
		abego.TiddlyWikiIncluder.sendProgress("Refreshing...","","");
		refreshDisplay();
		invokeLater(sendDone,0,REFRESH_PRIORITY);
	},0);
};

// Calls callback for every loaded store and returns the first non-false/null.. value returned by callback.
//
// @param callback  function(store, url)
//
var forEachLoadedStore = function(callback) {
	var result;
	for (var i = 0; i < includes.length; i++) {
		var theStore = abego.TiddlyWikiIncluder.getStore(includes[i]);
		if (theStore && (result = callback(theStore, includes[i])))
			return result;
	}
};

var attachToStore = function() {
	if (!window.store)
		return invokeLater(attachToStore,100);
		
	var orig_fetchTiddler = store.fetchTiddler;
	
	store.fetchTiddler = function(title) {
		var t = orig_fetchTiddler.apply(this,arguments);
		if (t) return t;
		
		// When there is a shadowtiddler with that name done look for
		// any included tiddler since these would hide the shadow
		if (config.shadowTiddlers[title] !== undefined) return undefined;
		
		// Don't look for the "New Tiddler" tiddler in the included TiddlyWikis,
		// since returning such a tiddler (that is readonly) will make it impossible
		// in the Main TiddlyWiki to create new tiddlers.
		if (title == config.macros.newTiddler.title) return undefined;

		return forEachLoadedStore(
				function(theStore, url) {
					var t = theStore.fetchTiddler(title);
					if (t) 
						t.includeURL = url;
					return t;
				});
	};

	// We also refresh TiddlyWiki to reflect the new included Tiddlers (if we have any).
	if (includes.length)
		refreshTiddlyWiki();
};

var includeFromIncludeList = function() {
	if (!window.store)
		return invokeLater(includeFromIncludeList,100);
		
	var includeListText = store.getTiddlerText("IncludeList");
	if (includeListText) 
		wikify(includeListText,document.createElement("div"));
};

var getFunctionUsingForReallyEachTiddler = function(func) {
	var wrapper = function() {
		var orig_forEachTiddler = store.forEachTiddler;

		var forEachTiddlerWithIncludes = function(callback) {
			var done = {};
			var includeURL;

			var callbackWrapper = function(title, tiddler) {
				// ensure every title is only processed once
				if (done[title]) 
					return;
				done[title] = 1;
				
				// for "included tiddlers" set the includeURL;
				if (includeURL)
					tiddler.includeURL = includeURL;
				
				callback.apply(this,arguments);
			};
			
			// forEachTiddler over the original tiddlers
			orig_forEachTiddler.call(store, callbackWrapper);
			
			// add all shadowTiddler titles to done 
			// (to avoid an included store hides a shadow tiddler)
			for (var n in config.shadowTiddlers)
				done[n] = 1;

			// add all the "New Tiddler" tiddlerto done 
			// (to avoid an included store (with "New Tiddler") makes it impossible to create new tiddlers)
			done[config.macros.newTiddler.title] = 1;

			// forEachTiddler over every included store
			forEachLoadedStore(
					function(theStore, url) {
						includeURL = url;
						theStore.forEachTiddler(callbackWrapper);
					});
		};
		
		store.forEachTiddler = forEachTiddlerWithIncludes;
		try {
			return func.apply(this,arguments);
		} finally {
			store.forEachTiddler = orig_forEachTiddler;
		}
	};
	
	return wrapper;
};

var useForReallyEachTiddler = function(object,property) {
	return object[property] = getFunctionUsingForReallyEachTiddler(object[property]);
};


//================================================================================
// abego.TiddlyWikiIncluder

abego.TiddlyWikiIncluder = {};

abego.TiddlyWikiIncluder.setProgressFunction = function(func) {
	progress = func;
};

abego.TiddlyWikiIncluder.getProgressFunction = function(func) {
	return progress;
};

abego.TiddlyWikiIncluder.sendProgress = function(message, sender, state) {
	if (progress)
		progress.apply(this,arguments);
};


// Called when an included TiddlyWiki could not be loaded.
//
// By default an error message is displayed.
//
abego.TiddlyWikiIncluder.onError = function(url, errorMessage) {
	displayMessage("Error when including '%0':\n%1".format([url, errorMessage]));
};


// Returns true when there are "pending" includes, i.e. TiddlyWiki that are not yet loaded.
//
// A TiddlyWiki that failed loading is not pending.
//
abego.TiddlyWikiIncluder.hasPendingIncludes = function() {
	for (var i = 0; i < includes.length; i++) {
		var state = abego.TiddlyWikiIncluder.getState(includes[i]);
		if (state == WAITING || state == LOADING)
			return true;
	}
	return false;
};


// @return [] of Strings, the URLs of the includes
//
abego.TiddlyWikiIncluder.getIncludes = function() {
	return includes.slice();
};


// @return [may be null] a state/error text of the store with the given URL, or null when the store is already loaded
//
abego.TiddlyWikiIncluder.getState = function(url) {
	var s = includedStores[url];
	if (!s)
		return getMissingIncludeMsg(url);
	return typeof s == "string" ? s : null;
};


// @return [may be null] the (TiddlyWiki) store  with the given URL, null if not (yet) loaded.
//
abego.TiddlyWikiIncluder.getStore = function(url) {
	var s = includedStores[url];
	if (!s)
		return getMissingIncludeMsg(url);
	return s instanceof TiddlyWiki ? s : null;
};


// Includes the (local or remote) TiddlyWiki store with the given url.
// 
// stores with urls already already included are ignored.
//
// @param url	see url@abego.loadTiddlyWikiStore
// @param delayMilliSeconds [optional] if defined loading starts delayMilliSeconds later, otherwise "immediately"
//
abego.TiddlyWikiIncluder.include = function(url, delayMilliSeconds) {
	if (!isIncludeEnabled() || includedStores[url])
		return;
	var self = this;
	
	includes.push(url);
	includedStores[url] = WAITING;

	var loadStoreCallback = function(theStore,urlInCallback,params,errorMessage) {
		if (theStore === undefined) {
			includedStores[url] = errorMessage;
			self.onError(url, errorMessage);
			return;
		}
		includedStores[url] = theStore;
		pendingOnLoadURLs.push(url);
		invokeLater(notifyListeners);
	};
	
	var loadStore = function() {
		includedStores[url] = LOADING;
		abego.loadTiddlyWikiStore(url,loadStoreCallback,null,progress);
	};
	
	if (delayMilliSeconds)
		invokeLater(loadStore, delayMilliSeconds);
	else
		loadStore();
};


// iterates over all tiddlers of "the store" and all tiddlers of included (and loaded) stores
//
abego.TiddlyWikiIncluder.forReallyEachTiddler = function(callback) {
	var caller = function() {
		store.forEachTiddler(callback);
	};
	
	getFunctionUsingForReallyEachTiddler(caller).call(store);
};


// function abego.TiddlyWikiIncluder.getFunctionUsingForReallyEachTiddler(func)
//
// Returns a function that behaves as func, but every call to store.forEachTiddler will actually 
// be a call to forReallyEachTiddler, i.e. iterate over the tiddlers the main store and of the 
// included TiddlyWikis
//
// @return the patched function
//
abego.TiddlyWikiIncluder.getFunctionUsingForReallyEachTiddler = getFunctionUsingForReallyEachTiddler;


// function abego.TiddlyWikiIncluder.useForReallyEachTiddler(object,property)
//
// Patches the function hold in the given property of the object in such a way that every call
// to store.forEachTiddler will actually be a call to forReallyEachTiddler, i.e. iterate over the
// tiddlers the main staire and of the included TiddlyWikis
//
// @param object
// @param property the name of the property of the object containing the function to be patched.
// @return the patched function
//
abego.TiddlyWikiIncluder.useForReallyEachTiddler = useForReallyEachTiddler;


// Add a listener function to the TiddlyWikiIncluder.
//
// @param listener function(urls)
//							url: [] of Strings, containing the urls of the TiddlyWiki just included
//									(see url@abego.TiddlyWikiIncluder.include)
//						called whenever one or more TiddlyWiki store are successfully included.
//
abego.TiddlyWikiIncluder.addListener = function(listener) {
	listeners.push(listener);
};

// -------------------------------------------------------------------------------
// TiddlyWikiIncluder initialization code

abego.TiddlyWikiIncluder.addListener(refreshTiddlyWiki);

//----------------------------------------------------------------------------
// Options Support

if (config.options.chkUseInclude === undefined) config.options.chkUseInclude = true;

config.shadowTiddlers.AdvancedOptions += "\n<<option chkUseInclude>> Include ~TiddlyWikis (IncludeList | IncludeState | [[help|http://tiddlywiki.abego-software.de/#%5B%5BIncludePlugin%20Documentation%5D%5D]])\n^^(Reload this ~TiddlyWiki to make changes become effective)^^";
config.shadowTiddlers.IncludeState = "<<includeState>>";

//================================================================================
// Default Progress Handling for abego.TiddlyWikiIncluder

var showAnimated = function(e, showing, duration) {
	if (!anim || !abego.ShowAnimation) {
		e.style.display = showing ? "block" : "none";
		return;
	}
	
	anim.startAnimating(new abego.ShowAnimation(e,showing,duration));
};

abego.TiddlyWikiIncluder.getDefaultProgressFunction = function() {

	setStylesheet(
		".includeProgressState{\n"+
		"background-color:#FFCC00;\n"+
		"position:absolute;\n"+
		"right:0.2em;\n"+
		"top:0.2em;\n"+
		"width:7em;\n"+
		"padding-left:0.2em;\n"+
		"padding-right:0.2em\n"+
		"}\n",
		"abegoInclude");

	var createStateElem = function() {
		var e = document.createElement("div");
		e.className = "includeProgressState";
		e.style.display = "none";
		document.body.appendChild(e);
		return e;
	};
	
	var stateElem = createStateElem();


	var showState = function(message) {
		removeChildren(stateElem);
		createTiddlyText(stateElem,message);
		showAnimated(stateElem,true,0);
	};

	var hideState = function() {
		// hide the state the next idle time 
		invokeLater(function() {
			showAnimated(stateElem,false,ANI_DURATION_HIDE_STATE);
		},100,ANIMATION_PRIORITY);
	};
	
	var myProgressFunction = function(message, sender, state, url, params) {
		
		if (state == "Done" || state == "Failed") {
			hideState();
			return;
		}
		
		if (sender == "abego.loadTiddlyWikiStore") {
			idleCount = 0;
			if (state == "Processing")
				showState("Including...");
		} else {
			showState(message);
		}
	};
	return myProgressFunction;
};

abego.TiddlyWikiIncluder.setProgressFunction(abego.TiddlyWikiIncluder.getDefaultProgressFunction());


//================================================================================
// The "include" macro
//
// Syntax: <<include {url}* [delay: {milliSeconds}] [hide: true] >>
//

config.macros.include = {};
config.macros.include.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    params = paramString.parseParams("url",null,true,false,true); // allowEval, cascadeDefaults, names allowed
	var delay = parseInt(getParam(params,"delay","0"));
	var urls = params[0]["url"];
	var hide = getFlag(params, "hide", false);
	if (!hide)
		createTiddlyText(createTiddlyElement(place,"code"),wikifier.source.substring(wikifier.matchStart, wikifier.nextMatch));
	for (var i = 0; urls && i < urls.length; i++)
		abego.TiddlyWikiIncluder.include(urls[i],delay);
};


//================================================================================
// The "includeState" macro
//
// Syntax: <<includeState>>

config.macros.includeState = {};
config.macros.includeState.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	var getFullState = function () {
		var s = "";
		var includes = abego.TiddlyWikiIncluder.getIncludes();
		if (!includes.length)
			return "{{noIncludes{\nNo includes or 'include' is disabled (see AdvancedOptions)\n}}}\n";
			
		s += "|!Address|!State|\n";
		for (var i = 0; i < includes.length; i++) {
			var inc = includes[i];
			s += "|{{{"+inc+"}}}|";
			var t = abego.TiddlyWikiIncluder.getState(inc);
			s += t ? "{{{"+t+"}}}" : "included";
			s += "|\n"
		}
		s += "|includeState|k\n";
		return s;
	};
	
	var updateState = function(){
		removeChildren(div);
		wikify(getFullState(),div);
		if (abego.TiddlyWikiIncluder.hasPendingIncludes())
			invokeLater(updateState,500,UPDATE_STATE_PRIORITY);
	};

	var div = createTiddlyElement(place,"div");
	
	invokeLater(updateState,0,UPDATE_STATE_PRIORITY);
};

//================================================================================
// Tiddler extension/modification

var orig_Tiddler_isReadOnly = Tiddler.prototype.isReadOnly;

// Includes tiddlers are readonly.
Tiddler.prototype.isReadOnly = function() {
	return orig_Tiddler_isReadOnly.apply(this,arguments) || this.isIncluded();
}

Tiddler.prototype.isIncluded = function() {
	return this.includeURL != undefined;
};

Tiddler.prototype.getIncludeURL = function() {
	return this.includeURL;
};


//================================================================================
// TiddlyWiki modifications

// In some TiddlyWiki functions the "forEachTiddler" should work on all tiddlers, also those from 
// included store. (E.g. TiddlyWiki.prototype.getTags)
//
// But not for all (e.g. TiddlyWiki.prototype.getTiddlers is used for saving, but only the "own" tiddlers should be saved)
//
// Therefore explicitly list the functions that should be "wrapped" to use the "forReallyEachTiddler".
//
var tiddlyWikiFunctionsUsingForReallyEachTiddler = {
	getMissingLinks: 1, getOrphans: 1,getTags:1, reverseLookup: 1, updateTiddlers: 1};
	
for (var n in tiddlyWikiFunctionsUsingForReallyEachTiddler)
	useForReallyEachTiddler(TiddlyWiki.prototype,n);


//================================================================================
// Make IntelliTagger "Include-aware"

var patchIntelliTagger = function() {
	if (abego.IntelliTagger)
		useForReallyEachTiddler(abego.IntelliTagger,"assistTagging");
};

//================================================================================
// Perform plugin startup tasks

attachToStore();
invokeLater(includeFromIncludeList,100);
invokeLater(patchIntelliTagger,100);

})();

//}}}
!!預約執行一次程序
*官方解釋:
*執行身份:
*重要參數
**時間表示:HH:MM、midnight、noon、teatime (4pm)、AM、PM
**日期表示:MMDDYY、MM/DD/YY、DD.MM.YY
**相對表示:now + __count__ __time-units__
***__time-units__: minutes、hours、days、weeks、years
**-f: 指定預約工作檔案
**-l: 列出目前的預約工作
**-r: 移除已預約的工作
*等效指令:[[atq]]

*背景執行
*不動聲色 (請重新導向其輸出結果)
!!!輸入完命令,按下 Ctrl+d 離開

{{{

mail -s 'test from iii' bearflatfish@gmail.com < /etc/passwd
find / -name *flatfish* > /tmp/flatfish.find
tar jcvf /tmp/flatfish.tar.bz2 /home/flatfish > /tmp/flatfish.tar.result
mail -s 'result' bearflatfish@gmail.com > /tmp/flatfish.find
mail -s 'tar' bearflatfish@gmail.com < /tmp/flatfish.tar.result
}}}
!!查詢目前 at 預約工作項目
*官方解釋:
*執行身份:
*重要參數
*等效指令:[[at -l|at]]
!!移除預約中的程序
*官方解釋:
*執行身份:
*重要參數
*等效指令:[[at -r|at]]
!!補做 at 佇列中的工作 (例如因關機而沒做到的佇列)
*官方解釋:run jobs queued for later execution
*執行身份:
*重要參數
*等效指令:[[atd -s|atd]]

{{{
#! /bin/sh
prefix=/usr
exec_prefix=/usr
exec /usr/sbin/atd -s "$@"
}}}
!!檔案的檔名 (扣掉目錄名稱)

{{{
[root@ms1 ~]# basename /etc/passwd
passwd
}}}
!!繼續執行背景程序
*官方解釋:
*執行身份:
*重要參數
**% {//##//}: 指定回到佇列編號 {//##//} 的程序背景
*等效指令:
!!.bz2 壓縮
*官方解釋:
*執行身份:
*重要參數
**-k: keep, 保留原檔
**-c: STDOUT (標準輸出)
**-d: 解壓縮
**-#: 1 ~ 9
***-1: 快
***-9: 好(預設值)
*等效指令:[[bunzip2]]、[[bzcat]]、[[bzless]]
!!判斷式
{{{
case	判斷式 in
	比對值 1|比對值 2|比對值 3|...)
		:
		:
		;; # break

esac
}}}
{{{
case $1 in
        start|begin|run)
                echo "$0 is running"
                ;;
        end|stop)
                echo "$0 is stop"
                ;;
        *)
                echo "Usage: $0 {start|begin|run|end|stop}"
                ;;
esac
}}}
!!改變密碼的有效期
**-E YYYY-MM-DD: 改變密碼有效期限至 YYYY 年 MM 月 DD 日
**-I: 多久內必須換密碼
**-W: 警告天數
!!改變檔案/目錄屬性

|chattr|+<br>-<br>=|A:有做 actime<br>S:同步<br>a:only append<br>i:不能刪除、不能移動、不能 ln|
!!設定及檢視目前服務開機啟動組態
*官方解釋:updates  and queries runlevel information for system services
*執行身份:
*重要參數
**{{{--list}}}
**{{{--level}}}
*等效指令:

{{{
chkconfig --list | grep syslog
}}}

*設定開機時期啟動服務
{{{
chkconfig --level 35 named on
}}}

!!改變 檔案 / 目錄 權限
*官方解釋:
*執行身份:
*重要參數
*等效指令:


| chmod | u<br>g<br>o<br>a | +<br>-<br>= | r<br>w<br>x |

{{{
chmod u-w,g+x,o=rw root.file1
chmod ug=rw root.file1
}}}

| 0 0 0 | 0 |- - - |
| 0 0 1 | 1 |- - x |
| 0 1 0 | 2 |- w - |
| 0 1 1 | 3 |- w x |
| 1 0 0 | 4 |r - - |
| 1 0 1 | 5 |r - x |
| 1 1 0 | 6 |r w - |
| 1 1 1 | 7 |r w x |

| 7 7 7 |r w x r w x r w x |
| 6 4 0 |r w - r - - - - - |
| 2 4|- - - - w - r - - |
| 7|- - - - - - r w x |
{{{
chmod 777 root.file1
chmod 24 root.file2
chmod 7 root.file3
}}}
*百位數十位數自動補 0
!!改變擁有者 / 群組
*官方解釋:
*執行身份:
*重要參數
**-R: 遞迴式改變檔案/目錄擁有者
*等效指令:[[chgrp]]

chown -R {//new-owner//} {//directory//}
chown {//new-owner.new-group//} {//filename//}
!!需安裝 ncompress 套件
!!壓縮為 .Z 的壓縮檔
*官方解釋:press and expand data
*執行身份:
*重要參數
**-c: STDOUT (標準輸出)
**-d: 解壓縮
**-f: 強制壓縮 (當壓縮後檔案大小 > 原始檔案時,compress 將不會執行壓縮,此時則需要 -f 強制壓縮)
*等效指令:[[uncompress]]、[[zcat]]
!!備份指令
**-o: 備份
**-i: 還原
**-v: verbose

*備份今天一天內 /etc 中有被修改過的檔案
{{{
find /etc -mtime -1 | cpio -ov > /tmp/etc.today.cpio
}}}

{{{
mkdir dir2
cd dir2
cpio -iv < ../etc.today.cpio
}}}
!!定期排程
*官方解釋:
*執行身份:
*重要參數
**-l: list
**-r: remove
**-e edit
*等效指令:

!!crontab 格式
|分|時|日|月|週|執行的命令||
|0|19|*|*|5|rpm -Va|每週五晚上七點執行 rpm -Va|
|30|6|*|*|1,3,5|mplayer xxx.mp3|每週一三五早上六點半執行 mplayer xxx.mp3|
|30|6|*|*|1-5|mplayer xxx.mp3|每週一到五早上六點半執行 mplayer yyy.mp3|
|0|8-17/2|*|*|1-5|mplayer zzz.mp3|每週一到五早上八點到下午五點每隔兩個小時執行 mplayer zzz.mp3|
*root 專用 ''/etc/crontab'' 表
|分|時|日|月|週|執行身分|執行的命令||
|01|*|*|*|*|root|run-parts /etc/cron.hourly||

Lab 範例
|50-59/2|13|11|8|*|mail -s 'test from crond' brad@brad.tw < /etc/group|
!!NNTP 伺服器控制命令
*官方解釋:control the InterNetNews daemon
*執行身份:
*重要參數
*等效指令:
{{{
ctlinnd newgroup {new_group_name}
}}}
!!垂直切出所需要的欄位

**-c#: 切出第 # 個字元
{{{
cut -c1-4 /etc/passwd
cut -c1,3,5 /etc/passwd
}}}
**-d":": 指定 『 : 』為分隔符號,需搭配 -f# 使用
***-f#: 切出第 # 個欄位
{{{
cut -d":" -f1 /etc/passwd
}}}
!!顯示目前軟體時鐘時間 (OS)


{{{
today=`date +%Y%m%d`.tgz
echo $today
}}}
!!讀入一個檔案,複製一份
*官方解釋:convert and copy a file
*執行身份:
*重要參數
**if: input file
**of: output file
**bs: block size (Bytes)
**count: block 數量
*等效指令:

{{{
dd if=/dev/hdc of=/tmp/mbr.bak bs=512 count=1
}}}
!!使用一個檔案當作 swap 空間
{{{
dd if=/dev/zero of=/tmp/myswap bs=4096 count=1000
mkswap /tmp/myswap
swapon /tmp/myswap
}}}
!!顯示檔案系統磁碟空間使用
*官方解釋:report file system disk space usage
*執行身份:
*重要參數
*等效指令:
*官方解釋:
*執行身份:
*重要參數
*等效指令:

{{{
dig microsoft mx
}}}
*挖 微軟 MX紀錄
{{{
dig @168.95.1.1 microsoft mx
dig @192.168.33.254 microsoft mx
}}}
@向特定 DNS server 查詢
!!顯示檔案所在的目錄

{{{
[root@ms1 ~]# dirname /etc/passwd
/etc
}}}
!!顯示 syslog 未載入前的系統日誌

{{{
dmesg
cat /var/log/dmesg
}}}
''horizontal:''
{{{
* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
* menu #3
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu>>
}}}
* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
* menu #3
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu>>

''vertical:''
{{{
* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu vertical>>
}}}

* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu vertical>>


/% %/
!!查詢一個目錄空間使用量
*官方解釋:estimate file space usage
*執行身份:
*重要參數
**-h: human readable, 轉換單位為 KB、MB、...
*等效指令:
!!備份檔案系統


*-0: 完整備份
*-u: 紀錄備份時間 /etc/dumpdates
*-f: 指定備份目的地

*dump [parameters] [destination] [source]
{{{
dump -0f /tmp/etc.dump /etc
}}}
!使用說明
{{{
1. 規劃標籤名
2. 根據 "標籤名" 產生 [編輯] 與 [顯示] 的 Template

    例如 : 標籤名為 HTML, 那麼二個 Template 的名稱為 HTMLEditTemplate, HTMLViewTemplate,
              以後只要文章的標籤有 HTML, 便會自動套用這二個 Template

3. 將以下巨集命令加入 ToolBar 文章中

    <<newTiddler  label:"新增網頁"    tag:"HTML"     template:"HTMLEditTemplate"   title:"新增網頁">>
                              ^                ^                      ^                           ^
                         按鈕名稱        新文章的標籤      新文章第一次使用的 Template     新文章的 Title

    * 必須要安裝 TaggedTemplateTweak 這個插件, 才有以上功能

}}}

請點選以下按鈕, 測試 easyEdit 功能

<<newTiddler label:新增網頁 tag:"HTML" template:"HTMLEditTemplate" title:"新增網頁">>


!HTMLEditTemplate
{{{
<div class='toolbar' macro='toolbar +saveTiddler  -cancelTiddler deleteTiddler'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='easyEdit text'></div>
                                      ^
                                 這是重點

<div class='editor' macro='edit tags'></div>
<div class='editorFooter'>
<span macro='message views.editor.tagPrompt'></span>
<span macro='tagChooser'></span>
</div>
}}}

!HTMLViewTemplate
{{{
<div class='toolbar' macro='toolbar closeTiddler closeOthers +easyEdit > fields syncing permalink references jump'></div>
                                                                    ^
                                                                這是重點
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
}}}
/***
|''Name:''|easyEditPlugin|
|''Description:''|Lite and extensible Wysiwyg editor for TiddlyWiki.|
|''Version:''|1.3.3|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0|
!Installation
#import the plugin,
#save and reload,
#use the <<toolbar easyEdit>> button in the tiddler's toolbar (in default ViewTemplate) or add {{{easyEdit}}} command in your own toolbar.
! Useful Addons
*[[HTMLFormattingPlugin|http://www.tiddlytools.com/#HTMLFormattingPlugin]] to embed wiki syntax in html tiddlers.<<br>>//__Tips__ : When this plugin is installed, you can use anchor syntax to link tiddlers in wysiwyg mode (example : #example). Anchors are converted back and from wiki syntax when editing.//
*[[TaggedTemplateTweak|http://www.TiddlyTools.com/#TaggedTemplateTweak]] to use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values.
!Configuration
|Buttons in the toolbar (empty = all).<<br>>//Example : bold,underline,separator,forecolor//<<br>>The buttons will appear in this order.| <<option txtEasyEditorButtons>>|
|EasyEditor default height | <<option txtEasyEditorHeight>>|
|Stylesheet applied to the edited richtext |[[EasyEditDocStyleSheet]]|
|Template called by the {{{write}}} button |[[EasyEditTemplate]]|
!How to extend EasyEditor
*To add your own buttons, add some code like the following in a systemConfig tagged tiddler (//use the prompt attribute only if there is a parameter//) :
**{{{EditorToolbar.buttons.heading = {label:"H", toolTip : "Set heading level", prompt: "Enter heading level"};}}} 
**{{{EditorToolbar.buttonsList +=",heading";}}}
*To get the list of all possible commands, see the documentation of the [[Gecko built-in rich text editor|http://developer.mozilla.org/en/docs/Midas]] or the [[IE command identifiers|http://msdn2.microsoft.com/en-us/library/ms533049.aspx]].
*To go further in customization, see [[Link button|EasyEditPlugin-LinkButton]] as an example.
!Code
***/

//{{{

var geckoEditor={};
var IEeditor={};

config.options.txtEasyEditorHeight = config.options.txtEasyEditorHeight ? config.options.txtEasyEditorHeight : "500px";
config.options.txtEasyEditorButtons = config.options.txtEasyEditorButtons ? config.options.txtEasyEditorButtons : "";

// TW2.1.x compatibility
config.browser.isGecko = config.browser.isGecko ? config.browser.isGecko : (config.userAgent.indexOf("gecko") != -1); 
config.macros.annotations = config.macros.annotations ? config.macros.annotations : {handler : function() {}}


// EASYEDITOR MACRO

config.macros.easyEdit = {
	handler : function(place,macroName,params,wikifier,paramString,tiddler) {
		var field = params[0];
		var height = params[1] ? params[1] : config.options.txtEasyEditorHeight;
		var editor = field ? new easyEditor(tiddler,field,place,height) : null;
	},
	gather: function(element){
		var iframes = element.getElementsByTagName("iframe");
		if (iframes.length!=1) return null
		var text = "<html>"+iframes[0].contentWindow.document.body.innerHTML+"</html>";
		text = config.browser.isGecko ? geckoEditor.postProcessor(text) : (config.browser.isIE ? IEeditor.postProcessor(text) : text);
		return text;
	}
}

// EASYEDITOR CLASS

function easyEditor(tiddler,field,place,height) {
	this.tiddler = tiddler;
	this.field = field;
	this.browser = config.browser.isGecko ? geckoEditor : (config.browser.isIE ? IEeditor : null);
	this.wrapper = createTiddlyElement(place,"div",null,"easyEditor");
	this.wrapper.setAttribute("easyEdit",this.field);
	this.iframe = createTiddlyElement(null,"iframe");
	this.browser.setupFrame(this.iframe,height,contextualCallback(this,this.onload));
	this.wrapper.appendChild(this.iframe);
}

easyEditor.prototype.onload = function(){
	this.editor = this.iframe.contentWindow;
	this.doc = this.editor.document;
	if (!this.browser.isDocReady(this.doc)) return null;
	
	if (!this.tiddler.isReadOnly() && this.doc.designMode.toLowerCase()!="on") {
		this.doc.designMode = "on";
		if (this.browser.reloadOnDesignMode) return false;	// IE fire readystatechange after designMode change
	}
	
	var internalCSS = store.getTiddlerText("EasyEditDocStyleSheet");
	setStylesheet(internalCSS,"EasyEditDocStyleSheet",this.doc);
	this.browser.initContent(this.doc,store.getValue(this.tiddler,this.field));

	var barElement=createTiddlyElement(null,"div",null,"easyEditorToolBar");
	this.wrapper.insertBefore(barElement,this.wrapper.firstChild);
	this.toolbar = new EditorToolbar(this.doc,barElement,this.editor);

	this.browser.plugEvents(this.doc,contextualCallback(this,this.scheduleButtonsRefresh));
	this.editor.focus();
}

easyEditor.SimplePreProcessoror = function(text) {
	var re = /^<html>(.*)<\/html>$/m;
	var htmlValue = re.exec(text);
	var value = (htmlValue && (htmlValue.length>0)) ? htmlValue[1] : text;
	return value;
}

easyEditor.prototype.scheduleButtonsRefresh=function() { //doesn't refresh buttons state when rough typing
	if (this.nextUpdate) window.clearTimeout(this.nextUpdate);
	this.nextUpdate = window.setTimeout(contextualCallback(this.toolbar,EditorToolbar.onUpdateButton),easyEditor.buttonDelay);
}

easyEditor.buttonDelay = 200;

// TOOLBAR CLASS

function EditorToolbar(target,parent,window){
	this.target = target;
	this.window=window;
	this.elements={};
	var row = createTiddlyElement(createTiddlyElement(createTiddlyElement(parent,"table"),"tbody"),"tr");
	var buttons = (config.options.txtEasyEditorButtons ? config.options.txtEasyEditorButtons : EditorToolbar.buttonsList).split(",");
	for(var cpt = 0; cpt < buttons.length; cpt++){
		var b = buttons[cpt];
		var button = EditorToolbar.buttons[b];
		if (button) {
			if (button.separator)
				createTiddlyElement(row,"td",null,"separator").innerHTML+="&nbsp;";
			else {
				var cell=createTiddlyElement(row,"td",null,b+"Button");
				if (button.onCreate) button.onCreate.call(this, cell, b);
				else EditorToolbar.createButton.call(this, cell, b);
			}
		}
	}
}

EditorToolbar.createButton = function(place,name){
	this.elements[name] = createTiddlyButton(place,EditorToolbar.buttons[name].label,EditorToolbar.buttons[name].toolTip,contextualCallback(this,EditorToolbar.onCommand(name)),"button");
}

EditorToolbar.onCommand = function(name){
	var button = EditorToolbar.buttons[name];
	return function(){
		var parameter = false;
		if (button.prompt) {
			var parameter = this.target.queryCommandValue(name);
			parameter = prompt(button.prompt,parameter);
		}
		if (parameter != null) {
			this.target.execCommand(name, false, parameter);
			EditorToolbar.onUpdateButton.call(this);
		}
		return false;
	}
}

EditorToolbar.getCommandState = function(target,name){
	try {return target.queryCommandState(name)}
	catch(e){return false}
}

EditorToolbar.onRefreshButton = function (name){
	if (EditorToolbar.getCommandState(this.target,name)) addClass(this.elements[name].parentNode,"buttonON");
	else removeClass(this.elements[name].parentNode,"buttonON");
	this.window.focus();
}

EditorToolbar.onUpdateButton = function(){
	for (b in this.elements) 
		if (EditorToolbar.buttons[b].onRefresh) EditorToolbar.buttons[b].onRefresh.call(this,b);
		else EditorToolbar.onRefreshButton.call(this,b);
}

EditorToolbar.buttons = {
	separator : {separator : true},
	bold : {label:"B", toolTip : "Bold"},
	italic : {label:"I", toolTip : "Italic"},
	underline : {label:"U", toolTip : "Underline"},
	strikethrough : {label:"S", toolTip : "Strikethrough"},
	insertunorderedlist : {label:"\u25CF", toolTip : "Unordered list"},
	insertorderedlist : {label:"1.", toolTip : "Ordered list"},
	justifyleft : {label:"[\u2261", toolTip : "Align left"},
	justifyright : {label:"\u2261]", toolTip : "Align right"},
	justifycenter : {label:"\u2261", toolTip : "Align center"},
	justifyfull : {label:"[\u2261]", toolTip : "Justify"},
	removeformat : {label:"\u00F8", toolTip : "Remove format"},
	fontsize : {label:"\u00B1", toolTip : "Set font size", prompt: "Enter font size"},
	forecolor : {label:"C", toolTip : "Set font color", prompt: "Enter font color"},
	fontname : {label:"F", toolTip : "Set font name", prompt: "Enter font name"},
	heading : {label:"H", toolTip : "Set heading level", prompt: "Enter heading level (example : h1, h2, ...)"},
	indent : {label:"\u2192[", toolTip : "Indent paragraph"},
	outdent : {label:"[\u2190", toolTip : "Outdent paragraph"},
	inserthorizontalrule : {label:"\u2014", toolTip : "Insert an horizontal rule"},
	insertimage : {label:"\u263C", toolTip : "Insert image", prompt: "Enter image url"}
}

EditorToolbar.buttonsList = "bold,italic,underline,strikethrough,separator,increasefontsize,decreasefontsize,fontsize,forecolor,fontname,separator,removeformat,separator,insertparagraph,insertunorderedlist,insertorderedlist,separator,justifyleft,justifyright,justifycenter,justifyfull,indent,outdent,separator,heading,separator,inserthorizontalrule,insertimage";

if (config.browser.isGecko) {
	EditorToolbar.buttons.increasefontsize = {onCreate : EditorToolbar.createButton, label:"A", toolTip : "Increase font size"};
	EditorToolbar.buttons.decreasefontsize = {onCreate : EditorToolbar.createButton, label:"A", toolTip : "Decrease font size"};
	EditorToolbar.buttons.insertparagraph = {label:"P", toolTip : "Format as paragraph"};
}

// GECKO (FIREFOX, ...) BROWSER SPECIFIC METHODS

geckoEditor.setupFrame = function(iframe,height,callback) {
	iframe.setAttribute("style","width: 100%; height:" + height);
	iframe.addEventListener("load",callback,true);
}

geckoEditor.plugEvents = function(doc,onchange){
	doc.addEventListener("keyup", onchange, true);
	doc.addEventListener("keydown", onchange, true);
	doc.addEventListener("click", onchange, true);
}

geckoEditor.postProcessor = function(text){return text};

geckoEditor.preProcessor = function(text){return easyEditor.SimplePreProcessoror(text)}

geckoEditor.isDocReady = function() {return true;}

geckoEditor.reloadOnDesignMode=false;

geckoEditor.initContent = function(doc,content){
	if (content) doc.execCommand("insertHTML",false,geckoEditor.preProcessor(content));
}

// INTERNET EXPLORER BROWSER SPECIFIC METHODS
	
IEeditor.setupFrame = function(iframe,height,callback) {
	iframe.width="99%";  //IE displays the iframe at the bottom if 100%. CSS layout problem ? I don't know. To be studied...
	iframe.height=height.toString();
	iframe.attachEvent("onreadystatechange",callback);
}

IEeditor.plugEvents = function(doc,onchange){
	doc.attachEvent("onkeyup", onchange);
	doc.attachEvent("onkeydown", onchange);
	doc.attachEvent("onclick", onchange);
}

IEeditor.isDocReady = function(doc){
	if (doc.readyState!="complete") return false;
	if (!doc.body) return false;
	return (doc && doc.getElementsByTagName && doc.getElementsByTagName("head") && doc.getElementsByTagName("head").length>0);
}

IEeditor.postProcessor = function(text){return text};

IEeditor.preProcessor = function(text){return easyEditor.SimplePreProcessoror(text)}

IEeditor.reloadOnDesignMode=true;

IEeditor.initContent = function(doc,content){
	if (content) doc.body.innerHTML=IEeditor.preProcessor(content);
}
	
function contextualCallback(obj,func){
    return function(){return func.call(obj)}
}
	
Story.prototype.previousGatherSaveEasyEdit = Story.prototype.previousGatherSaveEasyEdit ? Story.prototype.previousGatherSaveEasyEdit : Story.prototype.gatherSaveFields; // to avoid looping if this line is called several times
Story.prototype.gatherSaveFields = function(e,fields){
	if(e && e.getAttribute) {
		var f = e.getAttribute("easyEdit");
		if(f){
			var newVal = config.macros.easyEdit.gather(e);
			if (newVal) fields[f] = newVal;
		}
		this.previousGatherSaveEasyEdit(e, fields);
	}
}

config.commands.easyEdit={
	text: "編輯網頁",
	tooltip: "Edit this tiddler in wysiwyg mode",
	readOnlyText: "檢視",
	readOnlyTooltip: "View the source of this tiddler",
	handler : function(event,src,title) {
		clearMessage();
		var tiddlerElem = document.getElementById(story.idPrefix + title);
		var fields = tiddlerElem.getAttribute("tiddlyFields");
		story.displayTiddler(null,title,"EasyEditTemplate",false,null,fields);
		return false;
	}
}

config.shadowTiddlers.ViewTemplate = config.shadowTiddlers.ViewTemplate.replace(/\+editTiddler/,"+editTiddler easyEdit");

config.shadowTiddlers.EasyEditTemplate = config.shadowTiddlers.EditTemplate.replace(/macro='edit text'/,"macro='easyEdit text'");

config.shadowTiddlers.EasyEditToolBarStyleSheet = "/*{{{*/\n";
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar {font-size:0.8em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".editor iframe {border:1px solid #DDD}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar td{border:1px solid #888; padding:2px 1px 2px 1px; vertical-align:middle}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar td.separator{border:0}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .button{border:0;color:#444}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .buttonON{background-color:#EEE}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar {margin:0.25em 0}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .boldButton {font-weight:bold}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .italicButton .button {font-style:italic;padding-right:0.65em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .underlineButton .button {text-decoration:underline}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .strikeButton .button {text-decoration:line-through}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .unorderedListButton {margin-left:0.7em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .justifyleftButton .button {padding-left:0.1em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .justifyrightButton .button {padding-right:0.1em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .justifyfullButton .button, .easyEditorToolBar .indentButton .button, .easyEditorToolBar .outdentButton .button {padding-left:0.1em;padding-right:0.1em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .increasefontsizeButton .button {padding-left:0.15em;padding-right:0.15em; font-size:1.3em; line-height:0.75em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .decreasefontsizeButton .button {padding-left:0.4em;padding-right:0.4em; font-size:0.8em;}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .forecolorButton .button {color:red;}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .fontnameButton .button {font-family:serif}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet +="/*}}}*/";

store.addNotification("EasyEditToolBarStyleSheet", refreshStyles); 

config.shadowTiddlers.EasyEditDocStyleSheet = "/*{{{*/\n \n/*}}}*/";
if (config.annotations) config.annotations.EasyEditDocStyleSheet = "This stylesheet is applied when editing a text with the wysiwyg easyEditor";

//}}}
/***
!Link button add-on
***/
//{{{
EditorToolbar.createLinkButton = function(place,name) {
	this.elements[name] = createTiddlyButton(place,EditorToolbar.buttons[name].label,EditorToolbar.buttons[name].toolTip,contextualCallback(this,EditorToolbar.onInputLink()),"button");
}

EditorToolbar.onInputLink = function() {
	return function(){
		var browser = config.browser.isGecko ? geckoEditor : (config.browser.isIE ? IEeditor : null);
		var value = browser ? browser.getLink(this.target) : "";
		value = prompt(EditorToolbar.buttons["createlink"].prompt,value);
		if (value) browser.doLink(this.target,value);
		else if (value=="") this.target.execCommand("unlink", false, value);
		EditorToolbar.onUpdateButton.call(this);
		return false;
	}
}

EditorToolbar.buttonsList += ",separator,createlink";

EditorToolbar.buttons.createlink = {onCreate : EditorToolbar.createLinkButton, label:"L", toolTip : "Set link", prompt: "Enter link url"};


geckoEditor.getLink=function(doc){
	var range=doc.defaultView.getSelection().getRangeAt(0);
	var container = range.commonAncestorContainer;
	var node = (container.nodeType==3) ? container.parentNode : range.startContainer.childNodes[range.startOffset];
	if (node && node.tagName=="A") {
		var r=doc.createRange();
		r.selectNode(node);
		doc.defaultView.getSelection().addRange(r);
		return (node.getAttribute("tiddler") ? "#"+node.getAttribute("tiddler") : node.href);
	}
	else return (container.nodeType==3 ? "#"+container.textContent.substr(range.startOffset, range.endOffset-range.startOffset).replace(/ $/,"") : "");
}

geckoEditor.doLink=function(doc,link){ // store tiddler in a temporary attribute to avoid url encoding of tiddler's name
	var pin = "href"+Math.random().toString().substr(3);
	doc.execCommand("createlink", false, pin);
	var isTiddler=(link.charAt(0)=="#");
	var node = doc.defaultView.getSelection().getRangeAt(0).commonAncestorContainer;
	var links= (node.nodeType!=3) ? node.getElementsByTagName("a") : [node.parentNode];
	for (var cpt=0;cpt<links.length;cpt++) 
			if (links[cpt].href==pin){
				links[cpt].href=isTiddler ? "javascript:;" : link; 
				links[cpt].setAttribute("tiddler",isTiddler ? link.substr(1) : "");
			}
}

geckoEditor.beforeLinkPostProcessor = geckoEditor.beforelinkPostProcessor ? geckoEditor.beforelinkPostProcessor : geckoEditor.postProcessor;
geckoEditor.postProcessor = function(text){
	return geckoEditor.beforeLinkPostProcessor(text).replace(/<a tiddler="([^"]*)" href="javascript:;">(.*?)(?:<\/a>)/gi,"[[$2|$1]]").replace(/<a tiddler="" href="/gi,'<a href="');
}

geckoEditor.beforeLinkPreProcessor = geckoEditor.beforeLinkPreProcessor ? geckoEditor.beforeLinkPreProcessor : geckoEditor.preProcessor
geckoEditor.preProcessor = function(text){
	return geckoEditor.beforeLinkPreProcessor(text).replace(/\[\[([^|\]]*)\|([^\]]*)]]/g,'<a tiddler="$2" href="javascript:;">$1</a>');
}


IEeditor.getLink=function(doc){
	var node=doc.selection.createRange().parentElement();
	if (node.tagName=="A") return node.href;
	else return (doc.selection.type=="Text"? "#"+doc.selection.createRange().text.replace(/ $/,"") :"");
}

IEeditor.doLink=function(doc,link){
	doc.execCommand("createlink", false, link);
}

IEeditor.beforeLinkPreProcessor = IEeditor.beforeLinkPreProcessor ? IEeditor.beforeLinkPreProcessor : IEeditor.preProcessor
IEeditor.preProcessor = function(text){
	return IEeditor.beforeLinkPreProcessor(text).replace(/\[\[([^|\]]*)\|([^\]]*)]]/g,'<a ref="#$2">$1</a>');
}

IEeditor.beforeLinkPostProcessor = IEeditor.beforelinkPostProcessor ? IEeditor.beforelinkPostProcessor : IEeditor.postProcessor;
IEeditor.postProcessor = function(text){
	return IEeditor.beforeLinkPostProcessor(text).replace(/<a href="#([^>]*)">([^<]*)<\/a>/gi,"[[$2|$1]]");
}

IEeditor.beforeLinkInitContent = IEeditor.beforeLinkInitContent ? IEeditor.beforeLinkInitContent : IEeditor.initContent;
IEeditor.initContent = function(doc,content){
	IEeditor.beforeLinkInitContent(doc,content);
	var links=doc.body.getElementsByTagName("A");
	for (var cpt=0; cpt<links.length; cpt++) {
		links[cpt].href=links[cpt].ref; //to avoid IE conversion of relative URLs to absolute
		links[cpt].removeAttribute("ref");	
	}
}

config.shadowTiddlers.EasyEditToolBarStyleSheet += "\n/*{{{*/\n.easyEditorToolBar .createlinkButton .button {color:blue;text-decoration:underline;}\n/*}}}*/";

config.shadowTiddlers.EasyEditDocStyleSheet += "\n/*{{{*/\na {color:#0044BB;font-weight:bold}\n/*}}}*/";

//}}}
!!編輯磁碟配額
*官方解釋:
*執行身份:
*重要參數
**-u: 針對特定使用者編輯磁碟配額
**-t: 修改寬容時間
***寬容時間為整體設定,並非對單一使用者
*等效指令:
!!顯示目前環境變數
HISTSIZE
HISTFILE

**執行命令歷程中第 # 個命令
{{{
!462
}}}
!!將 tab 欄位展開為數個空格
!!匯出自訂變數至上層 shell


{{{
export a=4
}}}

{{{
[root@ms1 ~]# expr 10 + 3
13
[root@ms1 ~]# expr 10 - 3
7
[root@ms1 ~]# expr 10 \* 3
30
[root@ms1 ~]# expr 10 / 3
3
[root@ms1 ~]# expr 10 % 3
1
}}}
!!針對已 mount 的邏輯磁碟重新讀取已分配空間
(需安裝套件 ext2resize)
*官方解釋:
*執行身份:
*重要參數
*等效指令:
!!磁碟分割
*官方解釋:
*執行身份:
*重要參數
**-l: 列出磁碟分割狀況
*等效指令:

*{{{disk -l}}}
{{{
Disk /dev/sda: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1         783     6289416   83  Linux
/dev/sda2             784        1175     3148740   83  Linux
/dev/sda3            1176        1305     1044225   82  Linux swap / Solaris
}}}

*{{{fdisk {device_name} }}}
**m: 操作手冊
**p: 列出目前硬碟分割表
**l: 列出已知檔案系統類型
**n: 新增一個磁碟分割
**d: 刪除一個磁碟分割
**v: 驗證分割表
**w: 寫入分割表
**q: 不存檔離開

|>|>| MBR |
|Loader|Partition table|驗證|
|446B|64B|2B|
!!繼續執行前景程序
*官方解釋:
*執行身份:
*重要參數
**% {//##//}: 指定回到佇列編號 {//##//} 的程序前景
*等效指令:
!!實際在檔案系統搜尋
*官方解釋:
*執行身份:
*重要參數
**-perm: permission, 搜尋特定檔案權限
**-inode: 搜尋特定 inode 編號檔案,可用於尋找硬式連結檔案
**-exec: 邊找邊執行
*等效指令:

find {搜尋範圍} {類型1 關鍵字} {類型2 關鍵字} {類型3 關鍵字} {...}

{{{find / -perm 4755 -exec ls -l {} \;}}}

*找出同個 inode 編號的檔案,透過 -inum 指定編號,或是 -samefile 即可
{{{find / -inum 123456 }}}
{{{find / -samefile file2}}}

*接著,想試著找出某個檔案的 symbolic link,個人覺得應該有用到的一天,因為某個檔案要刪除之前,先找出連結到這個檔案的連結予以刪除應該是個不錯的點子
嚐試: -lname pattern: 列出所有連結檔案中,其連結與 pattern 完全相同的;結論是:只能完全比對,無法模糊比對,以下兩個 find 的用法結果完全不同
{{{find / -lname file2}}}
{{{find / -lname /tmp/link/file2}}}
笨方法 1: 列出所有 symbolic links,透過 ls -l 會在螢幕顯示出 link 指向,再用 | 來篩選條件;結論:笨方法一個,執行速度烏龜慢
{{{find / -type l -exec ls -l {} \; | grep file2}}}
超級笨方法 2: 利用 -lname 參數,找兩次;結論:無用,連結的方式百百種
{{{find / -lname file2 || find / -lname /tmp/link/file2}}}
比超級笨方法 2 強一點的方法 3: 利用 find 指令提供的 -or 運算,找出相對連結與絕對連結;結論:同上,連結方式百百種
{{{find / -lname file2 -or -lname /tmp/link/file2}}}
抄隔壁 Jason 的方法 4: 使用 -L 參數尋找所有 symbolic links 的檔案,且配合 -samefile 參數找出對應到相同檔案的連結檔案;結論:不管 hard links 還是 symbolic links 都無所遁形,但是缺點是不能在根目錄或是有 link 迴圈的目錄
{{{find -L /tmp/ -samefile /tmp/link/file2}}}
在實驗了將近兩個小時宣告失敗,還是找不出一個可以從根目錄搜尋的好方法

於是,放棄了第一個題目換第二個題目
先解決一個小難題,當 find 的使用者不是 root 身分時,某些無法存取的目錄將會在螢幕上顯示錯誤訊息,很礙眼,可以在指令後面加上 2>dev/null,送錯誤訊息到虛無去
{{{find / -perm 4755 -exec ls -l {} \; 2>/dev/null}}}

第二個題目是,想要針對某個權限做進階的搜尋,例如:檔案所有人與群組可以讀取,但其他人不能讀取,而執行與寫入權限不限
嘗試1: -perm 指令後面如果直接接數字,例如 755,則表示權限必須與 rwxr-xr-x 完全相符,多一個不行少一個也不行,但是 -400 則表示 owner 可以讀取,其他則不限
{{{find /tmp/ -perm -400 -exec ls -l {} \;}}}
方法: 以下的方法是嘗試過後的結果,也的確可行,但是如果 mode 使用 -755、-644 這類的結果就又看不懂了
{{{find /tmp/ -perm -400 -perm -040 ! -perm -004 -exec ls -l {} \;}}}

今天的 Lab 結論:
光一個 find 指令就可以摸很久了...Linux 真是博大精深
!!重新格式化文字檔案

{{{
cat /etc/squid/squid.conf | head -16 | tr '#' ' ' > tmp
fmt -w 30 tmp
}}}
For this "List" task we don't use the default action "addToList" (that simply adds all selected items to the list) but create the list using the "write" action and refer to the build-in variable "index" that is incremented for every tiddler being processed.
{{{
<<forEachTiddler
    where
        'tiddler.tags.contains("Notes")'
    write
        '(index < 10) ? "* [["+tiddler.title+"]]\n" : ""'
>>
}}}
In the write parameter there is a conditional output: when we are processing the tiddlers 0 to 9 it will write a line with:

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

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

''//Result://''
<<forEachTiddler
    where
        'tiddler.tags.contains("Notes")'
    write
        '(index < 10) ? "* [["+tiddler.title+"]]\n" : ""'
>>
{{{
<<forEachTiddler
    where
        'tiddler.tags.contains("plugin")'
    write
        '""'
        end 'count+" Tiddlers found\n"'
        none '"No Tiddlers found\n"'
>>
}}}
The macro writes an empty string for every tiddler tagged "basic", i.e. it writes nothing. 

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

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

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

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

    sortBy
       'tiddler.title.toUpperCase()'

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

        begin '"<<tabs txtMyAutoTab "'

        end '">"+">"'

        none '"//No tiddler tagged with \"文章整理\"//"'
>>
!!互動式命令 ftp
*官方解釋:ARPANET file transfer program
*執行身份:
*重要參數
*等效指令:

{{{
[root@ms1 ~]# ftp 
ftp> open 192.168.33.50
Connected to 192.168.33.50.
220 (vsFTPd 2.0.5)
530 Please login with USER and PASS.
530 Please login with USER and PASS.
KERBEROS_V4 rejected as an authentication type
Name (192.168.33.50:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> 
}}}
!!檢視目前 I/O 狀態
*官方解釋:
*執行身份:
*重要參數
**-v
**-m
*等效指令:


*{{{fuser -vm /dev/sda1}}}
{{{
                     USER        PID ACCESS COMMAND
/dev/sda1:           root          1 .rce. init
                     root          2 .rc.. migration/0
                     root          3 .rc.. ksoftirqd/0
                     root          4 .rc.. watchdog/0
                     root          5 .rc.. migration/1
                     root          6 .rc.. ksoftirqd/1
                     root          7 .rc.. watchdog/1
:
:
:
}}}
//{{{
//============================================================================
// getCreateDate Function
//============================================================================
//
// Returns the "create date" as generated by the AutoTaggerPlugin
// (http://www.TiddlyTools.com/#AutoTaggerPlugin).
// The create date must be stored in the default format "YYYY.0MM.0DD".
//
// @return [may be null] the create date (as a String) or null if no create 
// date is found.
//
version.extensions.getCreateDate = {major: 1, minor: 0, revision: 0, 
 date: new Date(2005,11,21), 
 provider: "http://tiddlywiki.abego-software.de"};
//
function getCreateDate(tiddler) {
 if (!tiddler || !tiddler.tags) {
 return null;
 }

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

//}}}
!!查看 ACL
*官方解釋:
*執行身份:
*重要參數
*等效指令:

*getfacl {//filename//}
!!設定群組密碼
*官方解釋:
*執行身份:
*重要參數
*等效指令:

gpasswd {//groupname//} {//password//}
*賦予該群組密碼
gpasswd -r {//groupname//}
*清空該群組密碼 (不使用密碼)
gpasswd -R {//groupname//}
*設定未啟用群組密碼
!!逐列過濾
*官方解釋:
*執行身份:
*重要參數
**-c: 計算符合條件的筆''數量''
**-n: 加入符合條件的''列號''
**-v: 列出 ''不'' 符合條件的資料
**-i: 忽略大小寫 (視為相同)
*等效指令:

{{{
grep 'flatfish' /etc/passwd
}}}
{{{
cat /etc/passwd | grep 'flatfish'
}}}

*列出非『 # 』、『 ; 』、空白列與非 tab 後接著『 # 』的註解列
{{{
grep -v "[^\t]*#" /etc/samba/smb.conf | grep -v "^$" | grep -v "^;"
}}}
!!新增群組帳號
*官方解釋:
*執行身份:
*重要參數
**-g : 指定 gid
*等效指令:

!!刪除群組
*官方解釋:
*執行身份:
*重要參數
*等效指令:
!!群組改名
*官方解釋:
*執行身份:
*重要參數
*等效指令:

{{{
groupmod -n 新群組 舊群組
}}}
!!群組 轉換為使用 遮蔽式密碼
*官方解釋:
*執行身份:
*重要參數
*等效指令:
群組 不使用 遮蔽式密碼 (gshadow)
/etc/gshadow 會消失
/etc/gshadow- 還在
{{{
grub
root (hd0,5)
setup (hd0)
!!解壓縮
*官方解釋:compress and expand data
*執行身份:
*重要參數
**-c: 標準輸出至螢幕
*等效指令:[[gzip]]、[[zcat]]

{{{
gunzip -c anaconda.log.gz > anaconda.log
}}}
!!壓縮檔案
*官方解釋:compress and expand data
*執行身份:
*重要參數
**-c: STDOUT (標準輸出)
**-d: 解壓縮
**-#: 1 ~ 9
***-1: 快
***-6: 預設值
***-9: 好
*等效指令:[[gunzip]]、[[zcat]]
!!關機
*官方解釋:stop the system
*執行身份:
*重要參數
*等效指令:[[init 0|init]]、[[poweroff]]、[[shutdown]]
!!列出前十列


**-n #: 列出前 n 列
***預設為 10
***可寫為 -#
*DNS
**abc.net
**xyz.net
*httpd
**VirtualHost X 3
**流量管制 (cb 模組)
**MRTG
*SAMBA
**提供使用者維護網站
*Apache 流量管制
**針對虛擬主機做流量管制
**利用 LoadModule 掛入模組

!!作業進度
*設定網路卡,改為靜態 IP 位址 → 完成
*建立 DNS service
**flatfish.net
**flatfish.com
*httpd
**三個虛擬網站
***www.flatfish.com
***www.flatfish.net
***blog.flatfish.net
***gallery.flatfish.net
**流量管制
***[[安裝方式參考頁|http://www.howtoforge.com/mod_cband_apache2_bandwidth_quota_throttling]]
**MRTG
***yum -y install mrtg
***[[設定方式參考頁|http://oss.oetiker.ch/mrtg/doc/mrtg-unix-guide.en.html]]
*Samba
*官方解釋:
*執行身份:
*重要參數
*等效指令:

{{{
host www.microsoft.com
}}}
!!改變網路主機名稱

{{{
ms1.flatfish.net.tw
}}}
{{{
htpasswd -c /var/www/staff.passwd test1
}}}
!!顯示目前硬體時鐘時間 (BIOS)

*-s / - -hctosys: 硬體時間寫入軟體時間
*-w / - -systohc:軟體時間寫入硬體時間
!!檢視該使用者 uid 與所屬群組
*官方解釋:
*執行身份:
*重要參數
*等效指令:
!!條件判斷
{{{
if [ 條件判斷 A ]
then
:
:
elif [ 條件判斷 B ]
then
:
:
fi
}}}


{{{
file=$1
if [ -f "$file" ]
then
	cat $file
elif [ -d $file ]
then
	ls -l $file
else
	echo "$file not found"
fi
}}}
!!顯示有關網路介面卡的資訊
*官方解釋:
*執行身份:
*重要參數
*等效指令:

{{{
eth0      Link encap:Ethernet  HWaddr 00:0C:29:58:64:F4
          inet addr:192.168.100.128  Bcast:192.168.100.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe58:64f4/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:13452 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11389 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:3940280 (3.7 MiB)  TX bytes:2184047 (2.0 MiB)
          Interrupt:169 Base address:0x2000
}}}

*暫時給予一個虛擬介面 IP
{{{
ifconfig eth0:1 192.168.100.129 netmask 255.255.255.0
}}}
*停用/啟用虛擬介面
{{{
ifconfig eth0:1 down/up
}}}
!!停用網路介面
*官方解釋:
*執行身份:
*重要參數
*等效指令:
!!啟用網路介面
*官方解釋:
*執行身份:
*重要參數
*等效指令:
!!依據不同的 Run Level 初始化
*官方解釋:
*執行身份:
*重要參數
**0123456: 依據 __/etc/inittab__ 中的組態設定初始化,每個分佈套件的預設都不同,以下的預設為 CentOS
***0: 保留給關機
***1: 保留給單人命令列模式
***2: 無網路下的多人命令列模式
***3: 完整的多人命令列模式
***4: 未使用 (雖說是未使用,但是在 /etc/inittab 中仍然有預設的組態
***5: 多人多工圖形化介面 (X11)
***6: 保留給重新啟動
**S 與 s : 不透過 /etc/inittab 進入單人命令列模式
*等效指令:[[telinit]]
!!載入模組


{{{
insmod /lib/modules/2.6.18-92.el5/kernel/fs/fat/fat.ko
insmod /lib/modules/2.6.18-92.el5/kernel/fs/msdos/msdos.ko
}}}
!!netfilter 防火牆
**-t: 表
***filter
***nat
***mangle
***raw
**-L
**-v
**-P: policy
***INPUT
***FORWARD
***OUTPUT
****DROP / ACCEPT
||功能~~全大寫~~|chain~~全大寫~~|封包的比對|動作~~全大寫~~|
|iptables|-L<br>-P~~定政策~~<br>-A~~新增~~<br>-D~~刪除~~<br>-I~~插入~~<br>-R~~取代~~|INPUT<br>FORWARD<br>OUTPUT|-s~~source~~<br>-p~~protocol~~<br>-d~~destination~~<br>{{{--}}}dport<br>{{{--}}}sport<br>-i~~input interface~~<br>-o~~output interface~~<br>-m~~模組~~|DROP<br>ACCEPT<br>SNAT~~source NAT~~<br>DNAT~~destination~~<br>MASQUERADE~~偽裝可用 IP - 是 SNAT 的特例~~|

{{{
iptables -P INPUT DROP
iptables -A INPUT -s 192.168.33.0 /24 -j ACCEPT
iptables -A INPUT -p icmp -s 192.168.33.30 -j ACCEPT
iptables -D INPUT 1
iptables -I INPUT 1 -d 192.168.10.50 -j ACCEPT
iptables -R INPUT 1 -p tcp -s 192.168.10.0/24 --dport 80 -j ACCEPT
iptables -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff -j ACCEPT
}}}

{{{
iptables -t nat -L
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to 192.168.33.50
iptables -A FORWARD -d www.playboy.com -j DROP
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to 192.168.10.129
}}}

{{{
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE
}}}
!!標準輸出 iptables 至螢幕

*Brad:強烈不建議使用這個指令,會造成維護上得困難
*建議直接寫在 script 檔,將 script 檔加入 /etc/rc.d/rc.local
!!檢視目前工作佇列
*官方解釋:
*執行身份:
*重要參數
**-l: 顯示 PID
*等效指令:
!!將相同的欄位貼在一起

**-j#: 以第 # 個欄位為索引貼在一起
!!對程序送出訊號,通常為插斷訊號
*官方解釋:
*執行身份:
*重要參數
**-l: 查詢所有訊號類型
**常用訊號類型:
***-1: GHUP - reload,套用新的組態檔
****PID 不會改變,環境變數皆繼續存在
****利用 service {//servicename//} restart 重新啟動將會改變 PID,且環境變數皆會改變

***-15: SIGTERM, by default - 正常結束 (由程序自行結束)
***-2: SIGINT: 直接中斷 (由程序自行結束) (Ctrl+C)
***-9: SIGKILL: 強制中斷

***-18: SIGCONT: 繼續
***-19: STOP: 暫停
***-20: TSTP: 暫停,常用 (Ctrl+Z)
**-n #: 送出編號 # 的訊號
*等效指令:

{{{
kill 5422
kill -15 5422
kill -TERM 5422
kill -SIGTERM 5422
kill -n 15 5422
}}}
!!針對 Programname 中斷程序
*官方解釋:
*執行身份:
*重要參數
*等效指令:

{{{
killall {programname}
}}}
!!最近連進來的使用者
!!列出相關相依函式庫

{{{
ldd /opt/firefox/firefox-bin
}}}

{{{
.so:share object
}}}
{{{
vi /etc/ld.so.conf
echo '/opt/firefox' > /etc/ld.so.conf.d/firefox.conf
ldconfig
cd /etc/ld.so.cache
}}}
或
{{{
LD_LIBARY_PATH
}}}
!!讀取檔案內容,可直接讀取 .Z、.gz等部分壓縮檔
*官方解釋:
*執行身份:
*重要參數
*等效指令:
!!建立連結檔
*官方解釋:make links between files
*執行身份:
*重要參數
**-s: symblic, 符號連結
*等效指令

*hard links
**ln {//original_filename//} {//links_filename//}
*symblic links
**ln -s {//original_filename//} {//links_filename//}
/***
|''Name:''|zh-HantTranslationPlugin|
|''Description:''|Translation of TiddlyWiki into Traditional Chinese|
|''Source:''|http://tiddlywiki-zh.googlecode.com/svn/trunk/|
|''Subversion:''|http://svn.tiddlywiki.org/Trunk/association/locales/core/zh-Hant/locale.zh-Hant.js|
|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|
|''Version:''|2.2.6|
|''Date:''|Dec 01, 2007|
|''Comments:''|Please make comments at http://groups-beta.google.com/group/TiddlyWiki-zh/|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.2.0|
***/

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

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

config.locale = 'zh-Hant'; // W3C language tag

if (config.options.txtUserName == 'YourName' || !config.options.txtUserName) // do not translate this line, but do translate the next line
	merge(config.options,{txtUserName: "YourName"});

merge(config.tasks,{
	save: {text: "儲存", tooltip: "儲存變更至此 TiddlyWiki", action: saveChanges},
	sync: {text: "同步", tooltip: "將你的資料內容與外部伺服器與檔案同步", content: '<<sync>>'},
	importTask: {text: "導入", tooltip: "自其他檔案或伺服器導入文章或套件", content: '<<importTiddlers>>'},
	tweak: {text: "選項", tooltip: "改變此 TiddlyWiki 的顯示與行為的設定", content: '<<options>>'},
	plugins: {text: "套件管理", tooltip: "管理已安裝的套件", content: '<<plugins>>'}
});

merge(config.optionsDesc,{
	txtUserName: "編輯文章所使用之作者署名",
	chkRegExpSearch: "啟用正規式搜尋",
	chkCaseSensitiveSearch: "搜尋時,區分大小寫",
	chkAnimate: "使用動畫顯示",
	chkSaveBackups: "儲存變更前,保留備份檔案",
	chkAutoSave: "自動儲存變更",
	chkGenerateAnRssFeed: "儲存變更時,也儲存 RSS feed",
	chkSaveEmptyTemplate: "儲存變更時,也儲存空白範本",
	chkOpenInNewWindow: "於新視窗開啟連結",
	chkToggleLinks: "點擊已開啟文章將其關閉",
	chkHttpReadOnly: "非本機瀏覽文件時,隱藏編輯功能",
	chkForceMinorUpdate: "修改文章時,不變更作者名稱與日期時間",
	chkConfirmDelete: "刪除文章前須確認",
	chkInsertTabs: "使用 tab 鍵插入定位字元,而非跳至下一個欄位",
	txtBackupFolder: "存放備份檔案的資料夾",
	txtMaxEditRows: "編輯模式中顯示列數",
	txtFileSystemCharSet: "指定儲存文件所在之檔案系統之字集 (僅適用於 Firefox/Mozilla only)"});

// Messages
merge(config.messages,{
	customConfigError: "套件載入發生錯誤,詳細請參考 PluginManager",
	pluginError: "發生錯誤: %0",
	pluginDisabled: "未執行,因標籤設為 'systemConfigDisable'",
	pluginForced: "已執行,因標籤設為 'systemConfigForce'",
	pluginVersionError: "未執行,套件需較新版本的 TiddlyWiki",
	nothingSelected: "尚未作任何選擇,至少需選擇一項",
	savedSnapshotError: "此 TiddlyWiki 未正確存檔,詳見 http://www.tiddlywiki.com/#DownloadSoftware",
	subtitleUnknown: "(未知)",
	undefinedTiddlerToolTip: "'%0' 尚無內容",
	shadowedTiddlerToolTip: "'%0' 尚無內容, 但已定義隱藏的預設值",
	tiddlerLinkTooltip: "%0 - %1, %2",
	externalLinkTooltip: "外部連結至 %0",
	noTags: "未設定標籤的文章",
	notFileUrlError: "須先將此 TiddlyWiki 存至檔案,才可儲存變更",
	cantSaveError: "無法儲存變更。可能的原因有:\n- 你的瀏覽器不支援此儲存功能(Firefox, Internet Explorer, Safari and Opera 經適當設定後可儲存變更)\n- 也可能是你的 TiddlyWiki 檔名包含不合法的字元所致。\n- 或是 TiddlyWiki 文件被改名或搬移。",
	invalidFileError: " '%0' 非有效之 TiddlyWiki 文件",
	backupSaved: "已儲存備份",
	backupFailed: "無法儲存備份",
	rssSaved: "RSS feed 已儲存",
	rssFailed: "無法儲存 RSS feed ",
	emptySaved: "已儲存範本",
	emptyFailed: "無法儲存範本",
	mainSaved: "主要的TiddlyWiki已儲存",
	mainFailed: "無法儲存主要 TiddlyWiki,所作的改變未儲存",
	macroError: "巨集 <<\%0>> 執行錯誤",
	macroErrorDetails: "執行巨集 <<\%0>> 時,發生錯誤 :\n%1",
	missingMacro: "無此巨集",
	overwriteWarning: "'%0' 已存在,[確定]覆寫之",
	unsavedChangesWarning: "注意! 尚未儲存變更\n\n[確定]存檔,或[取消]放棄存檔?",
	confirmExit: "--------------------------------\n\nTiddlyWiki 以更改內容尚未儲存,繼續的話將遺失這些更動\n\n--------------------------------",
	saveInstructions: "SaveChanges",
	unsupportedTWFormat: "未支援此 TiddlyWiki 格式:'%0'",
	tiddlerSaveError: "儲存文章 '%0' 時,發生錯誤。",
	tiddlerLoadError: "載入文章 '%0' 時,發生錯誤。",
	wrongSaveFormat: "無法使用格式 '%0' 儲存,請使用標准格式存放",
	invalidFieldName: "無效的欄位名稱:%0",
	fieldCannotBeChanged: "無法變更欄位:'%0'",
	loadingMissingTiddler: "正從伺服器 '%1' 的:\n\n工作區 '%3' 中的 '%2' 擷取文章 '%0'"});

merge(config.messages.messageClose,{
	text: "關閉",
	tooltip: "關閉此訊息"});

config.messages.backstage = {
	open: {text: "控制台", tooltip: "開啟控制台執行編寫工作"},
	close: {text: "關閉", tooltip: "關閉控制台"},
	prompt: "控制台:",
	decal: {
		edit: {text: "編輯", tooltip: "編輯 '%0'"}
	}
};

config.messages.listView = {
	tiddlerTooltip: "檢視全文",
	previewUnavailable: "(無法預覽)"
};

config.messages.dates.months = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];
config.messages.dates.days = ["星期日", "星期一","星期二", "星期三", "星期四", "星期五", "星期六"];
// config.messages.dates.shortMonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
config.messages.dates.shortMonths = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"];
// config.messages.dates.shortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
config.messages.dates.shortDays = ["日", "一","二", "三", "四", "五", "六"];
// suffixes for dates, eg "1st","2nd","3rd"..."30th","31st"
config.messages.dates.daySuffixes = ["st","nd","rd","th","th","th","th","th","th","th",
		"th","th","th","th","th","th","th","th","th","th",
		"st","nd","rd","th","th","th","th","th","th","th",
		"st"];
config.messages.dates.am = "上午";
config.messages.dates.pm = "下午";

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

merge(config.views.wikified.tag,{
	labelNoTags: "未設標籤",
	labelTags: "標籤: ",
	openTag: "開啟標籤 '%0'",
	tooltip: "顯示標籤為 '%0' 的文章",
	openAllText: "開啟以下所有文章",
	openAllTooltip: "開啟以下所有文章",
	popupNone: "僅此文標籤為 '%0'"});

merge(config.views.wikified,{
	defaultText: "",
	defaultModifier: "(未完成)",
	shadowModifier: "(預設)",
	dateFormat: "YYYY年0MM月0DD日",
	createdPrompt: "建立於"});

merge(config.views.editor,{
	tagPrompt: "設定標籤之間以空白區隔,[[標籤含空白時請使用雙中括弧]],或點選現有之標籤加入",
	defaultText: ""});

merge(config.views.editor.tagChooser,{
	text: "標籤",
	tooltip: "點選現有之標籤加至本文章",
	popupNone: "未設定標籤",
	tagTooltip: "加入標籤 '%0'"});

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

merge(config.macros.search,{
	label: " 尋找",
	prompt: "搜尋本 Wiki",
	accessKey: "F",
	successMsg: " %0 篇符合條件: %1",
	failureMsg: " 無符合條件: %0"});

merge(config.macros.tagging,{
	label: "引用標籤:",
	labelNotTag: "無引用標籤",
	tooltip: "列出標籤為 '%0' 的文章"});

merge(config.macros.timeline,{
	dateFormat: "YYYY年0MM月0DD日"});

merge(config.macros.allTags,{
	tooltip: "顯示文章- 標籤為'%0'",
	noTags: "沒有標籤"});

config.macros.list.all.prompt = "依字母排序";
config.macros.list.missing.prompt = "被引用且內容空白的文章";
config.macros.list.orphans.prompt = "未被引用的文章";
config.macros.list.shadowed.prompt = "這些隱藏的文章已預設內容";
config.macros.list.touched.prompt = "自下載或新增後被修改過的文章"; 

merge(config.macros.closeAll,{
	label: "全部關閉",
	prompt: "關閉所有開啟中的 tiddler (編輯中除外)"});

merge(config.macros.permaview,{
	label: "引用連結",
	prompt: "可存取現有開啟之文章的連結位址"});

merge(config.macros.saveChanges,{
	label: "儲存變更",
	prompt: "儲存所有文章,產生新的版本",
	accessKey: "S"});

merge(config.macros.newTiddler,{
	label: "新增文章",
	prompt: "新增 tiddler",
	title: "新增文章",
	accessKey: "N"});

merge(config.macros.newJournal,{
	label: "新增日誌",
	prompt: "新增 jounal",
	accessKey: "J"});

merge(config.macros.options,{
	wizardTitle: "增訂的進階選項",
	step1Title: "增訂的選項儲存於瀏覽器的 cookies",
	step1Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='false' name='chkUnknown'>顯示未知選項</input>",
	unknownDescription: "//(未知)//",
	listViewTemplate: {
		columns: [
			{name: 'Option', field: 'option', title: "選項", type: 'String'},
			{name: 'Description', field: 'description', title: "說明", type: 'WikiText'},
			{name: 'Name', field: 'name', title: "名稱", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'}
			]}
	});

merge(config.macros.plugins,{
	wizardTitle: "擴充套件管理",
	step1Title: "- 已載入之套件",
	step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
	skippedText: "(此套件因剛加入,故尚未執行)",
	noPluginText: "未安裝套件",
	confirmDeleteText: "確認是否刪除此文章:\n\n%0",
	removeLabel: "移除 systemConfig 標籤",
	removePrompt: "移除 systemConfig 標籤",
	deleteLabel: "刪除",
	deletePrompt: "永遠刪除所選",

	listViewTemplate : {
		columns: [
			{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
			{name: 'Tiddler', field: 'tiddler', title: "套件", type: 'Tiddler'},
			{name: 'Size', field: 'size', tiddlerLink: 'size', title: "大小", type: 'Size'},
			{name: 'Forced', field: 'forced', title: "強制執行", tag: 'systemConfigForce', type: 'TagCheckbox'},
			{name: 'Disabled', field: 'disabled', title: "停用", tag: 'systemConfigDisable', type: 'TagCheckbox'},
			{name: 'Executed', field: 'executed', title: "已載入", type: "Boolean", trueText: "是", falseText: "否"},
			{name: 'Startup Time', field: 'startupTime', title: "載入時間", type: 'String'},
			{name: 'Error', field: 'error', title: "載入狀態", type: 'Boolean', trueText: "錯誤", falseText: "正常"},
			{name: 'Log', field: 'log', title: "紀錄", type: 'StringList'}
			],
		rowClasses: [
			{className: 'error', field: 'error'},
			{className: 'warning', field: 'warning'}
			]}
	});

merge(config.macros.toolbar,{
	moreLabel: "其他",
	morePrompt: "顯示更多工具命令"});
	
merge(config.macros.refreshDisplay,{
	label: "刷新",
	prompt: "刷新此 TiddlyWiki 顯示"
	});
	
merge(config.macros.importTiddlers,{
	readOnlyWarning: "TiddlyWiki 於唯讀模式下,不支援導入文章。請由本機(file://)開啟 TiddlyWiki 文件",
	wizardTitle: "自其他檔案或伺服器導入文章",
	step1Title: "步驟一:指定伺服器或來源文件",
	step1Html: "指定伺服器類型:<select name='selTypes'><option value=''>選取...</option></select><br>請輸入網址或路徑:<input type='text' size=50 name='txtPath'><br>...或選擇來源文件:<input type='file' size=50 name='txtBrowse'><br><hr>...或選擇指定的饋入來源:<select name='selFeeds'><option value=''>選取...</option></select>",
	openLabel: "開啟",
	openPrompt: "開啟檔案或",
	openError: "讀取來源文件時發生錯誤",
	statusOpenHost: "正與伺服器建立連線",
	statusGetWorkspaceList: "正在取得可用之文章清單",
	step2Title: "步驟二:選擇工作區",
	step2Html: "輸入工作區名稱:<input type='text' size=50 name='txtWorkspace'><br>...或選擇工作區:<select name='selWorkspace'><option value=''>選取...</option></select>",
	cancelLabel: "取消",
	cancelPrompt: "取消本次導入動作",
	statusOpenWorkspace: "正在開啟工作區",
	statusGetTiddlerList: "正在取得可用之文章清單",
	step3Title: "步驟三:選擇欲導入之文章",
	step3Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='true' name='chkSync'>保持這些文章與伺服器的連結,便於同步後續的變更。</input><br><input type='checkbox' name='chkSave'>儲存此伺服器的詳細資訊於標籤為 'systemServer' 的文章名為:</input> <input type='text' size=25 name='txtSaveTiddler'>", 
	importLabel: "導入",
	importPrompt: "導入所選文章",
	confirmOverwriteText: "確定要覆寫這些文章:\n\n%0",
	step4Title: "步驟四:正在導入%0 篇文章",
	step4Html: "<input type='hidden' name='markReport'></input>", // DO NOT TRANSLATE
	doneLabel: "完成",
	donePrompt: "關閉",
	statusDoingImport: "正在導入文章 ...",
	statusDoneImport: "所選文章已導入",
	systemServerNamePattern: "%2 位於 %1",
	systemServerNamePatternNoWorkspace: "%1",
	confirmOverwriteSaveTiddler: "此 tiddler '%0' 已經存在。點擊「確定」以伺服器上料覆寫之,或「取消」不變更後離開",
	serverSaveTemplate: "|''Type:''|%0|\n|''網址:''|%1|\n|''工作區:''|%2|\n\n此文為自動產生紀錄伺服器之相關資訊。",
	serverSaveModifier: "(系統)",

	listViewTemplate: {
		columns: [
			{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
			{name: 'Tiddler', field: 'tiddler', title: "文章", type: 'Tiddler'},
			{name: 'Size', field: 'size', tiddlerLink: 'size', title: "大小", type: 'Size'},
			{name: 'Tags', field: 'tags', title: "標籤", type: 'Tags'}
			],
		rowClasses: [
			]}
	});

merge(config.macros.sync,{
	listViewTemplate: {
		columns: [
			{name: 'Selected', field: 'selected', rowName: 'title', type: 'Selector'},
			{name: 'Tiddler', field: 'tiddler', title: "文章", type: 'Tiddler'},
			{name: 'Server Type', field: 'serverType', title: "伺服器類型", type: 'String'},
			{name: 'Server Host', field: 'serverHost', title: "伺服器主機", type: 'String'},
			{name: 'Server Workspace', field: 'serverWorkspace', title: "伺服器工作區", type: 'String'},
			{name: 'Status', field: 'status', title: "同步情形", type: 'String'},
			{name: 'Server URL', field: 'serverUrl', title: "伺服器網址", text: "View", type: 'Link'}
			],
		rowClasses: [
			],
		buttons: [
			{caption: "同步更新這些文章", name: 'sync'}
			]},
	wizardTitle: "將你的資料內容與外部伺服器與檔案同步",
	step1Title: "選擇欲同步的文章",
	step1Html: '<input type="hidden" name="markList"></input>', // DO NOT TRANSLATE
	syncLabel: "同步",
	syncPrompt: "同步更新這些文章",
	hasChanged: "已更動",
	hasNotChanged: "未更動",
	syncStatusList: {
		none: {text: "...", color: 'transparent'},
		changedServer: {text: "伺服器資料已更動", color: '#80ff80'},
		changedLocally: {text: "本機資料已更動", color: '#80ff80'},
		changedBoth: {text: "已同時更新本機與伺服器上的資料", color: '#ff8080'},
		notFound: {text: "伺服器無此資料", color: '#ffff80'},
		putToServer: {text: "已儲存更新資料至伺服器", color: '#ff80ff'},
		gotFromServer: {text: "已從伺服器擷取更新資料", color: '#80ffff'}
		}
	});

merge(config.macros.annotations,{
	});

merge(config.commands.closeTiddler,{
	text: "關閉",
	tooltip: "關閉本文"});

merge(config.commands.closeOthers,{
	text: "關閉其他",
	tooltip: "關閉其他文章"});

merge(config.commands.editTiddler,{
	text: "編輯",
	tooltip: "編輯本文",
	readOnlyText: "檢視",
	readOnlyTooltip: "檢視本文之原始內容"});

merge(config.commands.saveTiddler,{
	text: "完成",
	tooltip: "確定修改"});

merge(config.commands.cancelTiddler,{
	text: "取消",
	tooltip: "取消修改",
	warning: "確定取消對 '%0' 的修改嗎?",
	readOnlyText: "完成",
	readOnlyTooltip: "返回正常顯示模式"});

merge(config.commands.deleteTiddler,{
	text: "刪除",
	tooltip: "刪除文章",
	warning: "確定刪除 '%0'?"});

merge(config.commands.permalink,{
	text: "引用連結",
	tooltip: "本文引用連結"});

merge(config.commands.references,{
	text: "引用",
	tooltip: "引用本文的文章",
	popupNone: "本文未被引用"});

merge(config.commands.jump,{
	text: "捲頁",
	tooltip: "捲頁至其他已開啟的文章"});

merge(config.commands.syncing,{
	text: "同步",
	tooltip: "本文章與伺服器或其他外部檔案的同步資訊",
	currentlySyncing: "<div>同步類型:<span class='popupHighlight'>'%0'</span></"+"div><div>與伺服器:<span class='popupHighlight'>%1 同步</span></"+"div><div>工作區:<span class='popupHighlight'>%2</span></"+"div>", // Note escaping of closing <div> tag
	notCurrentlySyncing: "無進行中的同步動作",
	captionUnSync: "停止同步此文章",
	chooseServer: "與其他伺服器同步此文章:",
	currServerMarker: "\u25cf ",
	notCurrServerMarker: "  "});

merge(config.commands.fields,{
	text: "欄位",
	tooltip: "顯示此文章的擴充資訊",
	emptyText: "此文章沒有擴充欄位",
	listViewTemplate: {
		columns: [
			{name: 'Field', field: 'field', title: "擴充欄位", type: 'String'},
			{name: 'Value', field: 'value', title: "內容", type: 'String'}
			],
		rowClasses: [
			],
		buttons: [
			]}});

merge(config.shadowTiddlers,{
	DefaultTiddlers: "GettingStarted",
	GettingStarted: "使用此 TiddlyWiki 的空白範本之前,請先修改以下預設文章:\n* SiteTitle 及 SiteSubtitle:網站的標題和副標題,顯示於頁面上方<br />(在儲存變更後,將顯示於瀏覽器視窗的標題列)。\n* MainMenu:主選單(通常在頁面左側)。\n* DefaultTiddlers:內含一些文章的標題,可於載入TiddlyWiki 後的預設開啟。\n請輸入您的大名,作為所建立/ 編輯的文章署名:<<option txtUserName>>",
	MainMenu: "[[使用說明|GettingStarted]]\n\n\n^^~TiddlyWiki 版本:<<version>>\n© 2007 [[UnaMesa|http://www.unamesa.org/]]^^",
	OptionsPanel: "這些設定將暫存於瀏覽器\n請簽名<<option txtUserName>>\n (範例:WikiWord)\n\n <<option chkSaveBackups>> 儲存備份\n <<option chkAutoSave>> 自動儲存\n <<option chkRegExpSearch>> 正規式搜尋\n <<option chkCaseSensitiveSearch>> 區分大小寫搜尋\n <<option chkAnimate>> 使用動畫顯示\n----\n [[進階選項|AdvancedOptions]]",
	SiteTitle: "我的 TiddlyWiki",
	SiteSubtitle: "一個可重複使用的個人網頁式筆記本",
	SiteUrl: 'http://www.tiddlywiki.com/',
	SideBarOptions: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal " YYYY年0MM月0DD日" "日誌">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel  "偏好設定 »" "變更 TiddlyWiki 選項">>',
	SideBarTabs: '<<tabs txtMainTab "最近更新" "依更新日期排序" TabTimeline "全部" "所有文章" TabAll "分類" "所有標籤" TabTags "更多" "其他" TabMore>>',
	StyleSheet: '[[StyleSheetLocale]]',
	TabMore: '<<tabs txtMoreTab "未完成" "內容空白的文章" TabMoreMissing "未引用" "未被引用的文章" TabMoreOrphans "預設文章" "已預設內容的隱藏文章" TabMoreShadowed>>'});

merge(config.annotations,{
	AdvancedOptions: "此預設文章可以存取一些進階選項。",
	ColorPalette: "此預設文章裡的設定值,將決定 ~TiddlyWiki 使用者介面的配色。",
	DefaultTiddlers: "當 ~TiddlyWiki 在瀏覽器中開啟時,此預設文章裡列出的文章,將被自動顯示。",
	EditTemplate: "此預設文章裡的 HTML template 將決定文章進入編輯模式時的顯示版面。",
	GettingStarted: "此預設文章提供基本的使用說明。",
	ImportTiddlers: "此預設文章提供存取導入中的文章。",
	MainMenu: "此預設文章的內容,為於螢幕左側主選單的內容",
	MarkupPreHead: "此文章的內容將加至 TiddlyWiki 文件的 <head> 段落的起始",
	MarkupPostHead: "此文章的內容將加至 TiddlyWiki 文件的 <head> 段落的最後",
	MarkupPreBody: "此文章的內容將加至 TiddlyWiki 文件的 <body> 段落的起始",
	MarkupPostBody: "此文章的內容將加至 TiddlyWiki 文件的 <body> 段落的最後,於 script 區塊之前",
	OptionsPanel: "此預設文章的內容,為於螢幕右側副選單中的選項面板裡的內容",
	PageTemplate: "此預設文章裡的 HTML template 決定的 ~TiddlyWiki 主要的版面配置",
	PluginManager: "此預設文章提供存取套件管理員",
	SideBarOptions: "此預設文章的內容,為於螢幕右側副選單中選項面板裡的內容",
	SideBarTabs: "此預設文章的內容,為於螢幕右側副選單中的頁籤面板裡的內容",
	SiteSubtitle: "此預設文章的內容為頁面的副標題",
	SiteTitle: "此預設文章的內容為頁面的主標題",
	SiteUrl: "此預設文章的內容須設定為文件發佈時的完整網址",
	StyleSheetColors: "此預設文章內含的 CSS 規則,為相關的頁面元素的配色。''勿修改此文'',請於 StyleSheet 中作增修。",
	StyleSheet: "此預設文章內容可包含 CSS 規則",
	StyleSheetLayout: "此預設文章內含的 CSS 規則,為相關的頁面元素的版面配置。''勿修改此文'',請於 StyleSheet 中作增修。",
	StyleSheetLocale: "此預設文章內含的 CSS 規則,可依翻譯語系做適當調整",
	StyleSheetPrint: "此預設文章內含的 CSS 規則,用於列印時的樣式",
	TabAll: "此預設文章的內容,為於螢幕右側副選單中的「全部」頁籤的內容",
	TabMore: "此預設文章的內容,為於螢幕右側副選單中的「更多」頁籤的內容",
	TabMoreMissing: "此預設文章的內容,為於螢幕右側副選單中的「未完成」頁籤的內容",
	TabMoreOrphans: "此預設文章的內容,為於螢幕右側副選單中的「未引用」頁籤的內容",
	TabMoreShadowed: "此預設文章的內容,為於螢幕右側副選單中的「預設文章」頁籤的內容",
	TabTags: "此預設文章的內容,為於螢幕右側副選單中的「分類」頁籤的內容",
	TabTimeline: "此預設文章的內容,為於螢幕右側副選單中的「最近更新」頁籤的內容",
	ViewTemplate: "此預設文章裡的 HTML template 決定文章顯示的樣子"
	});
//}}}
!!透過 mlocate.db 搜尋特定檔案
*官方解釋:
*執行身份:
*重要參數
**-b: basename, 以檔案名稱為查詢目標
**-w: wholename, 以完整名稱為查詢目標,預設值
**-r: regular, 以正規表示法查詢
*等效指令

內含 * 萬用字元,因此搜尋檔名不需要再加上『 * 』
Linux 因使用資料庫管理檔案,搜尋速度極快

{{{
locate filename
}}}

{{{
locate -br ^passwd$
}}}
!!使用正規表示法查詢
** ^: 開頭
** $: 結尾
!!寫入一個紀錄訊息到 syslog
*官方解釋:a shell command interface to the syslog(3) system log module
*執行身份:
*重要參數
**-p: 優先權
*等效指令:

{{{
logger -p local0.notice 'Hello, World'
}}}
!!列印

**-d   {//Printer_name//}
!!查詢目前列印工作

**-P{//印表機名稱//}
!!列印目前文件

**-P{//印表機名稱//}
**-#: 指定印 # 份
{{{
lpr -Pmyprinter /etc/passwd
}}}

!!移除列印佇列中的列印工作


lprm {//Job_number//}
{{{
[root@ms1 ~]# ls /
bin   dev  home  lost+found  misc  net  proc  sbin     srv  tmp  var
boot  etc  lib   media       mnt   opt  root  selinux  sys  usr
}}}
{{{
[root@ms1 ~]# ls / /hom123
ls: /hom123: 沒有此一檔案或目錄
/:
bin   dev  home  lost+found  misc  net  proc  sbin     srv  tmp  var
boot  etc  lib   media       mnt   opt  root  selinux  sys  usr
}}}
{{{
[root@ms1 ~]# ls / /hom123 1> /tmp/ls.1 2> /tmp/ls.2
}}}
{{{
[root@ms1 ~]# cat /tmp/ls.1
/:
bin
boot
dev
etc
home
lib
lost+found
media
misc
mnt
net
opt
proc
root
sbin
selinux
srv
sys
tmp
usr
var
}}}
{{{
[root@ms1 ~]# cat /tmp/ls.2
ls: /hom123: 沒有此一檔案或目錄
}}}
{{{
[root@ms1 ~]# ls / /home
/:
bin   dev  home  lost+found  misc  net  proc  sbin     srv  tmp  var
boot  etc  lib   media       mnt   opt  root  selinux  sys  usr

/home:
fish  flatfish  lost+found
}}}
!!列出已載入到記憶體中的模組
*官方解釋:
*執行身份:
*重要參數
*等效指令:

{{{
Module                  Size  Used by
autofs4                24517  2 
hidp                   23105  2 
rfcomm                 42457  0 
l2cap                  29505  10 hidp,rfcomm
bluetooth              53797  5 hidp,rfcomm,l2cap
}}}

*Used → 0:可卸載
*autoclean:自動卸載
!!列出所使用的晶片組
!!列出 USB 裝置
!!建立 LV

{{{
lvcreate -L 大小 -n 名字 從哪個VG
lvcreate -L 600M -n LV1 flatfishVG
}}}
!!檢視目前的 LV
!!擴充已建立的 LV

{{{
lvextend -L +400M /dev/flatfishVG/LV1
}}}
!!減少已存在的 LV 空間

{{{
lvreduce -L -400M /dev/flatfishVG/LV2
}}}
!!重新分配 LV 空間
*官方解釋:
*執行身份:
*重要參數
*等效指令:
!!檢查是否有排程中的 mail
*/var/spool/mqueue
!!設定重編核心的組態檔

all
config
menuconfig
xconfig
gconfig
oldconfig
modules
install
modules_install
depmod
rpm-pkg
!!顯示 Manual pages (說明)
*官方解釋:format and display the on-line manual pages
*執行身份:
*重要參數
**-k: 針對 keyword 搜尋
*等效指令:

1:使用者命令
2:系統呼叫
3:函式庫
4:特殊檔案
5:格式
6:game
7:雜項
8:系統管理
9:系統管理

/etc/man.config
→ MANPATH
!!建立 ext2/ext3 檔案系統
*官方解釋:
*執行身份:
*重要參數
**-L: 磁碟標籤
**-b: 區塊大小(block size)
*等效指令:
!!建立檔案系統
!!!類似微軟的 format 指令
*官方解釋:
*執行身份:
*重要參數
**-t: 檔案系統型態
***ext2: defauly
***ext3
***vfat
*等效指令:
!!檢視模組相關資訊

**-a: 作者 
**-d: 描述
**-p: 參數

{{{
modinfo /lib/modules/2.6.18-92.el5/kernel/fs/msdos/msdos.ko
}}}
!!載入模組 (自動解決相依關係)

**-r: 卸載模組

{{{
modprobe msdos
}}}


*也有自動卸載相依模組,但僅限於唯一相依關係
{{{
modprobe -r msdos
}}}
{{{
模組檔:     相依1   相依2   ......
  C          A       B
}}}
*C 需要 A 與 B

{{{
/lib/modules/2.6.18-92.1.6.el5/kernel/fs/msdos/msdos.ko: /lib/modules/2.6.18-92.1.6.el5/kernel/fs/fat/fat.ko
}}}
!!磁碟掛載
*官方解釋:
*執行身份:
*重要參數
**-t: 指定掛載的檔案系統類型
***cifs: NTFS
***vfat: FAT
***smbfs: SAMBA
*等效指令:

*mount {//device//} {//mount_point//}
{{{
mount /dev/hdc9 /mnt/dir1
}}}

*掛載光碟
**mount {/dev/cdrom} {/mnt/cdrom}
*掛載軟碟
**mount {/dev/fd0} {/mnt/floppy}
檢視目前網路狀態
*官方解釋:
*執行身份:
*重要參數
**-t: 檢視 TCP 
***-l: listening,目前聆聽的 port number
**-u: 檢視 UDP,請看:張君雅小妹妹廣告
**-n: 以數字顯示
**-p: 顯示佔用的程序 PID 與名稱
*等效指令:

{{{
[root@localhost ~]# netstat -tlun
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State
tcp        0      0 127.0.0.1:2208              0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:770                 0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN
tcp        0      0 127.0.0.1:631               0.0.0.0:*                   LISTEN
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN
tcp        0      0 127.0.0.1:2207              0.0.0.0:*                   LISTEN
tcp        0      0 :::22                       :::*                        LISTEN
udp        0      0 0.0.0.0:32768               0.0.0.0:*
udp        0      0 0.0.0.0:5353                0.0.0.0:*
udp        0      0 0.0.0.0:111                 0.0.0.0:*
udp        0      0 0.0.0.0:631                 0.0.0.0:*
udp        0      0 0.0.0.0:764                 0.0.0.0:*
udp        0      0 0.0.0.0:767                 0.0.0.0:*
udp        0      0 :::32769                    :::*
udp        0      0 :::5353                     :::*
}}}
*127.0.0.1:631:本機印表機管理
**直接在瀏覽器中管理,輸入網址 http:/ /localhost:631
!!改變要執行的程序優先權
*官方解釋:run a program with modified scheduling priority
*執行身份:''-1 ~ -20'' 需 root 身分
*重要參數
**-## : 累加 ## 至 PR(PRI) 值
*等效指令:
!!掃描目標電腦開啟的 port
*官方解釋:Network exploration tool and security / port scanner
*執行身份:
*重要參數
*等效指令:

{{{
nmap 192.168.33.50
}}}

!!對 NTP 伺服器對時
**-q: 僅查詢 NTP 伺服器時間而不對時

{{{
ntpdate -q ntp.ntu.edu.tw
}}}
!!轉換進位制

**-b: 轉換為八進位
**-x: 轉換為十六進位
/***
|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
|''Version:''|1.0.9 (2007-07-14)|
|''Source:''|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Table of Content<html><a name="TOC"/></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Description',null, event)">Description, Syntax</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Applications',null, event)">Applications</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('LongTiddler',null, event)">Refering to Paragraphs of a Longer Tiddler</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Citation',null, event)">Citation Index</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('TableCells',null, event)">Creating "multi-line" Table Cells</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Tabs',null, event)">Creating Tabs</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Sliders',null, event)">Using Sliders</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Revisions',null, event)">Revision History</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Code',null, event)">Code</a></html>
!Description<html><a name="Description"/></html>
With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate (named) parts. 
Each part can be referenced as a "normal" tiddler, using the "//tiddlerName//''/''//partName//" syntax (e.g. "About/Features").  E.g. you may create links to the parts (e.g. {{{[[Quotes/BAX95]]}}} or {{{[[Hobbies|AboutMe/Hobbies]]}}}), use it in {{{<<tiddler...>>}}} or {{{<<tabs...>>}}} macros etc.


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

!Revision history<html><a name="Revisions"/></html>
* v1.0.9 (2007-07-14)
** Bugfix: Error when using the SideBarTabs example and switching between "More" and "Shadow". Thanks to cmari for reporting the issue.
* v1.0.8 (2007-06-16)
** Speeding up display of tiddlers containing multiple pard definitions. Thanks to Paco Rivière for reporting the issue.
** Support "./partName" syntax inside <<tabs ...>> macro
* v1.0.7 (2007-03-07)
** Bugfix: <<tiddler "./partName">> does not always render correctly after a refresh (e.g. like it happens when using the "Include" plugin). Thanks to Morris Gray for reporting the bug.
* v1.0.6 (2006-11-07)
** Bugfix: cannot edit tiddler when UploadPlugin by Bidix is installed. Thanks to José Luis González Castro for reporting the bug.
* v1.0.5 (2006-03-02)
** Bugfix: Example with multi-line table cells does not work in IE6. Thanks to Paulo Soares for reporting the bug.
* v1.0.4 (2006-02-28)
** Bugfix: Shadow tiddlers cannot be edited (in TW 2.0.6). Thanks to Torsten Vanek for reporting the bug.
* v1.0.3 (2006-02-26)
** Adapt code to newly introduced Tiddler.prototype.isReadOnly() function (in TW 2.0.6). Thanks to Paulo Soares for reporting the problem.
* v1.0.2 (2006-02-05)
** Also allow other macros than the "tiddler" macro use the "." in the part reference (to refer to "this" tiddler)
* v1.0.1 (2006-01-27)
** Added Table of Content for plugin documentation. Thanks to RichCarrillo for suggesting.
** Bugfix: newReminder plugin does not work when PartTiddler is installed. Thanks to PauloSoares for reporting.
* v1.0.0 (2006-01-25)
** initial version
!!要求作業系統讀取新的磁碟分割表
*官方解釋: inform the OS of partition table changes
*執行身份:
*重要參數
*等效指令:

{{{
partprobe
}}}
!!使用者密碼
*官方解釋:
*執行身份:
*重要參數
**-l (lock): shadow 加密後的密碼欄位前加上 『 !! 』,凍結密碼
***該使用者無法登入,該使用者信箱仍可收到信,但使用者無法藉此帳號讀信
**-u (unlock): 解凍密碼
*等效指令:

*可直接修改 shadow 密碼,只要能還原密碼
!!將兩個檔案水平地貼在一起
!!關機
*官方解釋:stop the system
*執行身份:
*重要參數
*等效指令:[[halt]]、[[init 0 |init]]、[[shutdown]]
!!產生列印格式,不是列印

*早期報表紙一張 22 孔,一孔 3 列,pr 指令將檔案每 66 列產生一頁報表
!!顯示目前的程序
*官方解釋:report a snapshot of the current processes
*執行身份:
*重要參數
**a: 所有的 TTY
***au: 以使用者角度顯示
****aux: 顯示目前所有的 process,TTY 為 ? 的是系統執行的 process
***al: 顯示包含 PPID 等詳細資訊
*等效指令:

{{{
  PID TTY           TIME CMD
10526 pts/3
}}}

*STAT 狀態碼
**D: 無法插斷 (Uninterruptible) 的休眠 (sleep) 狀態,通常是 I/O
**S: 可插斷 (Interruptible) 的休眠狀態,通常為等待某事件的發生
**R: 可執行 (Runnable) 或是正在執行 (Running),在執行佇列中 (run queue)
**T: 暫停 (Stopped),
**W: 分頁模式 (kernel 2.6+ 不在出現)
**X: dead,應該是看不到
**Z: Zombie,程式設計不當,結束程序時卻未將記憶體空間釋放
!!顯示樹狀程序
*官方解釋:display a tree of processes
*執行身份:
*重要參數
**-p: show PID
*等效指令:
!!建立 PV

{{{
pvcreate /dev/hdc8
pvcreate /dev/hdc9
}}}
!!檢視目前 PV 狀態
!!使用者帳號 轉換為 遮蔽式密碼
*官方解釋:
*執行身份:
*重要參數
*等效指令:
!!顯示目前工作目錄 __P__rint __W__orking __D__irectory
*官方解釋:print name of current/working directory
*執行身份:All
*重要參數
*等效指令:
!!使用者帳號 轉換為非遮蔽式密碼
*官方解釋:
*執行身份:
*重要參數
*等效指令:
!!查詢個人目前磁碟配額限制
!!檢查目前的 Quota 狀況
*官方解釋:
*執行身份:
*重要參數
**-a: /etc/fastab 中有 auto 選項
**-v: 
**-u: usrquota
**-g: grpquota
**-m: 強制檢查
*等效指令:

*aquota.user
*aquota.group
**owner: root, mode: 600
!!停用磁碟配額
*官方解釋:
*執行身份:
*重要參數
**-avug
*等效指令:

{{{
quotaoff -avug
}}}
!!啟用磁碟配額
*官方解釋:
*執行身份:
*重要參數
**-avug
*等效指令:

{{{
quotaon -avug
}}}
!!系統重新啟動
*官方解釋:
*執行身份:
*重要參數
*等效指令:[[init 6|init]]、[[shutdown -r|shutdown]]
!!針對已存在的 PID 修改優先權
*官方解釋:
*執行身份:提高優先權需 root 身分
*重要參數
** ## : 累加 ## 至 PR(PRI) 值
*等效指令:
!!檢視 Quota 報告
*官方解釋:
*執行身份:
*重要參數
*等效指令:
!!線上重整檔案系統
*使用時機:在已 mount 的 LV 磁碟重新調整大小後,又不希望 umount 或是重新開機
{{{
resizee2fs /dev/flatfishVG/LV1 1000M
}}}
!!還原備份檔案

{{{
restore -if /tmp/etc.dump
?
ls
cd etc
ls
add modprobe.conf
extract
}}}
!!移除已載入的模組

{{{
rmmod msdos
rmmod fat
}}}

{{{
rmmod msdos fat
}}}
!!顯示目前路由表
*官方解釋:
*執行身份:
*重要參數
**-n: 顯示 IP 位址
*等效指令:
!!小紅帽系列程式包裝管理程式
*官方解釋:
*執行身份:
*重要參數:參數第一碼為功能,不能掉換位置
**-ivh
**-U / -F: 升級安裝,-U 原套件未安裝也可以, -F 必須要有原套件
**-q: 查詢
***a: 列出所有安裝的 rpm 套件
***i: 針對 package name 查詢
***l: 列出該 package 安裝的檔案、目錄
***f: 列出該檔案所屬的套件
***R: 列出該套件相依的函式庫或檔案
**-e: erase 移除 rpm 套件
**-V: 驗證套件安裝正常與否
***a: 驗證全部套件
***c: 查詢該套件相關組態檔
**{{{--}}}nodeps: 不檢查相依關係
**{{{--}}}force: 強制安裝,不理會衝突
!!!驗證錯誤訊息
**Log、config 檔案大小經常變動,因此 S、5 出現為正常現象

|S|file Size differs|檔案大小與原始包裝大小不同|
|M|Mode differs|相關檔案權限不同|
|5|MD5 sum differs|MD5 驗證不同|
|D|Device major/minor number mismatch|裝置不同|
|L|readLink path mismatch||
|U|User ownership differs||
|G|Group owenership differs||
|T|mTime differs||
|missing|||


*等效指令:

*Lab
{{{
which passwd
rpm -qf /usr/bin/passwd
rpm -qi passwd
}}}
!!
*官方解釋:
*執行身份:
*重要參數
**
**
*等效指令:

{{{
rpmbuild --rebuild xxx.src.rpm
}}}

編譯完在 /usr/src/redhat/RPMS/ 內
**-v: 顯示過程
**-q: 不顯示過程 (包含錯誤訊息也不顯示)
**-r: 遞迴同步,包含目錄
**-l:符號連結檔只複製符號連結,不會複製原檔
**-H: 硬是連結檔只複製硬式連結檔,不會複製原檔
**-o: 保留原擁有者
**-u: 保留原群組

{{{
rsync -vrlHpogt --password-file rsync.passwd /home/flatfish bkuser@192.168.33.50::bk1
}}}
*bk1 為 rsync 伺服器上的自訂備份主機名稱
{{{
bkuser1:123456
}}}
*rsync 帳號/密碼檔格式
使用者名稱:密碼

*權限必須設定為 600
!!執行目錄下所有檔案
!!顯示上一個及目前的 Run Level
*官方解釋:
*執行身份:
*重要參數
*等效指令:

*N 代表開機到目前沒有切換過 runlevel
!!安全性複製
*官方解釋:secure copy (remote file copy program)
*執行身份:
*重要參數
**-r: recurrsive,遞迴複製整個目錄
*等效指令:


{{{
scp root@192.168.33.50:/tmp/web* /tmp/
}}}
{{{
scp -r root@192.168.33.128:/tmp root@192.168.33.100:/tmp
}}}
!!修改檔案內某一段內容
*


*sed '表示式' 檔案
**表示式:位置+功能
**位置
***/RE/:正規表示法指定
***n,m:從第 n 列至第 m 列執行指定的功能
***n,$:從第 n 列至最後
***n,+m:從第 n 列至 n+m 列
***若是整個檔案則不用指定位置
**功能:
***a:接著字串,字在下一新列
***i:接著字串,字在前一新列
***c:接著字串,字在本列取代
***d:刪除該列
***s:置換

*test1
{{{
I have  a dog.
This dog is yellow.
}}}
{{{
sed 's/dog/cat/' test1
}}}
*
{{{
sed 's/dog/cat/g' test1
}}}
*
{{{
sed 's/\<is\>/was/g' test1
}}}
start
stop
restart
status
!!顯示所有變數 (包含自訂與環境變數)
!!設定 ACL
*官方解釋:
*執行身份:
*重要參數
**-m: 
***u:{//username//}:{//mode//}
**-x: 移除一項 ACL 設置
***u:{//username//}
*等效指令:

{{{
setfacl -m u:brad:rw test1
}}}
!!設定/查詢 序列埠組態

{{{
setserial /dev/ttyS0
}}}
{{{
setserial /dev/ttyS0 spd_hi
}}}
{{{
sftp 192.168.33.128
?
}}}
*講本地指令前面加上『 l 』,例如:lls、lcd、lpwd......
{{{
echo $*
echo $#
echo $0
echo $1
echo $2
echo $3
echo $4
echo $5
echo $6
echo $7
echo $8
echo $9
echo $10
echo $11
}}}
{{{
[root@ms1 ~]# sh sh02.sh a b c d e f g h i j k l m
a b c d e f g h i j k l m
13
sh02.sh
a
b
c
d
e
f
g
h
i
a0
a1
}}}
{{{
declare -i sum=$1+$2
echo $sum
}}}
{{{
ttp=`netstat -tlnp | grep ':80 '`
smtp=`netstat -tlnp | grep ':25 '`
pop3=`netstat -tlnp | grep ':110 '`
ssh=`netstat -tlnp | grep ':22 '`
if [ -z "$http" ]; then
        echo "Web server is down"
else
        echo "Web server is running"
fi
if [ -z "$smtp" ]; then
        echo "SMTP server is down"
else
        echo "SMTP server is running"
fi
if [ -z "$pop3" ]; then
        echo "POP3 server is down"
else
        echo "POP3 server is running"
fi
if [ -z "$ssh" ]; then
        echo "SSH server is down"
else
        echo "SSH server is running"
fi
}}}
{{{
month=$1
year=$2
case $month in
	1|3|5|7|8|10|12)
		echo "31"
		;;
	4|6|9|11)
		echo "30"
		;;
	2)
		if [ $[$year%4] -ne 0 ]; then
			echo "28"
		elif [ $[$year%100] -ne 0 ]; then
			echo "29"
		elif [ $[$year%400] -ne 0 ]; then
			echo "28"
		else
			echo "29"
		fi
		;;
	*)
		echo "xxx"
		;;
esac
}}}
{{{
for ((i=0;i<=9;i++))
do
	echo $i
done
}}}
{{{
0
1
2
3
4
5
6
7
8
9
}}}
{{{
for ((k=0;k<=1;k++))
do
for ((j=1;j<=9;j++))
do
for ((i=2;i<=5;i++))
do
        result=$[$[$i+$k*4]*$j]
        echo -e "$[$i+$k*4] x $j = $result\t\c"
done
echo
done
echo '----------------------------------------------------------'
done
}}}
{{{
chmod u+w /etc/shadow

start=$1
end=$2
for ((i=$start;i<=$end;i++))
do
        if [ $i -lt 10 ]; then
                account="S97000$i"
        elif [ $i -lt 100 ]; then
                account="S9700$i"
        elif [ $i -lt 1000 ]; then
                account="S970$i"
        else
                account="S97$i"
        fi

        uid=$[$i+1000]
        echo "$account:x:${uid}:504::/home/${account}/:/bin/bash" >> /etc/passwd
        password='$1$678hMYys$h9LcFG1gC5dHsbjtaxxpN0'
        echo "${account}:${password}:14096:0:99999:7:::" >> /etc/shadow
        cp -rp /etc/skel /home/${account}
        chown -R ${account}.staff /home/${account}
done

chmod u-w /etc/shadow
}}}
{{{
a='a 2 345 67 abc def'
for i in $a
do
	echo $i
done
}}}

*超過 9 個參數的使用方式
{{{
a=$*
for i in $a
do
	echo $i
done
}}}
/***
|Name|ShowUpdatesPlugin|
|Created by|SaqImtiaz|
|Version|0.2 |
|Requires|~TW2.x|
!!!Description:
Allows you to list tiddlers that have changed since the users last visit. You can list only all changed tiddlers, or filter them to only show tiddlers that have or do not have a specific tag. By default a simple list of the titles of changed tiddlers is created. However, using an extremely versatile syntax you can provide a custom template for the generated text.

!!!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.

!!!Syntax:
{{{<<showUpdates>>}}}
additional optional params:
{{{<showUpdates excludeTag:TagToExclude onlyTag:TagToList maxEntries:10 write:CustomWriteParameter >>}}}
excludeTag: ~TagToExclude
onlyTag: ~TagToList
maxEntries: max number of entries displayed when there are no updates. (default is 10, which can be changed in the config.macros.showUpdates.settings part of the code)
write: if a write parameter is not provided, an un-numbered list of the updates is generated. Alternatively, you can specify a custom 'template' for the text generated. The syntax for the write parameter is identical to that of the forEachTiddler macro. Additonal documentation on this syntax will be provided soon.
Some of the variables available in the write parameter are 'index', 'count' and 'lastVisit' where lastVisit is the date of the last visit in the format YYYYMMDDHHMM. Also areUpdates is a boolean that is true if there are new updates since the users last visit.

!!!To Do:
*refactor code to facilitate translations
*a streamlined version without the custom write parameter


!!!Code
***/
//{{{
window.lewcidLastVisit = '';
window.old_lewcid_whatsnew_restart = window.restart;
window.restart = function()
{
        if(config.options.txtLastVisit)
                 lewcidLastVisit= config.options.txtLastVisit;
        config.options.txtLastVisit = (new Date()).convertToYYYYMMDDHHMM();
        saveOptionCookie('txtLastVisit');
        window.old_lewcid_whatsnew_restart();
}

TiddlyWiki.prototype.lewcidGetTiddlers = function(field,excludeTag,includeTag,updatesOnly)
{
              var results = [];
              this.forEachTiddler(function(title,tiddler)
                      {
                      if(excludeTag == undefined || !tiddler.isTagged(excludeTag))
                                    if(includeTag == undefined ||  tiddler.isTagged(includeTag))
                                            if ( updatesOnly == false || tiddler.modified.convertToYYYYMMDDHHMM()>lewcidLastVisit)
                                                  results.push(tiddler);
                      });
              if(field)
                  results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });
              return results;
}

config.macros.showUpdates={};
config.macros.showUpdates.settings =
{
         maxEntries: 10  //max items to show, if there are no updates since last visit
}

config.macros.showUpdates.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
          var args = paramString.parseParams("list",null,true);
          var write = getParam(args, "write", undefined);
          var onlyTag = getParam(args, "onlyTag", undefined);
          var excludeTag = getParam(args, "excludeTag", undefined);
          var sortBy = "modified";
          var maxEntries = getParam(args,"maxEntries",this.settings.maxEntries);

          if (lewcidLastVisit) 
                {var tiddlers = store.lewcidGetTiddlers(sortBy,excludeTag,onlyTag,true);
                 var areUpdates = tiddlers.length>0? true:false;}

          //if (!lewcidLastVisit)
          //     {var countLine = "!!最近的更新:";
                  var tiddlers = store.lewcidGetTiddlers(sortBy,excludeTag,onlyTag,false);
                  var areUpdates = false;
          //     }
          //else if (tiddlers.length == 0)
          //     {var countLine = "!!@@color:red;上次拜訪後, 沒有任何更新 " + (Date.convertFromYYYYMMDDHHMM(lewcidLastVisit)).formatString(" (DD/MM/YY)") + "@@\n!!最近的更新:";
         //      var tiddlers = store.lewcidGetTiddlers(sortBy,excludeTag,onlyTag,false);}
         // else
         //      {var countLine ="!!@@ 自從上次拜訪後, 共有 "+ tiddlers.length +" 更新 " + (Date.convertFromYYYYMMDDHHMM(lewcidLastVisit)).formatString(" (DD/MM/YY)") + "@@";}

          tiddlers = tiddlers.reverse();
          var lastVisit = lewcidLastVisit? lewcidLastVisit:undefined;
          var count = areUpdates == true? tiddlers.length : maxEntries;
          var sp = createTiddlyElement(place,"span","showUpdates");
          if (write==undefined)
                 {
                  //wikify(countLine,sp);
                  var list = createTiddlyElement(sp,"ul");
                  for (var i = 0; i < count; i++)
                          {
                           var tiddler = tiddlers[i];
                           createTiddlyLink(createTiddlyElement(list,"li"), tiddler.title, true);
                          }
                 }
          else
                {
                 var list = '';
                 for (var index = 0; index < count; index++) {
                 var tiddler = tiddlers[index];
                 list += eval(write); }
                 wikify(list, sp);
                }
}
//}}}
-e
!!可自訂的關機指令
*官方解釋:bring the system down
*執行身份:
*重要參數
**-t: n 秒後關機
**-k: 僅發出關機訊息的參數,並不會真的關機
**-r: 關機後立即開機,等效於 [[init 6|init]]、[[reboot]]
*等效指令:[[halt]]、[[init 0|init]]、[[poweroff]]
!!建立 SAMBA 中 user 模式下的使用者密碼

**-a: 新增密碼


{{{
smbpasswd -a flatfish
}}}
!!排序
!!水平切出所需要的列數

**-l #: 以 # 行為單位切割檔案

*切割 /etc/passwd 檔案,以 10 列為單位,檔名前加字元為 『 passwd_ 』
{{{
split -l 10 /etc/passwd passwd_
}}}
{{{
[root@ms1 split]# ls
passwd_aa  passwd_ab  passwd_ac  passwd_ad  passwd_ae
}}}
!!proxy server 

**-z: 針對 proxy 存放目錄格式化
**-k signal: squid 針對送出訊號
**reconfigure: 重讀組態檔
!!產生 ssh 的 公/私 鑰
*官方解釋:
*執行身份:
*重要參數
**-t: 類型
***rsa
*等效指令:

{{{
ssh-keygen -t rsa
}}}
{{{
[flatfish@localhost .ssh]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/flatfish/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/flatfish/.ssh/id_rsa.
Your public key has been saved in /home/flatfish/.ssh/id_rsa.pub.
The key fingerprint is:
da:7a:9f:42:d7:0e:77:2a:f7:18:51:60:b9:cb:27:d9 flatfish@localhost.localdomain
}}}
{{{
-rw------- 1 flatfish flatfish 1675  8月 14 00:33 id_rsa
-rw-r--r-- 1 flatfish flatfish  412  8月 14 00:33 id_rsa.pub
}}}
!!顯示檔案或檔案系統狀態
*官方解釋:display file or file system status
*執行身份:
*重要參數
*等效指令:

可顯示 存取時間(access time)、修改時間(modify time)、權限修改時間(change time)
!!設定序列埠組態
!!切換使用者模式
*官方解釋:
*執行身份:
*重要參數
**-l: 模擬該使用者的環境(進入該使用者的家目錄),可簡化為 -
*等效指令:
!!停用 swap

{{{
swapoff /dev/hdc8
}}}
!!貓 (cat) 倒過來
!!顯示檔案最後的部分
*官方解釋:output the last part of files
*執行身份:
*重要參數
**-f: 持續顯示檔案最後的部分
**-n #: 顯示最後 n 列
*等效指令:

*適合用於觀看 Log 檔
!!tar 封存程式
*官方解釋:The GNU version of the tar archiving utility
**TAR = __T__ape __AR__chiving
*執行身份:
*重要參數
**z: 配合 gzip 壓縮
***.tar.gz
***.tgz
**j: 配合 bzip2 壓縮
***.tar.bz2
***(.tb2)
**cvf: 打包
**xvf: 解包
*等效指令:

|tar|(z)<br>(j)|c<br>x|vf|{//filename//}.tar|{//file1//}|{//file2//}|{//file3//}|{//file4//}|{//file5//}|...|
!!測試判斷式
*官方解釋:check file types and compare values
*執行身份:
*重要參數
**-d: 目錄是某存在
**-f: 判斷檔案是否存在,且為一般檔案 (非目錄)
**-e: 檔案是否存在 (不分檔案類型、目錄或裝置)
**-O: 核心判定是否為有效的擁有人
***Kernel2.4 UID 上限 65535,>65535 將被核心視為無效
***Kernel2.6 UID 上限 2^^32^^
**-G: 核心判定是否為有效的群組
**-w: 該檔案是否存在且執行測試的身份對其是否有寫入的權限
**數值比較
***-eq: 等於
***-ge: 大於等於
***-gt: 大於
***-le: 小於等於
***-lt: 小於
***-ne: 不等於
**字串比較
***=: 字串相等
***!=: 字串不相等
**-a: and
**-o: or
>>{{{[ 條件式A -a/o 條件式B ]}}}
*等效指令:中括號

{{{
test -f /tmp/sh/flatfish || touch /tmp/sh/flatfish && cat /tmp/sh/flatfish
}}}
{{{
[ -f /etc/passwd -a -d /home ]
}}}
{{{
service httpd start
http=`netstat -tlnp | grep ":80 "
test -z "$http"
}}}

!!可直接寫為 __[ 條件式 ]__
*[ ] 與條件式必須有空格隔開
/***
|''巨集名稱:''|toBalaAjax|
|''版本:''|1.0 (2008-03-06)|
|''原始檔:''||
|''作者:''|S L CHEN|
|''授權:''|BSD|
|''倚賴''|toBalaHTML, toBalaFile|
|''TiddlyWiki 適用版本''|2.3+|
|''適用瀏覽器''|Firefox 1.5+, IE 6.0|
|''使用語法''| |
***/

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

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

  if (!params[0]) {
     alert("請給檔名");
     return;
  }

  // 檔名
  var xfname = params[0]; 

  var slabel = params[1] || "儲存網頁";
  var olabel = params[2] || "檢視網頁";
  var xwidth = params[3] || 550;
  var xheight = params[4] || 400;

  createTiddlyButton(place, olabel, olabel,
       function(e) { config.macros.toBalaHTML.show(e,"",xfname,xwidth,xheight); },
       null, null, null);

  if (readOnly) {
     return;
  }

  createTiddlyButton(place, slabel, slabel,
       function(e) { config.macros.toBalaSaveFile.show(e, tiddler.title,xfname); },
       null, null, null);
}
//}}}
!使用說明
{{{
<<toBalaAjax  "ajax\html\testAjax.htm"  "儲存網頁 : ajax\html\testAjax.htm">>
}}}

!實作範例
<<toBalaAjax "ajax\html\testAjax.htm" "儲存網頁 : ajax\html\testAjax.htm">>
/*{{{*/
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf8">
</head>

<body>
<h2 align=center>顯示網頁載入時間的警告視窗</h2>
<hr>

<script>
today = new Date();			// 產生日期物件
hour = today.getHours();		// 取得時數
minute = today.getMinutes();		// 取得分數
second = today.getSeconds();		// 取得秒數
string = "網頁載入時間是"+hour+"點"+minute+"分"+second+"秒";	// 連接字串
</script>
<a href="javascript:alert(string)">網頁載入時間</a>

<hr>
</body>
</html>
/*}}}*/
<<toBalaAjax "ajax\AjaxCall.htm" "儲存網頁 : ajax\AjaxCall.htm" "" "700" "450">>
/*{{{*/
<!-- 
程式名稱 : AjaxCall.html
程式描述 : Call XMLHTTP Object
適用瀏覽器 : Firefox 2.0,IE 5.5
參考文件 : 
-->
<html>
	
<head>
	
<meta http-equiv="Expires" content="0">
<meta http-equiv="Content-Type" content="text/html; charset=utf8">

<script>
var xmlhttp
function show(){
 
 if (window.XMLHttpRequest) {
    netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
    xmlhttp = new XMLHttpRequest();    
 }
 else if (window.ActiveXObject){ 
    try {
          xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
         }
    catch (e){
      try{
         xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
      catch (e){}
    }
 }

 xmlhttp.open(document.getElementById("c").value,document.getElementById("u").value,false);
 xmlhttp.send("");
 if (parseInt(xmlhttp.status)>300){
     alert(xmlhttp.status);
 }
 else {
  document.getElementById("h").innerHTML=xmlhttp.getAllResponseHeaders();
  
  if (xmlhttp.getResponseHeader("Content-Type") == "text/xml"){
  	 xmlobj=xmlhttp.responseXML;
     document.getElementById("x").innerHTML=xmlobj.getElementsByTagName('app')[0].firstChild.nodeValue;
  }
  else{
  	 document.getElementById("x").innerHTML="";
     var testFrame = document.getElementById("myFrame");
     var doc = testFrame.contentDocument;
     if (doc == undefined || doc == null)
        doc = testFrame.contentWindow.document;
     doc.open();
     doc.write(xmlhttp.responseText);
	 doc.close(); 
  }  
 }
}
</script>
</head>

<style type="text/css">
body {
 background-color:white;
}
</style>

<body>
<h2>Ajax 測試程式 (使用本機的瀏覽器以 "開啟檔案" 方式執行)</h2>
<hr>
Method: <input id="c" value="GET" style="width: 100px;" type="text"><span> (要大寫) </span><br> 
URL: <input style="width: 250px;" id="u" value="http://" type="text"><br>

<button onclick="show();">傳送命令</button>
<hr>

<b>Response Header</b>
<pre id="h"></pre>

<b>Response XML</b>
<pre id="x"></pre>

<b>Response HTML</b><br>
<iframe id="myFrame" height="30%" width="100%"></iframe>

</body>
</html>

<!--
HTTP Methods
-------------
HTTP defines eight methods (sometimes referred to as "verbs") indicating the desired 
action to be performed on the identified resource.

HEAD
    Asks for the response identical to the one that would correspond to a GET request, 
    but without the response body. This is useful for retrieving meta-information 
	written in response headers, without having to transport the entire content.
GET
    Requests a representation of the specified resource. By far the most common method
	used on the Web today. Should not be used for operations that cause side-effects 
	(using it for actions in web applications is a common mis-use). See 'safe methods' 
	below.
POST
    Submits data to be processed (e.g. from an HTML form) to the identified resource. 
	The data is included in the body of the request. This may result in the creation 
	of a new resource or the updates of existing resources or both.
PUT
    Uploads a representation of the specified resource.
DELETE
    Deletes the specified resource.
TRACE
    Echoes back the received request, so that a client can see what intermediate 
	servers are adding or changing in the request.
OPTIONS
    Returns the HTTP methods that the server supports. This can be used to check the 
	functionality of a web server.
CONNECT
    For use with a proxy that can change to being an SSL tunnel.


WebDAV added the following methods to HTTP:

    * PROPFIND — Used to retrieve properties, persisted as XML, from a resource. 
	             It is also overloaded to allow one to retrieve the collection 
				 structure (a.k.a. directory hierarchy) of a remote system.
    * PROPPATCH — Used to change and delete multiple properties on a resource 
	              in a single atomic act.
    * MKCOL — Used to create collections (a.k.a. directory).
    * COPY — Used to copy a resource from one URI to another.
    * MOVE — Used to move a resource from one URI to another.
    * LOCK — Used to put a lock on a resource. WebDAV supports both shared and 
	         exclusive locks.
    * UNLOCK — To remove a lock from a resource.

-->
/*}}}*/
config.options.chkAutoSave=false;
config.options.chkSaveBackups=false;
config.options.txtUserName="比目魚";
config.options.txtMaxEditRows=25;
config.options.chkHttpReadOnly=true;

config.options.chkHideTabsBarWhenSingleTab=true;

config.options.chkDisableWikiLinks=true;
config.options.chkAllowLinksFromShadowTiddlers=true;
config.options.chkDisableNonExistingWikiLinks=true;
/***
|''巨集名稱:''|toBalaFile|
|''版本:''|1.0 (2008-03-18)|
|''原始檔:''||
|''作者:''|S L CHEN|
|''授權:''|BSD|
|''倚賴''||
|''TiddlyWiki 適用版本''|2.3+|
|''適用瀏覽器''|Firefox 1.5+, IE 6.0+|
|''使用語法''||
***/

//{{{
config.macros.toBalaFile={
	
	editLabel: "編輯",
	editTip: "編輯",
        saveLabel: "儲存",
	saveTip: "儲存",
        cancelLabel: "取消",
	cancelTip: "取消",
    
	GUIEditButtonOnclick: function(e,xtiddler,xbox,xfname,xx,yy) {

            if (config.browser.isIE) {
               window.event.cancelBubble=true;
            } else {  
               e.cancelBubble = true;   
               if (e.stopPropagation)  
                  e.stopPropagation();
            }

            removeChildren(xbox);

            var boxtool = createTiddlyElement(xbox,"div",null,"toBalaFileToolBar",null,null);
            var boxtext = createTiddlyElement(xbox,"textarea",null,null,null,null);
            wikify("@@color:#841;border:2px dotted #841;padding:2px;檔案 : <nowiki>"+xfname+"</nowiki>@@ ",boxtool);

            createTiddlyButton(boxtool,this.saveLabel,this.saveTip,
                            function(e) { config.macros.toBalaFile.GUISaveButtonOnclick(e,xtiddler,xbox,xfname,boxtext,xx,yy); },
                            "toBalaFileSave",null,null);
	    createTiddlyButton(boxtool,this.cancelLabel,this.cancelTip,
                            function(e) { config.macros.toBalaFile.GUICancelButtonOnclick(e,xtiddler,xbox,xfname,xx,yy); },
                            "toBalaFileCancel",null,null);

            // alert(xtitle+":"+xx+":"+yy);
            boxtext.setAttribute("rows",20);
            boxtext.setAttribute("cols",88);
            boxtext.value = xtiddler.text.substring(xx,yy);
        },

	GUISaveButtonOnclick: function(e,xtiddler1,xbox1,xfname1,boxtext1,xx1,yy1) {

            if (config.browser.isIE) {
               window.event.cancelBubble=true;
            } else {  
               e.cancelBubble = true;   
               if (e.stopPropagation)  
                  e.stopPropagation();
            }
 
            removeChildren(xbox1);
            var xtext=boxtext1.value;
            if (config.browser.isIE) {              
               xtext=xtext.replace(/\r/g,"");   // 請看最後的註解
            }
            var toptext=xtiddler1.text.substring(0,xx1);
            var bottomtext=xtiddler1.text.substring(yy1);
            xtiddler1.text=toptext+xtext+"\n"+bottomtext;

            story.refreshTiddler(xtiddler1.title,null,true);
            saveChanges(false);              // 參數 false, 代表不管 Dirty 與否, 均要執行存檔動作

            var baseDIR = getLocalPath(document.URL);
  
            if (config.browser.isWindows) {
                var baseDIR = baseDIR.replace(/\//g,"");
                var x = baseDIR.lastIndexOf("\\");
             } else {
                var x = baseDIR.lastIndexOf("/");
             }

            baseDIR = baseDIR.substr(0,x+1);

            var s = saveFile(baseDIR+ (config.browser.isWindows ? xfname1 : xfname1.replace(/\\/g,"\/")), 
                                          convertUnicodeToUTF8(boxtext1.value));
            if (!s) {
               alert("存檔失敗");
            }
        },

	GUICancelButtonOnclick: function(e,xtiddler1,xbox1,xfname1,xx1,yy1) {

            if (config.browser.isIE) {
               window.event.cancelBubble=true;
            } else {  
               e.cancelBubble = true;   
               if (e.stopPropagation)  
                  e.stopPropagation();
            }

            removeChildren(xbox1);

            var boxtool = createTiddlyElement(xbox1,"div",null,"toBalaFileToolBar",null,null);
            wikify("@@color:#841;border:2px dotted #841;padding:2px;檔案 : <nowiki>"+xfname1+"</nowiki>@@ ",boxtool);

	    createTiddlyButton(boxtool,this.editLabel,this.editTip,
                            function(e) { config.macros.toBalaFile.GUIEditButtonOnclick(e,xtiddler1,xbox1,xfname1,xx1,yy1);},
                            "toBalaFileEdit",null,null);

             var boxarea = createTiddlyElement(xbox1,"div",null,null,null,null);
	     wikify("{{{\n"+xtiddler1.text.substring(xx1,yy1)+"\n}}}",boxarea);
        },

	handler : function(place,macroName,params,wikifier,paramString,tiddler){

                if (!params[0]) {
                  alert("請給檔名");
                  return;
                } 

		var xtext=store.getTiddlerText(tiddler.title);
                var x1=xtext.indexOf("/"+"/"+"/"+"%" + params[0]);

                // 自動產生 TiddlyWiki 備註
                if (x1 == -1) { 
                   xtext=xtext+"\n\n/"+"/"+"/"+"%" + params[0] + "\n" + "/"+"/"+"%"+"/";
                   tiddler.text=xtext; 
                   story.refreshTiddler(tiddler.title,null,true);
                   saveChanges(false);
                   return;
                 }
                var x2=xtext.indexOf("/"+"/"+"%"+"/",x1);
                x1=x1+params[0].length+5;

		var box = createTiddlyElement(place,"div",tiddler.title+"-"+x1,"toBalaFile",null,null);
                var boxtool = createTiddlyElement(box,"div",null,"toBalaFileToolBar",null,null);
                wikify("@@color:#841;border:2px dotted #841;padding:2px;檔案 : <nowiki>"+params[0]+"</nowiki>@@ ",boxtool);

                var boxtext = createTiddlyElement(box,"div",null,null,null,null);
		wikify("{{{\n"+xtext.substring(x1,x2)+"\n}}}",boxtext);

                if (readOnly) {
                   return;
                }
		createTiddlyButton(boxtool,this.editLabel,this.editTip,
                            function(e) { config.macros.toBalaFile.GUIEditButtonOnclick(e,tiddler,box,params[0],x1,x2);},
                            "toBalaFileEdit",null,null);
	}		
};

/*
HTML 的 textarea 標籤, 對於換行在不同的瀏覽器有不同的處理方式

As you may know, the humble line break actually has three forms depending on which operating system is doing the breaking. On Unix machines, a single newline character ‘\n’ does the job. On Macs, a carriage return ‘\r’ is used. DOS and Windows use both: ‘\r\n’. It’s one of those relatively subtle issues that can bite you hard if you don’t know what to look out for.
*/

//}}}
!說明
{{{

<<toBalaFile "檔名">>

}}}
!範例
<<toBalaFile "xml\abc.xml">>


///%xml\abc.xml
<?xml version='1.0'?>
<root>
  <marble color="red"/>
  <marble color='red'/>
</root> 
//%/
/***
|''巨集名稱:''|toBalaFlashPlayer|
|''版本:''|1.0 (2008-03-06)|
|''原始檔:''||
|''作者:''|S L CHEN|
|''授權:''|BSD|
|''倚賴''||
|''TiddlyWiki 適用版本''|2.3+|
|''適用瀏覽器''|Firefox 1.5+, IE 6.0+|
|''使用語法''| |
***/
//{{{
config.macros.toBalaFlashPlayer = {};

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

  var xname = params[0] || tiddler.title;
  var label = params[1] || "撥放 " + xname;
  var xwidth = params[2] || 600;
  var xheight = params[3] || 450;

  createTiddlyButton(place, label, label,
       function(e) { config.macros.toBalaFlashPlayer.show(e, xname, xwidth, xheight); },
       null, null, null);
}

config.macros.toBalaFlashPlayer.show = function(ev,fname,xw,xh) {

  if (config.browser.isIE) {
     window.event.cancelBubble=true;
  } else {  
     ev.cancelBubble = true;   
     if (ev.stopPropagation)  
        ev.stopPropagation();
  }

  if (config.browser.isIE)
     var URLtext = document.URL.replace(/\\/g,"\/");
  else 
     var URLtext = document.URL;
  //alert(URLtext);

  var x = URLtext.lastIndexOf("/");
  var baseDIR = URLtext.substr(0,x);
  var jsDIR = '<script type="text/javascript" src="' + baseDIR + '/jslib/swfobject/swfobject.js"></script>'
  //alert(jsDIR);

  var generator=window.open('','name','height=' + xh +',width=' + xw);
  generator.document.open();
  generator.document.write('<html><head><title>toBala Flash Player</title>');
  generator.document.write(jsDIR);
  generator.document.write('</head><body>');
  generator.document.write('<div id="flashTag" style="width:'+(xw-5)+'px;height:'+(xh-5)+'px;overflow:auto"></div>');
  generator.document.write('<script type="text/javascript">');
  generator.document.write('var xo = new SWFObject("' + baseDIR + '/' + fname + '","mymovie","'+(xw-5)+'","'+(xh-5)+'","8", "#336699");');
  //generator.document.write('xo.addParam("wmode", "transparent");');
  generator.document.write('xo.write("flashTag");');
  generator.document.write('</script>');
  generator.document.write('</body></html>');
  generator.document.close();

}
//}}}
使用 toBalaFlashPlayer 巨集, 來撥放指定的 Flash 檔, 命令格式如下 :
{{{
<<toBalaFlashPlayer "movie/infotree.swf" "" "820" "610">>
}}}

!實作

<<toBalaFlashPlayer "movie/infotree.swf" "" "820" "610">>

/***
|''巨集名稱:''|toBalaHTML|
|''版本:''|1.0 (2008-03-18)|
|''原始檔:''||
|''作者:''|S L CHEN|
|''授權:''|BSD|
|''倚賴''||
|''TiddlyWiki 適用版本''|2.3+|
|''適用瀏覽器''|Firefox 1.5+, IE 6.0+|
|''使用語法''|&lt;&lt;toBalaHTML  title  filename  label  tooltip  width  height&gt;&gt; |
***/

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

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

  var title = params[0] || tiddler.title;
  var xfname = params[1] || "";          // 外部檔名
  var label = params[2] || "測試網頁";
  var tooltip = params[3] || "開啟另一個視窗, 檢視網頁";
  var xwidth = params[4] || 550;
  var xheight = params[5] || 400;

  createTiddlyButton(place, label, tooltip,
       function(e) { config.macros.toBalaHTML.show(e,title,xfname,xwidth,xheight); },
       null, null, null);
}

config.macros.toBalaHTML.show = function(ev,xtitle,xf,xw,xh) {

  if (config.browser.isIE) {
     window.event.cancelBubble=true;
  } else {  
     ev.cancelBubble=true;   
     if (ev.stopPropagation)  
        ev.stopPropagation();
  }

  // 將視窗置中
  var winl = (screen.width-xw)/2;
  var wint = (screen.height-xh)/2;
  if (winl < 0) winl = 0;
  if (wint < 0) wint = 0;
  var settings = 'height='  + xh +  ', width=' + xw  + ',top='  + wint  + ',left='  + winl;

  if (xf != "") {

     xf=xf.replace(/\\/mg,"/");

     // alert(xf+":"+settings);
     var xwin=window.open(xf,"HTMLWIN",settings);
     xwin.window.focus();

  } else {
    // alert(store.getTiddlerText(xtitle));
    xtext=store.getTiddlerText(xtitle);

    x1=xtext.indexOf("/*{{{*/");
    x2=xtext.indexOf("/*}}}*/");
    // alert(xtext.substring(x1+8,x2));
    xtext = xtext.substring(x1+8,x2);

    var xwin=window.open('','',settings);
    xwin.document.open();
    xwin.document.write(xtext);
    xwin.document.close();
  }
}
/*
window.open() 參數
----------------------------------------------
* width:定義新視窗的寬度。
* height:定義新視窗的高度。
* resizable:能否讓用戶調整視窗大小,可能的設定值為:yes或no(或者1與0)。
* menubar:是否要顯示主功能表,可能的設定值為:yes或no。
* toolbar:是否要顯示「標準按鈕」工具列,可能的設定值為:yes或no。
* location:是否要顯示網址欄位,可能的設定值為:yes或no。
* scrollbars:能否顯示捲軸,可能的設定值為:yes或no。
* status:是否要呈現狀態列,可能的設定值為:yes或no。
* directories:是否要呈現額外的按鈕(例如:「連結」列,以及「標準按鈕」以外的其他按鈕),可能的設定值為:yes或no。
* copyhistory:是否要複製原有瀏覽器視窗的瀏覽歷程(history),可能的設定值為:yes或no。
* fullscreen:是否要以全螢幕方式開啟新視窗(適用於IE瀏覽器),可能的設定值為:yes或no。
*/
//}}}
<<toBalaHTML "" "ajax/html/e4x.htm" "網頁測試 : ajax/html/e4x.htm">><<toBalaFile "ajax\html\e4x.htm">>

///%ajax\html\e4x.htm
<html>
<script type="text/javascript;e4x=1">
      myquestion = <question>          
      <display>Is it animal, vegetable, or mineral?</display>              
      <answerOption>Animal</answerOption>
      <answerOption>Vegetable</answerOption>
      <answerOption>Mineral</answerOption>
      </question>;
      alert("The question is '" + myquestion.display + "'");             
</script>
</html>
//%/
這範例程式可在 IE, Firefox, Opera  等瀏覽器中執行

<<toBalaHTML "" "ajax\html\contentEditableFF.htm">><<toBalaFile "ajax\html\contentEditableFF.htm">>

///%ajax\html\contentEditableFF.htm
<body>
<iFrame id="jia" src="about:blank"></iFrame>  
<script>  
  // window.onload   =   function(){  
  var jia = document.getElementById("jia");  
  jia.contentWindow.document.designMode="on";  
  jia.contentWindow.document.contentEditable=true;  
  jia.contentWindow.document.open();  
  jia.contentWindow.document.write("<html><head></head><body></body></html>");  
  jia.contentWindow.document.close();  
  // }  
</script>
</body>
//%/
必須關閉瀏覽器 [阻檔 POPUP 視窗] 功能, 以下程式才能執行

<<toBalaHTML "" "ajax\html\popup.htm">><<toBalaFile "ajax\html\popup.htm">>


///%ajax\html\popup.htm
<html>
<head>
<script type="text/javascript">
function show_popup()
{
   var p=window.createPopup();
   var pbody=p.document.body;
   pbody.style.backgroundColor="lime";
   pbody.style.border="solid black 1px";
   pbody.innerHTML="This is a pop-up! Click outside to close.";
   p.show(150,150,200,50,document.body);
}
</script>
</head>

<body>
<button onclick="show_popup()">Create pop-up!</button>
</body>

</html>
//%/
/***
|''巨集名稱:''|toBalaJava|
|''版本:''|1.0 (2008-04-01)|
|''原始檔:''||
|''作者:''|S L CHEN|
|''授權:''|BSD|
|''倚賴''|toBalaRun|
|''TiddlyWiki 適用版本''|2.3+|
|''適用瀏覽器''|Firefox 1.5+, IE 6.0+|
|''使用語法''|&lt;&lt;toBalaJava  "程式檔名"  "前置編譯參數"  "前置執行參數"  "後置執行參數" "按鈕提示資訊" "按鈕提示資訊"&gt;&gt; |
***/

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

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

  if (readOnly) {
     return;
  }

  if (!params[0].match(".java")) {
     alert("請給檔名或副檔名錯誤");
     return;
  }

  // 程式檔名
  var xfname = params[0]; 

  // 前置編譯參數 
  var cprearg = params[1] || "";

  // 前置執行參數 
  var eprearg = params[2] || "";

  // 後置執行參數 
  var postarg = params[3] || "";

  var cargs = (cprearg=="" ? "":cprearg+" ") + xfname;
  //alert(cargs);

  var p = xfname.indexOf(".java");
  yfname=xfname.substring(0,p);
  p=yfname.lastIndexOf("\\");
  yfname=yfname.substring(p+1,yfname.length);

  var rargs = (eprearg==""?"":eprearg+" ") + yfname + (postarg==""?"":" "+postarg);
  //alert(rargs);

  // 按鈕提示資訊
  var clabel = params[4] || "翻譯程式 :" + xfname;
  var rlabel = params[5] || "執行程式 :" + yfname;

  // 翻譯程式
  createTiddlyButton(place, clabel, clabel,
       function(e) { config.macros.toBalaRun.cmd(e,"tbjavac.exe",cargs,"yes"); },
       null, null, null);

  // 執行程式
  createTiddlyButton(place, rlabel, rlabel,
       function(e) { config.macros.toBalaRun.cmd(e,"tbjava.exe",rargs,"yes"); },
       null, null, null);
}
//}}}
!程式範例 

{{{
使用 toBalaFile 巨集, 編輯及儲存 Java 程式, 命令格式如下 :

<<toBalaFile "java\hello.java">>
}}}

<<toBalaFile "java\hello.java">>
----
{{{
使用 toBalaJava 巨集, 編譯及執行 Java 程式, 命令格式如下 :

<<toBalaJava "java\hello.java" "" "">>
}}}

<<toBalaJava "java\hello.java" "" "">>


!程式範例 : 輸入 [編譯] 及 [執行] 參數

<<toBalaFile "java\assertion.java">>
----
{{{
使用 toBalaJava 巨集, 編譯及執行 Java 程式, 命令格式如下 :
<<toBalaJava "java\assertion.java" "-source 1.4" "-ea">>

"-source 1.4" 是編譯參數
"-ea" 是執行參數

}}}

<<toBalaJava "java\assertion.java" "-source 1.4" "-ea">>


///%java\hello.java
public class hello {
  public static void main(String[] args){
     System.out.println("大家好好");
  }
}
//%/

///%java\assertion.java
class assertion {
  public static void main(String[] args){
    int i=-11;
    if (i%3==0) 
      { System.out.println("0"); }
    else if (i%3==1) 
      { System.out.println("1"); }
    else {
      assert((i%3)==2):i;
    }
  }
}
//%/
{{{
if (!window.toBala) window.toBala = {};

toBala.showMsg = function(msg,xw,xh) {
      var winl = (screen.width-xw)/2;
      var wint = (screen.height-xh)/2;
      if (winl < 0) winl = 0;
      if (wint < 0) wint = 0;
      var settings = 'height='  + xh +  ', width=' + xw  + ',top='  + wint  + ',left='  + winl;
      var xwin=window.open("","",settings);
      xwin.document.open();
      xwin.document.write(msg);
      xwin.document.close();
      return xwin;
};
}}}
/***
|''巨集名稱:''|toBalaManager|
|''版本:''|1.0 (2008-05-05)|
|''原始檔:''||
|''作者:''|S L CHEN|
|''授權:''|BSD|
|''倚賴''||
|''~TiddlyWiki 適用版本''|2.3+|
|''適用瀏覽器''|Firefox 1.5+, IE 6.0+|
|''使用語法''||
***/
//{{{
config.macros.toBalaManager={
	preText: "",
	save: function(e,ytiddler,yform) {
            //for (var i=0,str="";i<yform.elements.length;++i){
            //  str=str+yform.elements[i].type+":"+yform.elements[i].tagName+":"+yform.elements[i].value;
            //}
            //alert(str);  
      
            // 設定主標題
            var xt = store.getTiddler("SiteTitle");  
            xt.text=  yform.elements[0].value;

            // 設定次標題
            var xt = store.getTiddler("SiteSubtitle");  
            xt.text=  yform.elements[1].value;

            // 設定 MainMenu
            var xt = store.getTiddler("MainMenu");  
            xt.text=  yform.elements[2].value;

            // 設定 ToolBar
            var xt = store.getTiddler("ToolBar");  
            xt.text=  yform.elements[3].value;

            // 備份 SiteTitle, SiteSubtitle, ToolBar, MainMenu  
            ytiddler.text=preText; 
            saveChanges(false);   // 參數 false, 代表不管 Dirty 與否, 均要執行存檔動作
        },

	handler : function(place,macroName,params,wikifier,paramString,tiddler){

                if (readOnly) {
                   return;
                }

		createTiddlyButton(place,"儲存","儲存",
                          function(e) { config.macros.toBalaManager.save(e,tiddler,xform); },
                          "toBalaManagerSave",null,null);

		var xform = createTiddlyElement(place,"form",tiddler.title+"-form","toBalaManager",null,null);
                // 讀取主標題
                var xlabel1 = createTiddlyElement(xform,"label",null,"",null,null);
		wikify("''主標題 (~SiteTitle) :  ''",xlabel1);
                var xtitle1 = createTiddlyElement(xform,"input",null,"xManagerMT",null,null);
                var xt = store.getTiddler("SiteTitle");   
		xtitle1.value=xt.text;
		wikify("\n\n",xform);

                // 讀取次標題
                var xlabel2 = createTiddlyElement(xform,"label",null,"",null,null);
                wikify("''次標題 (~SiteSubtitle) :  ''",xlabel2);
                var xtitle2 = createTiddlyElement(xform,"input",null,"xManagerST",null,null);
                var xt = store.getTiddler("SiteSubtitle");   
		xtitle2.value=xt.text;
		wikify("\n\n",xform);

                // 讀取 MainMenu
                var xlabel4 = createTiddlyElement(xform,"label",null,"",null,null);
                wikify("''資訊樹 (TagsTree)''",xlabel4);
		wikify("\n",xform);
                var xmm = createTiddlyElement(xform,"textarea",null,"xManagerMM",null,null);
                var xt = store.getTiddler("MainMenu");   
                xmm.value=xt.text;
		wikify("\n\n",xform);

                // 讀取 ToolBar
                var xlabel3 = createTiddlyElement(xform,"label",null,"",null,null);
                wikify("''工具列 (~ToolBar)''",xlabel3);
		wikify("\n",xform);
                var xtb = createTiddlyElement(xform,"textarea",null,"xManagerTB",null,null);
                var xt = store.getTiddler("ToolBar");   
                xtb.value=xt.text;
		wikify("\n\n",xform);

                // 備份 SiteTitle, SiteSubtitle, ToolBar, MainMenu
	        var xtext=store.getTiddlerText(tiddler.title);
                var x1 = xtext.indexOf("/"+"/"+"/"+"%");
                xtext = ( x1 == -1 ? xtext : xtext.substring(0,x1) );

                preText=xtext+"\n\n/"+"/"+"/"+"%" ;
                preText=preText+"\n\n"+xtitle1.value;
                preText=preText+"\n\n"+xtitle2.value;
                preText=preText+"\n\n"+xmm.value;
                preText=preText+"\n\n"+xtb.value;
                preText=preText+"\n" + "/"+"/"+"%"+"/";

	}		
};

setStylesheet(".toBalaManager {background:#eee; font-size:12px;border:1px solid #ccc; padding:2px; margin:5px;}\n"+
".xManagerMT {width:550px;height:25px;}\n" +
".xManagerST {width:550px;height:25px;}\n" +
".xManagerTB {width:680px;height:150px;}\n" +
".xManagerMM {width:680px;height:250px;}\n" +
".toBalaManagerSave {border:1px solid #ccc;font-size:14px;padding:2px;margin-left:4px;margin-bottom:2px;}\n" ,
"toBalaManagerStyles");
//}}}
/***
|''巨集名稱:''|toBalaNotes|
|''版本:''|1.0 (2008-03-18)|
|''原始檔:''||
|''作者:''|S L CHEN|
|''授權:''|BSD|
|''倚賴''||
|''TiddlyWiki 適用版本''|2.3+|
|''適用瀏覽器''|Firefox 1.5+, IE 6.0+|
|''使用語法''||
***/

//{{{
config.macros.toBalaNotes={
	
	editLabel: "編輯",
	editTip: "編輯",
        saveLabel: "儲存",
	saveTip: "儲存",
        cancelLabel: "取消",
	cancelTip: "取消",
        heading: "@@font-size:12px;color:#841;註解@@",
    
	GUIEditButtonOnclick: function(e,xtiddler,xbox,xx,yy) {
            removeChildren(xbox);

            var boxtool = createTiddlyElement(xbox,"div",null,"toBalaNotesToolBar",null,null);
            var boxtext = createTiddlyElement(xbox,"textarea",null,null,null,null);
	    wikify(this.heading+" : ",boxtool);

            createTiddlyButton(boxtool,this.saveLabel,this.saveTip,
                            function(e) { config.macros.toBalaNotes.GUISaveButtonOnclick(e,xtiddler,xbox,boxtext,xx,yy); },
                            "toBalaNotesSave",null,null);
	    createTiddlyButton(boxtool,this.cancelLabel,this.cancelTip,
                            function(e) { config.macros.toBalaNotes.GUICancelButtonOnclick(e,xtiddler,xbox,xx,yy); },
                            "toBalaNotesCancel",null,null);

            // alert(xtitle+":"+xx+":"+yy);
            boxtext.setAttribute("rows",15);
            boxtext.setAttribute("cols",88);
            boxtext.value = xtiddler.text.substring(xx,yy);
        },

	GUISaveButtonOnclick: function(e,xtiddler1,xbox1,boxtext1,xx1,yy1) {
            removeChildren(xbox1);
            toptext=xtiddler1.text.substring(0,xx1);
            bottomtext=xtiddler1.text.substring(yy1);
            xtiddler1.text=toptext+boxtext1.value+bottomtext;
            story.refreshTiddler(xtiddler1.title,null,true);
            saveChanges(false);   // 參數 false, 代表不管 Dirty 與否, 均要執行存檔動作
        },

	GUICancelButtonOnclick: function(e,xtiddler1,xbox1,xx1,yy1) {
            removeChildren(xbox1);

            var boxtool = createTiddlyElement(xbox1,"div",null,"toBalaNotesToolBar",null,null);
	    wikify(this.heading+" : ",boxtool);

	    createTiddlyButton(boxtool,this.editLabel,this.editTip,
                            function(e) { config.macros.toBalaNotes.GUIEditButtonOnclick(e,xtiddler1,xbox1,xx1,yy1);},
                            "toBalaNotesEdit",null,null);

             var boxarea = createTiddlyElement(xbox1,"div",null,null,null,null);
	     wikify(xtiddler1.text.substring(xx1,yy1),boxarea);
        },

	handler : function(place,macroName,params,wikifier,paramString,tiddler){

		var xtext=store.getTiddlerText(tiddler.title);
                var x1=xtext.indexOf("/"+"/"+"/"+"%" + params[0]);

                // 自動產生 TiddlyWiki 備註
                if (x1 == -1) { 
                   xtext=xtext+"\n\n/"+"/"+"/"+"%" + params[0] + "\n" + "/"+"/"+"%"+"/";
                   tiddler.text=xtext; 
                   story.refreshTiddler(tiddler.title,null,true);
                   saveChanges(false);     // 參數 false, 代表不管 Dirty 與否, 均要執行存檔動作
                   clearMessage();
                   return;
                 }
                var x2=xtext.indexOf("/"+"/"+"%"+"/",x1);
                x1=x1+params[0].length+5;

		var box = createTiddlyElement(place,"div",tiddler.title+"-"+x1,"toBalaNotes",null,null);
                var boxtool = createTiddlyElement(box,"div",null,"toBalaNotesToolBar",null,null);
		wikify(this.heading+" : ",boxtool);

                var boxtext = createTiddlyElement(box,"div",null,null,null,null);
		wikify(xtext.substring(x1,x2),boxtext);

                if (readOnly) {
                   return;
                }

		createTiddlyButton(boxtool,this.editLabel,this.editTip,
                            function(e) { config.macros.toBalaNotes.GUIEditButtonOnclick(e,tiddler,box,x1,x2);},
                            "toBalaNotesEdit",null,null);
	}		
};

setStylesheet(".toBalaNotes {background:#eee; border:1px solid #ccc; padding:2px; margin:5px;}\n"+
".toBalaNotesEdit {border:1px solid #ccc;padding:2px;margin-top:2px;margin-bottom:2px;}\n" +
".toBalaNotesCancel {border:1px solid #ccc;padding:2px;margin-top:2px;margin-right:2px;margin-bottom:2px;}\n" +
".toBalaNotesToolBar {border-bottom: 2px dotted #556b2f;padding:1px 0px 5px 0px;margin:1px;}\n" +
".toBalaNotesSave {border:1px solid #ccc;padding:2px;margin-top:2px;margin-right:2px;margin-bottom:2px;}\n",
"toBalaNotesStyles");
//}}}
/***
|''巨集名稱:''|toBalaRun|
|''版本:''|1.0 (2008-04-01)|
|''原始檔:''||
|''作者:''|S L CHEN|
|''授權:''|BSD|
|''倚賴''||
|''TiddlyWiki 適用版本''|2.3+|
|''適用瀏覽器''|Firefox 1.5+, IE 6.0+|
|''使用語法''| |
***/

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

  if (readOnly) {
     return;
  }

  if (!params[0]) {
     alert("請給檔名");
     return;
  }
  var fname = params[0];                //  執行檔名
  var varg = params[1] || "";             //  執行參數
  var label = params[2] || "執行 : "+fname + " " + varg;
  var tooltip = params[3] || "執行檔名 : "+fname + " " + varg;
  var result = params[4] || "yes";

  window.status="";
  createTiddlyButton(place, label, tooltip,
       function(e) { config.macros.toBalaRun.cmd(e,fname,varg,result); },
       null, null, null);
}

config.macros.toBalaRun.cmd = function(ev,xfname,xarg,xresult) {

  if (!xfname.match(".bat")) {
      //var xwin = toBala.showMsg("<h1>執行中, 請稍後</h1>",250,50);
      window.status = xfname + " " + xarg + " 執行中, 請稍後";
  }

  if (config.browser.isIE) {
     window.event.cancelBubble=true;
  } else {  
     ev.cancelBubble = true;   
     if (ev.stopPropagation)  
        ev.stopPropagation();
  }

  var baseDIR = getLocalPath(document.URL);
  //alert(baseDIR);

   if (config.browser.isWindows) {
      var baseDIR = baseDIR.replace(/\//g,"");
      var x = baseDIR.lastIndexOf("\\");
      xfname = "\\" + xfname.replace(/\//g,"\\");
      xarg = xarg.replace(/\//g,"\\");
   } else {
      var x = baseDIR.lastIndexOf("/");
      xfname = "/" + xfname.replace(/\\/g,"/");
      xarg = xarg.replace(/\\/g,"/");
   }

   baseDIR = baseDIR.substr(0,x);
   //alert(baseDIR);

   if (config.browser.isIE) {
	var theShell = new ActiveXObject("WScript.Shell");
	if (theShell) {
            var runstr = baseDIR + xfname + " " + xarg;
            // alert(runstr);
	    try {
	        theShell.run(runstr,1, (xresult == "yes" ? true:false));
	    } catch (e) {
                try {          //  執行系統命令
                    var runstr = xfname.substring(1)+ " " + xarg;
                    theShell.run(runstr,1, (xresult == "yes" ? true:false));
                } catch(e) {
                   if (!xfname.match(".bat")) 
                      window.status="";
		   displayMessage("執行失敗 :" + runstr);
		   return;
                }
	    }
	} 
   } else if (config.browser.isGecko) { 
	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);

        try {
           var runstr = baseDIR +xfname; 
           // alert(runstr);
           file.initWithPath(runstr);
        }catch (e) {
           if (!xfname.match(".bat")) 
              window.status="";
           displayMessage("執行字串格式錯誤 : " + runstr);
           return;
        }

	try {
	   var process = Components.classes['@mozilla.org/process/util;1'].createInstance(Components.interfaces.nsIProcess);
           var Aargs = xarg.split(" ");
           // alert(Aargs);
           process.init(file);
           process.run((xresult == "yes" ? true:false), Aargs, Aargs.length);
	} catch (e) {
            try {    //  執行系統命令
                runstr=xfname.substring(1);
                file.initWithPath(runstr);
                process.init(file);
                process.run((xresult == "yes" ? true:false), Aargs, Aargs.length);
            } catch (e) {
                if (!xfname.match(".bat")) 
                    window.status="";
	        displayMessage("執行失敗 : " + runstr);
                return;
            }
	}
   }
   // 顯示執行結果
   if ( !xfname.match(".bat") && !xfname.match(".sh") && xresult == "yes") {
      window.status="";
      xf = baseDIR+xfname+".htm"
      // alert(xf);
      var xh = 400;
      var xw = 780;
      var winl = (screen.width-xw)/2;
      var wint = (screen.height-xh)/2;
      if (winl < 0) winl = 0;
      if (wint < 0) wint = 0;
      var settings = 'height='  + xh +  ', width=' + xw  + ',top='  + wint  + ',left='  + winl + ',scrollbars=yes';
      var ywin=window.open("file:///"+xf,"HTMLWIN",settings);
   }
}
//}}}
<<toBalaFile "xml\dtd01.xml">><<toBalaRun "java\jaxp\JAXPDTD.bat" "xml\dtd01.xml" "檢核">>

----

<<toBalaFile "xml\dtd02.xml">><<toBalaRun "java\jaxp\JAXPDTD.bat" "xml\dtd02.xml" "檢核">>


///%xml\dtd01.xml
<?xml version="1.0" encoding="big5"?>
<!DOCTYPE PersonData [
  <!ELEMENT PersonData (name,spouse)>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT spouse (#PCDATA)>
]>
<PersonData>
    <spouse>Teley</spouse>
    <name>Ryan</name>
</PersonData>
//%/

///%xml\dtd02.xml
<?xml version="1.0"?>
<!DOCTYPE user [
  <!ELEMENT user (name+,e-mail*,title?)>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT e-mail (#PCDATA)>
  <!ELEMENT title (#PCDATA)>
]>
<user>
  <name>Austin Sours</name>
  <e-mail>xchen@cmt.com.tw</e-mail>
  <e-mail>aaa@x,y,z</e-mail>
</user>
//%/
<<toBalaFile "xml\well01.xml">><<toBalaRun "java\jaxp\JAXPWell.bat" "xml\well01.xml" "檢核">>

----

<<toBalaFile "xml\well02.xml">><<toBalaRun "java\jaxp\JAXPWell.bat" "xml\well02.xml" "檢核">>


///%xml\well01.xml
<root>
  <marble color="red"/>
  <marble color='red'/>
</root>
//%/

///%xml\well02.xml
<first_tag>
  <second_tag>
     <third_tag>Contents of third tag
  </second_tag>
</First_tag>
//%/
<<toBalaFile "xml\stype.xsd">>


<<toBalaFile "xml\stype.xml">><<toBalaRun "java\jaxp\JAXPSchema.bat" "xml\stype.xml xml\stype.xsd" "檢核">>


///%xml\stype.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                  targetNamespace="http://xsdtesting">
    <xs:element name="author" type="xs:date"/>
</xs:schema>
//%/

///%xml\stype.xml
<?xml version="1.0"?>
<x:author xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xmlns:x="http://xsdtesting"
          xsi:schemaLocation="http://xsdtesting stype.xsd">
123.5
</x:author>
//%/
<<toBalaFile "xml\deftemp.xml">>
DOM Tree
----------------
{{{
       .
       |
       |--- <?xml-stylesheet  type="text/xsl"  .... ?>   
       |--- <root>
                |
                |--- <text>
                |
                |
                |--- <text>
                |
                |
                |--- <!-- abcd --> 

}}}


<<toBalaFile "xml\deftemp.xsl">><<toBalaRun "java\jaxp\JAXPXSLT.bat" "xml\deftemp.xml xml\deftemp.xsl" "轉換">>


///%xml\deftemp.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="deftemp.xsl"?>
<root>
  <text>
    Roses are <color>red</color>, violets are <color>blue</color>.
  </text>
  <text>
    My <color>green</color> and <color id="xxx">yellow</color> 
    sweater is just the right hue.
    <?name type="bebo"?>
  </text>
  <!-- abcd -->
</root>
//%/

///%xml\deftemp.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<!-- <xsl:template match="*|/">
</xsl:template>  -->

<!-- <xsl:template match="processing-instruction()">
  PI : <xsl:value-of select="."/>
</xsl:template> -->

<!-- <xsl:template match="root"/> -->

</xsl:stylesheet>
//%/
<<toBalaRun "tbzoomit.bat" "" "ZoomIt v1.8" "" "no">>

!~ZoomIt v1.8
By Mark Russinovich
Published: March 10, 2008
網址 : http://technet.microsoft.com/zh-tw/sysinternals/bb897434(en-us).aspx

''Introduction''
~ZoomIt is screen zoom and annotation tool for technical presentations that include application demonstrations. ~ZoomIt runs unobtrusively in the tray and activates with customizable hotkeys to zoom in on an area of the screen, move around while zoomed, and draw on the zoomed image. I wrote ~ZoomIt to fit my specific needs and use it in all my presentations.

~ZoomIt works on all versions of Windows and you can use pen input for ~ZoomIt drawing on tablet ~PCs.

''Using ~ZoomIt''
The first time you run ~ZoomIt it presents a configuration dialog that describes ~ZoomIt's behavior, let's you specify alternate hotkeys for zooming and for entering drawing mode without zooming, and customize the drawing pen color and size. I use the draw-without-zoom option to annotate the screen at its native resolution, for example. ~ZoomIt also includes a break timer feature that remains active even when you tab away from the timer window and allows you to return to the timer window by clicking on the ~ZoomIt tray icon.

!tbzoomit.bat 程式碼
{{{
@echo off

REM 取得這個 Batch File 的目錄
set toBalaPath=%~p0

REM 取得這個 Batch File 的磁碟代號
set toBalaDrv=%~d0

REM 轉換磁碟及目錄
call %toBalaDrv%
cd %toBalaPath%

REM 設定環境變數
REM -----------------
set PATH=.;%cd%\cmdtools;%PATH%
start /B zoomit.exe
exit

}}}
/***
|''巨集名稱:''|toBalaWrite|
|''版本:''|1.0 (2008-04-01)|
|''原始檔:''||
|''作者:''|S L CHEN|
|''授權:''|BSD|
|''倚賴''||
|''TiddlyWiki 適用版本''|2.3+|
|''適用瀏覽器''|Firefox 1.5+, IE 6.0+|
|''使用語法''| |
***/

//{{{
config.macros.toBalaWrite = {};
config.macros.toBalaWrite.handler = function(place, macroName, params, wikifier, paramString, tiddler) {
	var title = params[0];
	if(title == tiddler.title) {
            title = "Error: Can't use the same tiddler from which the macro is called (infinite recursion)!";
            alert(title);
            return;
	}
	var tiddler = store.getTiddler(title);
        var contents = tiddler.text;
	wikify(contents, place);
}
//}}}
!!即時檢視目前 processes 資源使用量
*官方解釋:display Linux tasks
*執行身份:
*重要參數
*等效指令:
*操作
**P: 按照 %CPU 排列
**M: 按照 %MEM 排列
**N: 按照 PID 排列
**Z: 改變介面顏色
**k: 送出中斷程序訊號
**r: 改變程序優先權
!!轉譯,中介指令,必須接在管線後



*tr 原來的樣式 新的樣式
{{{
tr a-z A-Z
}}}
*a 轉換為 x,b 轉換為 y,c 轉換為 z
{{{
tr abc xyz
}}}
!!路徑追蹤
*官方解釋:
*執行身份:
*重要參數
**-I: 利用 ICMP 封包查詢路徑
*等效指令:
!!限制使用者最大使用資源
!!磁碟卸載
*官方解釋:
*執行身份:
*重要參數
**-o: 設定掛載選項
***async / sync: 非同步(default) / 同步 的方式掛載
***atime / noatime: 每次存取更新 access time(default) / 不更新 access time
***dev / nodev: 
***exec / noexec: 允許執行檔(default) / 不允許執行檔
***user (group): 一般帳號可掛載,不可卸載
***users (groups): 一般帳號可以掛載與卸載
***nouser (nogroups): 一般帳號皆不可掛載與卸除
***rw / ro: 可讀寫(default) / 唯讀
***suid / nosuid: 允許 SetUID 與 SetGID / 不允許 SetUID 與 SetGID
***auto: 是否可以被 -a 選項掛載
***defaults: rw, suid, dev, exec, auto, nouser, async

*等效指令:

*umount {//volume_name//}
**同一個磁碟分割區掛載多次時,以 FILO 順序卸載
*umount {//mount_point//}

!!無法成功卸載的原因
#工作目錄為要卸載的目標
#正在 I/O
!!顯示系統資訊
*官方解釋:print system information
*執行身份:
*重要參數
**-a: 顯示所有資訊
**-r: 顯示核心版本
*等效指令:
!!需安裝 ncompress 套件
!!解壓縮
*官方解釋:compress and expand data
*執行身份:
*重要參數
**-c: 標準輸出至螢幕
*等效指令:[[compress]]、[[zcat]]

{{{
uncompress -c anaconda.log.Z > anaconda.log
}}}
!!將相同且連續的列結合
!!變數脫離
!!更新 mlocate 資料庫
*官方解釋:update a database for mlocate
*執行身份:root
*重要參數
*等效指令:

該資料庫存放在 ''/var/lib/mlocate/mlocate.db''
!新增使用者
*-m: 使用者目錄如不存在則自動建立
*-M: 不建立使用者目錄
*-d: 只定使用者的家目錄
*-k: 參考指定的骨架來源
**/etc/skel/ 預設參考骨架來源
*-c: 增加註解,使用 {{{//  //}}} 或是 {{{/  /}}} 包裹起來
-g: 加入該 GID 的主要群組,不會再建立私有群組
!!刪除帳號
*官方解釋:
*執行身份:
*重要參數
**-r (recurrsive): 遞迴式刪除帳號,使用者目錄與 Mail box 中該帳號的資料一併刪除
*等效指令:

!!修改使用者帳號
*官方解釋:
*執行身份:
*重要參數
**-l: 修改帳號名稱
***登入帳號名稱會被修改,mail box 名稱也會跟著改,但家目錄不變
**-L: 加密後的密碼欄位前加上 『 ! 』,凍結密碼
**-U: 解凍密碼
*等效指令:

{{{
usermod -l 新帳號 舊帳號
}}}

{{{
usermod -d 新目錄 -m 帳號名稱
}}}
!!建立 VG

{{{
vgcreate flatfishVG /dev/hdc8 /dev/hdc9
}}}
!!擴充 VG
{{{
vgextend flatfishVG /dev/hdc10
}}}
!!誰在線上
!!計數器

**-l: lines,列數
**-c: characters,字元數
**-w: words,單字
http://www.squirrelmail.org

openwebmail
!!『搜尋』指令只令相關,包含指令檔、manual pages、source,透過 $PATH 尋找
*官方解釋:
*執行身份:
*重要參數
**-b: 搜尋指定檔,包含組態檔
**-m:  搜尋 manual pages
**-s: 搜尋 source code
*等效指令:
!!『搜尋』指令,透過 $PATH 尋找指令
*官方解釋:
*執行身份:
*重要參數
*等效指令:[[whereis -b|whereis]]

{{{
which passwd
}}}
!!誰在線上
!!查詢 網域 / IP 所屬資訊
!!使用數據機撥號
!!召喚一個 X 時鐘
*官方解釋:
*執行身份:
*重要參數
**& : 背景處理
*等效指令:
!!召喚一顆圖形介面的 X 眼睛
*官方解釋:
*執行身份:
*重要參數
**& : 背景執行
*等效指令:
!!掌管 Xserver 允不允許終端連線

*全部允許
{{{
xhost +
}}}
*全部禁止
{{{
xhost -
}}}
*允許特定對象連線
{{{
xhost -
xhost +192.168.33.128
}}}
*禁止特定對象連線
{{{
xhost +
xhost -192.168.33.128
}}}
遠端控制
ssh -X 192.168.33.50
xterm
!!讀取壓縮檔案內容
*官方解釋:compress and expand data
*執行身份:
*重要參數
*等效指令:[[gzip]]、[[gunzip]]
!!管線命令

{{{
rpm -qa | wc -l
rpm -qa | grep ncompress
}}}

/***
|''Name:''|DropDownMenuPlugin|
|''Description:''|Create dropdown menus from unordered lists|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#DropDownMenuPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.1|
|''Date:''|11/04/2007|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.5|

!!Usage:
* create a two-level unordered list using wiki syntax, and place {{{<<dropMenu>>}}} on the line after it.
* to create a vertical menu use {{{<<dropMenu vertical>>}}} instead.
* to assign custom classes to the list, just pass them as parameters to the macro {{{<<dropMenu className1 className2 className3>>}}}

!!Features:
*Supports just a single level of drop-downs, as anything more usually provides a poor experience for the user.
* Very light weight, about 1.5kb of JavaScript and 4kb of CSS.
* Comes with two built in css 'themes', the default horizontal and vertical. 

!!Customizing:
* to customize the appearance of the menu's, you can either add a custom class as described above or, you can edit the CSS via the StyleSheetDropDownMenu shadow tiddler.


***/
// /%
//!BEGIN-PLUGIN-CODE
config.macros.dropMenu={

	dropdownchar: "\u25bc",

	handler : function(place,macroName,params,wikifier,paramString,tiddler){
		list = findRelated(place.lastChild,"UL","tagName","previousSibling");
		if (!list)
			return;
		addClass(list,"suckerfish");
		if (params.length){
			addClass(list,paramString);
		}
		this.fixLinks(list);
	},
	
	fixLinks : function(el){
		var els = el.getElementsByTagName("li");
		for(var i = 0; i < els.length; i++) {
			if(els[i].getElementsByTagName("ul").length>0){
				var link = findRelated(els[i].firstChild,"A","tagName","nextSibling");
				if(!link){
					var ih = els[i].firstChild.data;
					els[i].removeChild(els[i].firstChild);
					var d = createTiddlyElement(null,"a",null,null,ih+this.dropdownchar,{href:"javascript:;"});
					els[i].insertBefore(d,els[i].firstChild);
				}
				else{
					link.firstChild.data = link.firstChild.data + this.dropdownchar;
					removeClass(link,"tiddlyLinkNonExisting");
				}
			}
			els[i].onmouseover = function() {
				addClass(this, "sfhover");
			};
			els[i].onmouseout = function() {
				removeClass(this, "sfhover");
			};
		}
	}	
};

config.shadowTiddlers["StyleSheetDropDownMenuPlugin"] = 
	 "/*{{{*/\n"+
	 "/***** LAYOUT STYLES -  DO NOT EDIT! *****/\n"+
	 "ul.suckerfish, ul.suckerfish ul {\n"+
	 "	margin: 0;\n"+
	 "	padding: 0;\n"+
	 "	list-style: none;\n"+
	 "	line-height:1.4em;\n"+
	 "}\n\n"+
	 "ul.suckerfish  li {\n"+
	 "	display: inline-block; \n"+
	 "	display: block;\n"+
	 "	float: left; \n"+
	 "}\n\n"+
	 "ul.suckerfish li ul {\n"+
	 "	position: absolute;\n"+
	 "	left: -999em;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover ul, ul.suckerfish li.sfhover ul {\n"+
	 "	left: auto;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li {\n"+
	 "	float: none;\n"+
	 "	border-right: 0;\n"+
	 "	border-left:0;\n"+
	 "}\n\n"+
	 "ul.suckerfish a, ul.suckerfish a:hover {\n"+
	 "	display: block;\n"+
	 "}\n\n"+
	 "ul.suckerfish li a.tiddlyLink, ul.suckerfish li a, #mainMenu ul.suckerfish li a {font-weight:bold;}\n"+
	 "/**** END LAYOUT STYLES *****/\n"+
	 "\n\n"+
	 "/**** COLORS AND APPEARANCE - DEFAULT *****/\n"+
	 "ul.suckerfish li a {\n"+
	 "	padding: 0.5em 1.5em;\n"+
	 "	color: #FFF;\n"+
	 "	background: #0066aa;\n"+
	 "	border-bottom: 0;\n"+
	 "	font-weight:bold;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover a, ul.suckerfish li.sfhover a{\n"+
	 "	background: #00558F;\n"+
	 "}\n\n"+
	 "ul.suckerfish li:hover ul a, ul.suckerfish li.sfhover ul a{\n"+
	 "	color: #000;\n"+
	 "	background: #eff3fa;\n"+
	 "	border-top:1px solid #FFF;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li a:hover {\n"+
	 "	background: #e0e8f5;\n"+
	 "}\n\n"+
	 "ul.suckerfish li a{\n"+
	 "	width:9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish ul li a, ul.suckerfish ul li a:hover{\n"+
	 "	display:inline-block;\n"+
	 "	width:9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish li {\n"+
	 "	border-left: 1px solid #00558F;\n"+
	 "}\n"+
	 "/***** END COLORS AND APPEARANCE - DEFAULT *****/\n"+
	 "\n\n"+
	 "/***** LAYOUT AND APPEARANCE: VERTICAL *****/\n"+
	 "ul.suckerfish.vertical li{\n"+
	 "	width:10em;\n"+
	 "	border-left: 0px solid #00558f;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical ul li, ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a {\n"+
	 "	border-left: 0.8em solid #00558f;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a,  ul.suckerfish.vertical li.sfhover a:hover{\n"+
	 "	width:8em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical {\n"+
	 "	width:10em; text-align:left;\n"+
	 "	float:left;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li a {\n"+
	 "	padding: 0.5em 1em 0.5em 1em;\n"+
	 "	border-top:1px solid  #fff;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical, ul.suckerfish.vertical ul {\n"+
	 "	line-height:1.4em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul, ul.suckerfish.vertical li.sfhover ul { \n"+
	 "	margin: -2.4em 0 0 10.9em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul li a, ul.suckerfish.vertical li.sfhover ul li a {\n"+
	 "	border: 0px solid #FFF;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a{\n"+
	 "	padding-right:1.1em;\n"+
	 "}\n\n"+
	 "ul.suckerfish.vertical li:hover ul li, ul.suckerfish.vertical li.sfhover ul li {\n"+
	 "	border-bottom:1px solid  #fff;\n"+
	 "}\n\n"+
	 "/***** END LAYOUT AND APPEARANCE: VERTICAL *****/\n"+
	 "/*}}}*/";
store.addNotification("StyleSheetDropDownMenuPlugin",refreshStyles);
//!END-PLUGIN-CODE
// %/
kill  `cat /var/run/httpd.pid`

backupfile=`date +%Y%m%d`.tgz
echo $backupfile
{{{
echo $[10+3]
echo $[10-3]
echo $[10*3]
echo $[10/3]
echo $[10%3]
echo $[10**3]
}}}

http://drbl.nchc.org.tw
集中管理環境
{{{
SayYa(){
     echo "Ya...$1"
     return 4
}

SayYa Mary
echo $?

exit 7
echo "OK"
}}}

{{{
fx(){
        ret=`echo $[2*$1+1]`
        return $ret
}     

fx 3
result=$?
echo $result
}}}

<<importTiddlers inline>>
/***
|''Name:''|LaunchApplicationPlugin|
|''Author:''|Lyall Pearce|
|''Source:''|http://www.Remotely-Helpful.com/TiddlyWiki/LaunchApplication.html|
|''License:''|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''Version:''|1.4.0|
|''~CoreVersion:''|2.3.0|
|''Requires:''| |
|''Overrides:''| |
|''Description:''|Launch an application from within TiddlyWiki using a button|
!!!!!Usage
<<<
{{{<<LaunchApplication "buttonLabel" "tooltip" "application" ["arguments" ...]>>}}}
{{{<<LaunchApplicationButton "buttonLabel" "tooltip" "application" ["arguments" ...]>>}}}
{{{<<LaunchApplicationLink "buttonLabel" "tooltip" "application" ["arguments" ...]>>}}}
* buttonLabel is anything you like
* tooltip is anything you like
* application is a path to the executable (which is Operating System dependant)
* arguments is any command line arguments the application requires.
* You must supply relative path from the location of the TiddlyWiki OR a fully qualified path
* Forward slashes works fine for Windows

{{{<<LaunchApplication...>>}}} functions the same as {{{<<LaunchApplicationButton...>>}}}

eg.

{{{
<<LaunchApplicationButton "Emacs" "Linux Emacs" "file:///usr/bin/emacs">>
}}}
<<LaunchApplicationButton "Emacs" "Linux Emacs" "file:///usr/bin/emacs">>

{{{
<<LaunchApplicationLink "LocalProgram" "Program relative to Tiddly html file" "localDir/bin/emacs">>
}}}
<<LaunchApplicationLink "LocalProgram" "Program relative to Tiddly html file" "localDir/bin/emacs">>
					     
{{{
<<LaunchApplicationButton "Open Notepad" "Text Editing" "file:///e:/Windows/notepad.exe">>
}}}
<<LaunchApplicationButton "Open Notepad" "Text Editing" "file:///e:/Windows/notepad.exe">>

{{{
<<LaunchApplicationLink "C Drive" "Folder" "file:///c:/">>
}}}
<<LaunchApplicationLink "C Drive" "Folder" "file:///c:/">>


!!!!!Revision History
* 1.1.0 - leveraged some tweaks from from Bradly Meck's version (http://bradleymeck.tiddlyspot.com/#LaunchApplicationPlugin) and the example text.
* 1.2.0 - Make launching work in Linux too and use displayMessage() to give diagnostics/status info.
* 1.3.0 - execute programs relative to TiddlyWiki html file plus fix to args for firefox.
* 1.3.1 - parameters to the macro are properly parsed, allowing dynamic paramters using {{{ {{javascript}} }}} notation.
* 1.4.0 - updated core version and fixed empty tooltip and added launch link capability
***/



聯絡我: mailto:bearflatfish@gmail.com

<html><a href="../weblog/weblog.html" target="mainFrame"> 更多的 ''比目魚'' 請看 My Weblog </a></html>
/***
|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
|''Version:''|1.0.9 (2007-07-14)|
|''Source:''|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Table of Content<html><a name="TOC"/></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Description',null, event)">Description, Syntax</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Applications',null, event)">Applications</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('LongTiddler',null, event)">Refering to Paragraphs of a Longer Tiddler</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Citation',null, event)">Citation Index</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('TableCells',null, event)">Creating "multi-line" Table Cells</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Tabs',null, event)">Creating Tabs</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Sliders',null, event)">Using Sliders</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Revisions',null, event)">Revision History</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Code',null, event)">Code</a></html>
!Description<html><a name="Description"/></html>
With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate (named) parts. 
Each part can be referenced as a "normal" tiddler, using the "//tiddlerName//''/''//partName//" syntax (e.g. "About/Features").  E.g. you may create links to the parts (e.g. {{{[[Quotes/BAX95]]}}} or {{{[[Hobbies|AboutMe/Hobbies]]}}}), use it in {{{<<tiddler...>>}}} or {{{<<tabs...>>}}} macros etc.


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

!Revision history<html><a name="Revisions"/></html>
* v1.0.9 (2007-07-14)
** Bugfix: Error when using the SideBarTabs example and switching between "More" and "Shadow". Thanks to cmari for reporting the issue.
* v1.0.8 (2007-06-16)
** Speeding up display of tiddlers containing multiple pard definitions. Thanks to Paco Rivière for reporting the issue.
** Support "./partName" syntax inside <<tabs ...>> macro
* v1.0.7 (2007-03-07)
** Bugfix: <<tiddler "./partName">> does not always render correctly after a refresh (e.g. like it happens when using the "Include" plugin). Thanks to Morris Gray for reporting the bug.
* v1.0.6 (2006-11-07)
** Bugfix: cannot edit tiddler when UploadPlugin by Bidix is installed. Thanks to José Luis González Castro for reporting the bug.
* v1.0.5 (2006-03-02)
** Bugfix: Example with multi-line table cells does not work in IE6. Thanks to Paulo Soares for reporting the bug.
* v1.0.4 (2006-02-28)
** Bugfix: Shadow tiddlers cannot be edited (in TW 2.0.6). Thanks to Torsten Vanek for reporting the bug.
* v1.0.3 (2006-02-26)
** Adapt code to newly introduced Tiddler.prototype.isReadOnly() function (in TW 2.0.6). Thanks to Paulo Soares for reporting the problem.
* v1.0.2 (2006-02-05)
** Also allow other macros than the "tiddler" macro use the "." in the part reference (to refer to "this" tiddler)
* v1.0.1 (2006-01-27)
** Added Table of Content for plugin documentation. Thanks to RichCarrillo for suggesting.
** Bugfix: newReminder plugin does not work when PartTiddler is installed. Thanks to PauloSoares for reporting.
* v1.0.0 (2006-01-25)
** initial version
{{{
用rsync對網站進行鏡像備份
本文出自:http://xfocus.org/ 作者:inburst[inburst@263.net] (2001-09-08 13:05:00)
對系統管理員來說,平時的工作重心應該集中在維護系統正常運轉,能夠正常提供服務上,這裡往往牽涉到一個
數據備份的問題,在我所了解 

的情況中,有80%的系統管理員不是太關心自己服務器的安全性,但往往對備分鏡像的技術相當感興趣,但由商
業產品的軟硬件價格都相當高 

昂,因此往往會選擇自由軟件。這裡準備介紹的rsync就是這樣的軟件,它可以滿足絕大多數要求不是特別高的備
份需求。 

一、特性簡介 

rsync是類unix系統下的數據鏡像備份工具,從軟件的命名上就可以看出來了remote sync。它的特性如下: 

1、可以鏡像保存整個目錄樹和文件系統。 
2、可以很容易做到保持原來文件的權限、時間、軟硬鏈接等等。 
3、無須特殊權限即可安裝。 
4、優化的流程,文件傳輸效率高。 
5、可以使用rcp、ssh等方式來傳輸文件,當然也可以通過直接的socket連接。 
6、支持匿名傳輸。 

二、使用方法 

rsync的使用方法很簡單,我就舉自己使用的例子來說明吧。 

1、系統環境 

rsync支持大多數的類unix系統,無論是Linux、Solaris還是BSD上都經過了良好的測試。我的系統環境為: 

server: FreeBSD 4.3  ip: 192.168.168.52 
client: Solaris 8    ip: 192.168.168.137 
rsync 版本 2.4.6(可以從http://rsync.samba.org/rsync/獲得最新版本) 

2、配置server端的/etc/rsyncd.conf文件 

bash-2.03# cat /etc/rsyncd.conf 

uid = nobody 
gid = nobody 
use chroot = no         # 不使用chroot 
max connections = 4         # 最大連接數為4 
pid file = /var/run/rsyncd.pid 
lock file = /var/run/rsync.lock 
log file = /var/log/rsyncd.log    # 日志記錄文件 

[inburst]            # 這裡是認証的模塊名,在client端需要指定 
path = /home/inburst/python/    # 需要做鏡像的目錄 
comment = BACKUP CLIENT IS SOLARIS 8 E250 
ignore errors            # 可以忽略一些無關的IO錯誤 
read only = yes            # 只讀 
list = no            # 不允許列文件 
auth users = inburst        # 認証的用戶名,如果沒有這行,則表明是匿名 
secrets file = /etc/inburst.pas    # 認証文件名 

[web] 
path = /usr/local/apache/htdocs/ 
comment = inburst.org web server 

3、在server端生成一個密碼文件/etc/inburst.pas 

bash-2.03# cat /etc/inburst.pas 
inburst:hack 

出安全目的,文件的屬性必需是只有屬主可讀。 

4、在server端將rsync以守護進程形式啟動 

bash-2.03# rsync --daemon 

如果要在啟動時把服務起來,有幾種不同的方法,比如: 

  a、加入inetd.conf 

    編輯/etc/services,加入rsync   873/tcp,指定rsync的服務端口是873 
    編加/etc/inetd.conf,加入rsync  stream  tcp   nowait  root  /bin/rsync rsync --daemon 

  b、加入rc.local 

    在各種操作系統中,rc文件存放位置不盡相同,可以修改使系統啟動時rsync --daemon加載進去。 

5、從client端進行測試 

下面這個命令行中-vzrtopg裡的v是verbose,z是壓縮,r是recursive,topg都是保持文件原有屬性如屬主、時間
的參數。--progress是指顯示 

出詳細的進度情況,--delete是指如果服務器端刪除了這一文件,那客戶端也相應把文件刪除,保持真正的一致。
面的inburst@ip中, 

inburst是指定密碼文件中的用戶名,之的::inburst這一inburst是模塊名,也就是在/etc/rsyncd.conf中自定義
的名稱。最的/tmp是備份 

到本地的目錄名。 

在這裡面,還可以用-e ssh的參數建立起加密的連接。可以用--password-file=/password/path/file來指定密碼文
件,這樣就可以在腳本中使 

用而無需交互式地輸入驗証密碼了,這裡需要注意的是這份密碼文件權限屬性要設得只有屬主可讀。 

bash-2.03# rsync -vzrtopg --progress --delete inburst@192.168.168.52::inburst /tmp/ 
Password: 
receiving file list ... done 
./ 
1 
785 (100%) 
1.py 
4086 (100%) 
2.py 
10680 (100%) 
a 
0 (100%) 
ip 
3956 (100%) 
./ 
wrote 190 bytes  read 5499 bytes  758.53 bytes/sec 
total size is 19507  speedup is 3.43 

6、創建更新腳本 

如果有比較復雜的工作,利用一些常見的腳本語言可以有幫助。比如: 

bash-2.03# cat /usr/local/bin/rsync.sh 

#!/bin/sh 
DATE=`date +%w` 

rsync -vzrtopg --progress --delete inburst@192.168.168.52::inburst /home/quack/backup/$DATE --password-file=/etc/rsync.pass > 

/var/log/rsync.$DATE 

7、修改/etc/crontab做好定時 

比如: 

bash-2.03# echo "15      4       *       *       6       root    rsync.sh">>/etc/crontab 

三、FAQ 

Q:如何通過ssh進行rsync,而且無須輸入密碼? 
A:可以通過以下幾個步驟 

1. 通過ssh-keygen在server A上建立SSH keys,不要指定密碼,你會在~/.ssh下看到identity和identity.pub文件 
2. 在server B上的home目錄建立子目錄.ssh 
3. 將A的identity.pub拷貝到server B上 
4. 將identity.pub加到~[user b]/.ssh/authorized_keys 
5. 是server A上的A用戶,可通過下面命令以用戶B ssh到server B上了 
                e.g. ssh -l userB serverB 
這樣就使server A上的用戶A就可以ssh以用戶B的身份無需密碼登陸到server B上了。 

Q:如何通過在不危害安全的情況下通過防火牆使用rsync? 
A:解答如下: 

這通常有兩種情況,一種是服務器在防火牆內,一種是服務器在防火牆外。 
無論哪種情況,通常還是使用ssh,這時最好新建一個備份用戶,並且配置sshd僅允許這個用戶通過RSA認証方式進入。 
如果服務器在防火牆內,則最好限定客戶端的IP地址,拒絕其它所有連接。 
如果客戶機在防火牆內,則可以簡單允許防火牆打開TCP端口22的ssh外發連接就ok了。 

Q:我能將更改過或者刪除的文件也備份上來嗎? 
A:當然可以: 

你可以使用如:rsync -other -options -backupdir = ./backup-2000-2-13  ...這樣的命令來實現。 
這樣如果源文件:/path/to/some/file.c改變了,那舊的文件就會被移到./backup-2000-2-13/path/to/some/file.c,
這裡這個目錄需要自己 

手工建立起來 

Q:我需要在防火牆上開放哪些端口以適應rsync? 
A:視情況而定 

rsync可以直接通過873端口的tcp連接傳文件,也可以通過22端口的ssh來進行文件傳遞,但你也可以通過下列命令改變它的端口: 

rsync --port 8730 otherhost:: 
或者 
rsync -e 'ssh -p 2002' otherhost: 

Q:我如何通過rsync只復制目錄結構,忽略掉文件呢? 
A:rsync -av --include '*/' --exclude '*' source-dir dest-dir 

Q:為什我總會出現"Read-only file system"的錯誤呢? 
A:看看是否忘了設"read only = no"了 

Q:為什我會出現'@ERROR: invalid gid'的錯誤呢? 
A:rsync使用時默認是用uid=nobody;gid=nobody來運行的,如果你的系統不存在nobody組的話,就會出現這樣的錯誤,可以試試gid = 

nogroup或者其它 

Q:綁定端口873失敗是怎回事? 
A:如果你不是以root權限運行這一守護進程的話,因為1024端口以下是特權端口,會出現這樣的錯誤。你可以用--port參數來改變。 

Q:為什我認証失敗? 
A:從你的命令行看來: 

你用的是: 
> bash$ rsync -a 144.16.251.213::test test 
> Password: 
> @ERROR: auth failed on module test 
> 
> I dont understand this. Can somebody explain as to how to acomplish this. 
> All suggestions are welcome. 

應該是沒有以你的用戶名登陸導致的問題,試試rsync -a max@144.16.251.213::test test 

四、一些可借鑒的腳本 

這裡這些腳本都是rsync網站上的例子: 

1、每隔七天將數據往中心服務器做增量備份 

#!/bin/sh 

# This script does personal backups to a rsync backup server. You will end up 
# with a 7 day rotating incremental backup. The incrementals will go 
# into subdirectories named after the day of the week, and the current 
# full backup goes into a directory called "current" 
# tridge@linuxcare.com 

# directory to backup 
BDIR=/home/$USER 

# excludes file - this contains a wildcard pattern per line of files to exclude 
EXCLUDES=$HOME/cron/excludes 

# the name of the backup machine 
BSERVER=owl 

# your password on the backup server 
export RSYNC_PASSWORD=XXXXXX 


######################################################################## 

BACKUPDIR=`date +%A` 
OPTS="--force --ignore-errors --delete-excluded --exclude-from=$EXCLUDES 
      --delete --backup --backup-dir=/$BACKUPDIR -a" 

export PATH=$PATH:/bin:/usr/bin:/usr/local/bin 

# the following line clears the last weeks incremental directory 
[ -d $HOME/emptydir ] || mkdir $HOME/emptydir 
rsync --delete -a $HOME/emptydir/ $BSERVER::$USER/$BACKUPDIR/ 
rmdir $HOME/emptydir 

# now the actual transfer 
rsync $OPTS $BDIR $BSERVER::$USER/current 

2、備份至一個空閑的硬盤 

#!/bin/sh 

export PATH=/usr/local/bin:/usr/bin:/bin 

LIST="rootfs usr data data2" 

for d in $LIST; do 
    mount /backup/$d 
    rsync -ax --exclude fstab --delete /$d/ /backup/$d/ 
    umount /backup/$d 
done 

DAY=`date "+%A"` 
     
rsync -a --delete /usr/local/apache /data2/backups/$DAY 
rsync -a --delete /data/solid /data2/backups/$DAY 

3、對vger.rutgers.edu的cvs樹進行鏡像 

#!/bin/bash 

cd /var/www/cvs/vger/ 
PATH=/usr/local/bin:/usr/freeware/bin:/usr/bin:/bin 

RUN=`lps x | grep rsync | grep -v grep | wc -l` 
if [ "$RUN" -gt 0 ]; then 
    echo already running 
    exit 1 
fi 

rsync -az vger.rutgers.edu::cvs/CVSROOT/ChangeLog $HOME/ChangeLog 

sum1=`sum $HOME/ChangeLog` 
sum2=`sum /var/www/cvs/vger/CVSROOT/ChangeLog` 

if [ "$sum1" = "$sum2" ]; then 
    echo nothing to do 
    exit 0 
fi 

rsync -az --delete --force vger.rutgers.edu::cvs/ /var/www/cvs/vger/ 
exit 0 

4、利用find的一種巧妙方式 

rsync -avR remote:'`find /home -name "*.[ch]"`' /tmp/ 

可以用這種方法列出需要備份的文件列表這種方法似乎比較少人用到。 

五、參考資料: 

1、http://rsync.samba.org/ 
2、rsync examples 
3、rsync FAQ   
}}}

http://fanqiang.chinaunix.net/a6/b7/20010908/1305001258_b.html

{{{
# 下面一行:本程式是基於 /bin/bash 撰寫的
#!/bin/bash

a=3
b=4
declare -i c=$a+$b
echo $c
echo $SHLVL
}}}
*執行 sh sh01.sh
*declare -i:宣告以下面變數為整數,『 + 』將被視為運算元

{{{
#! /bin/bash
#	狀況模擬
#	狀況1. 目前上課教室為 303,使用 192.168.33.0 網段
#	狀況2. 每週一三五晚上與星期六日的自習時間使用 304 教室,使用 192.168.34.0 網段
#	狀況3. 臨時換教室不知道使用網段為何,採用 DHCP 自動取得方式
#	狀況4. 手動指定 IP 位址

case $1 in
	i303)
		proto='BOOTPROTO=static'
		ip='IPADDR=192.168.33.129'
		mask='NETMASK=255.255.255.0'
		gate='GATEWAY=192.168.33.254'
		;;
	i304)
		proto='BOOTPROTO=static'
		ip='IPADDR=192.168.34.129'
		mask='NETMASK=255.255.255.0'
		gate='GATEWAY=192.168.34.254'
		;;
	dhcp)
		proto='BOOTPROTO=dhcp'
		;;
	manual)
		proto='BOOTPROTO=static'
		echo Your IP address:
		read ipadd
		echo Your Subnet mask:
		read netmask
		echo Your default Gateway:
		read gateway
		ip="IPADDR=${ipadd}"
		mask="NETMASK=${netmask}"
		gate="GATEWAY=${gateway}"
		;;
	*)
		echo ERR
		;;
esac

#	寫入至組態檔
echo DEVICE=eth0 > /etc/sysconfig/network-scripts/ifcfg-eth0
echo ONBOOT=yes >> /etc/sysconfig/network-scripts/ifcfg-eth0
echo $proto >> /etc/sysconfig/network-scripts/ifcfg-eth0
echo $ip >> /etc/sysconfig/network-scripts/ifcfg-eth0
echo $mask >> /etc/sysconfig/network-scripts/ifcfg-eth0
echo $gate >> /etc/sysconfig/network-scripts/ifcfg-eth0

#	重新啟動網路介面,若有錯誤時在螢幕上顯示
service network restart > /dev/null

#	假設本身 DNS 服務不啟動,使用中華電信 DNS server
echo nameserver=168.95.1.1 > /etc/resolv.conf
}}}

{{{
echo $((10+3))
echo $((10-3))
echo $((10*3))
echo $((10/3))
echo $((10%3))
}}}
!Brad 名言
#No news is a good news.
#Everything is a file.
#英文不好不是我的錯
#less is more.
**譯:less 指令就是 more (less 指令比較多)