This site offers the 226 "programmed reading exercises" found in part two of Franklin Huffman's 1970 textbook, //Cambodian System of Writing and Beginning Reader.// Huffman placed the text into the public domain five years after publication by Yale University Press (which still publishes a paperback version) and we are grateful for his allowing its dissemination.\n\nStart with the [[Introduction|I Intro]] and [[Phonological Summary|II Phonological Summary]]. The first [[exercise|Exercise 1]] follows those two sections. \n\nEach exercise links to the next exercise as well as back to the preceding one. The answer can be displayed or hidden by clicking on the //Answer// button in the exercise. \n\nThe menus at the top provide access to any specific exercise.\n\nInformation about downloading the content in PDF form is [[here|PDF]]. While the site is under construction, the PDF will probably contain more exercises than this online version.\n\n----\n\nIn order to properly view this site, you need to install a Unicode font containing the Khmer characters. The fonts from [[KhmerOS|]] work very well and were used to build this site. You also require a Unicode font that contains the IPA phonetic symbols used here. Microsoft Office and some other Microsoft software comes with Arial Unicode MS, which works fine, as should the shareware font [[Code2000|]]; many Unicode fonts can be located at [[Alan Wood's Unicode Resources|]] page.\n\nOn Windows computers, a recent version of usp10.dll must be installed (any version after Office 2003 installs this as a matter of course). Information on this can be found at [[KhmerOS|]]; the dll file itself can be downloaded from the [[Khmer Culture Center in Switzerland|]] site. The Khmer unicode installation program will copy usp10.dll to the System folder so that all programs can access it.\n\nIn the Firefox browser, you can easily identify separate fonts for the different Unicode page codes -- select the //Options// command in the //Tools// menu; click on the //Content// tab, where the bottom section deals with fonts; clicking on the //Advanced// button takes you to a //Fonts// dialog. There you use the popup menu to choose one set of fonts for //Western// scripts (your choice), another for //Khmer// (eg, ~KhmerOS Freehand or ~KhmerOS), and a third for //Other Languages// (Arial Unicode MS or some alternative, such as Lucida Sans Unicode). I also set the size of the Khmer font a couple points larger than the Western font to make these unfamiliar characters more readable.\n\nHow this works in IE, Safari or Opera, I will have to investigate and add to this explanation.\n\n----\n\nThis site was built using [[TiddlyWiki|]], a "microcontent ~WikiWikiWeb," created by Jeremy Ruston, specifically using the [[MonkeyPirateTW|]] variation from Simon Baird. It is hosted free at [[tiddlyspot|]], to whom much appreciation is due. \n\nA ~TiddlyWiki consists of a single html file. Visitors cannot edit or alter the web version of this site, but can download it to their local drive, using the [[download|]] link in the sidebar. Guidance on how to add to and alter a ~TiddlyWiki can be found at [[TiddlyWikiGuides|]].\n\n----\n\nA scanned version of Huffman's text in PDF form can be downloaded from [[|]]. That is the complete version; this is just the second of the four parts -- the other parts consist of //Cambodian System of Writing, Beginning Reader// and //~Cambodian-English glossary.// Huffman's text notes that it was created with the assistance of ~Chhom-Rak Thong Lambert and Im Proum. \n\nRoger Sperberg entered the text and put it into wiki format here; he also inserted pronunciation notes from part one of Huffman's text, and some alternative pronunciations provided by David Smyth in his language course, //Colloquial Cambodian//, and in the //Tuttle Practical Cambodian Dictionary,// edied by Smyth and Tran Kien.
config.options.chkHttpReadOnly = false;\n
\n''A:'' 18\n\n//Editor’s note:// Smyth allows for four additional consonant sounds — g, j, a “sharp p sound midway between b and p,” and a “sharp t sound midway between d and t.” Scanning Huffman’s [[Phonological Summary|II Phonological Summary]] reveals that the consonant sounds v and z are unrepresented.\n\n
\n''A:'' គា \n kiə\n
\n''A:'' ខា khaa, ឃា khiə, ងា ŋiə
\n''A:'' ចា caa, ជា cie [Smyth: jee-a]
\n''A:'' ចា caa, ឆា chaa, ជា cie, ឈា chie, ញា ñie
\n''A:'' កី kəy, គី kii [Smyth: កី gay (to rhyme with English //pay//), គី gee]
\n''A:'' \n| kɑɑ | khɑɑ | kɔɔ | khɔɔ | ŋɔɔ | cɑɑ | chɑɑ | cɔɔ | chɔɔ | ñɔɔ |\n| kaa | khaa | kiə | khiə | ŋiə | caa | chaa | ciə | chiə | ñiə |\n| kəy | khəy | kii | khii | ŋii | cəy | chəy | cii | chii | ñii |\n\n//Editor’s note:// As a reminder for how these sounds are transcribed and pronunced, here are Huffman’s descriptions, as well as a couple notes from Smyth: \n/ɑɑ/ “backer than the English ‘a’ in father but fronter than the English ‘aw’ in law”\n/ɔɔ/ “a lower-mid, back, semi-rounded vowel, with lax and breathy articulation, that occurs only long”\n/aa/ “a tense lower-mid, front-of-center vowel similar to the ‘a’ in French va and fronter and higher than the English ‘a’ in father.”\n/iə/ “a falling diphthong, moving from a high front to a mid central position”; Smyth uses ‘ee-a’ to transcribe this sound.\n/əy/ “/ə/ is a mid, central, unrounded short vowel, slightly higher than ‘u’ in Standard American English but” while “/y/ is a voiced palatal semi-vowel, pronounced like the English ‘y’ in you, but more tense”; Smyth transcribes this vowel as ‘ay’ as in English pay.\n/ii/ “a long, high, front unrounded vowel like the English ‘ee’ in cheek.”\n/c/ “a voiceless, unaspirated palatal stop, pronounced like the ‘ch’ in cheese, but without the aspiration, when it is in the initial position”; Smyth gives ‘j’ as the pronunciation for ច and ជ when followed by a vowel instead.\n/k/ Smyth gives ‘g’ as the pronunciation for ក and គ when either precedes a vowel.\n/ŋ/ “a voiced velar nasal pronounced like ‘ng’ in sing.”\n/ñ/ “a voiced palatal nasal, like the ‘ny’ in canyon.”\n
\n''A:''\n| ក | ខ | គ | ឃ | ង | ច | ឆ | ជ | ឈ | ញ |\n| កា | ខា | គា | ឃា | ងា | ចា | ឆា | ជា | ឈា | ញា |\n| កី | ខី | គី | ឃី | ងី | ចី | ឆី | ជី | ឈី | ញី|\n
\n''A:'' 2 -- one for each series.
\n''A:'' ក \n k&#x0251;&#x0251; <html><object type="application/x-shockwave-flash" data="" width="17" height="17"> <param name="movie" value="" /> <img src="noflash.gif" width="17" height="17" alt="" /></object></html>
\n''A.'' គ \nkɔɔ <html><object type="application/x-shockwave-flash" data="" width="17" height="17"> <param name="movie" value="" /> <img src="noflash.gif" width="17" height="17" alt="" /></object></html>\n
\n''A:'' ខ \nkhɑɑ <html><object type="application/x-shockwave-flash" data="" width="17" height="17"> <param name="movie" value="" /> <img src="noflash.gif" width="17" height="17" alt="" /></object></html>\n
\n''A:'' ឃ \nkhɔɔ <html><object type="application/x-shockwave-flash" data="" width="17" height="17"> <param name="movie" value="" /> <img src="noflash.gif" width="17" height="17" alt="" /></object></html>\n
\n''A:'' ង \nŋɔɔ <html><object type="application/x-shockwave-flash" data="" width="17" height="17"> <param name="movie" value="" /> <img src="noflash.gif" width="17" height="17" alt="" /></object></html>\n
\n''A:'' ក ខ គ ឃ ង\nkɑɑ khɑɑ kɔɔ khɔɔ ŋɔɔ <html><object type="application/x-shockwave-flash" data="" width="17" height="17"> <param name="movie" value="" /> <img src="noflash.gif" width="17" height="17" alt="" /></object></html>\n
\n''A:'' កា \n kaa\n
/***\n| Name:|CloseOnCancelPlugin|\n| Description:|Closes the tiddler if you click new tiddler then cancel. Default behaviour is to leave it open|\n| Version:|6.9.3|\n| Date:|30-Sep-2006|\n| Source:||\n| Author:|Simon Baird <>|\n| CoreVersion:|2.1.x|\n***/\n//{{{\nmerge(config.commands.cancelTiddler,{\n\n handler_orig_closeUnsaved: config.commands.cancelTiddler.handler,\n\n handler: function(event,src,title) {\n this.handler_orig_closeUnsaved(event,src,title);\n if (!store.tiddlerExists(title) && !store.isShadowTiddler(title))\n story.closeTiddler(title,true);\n return false;\n }\n\n});\n\n//}}}\n\n
Background: #fff\nForeground: #000\nPrimaryPale: #8cf\nPrimaryLight: #6bf\nPrimaryMid: #04b\nPrimaryDark: #014\nSecondaryPale: #ffc\nSecondaryLight: #fe8\nSecondaryMid: #db4\nSecondaryDark: #841\nTertiaryPale: #eee\nTertiaryLight: #ccc\nTertiaryMid: #999\nTertiaryDark: #666\nError: #f88\n
//{{{\nconfig.options.chkHttpReadOnly = false; // means web visitors can experiment with your site by clicking edit\nconfig.views.wikified.defaultText = ""; // don't need message when a tiddler doesn't exist\nconfig.views.editor.defaultText = ""; // don't need message when creating a new tiddler \n//}}}\n
[[Title page]]
There are 33 consonant symbols in the Cambodian writing system. How many different consonant sounds are there in the Cambodian language? (Refer to the [[Phonological Summary|II Phonological Summary]] to count them.)\n\n<<slider ans1slider [[Answer 1]] answer "Display answer to exercise 1">>\n\n<<tiddler NextTiddlerWithFocus with: [[II Phonological Summary]] "Return to Phonological Summary">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 2]] "Go to next exercise">>
The second series value of ា is /iə/. គ + ា is written គា. Write, transcribe and pronounce it.\n\n//Editor’s note:// Part One indicates that /iə/ is pronounced as in the Khmer word /biə/ (បៀ, //playing cards//). It is a falling diphthong, moving from a high front to a mid central position. \n\n//Editor’s note:// Smyth //(Colloquial Cambodian)// transcribes this as ‘ee-a’.\n\n<<slider ans910slider [[Answer 10]] answer "Display/hide answer to exercise 10">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 9]] "Back to exercise 9">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 11]] "Next exercise">>
Write, transcribe, and pronounce the following syllables: ខា ឃា ងា \n\n<<slider ans11slider [[Answer 11]] answer "Display/hide answer to exercise 11">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 10]] "Back to exercise 10">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 12]] "Next exercise">>
ច is the 1st series consonant symbol for /c/. Its 2nd series counterpoint is ជ. Write, transcribe and pronounce the syllables ចា and ជា.\n\n//Editor’s note:// Part One indicates that /c/ is a voiceless, unaspirated palatal stop, pronounced like the //ch// in //cheese//, but without the aspiration, when it is in the initial position. (In the final position, it represents an unreleased closure made with the blade of the tongue against the front part of the hard palate.)\n\nSmyth //(Colloquial Cambodian)// gives //j// as the pronunciation for ច and ជ when followed by a vowel.\n\n<<slider ans12slider [[Answer 12]] answer "Display/hide answer to exercise 12">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 11]] "Back to exercise 11">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 13]] "Next exercise">>
The second group of consonant symbols in the Cambodian alphabet are the //Palatals//. They are: ច /cɑɑ/, ឆ /chɑɑ/, ជ /cɔɔ/, ឈ /chɔɔ/, ញ /ñɔɔ/. Write, transcribe and pronounce each of them in combination with the vowel symbol ា.\n\n//Editor's note:// Part One describes ñ as a voiced palatal nasal, like the //ny// in //canyon// but which can occur both initially and finally in Cambodian.\n\n<<slider ans13slider [[Answer 13]] answer "Display/hide answer to exercise 13">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 12]] "Back to exercise 12">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 14]] "Next exercise">>
The vowel symbol ‌‌ ី is called /sraq qəy/. Its 1st series value is /əy/ and its 2nd series value is /ii/. \n\n//Editor’s note:// In Part One, Huffman indicates that /y/ is a voiced palatal semi-vowel, pronounced like the English //y// in //you//, but more tense.\n\nPart One further indicates that /ə/ is pronounced as in the Khmer word /bət/ (បិទ, //to close//). It is a mid, central, unrounded short vowel, slightly higher than //u// in Standard American English //but//.\n\nPart One pronounces /ii/ as in the Khmer word /ciik/ (ជក, to dig). It is a long, high, front unrounded vowel like the English //ee// in //cheek//.\n\nWrite, transcribe and pronounce the syllables កី and គី.\n\n<<slider ans14slider [[Answer 14]] answer "Display/hide answer to exercise 14">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 13]] "Back to exercise 13">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 15]] "Next exercise">>
You should now be able to read 30 different Cambodian syllables, as follows:\n\n| ក | ខ | គ | ឃ | ង | ច | ឆ | ជ | ឈ | ញ |\n| កា | ខា | គា | ឃា | ងា | ចា | ឆា | ជា | ឈា | ញា |\n| កី | ខី | គី | ឃី | ងី | ចី | ឆី | ជី | ឈី | ញី|\n\n<<slider ans15slider [[Answer 15]] answer "Display/hide answer to exercise 15">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 14]] "Back to exercise 14">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 16]] "Next exercise">>\n
Now take the 30 syllables you have just transcribed and write as many of them as you can using the Cambodian symbols. Refer to the symbols in exercise 15 only for those symbols you are unable to remember.\n\n<<slider ans16slider [[Answer 16]] answer "Display/hide answer to exercise 16">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 15]] "Back to exercise 15">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 17]] "Next exercise">>\n
Thus there are about twice as many consonant symbols as are needed to represent the consonant sounds of the language. In fact, there are two ways to represent every consonant sound, so that there are actually two series of consonant symbols in the Cambodian writing system. The pronunciation of a vowel symbol is determined by the series to which the preceding consonant symbol belongs. \n\nEvery vowel symbol then has how many values or pronunciations?\n\n<<slider ans2slider [[Answer 2]] answer "Display answer to exercise 2">>\n\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 1]] "Back to exercise 1">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 3]] "Next exercise">>
When a consonant symbol is written alone, with no accompanying vowel symbol, it is pronounced with an “inherent” vowel. The inherent vowel with which 1st series consonant symbols are pronounced is /ɑɑ/. The first letter of the Cambodian alphabet is ក. It is a 1st series consonant which represents the sound /k/.\n\n//Editor’s note:// Part One indicates that /ɑɑ/ is pronounced as in the Khmer word /kɑɑ/ (ក, //neck//). It is a low, central, unrounded vowel, backer than the English //a// in father but fronter than the English //aw// in //law//.\n\n//Editor’s note:// Smyth //(Colloquial Cambodian)// gives //g// as the pronunciation for ក when it precedes a vowel.\n\nWrite, transcribe and pronounce the symbol ក with its inherent vowel.\n\n<<slider ans3slider [[Answer 3]] answer "Display/hide answer to exercise 3">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 2]] "Back to exercise 2">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 4]] "Next exercise">>\n
When a 2nd series consonant symbol is written with no accompanying vowel symbol, it is pronounced with the “inherent” vowel /ɔɔ/. The 2nd series consonant symbol representing /k/ is គ. \n\n//Editor’s note:// Part One indicates that /ɔɔ/ is pronounced as in the Khmer word /rɔɔk/ (រក, //to seek//). It is a lower-mid, back, semi-rounded vowel, with lax and breathy articulation. It occurs only long.\n\n//Editor’s note:// Smyth //(Colloquial Cambodian)// gives //g// as the pronunciation for គ when it precedes a vowel.\n\nWrite, transcribe, and pronounce គ.\n\n<<slider ans4slider [[Answer 4]] answer "Display/hide answer to exercise 4">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 3]] "Back to exercise 3">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 5]] "Next exercise">>\n
The initial consonant sequences /kh-, ch-, th- ph-/ are represented by unit symbols, although phonologically they are clusters. The 1st series symbol for the cluster /kh-/ is ខ. \n\nWrite, transcribe and pronounce it.\n\n<<slider ans5slider [[Answer 5]] answer "Display/hide answer to exercise 5">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 4]] "Back to exercise 4">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 6]] "Next exercise">>
The second series symbol for /kh-/ is ឃ. Write, transcribe and pronounce it.\n\n<<slider ans6slider [[Answer 6]] answer "Display/hide answer to exercise 6">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 5]] "Back to exercise 5">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 7]] "Next exercise">>\n
All nasal symbols (except ណ /n/), when unmodified, are pronounced with the 2nd series inherent vowel, and are classed as 2nd series consonant symbols. (The conversion of nasal symbols to 1st series will be discussed later.) The symbol for the velar nasal /ŋ/ is ង. \n\n//Editor’s note:// Part One indicates that /ŋ/ is a voiced Velar nasal. It is pronounced like //ng// in //sing//, but occurs both initially and finally in Cambodian. After the vowels /ii, ei, ee, ae/ it is intermediate between /ŋ/ and /ñ/; the two never contrast in that position.\n\nWrite, transcribe and pronounce ង.\n\n<<slider ans7slider [[Answer 7]] answer "Display/hide answer to exercise 7">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 6]] "Back to exercise 6">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 8]] "Next exercise">>
You have now been introduced to the first five letters of the Cambodian alphabet. They are ក ខ គ ឃ ង. The Cambodian alphabet is divided into five groups, based on position of articulation, proceeding from the back to the front of the mouth, and one residual group usually labeled miscellaneous. The letters in the group above are all //Velars//. Within each articulatory group, the order of letters is as follows:\n\n|1st series unaspirated consonant symbol| (ក) |\n|1st series aspirated consonant symbol| (ខ) |\n|2nd series unaspirated consonant symbol| (គ) |\n|2nd series aspirated consonant symbol| (ឃ) |\n|2nd series homogranic nasal| (ង) |\n\nWrite, transcribe and pronounce the Velar series above.\n\n<<slider ans8slider [[Answer 8]] answer "Display/hide answer to exercise 8">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 7]] "Back to exercise 7">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 9]] "Next exercise">>
Every vowel symbol (with the exception of three, which will be discussed later) has two pronunciations, depending on the series of the initial consonant. In spelling a word aloud, however, Cambodians usually refer to vowel symbols by their 1st series values, regardless of the series of the preceding consonant. The vowel symbol ា is called /sraq qaa/ “the vowel qaa”. Its 1st series value is /aa/. ក + ា is written as កា. \n\n//Editor’s note:// Part One indicates that /q/ is a voiceless unaspirated glottal stop. It is pronounced in the initial position like the closure at the beginning of the word //Oh!// when pronounced explosively. (As the final character, it’s pronounced like the closure which occurs at the end of the first //Oh!// in the exclamation //Oh, oh — he’s done it again!//)\n\nPart One further indicates that /aa/ is pronounced as in the Khmer word /kaa/ (កា, work). It is a tense lower-mid, front-of-center vowel similar to the //a// in French //va//. (Huffman adds that this vowel is fronter and higher than the English //a// in //father//; to pronounce it as such would confuse it with the vowel /ɑɑ/ to the ear of a Cambodian.)\n\nWrite, transcribe and pronounce កា.\n\n<<slider ans9slider [[Answer 9]] answer "Display/hide answer to exercise 9">>\n\n<<tiddler NextTiddlerWithFocus with: [[Exercise 8]] "Back to exercise 8">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 10]] "Next exercise">>
''A:'' ក \n k&#x0251;&#x0251;\n
/***\n| Name:|HideWhenPlugin|\n| Description:|Allows conditional inclusion/exclusion in templates|\n| Version:|6.9.3|\n| Date:|30-Sep-2006|\n| Source:||\n| Author:|Simon Baird <>|\nFor use in ViewTemplate and EditTemplate. Eg\n{{{<div macro="showWhen tiddler.tags.contains('Task')">[[TaskToolbar]]</div>}}}\n{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}\n***/\n//{{{\nmerge(config.macros,{\n\n hideWhen: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n if (eval(paramString)) {\n removeChildren(place);\n place.parentNode.removeChild(place);\n }\n }},\n\n showWhen: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n config.macros.hideWhen.handler(place,macroName,params,wikifier,'!('+paramString+')',tiddler);\n }}\n\n});\n\n//}}}\n\n
Part One of this book presents a formal analysis of the relationship between sound and symbol in modern Cambodian. The purpose of this section is to provide the student with a step-by-step introduction to reading and writing Cambodian words. Each exercise introduces a small amount of new material. The exercises are cumulative, building on and reinforcing points that have already been introduced. The student should go back and review the exercises dealing with any point in the review exercise with which he has difficulty.\n\nSince the primary aim of this section, and indeed, of the entire book, is to develop facility in reading, the great majority of the exercises involve a symbol-to-sound operation. However, some of the exercises involve a sound-to-symbol operation (much less predictable in the Cambodian), since it is felt that the most effective way to help the student recognize the sometimes minute differences between symbols is to have him draw them himself.\n\nAs in Part One, it is assumed that the student is familiar with the transcription system used in the author’s Spoken Cambodian, of which a summary is presented for convenience below.\n\nHowever, if the student is unfamiliar with the sound system of spoken Cambodian, or if he intends to use this section without the aid of a native speaker, he should read carefully the chapter on phonology in Part One. To use this section effectively, the student should follow these directions:\n\n#Cover the answer to each exercise (marked A.) with a blank sheet of paper.\n#Write the answer called for on the paper, and pronounce it aloud.\n#Check your answer against the correct answer, which follows each exercise.\n#If you have made a mistake, practice the exercise until you can do it correctly from memory.\n\n<<tiddler NextTiddlerWithFocus with: [[II Phonological Summary]] "Next -- Phonological Summary">>\n
\n|>|>|>|>|>|bgcolor(LightSkyBlue): ''Consonants'' |\n| | ''Labial'' | ''Dental'' | ''Palatal'' | ''Velar'' | ''Glottal'' |\n|''Stops''| | | | | |\n|''-Voiceless''| -p | -t | -c | -k | -q |\n|''-Voiced''| b | d | | | |\n|''Spirants''| | | | | |\n|''-Voiceless''| (f) | s | | | -b |\n|''Continuants''| | | | | |\n|''-Nasal''| -m | -n | -ñ | -ŋ | |\n|''-Semivocalic''| -w | | -y | | |\n|''-Lateral''| | -l | | | |\n|''-Trilled''| | r | | | |\n\n|>|>|>|>|>|>|>|>|>|>|bgcolor(LightSkyBlue): ''Vowels'' |\n|>|>| ''Long Vowels'' |>|>| ''Long Diphthongs'' |>|>| ''Short Vowels'' |>| ''Short Diphthongs'' |\n| ii | ɨɨ | uu | iə | ɨə | uə | i | ɨ | u | | u˘ə |\n| ee | əə | oo | ei | əɨ | ou | e | e | o | e˘ə | o˘ə |\n| ɛɛ | aa | ɔɔ | ae | aə | ao | | a | | | |\n| | ɑɑ | | | ɔə | | | ɑ | | | |\n|>|>| (10) |>|>| (10) |>|>| (8) |>| (3) |\n\n<<tiddler NextTiddlerWithFocus with: [[I Intro]] "Back to Introduction">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 1]] "Go to exercise 1">>
/***\n|''Name:''|InlineJavascriptPlugin|\n|''Source:''||\n|''Author:''|Eric Shulman - ELS Design Studios|\n|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|]]|\n|''~CoreVersion:''|2.0.10|\n\nInsert Javascript executable code directly into your tiddler content. Lets you ''call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.\n!!!!!Usage\n<<<\nWhen installed, this plugin adds new wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be treated as embedded javascript and executed each time the tiddler is rendered.\n\n''Deferred execution from an 'onClick' link''\nBy including a label="..." parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered.\n\n''External script source files:''\nYou can also load javascript from an external source URL, by including a src="..." parameter in the initial {{{<script>}}} marker (e.g., {{{<script src="demo.js"></script>}}}). This is particularly useful when incorporating third-party javascript libraries for use in custom extensions and plugins. The 'foreign' javascript code remains isolated in a separate file that can be easily replaced whenever an updated library file becomes available.\n\n''Display script source in tiddler output''\nBy including the keyword parameter "show", in the initial {{{<script>}}} marker, the plugin will include the script source code in the output that it displays in the tiddler.\n\n''Defining javascript functions and libraries:''\nAlthough the external javascript file is loaded while the tiddler content is being rendered, any functions it defines will not be available for use until //after// the rendering has been completed. Thus, you cannot load a library and //immediately// use it's functions within the same tiddler. However, once that tiddler has been loaded, the library functions can be freely used in any tiddler (even the one in which it was initially loaded).\n\nTo ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that will be rendered as soon as your TiddlyWiki document is opened. For example, you could put your {{{<script src="..."></script>}}} syntax into a tiddler called LoadScripts, and then add {{{<<tiddler LoadScripts>>}}} in your MainMenu tiddler.\n\nSince the MainMenu is always rendered immediately upon opening your document, the library will always be loaded before any other tiddlers that rely upon the functions it defines. Loading an external javascript library does not produce any direct output in the tiddler, so these definitions should have no impact on the appearance of your MainMenu.\n\n''Creating dynamic tiddler content''\nAn important difference between this implementation of embedded scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document:\n* In a typical web document, you use the document.write() function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.\n* However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and completely replaces the entire ~TiddlyWiki document in your browser window.\n* To allow these scripts to work unmodified, the plugin automatically converts all occurences of document.write() so that the output is inserted into the tiddler content instead of replacing the entire ~TiddlyWiki document.\n\nIf your script does not use document.write() to create dynamically embedded content within a tiddler, your javascript can, as an alternative, explicitly return a text value that the plugin can then pass through the wikify() rendering engine to insert into the tiddler display. For example, using {{{return "thistext"}}} will produce the same output as {{{document.write("thistext")}}}.\n\n//Note: your script code is automatically 'wrapped' inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler. To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.//\n\n''Accessing the ~TiddlyWiki DOM''\nThe plugin provides one pre-defined variable, 'place', that is passed in to your javascript code so that it can have direct access to the containing DOM element into which the tiddler output is currently being rendered.\n\nAccess to this DOM element allows you to create scripts that can:\n* vary their actions based upon the specific location in which they are embedded\n* access 'tiddler-relative' information (use findContainingTiddler(place))\n* perform direct DOM manipulations (when returning wikified text is not enough)\n<<<\n!!!!!Examples\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''InlineJavascriptPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2006.06.01 [1.5.1]'' when calling wikify() on script return value, pass hightlightRegExp and tiddler params so macros that rely on these values can render properly\n''2006.04.19 [1.5.0]'' added 'show' parameter to force display of javascript source code in tiddler output\n''2006.01.05 [1.4.0]'' added support 'onclick' scripts. When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked. 'place' value is set to match the clicked button/link element.\n''2005.12.13 [1.3.1]'' when catching eval error in IE, e.description contains the error text, instead of e.toString(). Fixed error reporting so IE shows the correct response text. Based on a suggestion by UdoBorkowski\n''2005.11.09 [1.3.0]'' for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content. Based on a suggestion by BradleyMeck\n''2005.11.08 [1.2.0]'' handle loading of javascript from an external URL via src="..." syntax\n''2005.11.08 [1.1.0]'' pass 'place' param into scripts to provide direct DOM access \n''2005.11.08 [1.0.0]'' initial release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/]]\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.inlineJavascript= {major: 1, minor: 5, revision: 1, date: new Date(2006,6,1)};\n\nconfig.formatters.push( {\n name: "inlineJavascript",\n match: "\s\s<script",\n lookahead: "\s\s<script(?: src=\s\s\s"((?:.|\s\sn)*?)\s\s\s")?(?: label=\s\s\s"((?:.|\s\sn)*?)\s\s\s")?( show)?\s\s>((?:.|\s\sn)*?)\s\s</script\s\s>",\n\n handler: function(w) {\n var lookaheadRegExp = new RegExp(this.lookahead,"mg");\n lookaheadRegExp.lastIndex = w.matchStart;\n var lookaheadMatch = lookaheadRegExp.exec(w.source)\n if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n if (lookaheadMatch[1]) { // load a script library\n // make script tag, set src, add to body to execute, then remove for cleanup\n var script = document.createElement("script"); script.src = lookaheadMatch[1];\n document.body.appendChild(script); document.body.removeChild(script);\n }\n if (lookaheadMatch[4]) { // there is script code\n if (lookaheadMatch[3]) // show inline script code in tiddler output\n wikify("{{{\sn"+lookaheadMatch[0]+"\sn}}}\sn",w.output);\n if (lookaheadMatch[2]) { // create a link to an 'onclick' script\n // add a link, define click handler, save code in link (pass 'place'), set link attributes\n var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",lookaheadMatch[2]);\n link.onclick=function(){try{return(eval(this.code))}catch(e){alert(e.description?e.description:e.toString())}}\n link.code="function _out(place){"+lookaheadMatch[4]+"};_out(this);"\n link.setAttribute("href","javascript:;"); link.setAttribute("title","");"pointer";\n }\n else { // run inline script code\n var code="function _out(place){"+lookaheadMatch[4]+"};_out(w.output);"\n code=code.replace(/document.write\s(/gi,'place.innerHTML+=(');\n try { var out = eval(code); } catch(e) { out = e.description?e.description:e.toString(); }\n if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);\n }\n }\n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n }\n }\n} )\n//}}}\n
\n/***\n|Name|KeepAndNextTiddler macro|\n|Created by|Eric Shulman|\n|Location|Google Groups "step-wise presentation mode desired" message 5 |\n!!!Description:\nKeep the current tiddler open, close all others, and open a new tiddler.\nsyntax is: tiddler KeepAndNextTiddler NewTiddlerTitle "linktext"\n\n!!!Code\n***/\n\n//{{{\n/%\ninsert link that closes other tiddlers and then opens another one\nsyntax is: <<tiddler KeepAndNextTiddler NewTiddlerTitle "linktext">>\n%/\n<script label="$2">\n var tiddler=story.findContainingTiddler(place);\n story.closeAllTiddlers(;\n story.displayTiddler(tiddler,"$1");\n</script>\n//}}}
/***\n|''Name:''|LegacyStrikeThroughPlugin|\n|''Description:''|Support for legacy (pre 2.1) strike through formatting|\n|''Version:''|1.0.1|\n|''Date:''|Jul 21, 2006|\n|''Source:''||\n|''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|\n|''License:''|[[BSD open source license]]|\n|''CoreVersion:''|2.1.0|\n|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|\n\n***/\n\n//{{{\n\n// Ensure that the LegacyStrikeThrough Plugin is only installed once.\nif(!version.extensions.LegacyStrikeThroughPlugin)\n {\n version.extensions.LegacyStrikeThroughPlugin = true;\n\nconfig.formatters.push(\n{\n name: "legacyStrikeByChar",\n match: "==",\n termRegExp: /(==)/mg,\n element: "strike",\n handler: config.formatterHelpers.createElementAndWikify\n});\n\n} // end of "install only once"\n//}}}\n
<<tag Intro|intro>> <<tag 1-25>> [[Download PDF|PDF]]
<!--{{{-->\n<div class="toolbar" macro="toolbar +saveTiddler closeOthers cancelTiddler deleteTiddler"></div>\n<div class="title" macro="view title"></div>\n<div class="editLabel">Title</div><div class="editor" macro="edit title"></div>\n<div class="editLabel">Tags</div><div class="editor" macro="edit tags"></div>\n<div class="editorFooter"><span macro="message views.editor.tagPrompt"></span><span macro="tagChooser"></span></div>\n<div class="editor" macro="edit text"></div>\n<!--}}}-->\n
/***\n| Name:|MptwLayoutPlugin|\n| Description:|A package containing templates and css for the MonkeyPirateTiddlyWiki layout|\n| Version:|6.1.1|\n| Date:|01-Oct-2006|\n| Source:||\n| Author:|Simon Baird <>|\n| CoreVersion:|2.1.x|\n!Notes\nPresumes you have TagglyTaggingPlugin installed.\n***/\n//{{{\nconfig.shadowTiddlers.GettingStarted += "\sn\snSee also MonkeyPirateTiddlyWiki.";\n//}}}\n\n//{{{\nmerge(config.shadowTiddlers,{\n\nMonkeyPirateTiddlyWiki:[\n "[[MonkeyPirateTiddlyWiki|]] is a distribution of [[TiddlyWiki|]] created by Simon Baird. See [[the web site|]] for more information.",\n "!!Upgrading ~MonkeyPirateTiddlyWiki",\n "This \s"empty\s" ~MonkeyPirateTiddlyWiki file comes pre-installed with the core ~MonkeyPirateTiddlyWiki plugins. You can upgrade these core plugins to the latest version by doing the following:",\n "# Click ImportTiddlers",\n "# Click \s"Choose...\s" and select \s"~MptwUpgradeURL\s"",\n "# Click \s"fetch\s"",\n "# Click the checkbox in the first column heading to select all tiddlers",\n "# Click \s"More actions...\s" and select \s"Import these tiddlers\s"",\n "# Click \s"OK\s" to confirm you want to overwrite the tiddlers",\n ""\n].join("\sn"),\n\nMptwStyleSheet:[\n "/*{{{*/",\n "/* a contrasting background so I can see where one tiddler ends and the other begins */",\n "body {",\n " background: [[ColorPalette::TertiaryLight]];",\n "}",\n "",\n "/* sexy colours and font for the header */",\n ".headerForeground {",\n " color: [[ColorPalette::PrimaryLight]];",\n "}",\n ".headerShadow {",\n " color: [[ColorPalette::PrimaryMid]];",\n "}",\n ".headerForeground, .headerShadow {",\n " padding: 1em 1em 0;",\n " font-family: 'Trebuchet MS' sans-serif;",\n " font-weight:bold;",\n "}",\n "",\n "/* make shadow go and down right instead of up and left */",\n ".headerShadow {",\n " left: 1px;",\n " top: 1px;",\n "}",\n "",\n "/* prefer monospace for editing */",\n ".editor textarea {",\n " font-family: 'Consolas' monospace;",\n "}",\n "",\n "/* sexy tiddler titles */",\n ".title {",\n " font-size: 250%;",\n " color: [[ColorPalette::PrimaryLight]];",\n " font-family: 'Trebuchet MS' sans-serif;",\n "}",\n "",\n "/* more subtle tiddler subtitle */",\n ".subtitle {",\n " padding:0px;",\n " margin:0px;",\n " padding-left:0.5em;",\n " font-size: 90%;",\n " color: [[ColorPalette::TertiaryMid]];",\n "}",\n ".subtitle .tiddlyLink {",\n " color: [[ColorPalette::TertiaryMid]];",\n "}",\n "",\n "/* a little bit of extra whitespace */",\n ".viewer {",\n " padding-bottom:3px;",\n "}",\n "",\n "/* don't want any background color for headings */",\n "h1,h2,h3,h4,h5,h6 {",\n " background: [[ColorPalette::Background]];",\n " color: [[ColorPalette::Foreground]];",\n "}",\n "",\n "/* give tiddlers 3d style border and explicit background */",\n ".tiddler {",\n " background: [[ColorPalette::Background]];",\n " border-right: 2px [[ColorPalette::TertiaryMid]] solid;",\n " border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;",\n " margin-bottom: 1em;",\n " padding-bottom: 2em;",\n "}",\n "",\n "/* make options slider look nicer */",\n "#sidebarOptions .sliderPanel {",\n " border:solid 1px [[ColorPalette::PrimaryLight]];",\n "}",\n "",\n "",\n "/* the borders look wrong with the body background */",\n "#sidebar .button {",\n " border-style: none;",\n "}",\n "",\n "/* displays the list of a tiddler's tags horizontally. used in ViewTemplate */",\n ".tagglyTagged li.listTitle {",\n " display:none",\n "}",\n ".tagglyTagged li {",\n " display: inline; font-size:90%;",\n "}",\n ".tagglyTagged ul {",\n " margin:0px; padding:0px;",\n "}",\n "",\n "/* horizontal main menu stuff */",\n "#displayArea {",\n " margin: 1em 15.7em 0em 1em; /* use the freed up space */",\n "}",\n "#topMenu br {",\n " display: none;",\n "}",\n "#topMenu {",\n " background: [[ColorPalette::PrimaryMid]];",\n " color:[[ColorPalette::PrimaryPale]];",\n "}",\n "#topMenu {",\n " padding:2px;",\n "}",\n "#topMenu .button, #topMenu .tiddlyLink, #topMenu a {",\n " margin-left: 0.5em;",\n " margin-right: 0.5em;",\n " padding-left: 3px;",\n " padding-right: 3px;",\n " color: [[ColorPalette::PrimaryPale]];",\n " font-size: 115%;",\n "}",\n "#topMenu .button:hover, #topMenu .tiddlyLink:hover {",\n " background: [[ColorPalette::PrimaryDark]];",\n "}",\n "@media print {",\n " #topMenu {",\n " display: none ! important;",\n " }",\n "}",\n "/*}}}*/",\n ""\n].join("\sn"),\n\nMptwViewTemplate:[\n "<!--{{{-->",\n "<div class='toolbar'>",\n " <!-- some custom contextual checkboxes -->",\n " <span style=\s"padding-right:2em;\s" macro=\s"showWhen tiddler.tags.contains('systemConfig')\s">",\n " <span macro=\s"toggleTag systemConfigDisable . '[[disable|systemConfigDisable]]'\s"></span>",\n " <!-- <span macro=\s"toggleTag systemConfigForce . '[[force|systemConfigForce]]'\s"></span> -->",\n " </span>",\n " <!-- regular toolbar -->",\n " <span macro='toolbar closeTiddler closeOthers +editTiddler deleteTiddler undoChanges permalink references jump newHere newJournalHere'></span>",\n "</div>",\n "<!-- regular tags macro but uses taggly css -->",\n "<div class=\s"tagglyTagged\s" macro=\s"tags\s"></div>",\n "<div>",\n " <span class='title' macro='view title'></span>",\n " <span macro=\s"miniTag\s"></span>",\n "</div>",\n "<div class='subtitle'>",\n " <span macro='view modifier link'></span>,",\n " <span macro='view modified date [[DD-mmm-YY]]'></span>",\n " (<span macro='message views.wikified.createdPrompt'></span>",\n " <span macro='view created date [[DD-mmm-YY]]'></span>)",\n "</div>",\n "<!-- using taggly versions of these two",\n "<div class='tagging' macro='tagging'></div>",\n "<div class='tagged' macro='tags'></div> -->",\n "<div macro=\s"hideWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')\s">",\n " <div class='viewer' macro='view text wikified'></div>",\n "</div>",\n "<div macro=\s"showWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')\s">",\n " <div class='viewer'><pre macro='view text'></pre></div>",\n "</div>",\n "<div class=\s"tagglyTagging\s" macro=\s"tagglyTagging\s"></div>",\n "<div class='tagClear'></div>",\n "<!--}}}-->",\n ""\n].join("\sn"),\n\nMptwPageTemplate:[\n "<!--{{{-->",\n "<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>",\n " <div class='headerShadow'>",\n " <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;",\n " <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>",\n " </div>",\n " <div class='headerForeground'>",\n " <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;",\n " <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>",\n " </div>",\n "</div>",\n "<!-- horizontal MainMenu -->",\n "<div id='topMenu' refresh='content' tiddler='MainMenu'></div>",\n "<!-- original MainMenu menu -->",\n "<!-- <div id='mainMenu' refresh='content' tiddler='MainMenu'></div> -->",\n "<div id='sidebar'>",\n " <div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>",\n " <div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>",\n "</div>",\n "<div id='displayArea'>",\n " <div id='messageArea'></div>",\n " <div id='tiddlerDisplay'></div>",\n "</div>",\n "<!--}}}-->",\n ""\n].join("\sn"),\n\nMptwEditTemplate:[\n "<!--{{{-->",\n "<div class=\s"toolbar\s" macro=\s"toolbar +saveTiddler closeOthers cancelTiddler deleteTiddler\s"></div>",\n "<div class=\s"title\s" macro=\s"view title\s"></div>",\n "<div class=\s"editLabel\s">Title</div><div class=\s"editor\s" macro=\s"edit title\s"></div>",\n "<div class=\s"editLabel\s">Tags</div><div class=\s"editor\s" macro=\s"edit tags\s"></div>",\n "<div class=\s"editorFooter\s"><span macro=\s"message views.editor.tagPrompt\s"></span><span macro=\s"tagChooser\s"></span></div>",\n "<div class=\s"editor\s" macro=\s"edit text\s"></div>",\n "<!--}}}-->",\n ""\n].join("\sn")\n\n});\n//}}}\n
/*{{{*/\n/* a contrasting background so I can see where one tiddler ends and the other begins */\nbody {\n background: [[ColorPalette::TertiaryLight]];\n}\n\n/* sexy colors and font for the header */\n.headerForeground {\n color: [[ColorPalette::PrimaryLight]];\n}\n.headerShadow {\n color: [[ColorPalette::PrimaryMid]];\n}\n.headerForeground, .headerShadow {\n padding: 1em 1em 0;\n font-family: 'Trebuchet MS' sans-serif;\n font-weight:bold;\n}\n\n/* make shadow go and down right instead of up and left */\n.headerShadow {\n left: 1px;\n top: 1px;\n}\n\n.editor {\nfont-size: 1.1em;\n}\n\n/* prefer monospace for editing -- deactivated */\n/*.editor textarea { font-family: 'Consolas' monospace; } */\n\n/* sexy tiddler titles */\n.title {\n font-size: 150%;\n color: [[ColorPalette::PrimaryLight]];\n font-family: 'Trebuchet MS' sans-serif;\n}\n\n/* more subtle tiddler subtitle */\n.subtitle {\n padding:0px;\n margin:0px;\n padding-left:0.5em;\n font-size: 90%;\n color: [[ColorPalette::TertiaryMid]];\n}\n.subtitle .tiddlyLink {\n color: [[ColorPalette::TertiaryMid]];\n}\n\n/* a little bit of extra whitespace */\n.viewer {\n padding-bottom:3px;\n}\n\n/* don't want any background color for headings */\nh1,h2,h3,h4,h5,h6 {\n background: [[ColorPalette::Background]];\n color: [[ColorPalette::Foreground]];\n}\n\n/* give tiddlers 3d style border and explicit background */\n.tiddler {\n background: [[ColorPalette::Background]];\n border-right: 2px [[ColorPalette::TertiaryMid]] solid;\n border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;\n margin-bottom: 1em;\n padding-bottom: 2em;\n}\n\n/* make options slider look nicer */\n#sidebarOptions .sliderPanel {\n border:solid 1px [[ColorPalette::PrimaryLight]];\n}\n\n\n/* the borders look wrong with the body background */\n#sidebar .button {\n border-style: none;\n}\n\n/* displays the list of a tiddler's tags horizontally. used in ViewTemplate */\n.tagglyTagged li.listTitle {\n display:none\n}\n.tagglyTagged li {\n display: inline; font-size:90%;\n}\n.tagglyTagged ul {\n margin:0px; padding:0px;\n}\n\n/* horizontal main menu stuff */\n#displayArea {\n margin: 1em 15.7em 0em 1em; /* use the freed up space */\n}\n#topMenu br {\n display: none;\n}\n#topMenu {\n background: [[ColorPalette::PrimaryMid]];\n color:[[ColorPalette::PrimaryPale]];\n}\n#topMenu {\n padding:2px;\n}\n#topMenu .button, #topMenu .tiddlyLink, #topMenu a {\n margin-left: 0.5em;\n margin-right: 0.5em;\n padding-left: 3px;\n padding-right: 3px;\n color: [[ColorPalette::PrimaryPale]];\n font-size: 115%;\n}\n#topMenu .button:hover, #topMenu .tiddlyLink:hover {\n background: [[ColorPalette::PrimaryDark]];\n}\n@media print {\n #topMenu {\n display: none ! important;\n }\n}\n/*}}}*/\n
<!--{{{-->\n<div class='toolbar'>\n <!-- some custom contextual checkboxes -->\n <span style="padding-right:2em;" macro="showWhen tiddler.tags.contains('systemConfig')">\n <span macro="toggleTag systemConfigDisable . '[[disable|systemConfigDisable]]'"></span>\n <!-- <span macro="toggleTag systemConfigForce . '[[force|systemConfigForce]]'"></span> -->\n </span>\n <!-- regular toolbar -->\n <span macro='toolbar toggleView focusHere closeTiddler closeOthers +editTiddler deleteTiddler undoChanges permalink references jump'></span>\n</div>\n<!-- regular tags macro but uses taggly css -->\n<!--\n<div class="tagglyTagged" macro="tags"></div>\n-->\n<div>\n <span class='title' macro='view title'></span>\n<!--\n <span macro="miniTag"></span>\n-->\n</div>\n<div class="collapse">\n<!-- \n<div class='subtitle'>\n <span macro='view modifier link'></span>,\n <span macro='view modified date [[DD-mmm-YY]]'></span>\n (<span macro='message views.wikified.createdPrompt'></span>\n <span macro='view created date [[DD-mmm-YY]]'></span>)\n</div>\n-->\n<!-- using taggly versions of these two\n\n<div class='tagging' macro='tagging'></div>\n<div class='tagged' macro='tags'></div>\n -->\n<div macro="hideWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">\n <div class='viewer' macro='view text wikified'></div>\n</div>\n<div macro="showWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">\n <div class='viewer'><pre macro='view text'></pre></span>\n\n</div>\n</div>\n<div class="tagglyTagging" macro="tagglyTagging"></div>\n<div class='tagClear'></div>\n</div>\n<!--}}}-->\n
/***\n| Name:|NewCollapseTiddlersPlugin|\n| Created by:|BJ Backitis|\n| Location:||\n| Version:|0.6 (17 Aug 2006)|\n| Requires:|~TW2.x|\n!Description\nThis is a different way of doing the collapse and expand functions of the CollapseTiddlerPlugin, which does not do any switching around of templates. Instead, you modify any view templates you are using to identify which parts of the template you do NOT want displayed when the tiddler is "collapsed", and the display style property takes care of the rest.\n!Usage\n* In the toolbar of your view templates include the following commands:\n** toggleView (collapses and expands that one tiddler)\n** focusHere (expands this tiddler and collapses all other tiddlers)\n* In the body of the view template, surround any sections to be removed when the tiddler is collapsed by the following:\n{{{<div class="collapse"> ..... </div>}}}\nSee ViewTemplate for example.\n* In the main menu or Sidebar Options menus (or where ever you like) include the following macros:\n** {{{<<collapseAll>>}}} (collapses all tiddlers)\n** {{{<<expandAll>>}}} (expands all tiddlers)\n!Revision History\n* v0.5 -- BJ Backitis, 16 Aug 2006 (Original)\n* v0.6 -- BJ Backitis, 17 Aug 2006\n** applied suggestion from Eric Shulmann to handle nesting issue\n** tidied up conditional code in toggleView (another suggestion from Eric)\n!To Do\n* ==Be able to handle <div> and <span> nested within other <div> or <span> elements== (done! Thanks, Eric)\n\n!Code\n***/\n//{{{\nconfig.commands.toggleView = {\n text: "toggle",\n tooltip: "Collapse/Expand this tiddler",\n handler: function(event,src,title){\n var nodes = story.findContainingTiddler(src).getElementsByTagName("*"); \n for(var t=0; t<nodes.length; t++)\n if(nodes[t].className == "collapse")\n nodes[t].style.display=(nodes[t].style.display=="none")?"block":"none";\n }\n} \n\nconfig.commands.focusHere = {\n text: "focus",\n tooltip: "Expand this tiddler and collapse all others",\n handler: function(event,src,title){\n var e = story.findContainingTiddler(src);\n var nodes = story.findContainingTiddler(src).getElementsByTagName("*"); \n for(var t=0; t<nodes.length; t++)\n if(nodes[t].className == "collapse")\n nodes[t].style.display = "block"\n story.forEachTiddler(function(title,tiddler){\n if (tiddler!=e) {\n var nodes = tiddler.getElementsByTagName("*");\n for(var t=0; t<nodes.length; t++)\n if(nodes[t].className == "collapse")\n nodes[t].style.display = "none"\n }\n })\n }\n}\n\nconfig.macros.collapseAll = {\n handler: function(place,macroName,params,wikifier,paramString,tiddler){\n createTiddlyButton(place,"collapse all","Collapse all displayed tiddlers",function(){\n story.forEachTiddler(function(title,tiddler){\n var nodes = tiddler.getElementsByTagName("*"); \n for(var t=0; t<nodes.length; t++)\n if(nodes[t].className == "collapse")\n nodes[t].style.display = "none"\n })\n })\n }\n}\n\nconfig.macros.expandAll = {\n handler: function(place,macroName,params,wikifier,paramString,tiddler){\n createTiddlyButton(place,"expand all","Expand all collapsed tiddlers",function(){\n story.forEachTiddler(function(title,tiddler){\n var nodes = tiddler.getElementsByTagName("*"); \n for(var t=0; t<nodes.length; t++)\n if(nodes[t].className == "collapse")\n nodes[t].style.display = "block"\n })\n })\n }\n}\n\n\n//}}}\n\n
/***\n| Name:|NewHerePlugin|\n| Description:|Creates the new here and new journal toolbar commands|\n| Version:|6.9.3|\n| Date:|30-Sep-2006|\n| Source:||\n| Author:|Simon Baird <>|\n| CoreVersion:|2.1.x|\nTo use edit your ViewTemplate and add newHere to the toolbar div, eg\n{{{<div class='toolbar' macro='toolbar ... newHere'></div>}}}\nNote: would be good if we could do this instead some day\n{{{<<newTiddler tag:{{tiddler.title}} label:'new here'>>}}}\n***/\n//{{{\nmerge(config.commands,{\n\n newHere: {\n text: 'new here',\n tooltip: 'Create a new tiddler tagged as this tiddler',\n hideReadOnly: true,\n handler: function(e,src,title) {\n if (!readOnly) {\n clearMessage();\n var t=document.getElementById('tiddler'+title);\n story.displayTiddler(t,config.macros.newTiddler.title,DEFAULT_EDIT_TEMPLATE);\n story.setTiddlerTag(config.macros.newTiddler.title, title, 0);\n story.focusTiddler(config.macros.newTiddler.title,"title"); // doesn't work??\n return false;\n }\n }\n },\n\n newJournalHere: {\n //text: 'new journal here', // too long\n text: 'new journal',\n hideReadOnly: true,\n dataFormat: 'YYYY-0MM-0DD 0hh:0mm', // adjust to your preference\n tooltip: 'Create a new journal tiddler tagged as this tiddler',\n handler: function(e,src,title) {\n if (!readOnly) {\n clearMessage();\n var now = new Date();\n var t=document.getElementById('tiddler'+title);\n var newtitle = now.formatString(this.dataFormat)\n story.displayTiddler(t,newtitle,DEFAULT_EDIT_TEMPLATE);\n story.setTiddlerTag(newtitle, title, 0);\n story.focusTiddler(newtitle,"title");\n return false;\n }\n }\n }\n\n});\n//}}}\n
/%\nusage: <<tiddler NextTiddler with: NewTiddlerTitle linktext>> insert a link that, when clicked, closes the current tiddler and opens another one in its place\n%/\n<script label="$2">\n var tiddler=story.findContainingTiddler(place);\n story.displayTiddler(tiddler,"$1");\n story.closeTiddler(; // close self\n return false;\n</script>
/%\nusage: <<tiddler NextTiddlerWithFocus with: NewTiddlerTitle linktext>>\ninsert a link that, when clicked, collapses the current tiddler and opens another one in its place\n\n%/<script label="$2">\n story.displayTiddler(null,"$1");\n var tid=document.getElementById(story.idPrefix + "$1");\n config.commands.focusHere.handler(null,tid);\n return false;\n</script>
This site is under construction. That is to say, I'm learning the content and entering it as I go. The material is entered in a local file before being transferred to this site. You can view or download a (probably more complete) PDF version of what's been entered so far [[here|]].\n\nThe most recent PDF includes exercises 1-28 (of the total 226 exercises) and was posted on November 30, 2006.
/***\n| Name:|QuickOpenTagPlugin|\n| Description:|Changes tag links to make it easier to open tags as tiddlers|\n| Version:|6.1.1|\n| Date:|01-Oct-2006|\n| Source:||\n| Author:|Simon Baird <>|\n| CoreVersion:|2.1.x|\n***/\n//{{{\nconfig.quickOpenTag = {\n\n dropdownChar: (document.all ? "\su25bc" : "\su25be"), // the little one doesn't work in IE\n\n createTagButton: function(place,tag,excludeTiddler) {\n // little hack so we can to <<tag PrettyTagName|RealTagName>>\n var splitTag = tag.split("|");\n var pretty = tag;\n if (splitTag.length == 2) {\n tag = splitTag[1];\n pretty = splitTag[0];\n }\n \n var sp = createTiddlyElement(place,"span",null,"quickopentag");\n createTiddlyText(createTiddlyLink(sp,tag,false),pretty);\n \n var theTag = createTiddlyButton(sp,config.quickOpenTag.dropdownChar,\n config.views.wikified.tag.tooltip.format([tag]),onClickTag);\n theTag.setAttribute("tag",tag);\n if (excludeTiddler)\n theTag.setAttribute("tiddler",excludeTiddler);\n return(theTag);\n },\n\n miniTagHandler: function(place,macroName,params,wikifier,paramString,tiddler) {\n var tagged = store.getTaggedTiddlers(tiddler.title);\n if (tagged.length > 0) {\n var theTag = createTiddlyButton(place,config.quickOpenTag.dropdownChar,\n config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);\n theTag.setAttribute("tag",tiddler.title);\n theTag.className = "miniTag";\n }\n },\n\n allTagsHandler: function(place,macroName,params) {\n var tags = store.getTags();\n var theDateList = createTiddlyElement(place,"ul");\n if(tags.length == 0)\n createTiddlyElement(theDateList,"li",null,"listTitle",this.noTags);\n for (var t=0; t<tags.length; t++) {\n var theListItem = createTiddlyElement(theDateList,"li");\n var theLink = createTiddlyLink(theListItem,tags[t][0],true);\n var theCount = " (" + tags[t][1] + ")";\n theLink.appendChild(document.createTextNode(theCount));\n var theDropDownBtn = createTiddlyButton(theListItem," " +\n config.quickOpenTag.dropdownChar,this.tooltip.format([tags[t][0]]),onClickTag);\n theDropDownBtn.setAttribute("tag",tags[t][0]);\n }\n },\n\n // todo fix these up a bit\n styles: \n"/*{{{*/\sn"+\n"/* created by QuickOpenTagPlugin */\sn"+\n".tagglyTagged .quickopentag, .tagged .quickopentag \sn"+\n" { margin-right:1.2em; border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }\sn"+\n".quickopentag .tiddlyLink { padding:2px; padding-left:3px; }\sn"+\n".quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px;}\sn"+\n"/* extra specificity to make it work right */\sn"+\n"#displayArea .viewer .quickopentag a.button, \sn"+\n"#displayArea .viewer .quickopentag a.tiddyLink, \sn"+\n"#mainMenu .quickopentag a.tiddyLink, \sn"+\n"#mainMenu .quickopentag a.tiddyLink \sn"+\n" { border:0px solid black; }\sn"+\n"#displayArea .viewer .quickopentag a.button, \sn"+\n"#mainMenu .quickopentag a.button \sn"+\n" { margin-left:0px; padding-left:2px; }\sn"+\n"#displayArea .viewer .quickopentag a.tiddlyLink, \sn"+\n"#mainMenu .quickopentag a.tiddlyLink \sn"+\n" { margin-right:0px; padding-right:0px; padding-left:0px; margin-left:0px; }\sn"+\n"a.miniTag {font-size:150%;} \sn"+\n"#mainMenu .quickopentag a.button \sn"+\n" /* looks better in right justified main menus */\sn"+\n" { margin-left:0px; padding-left:2px; margin-right:0px; padding-right:0px; }\sn" + \n"#topMenu .quickopentag { padding:0px; margin:0px; border:0px; }\sn" +\n"#topMenu .quickopentag .tiddlyLink { padding-right:1px; margin-right:0px; }\sn" +\n"#topMenu .quickopentag .button { padding-left:1px; margin-left:0px; border:0px; }\sn" +\n"/*}}}*/\sn"+\n "",\n\n init: function() {\n // we fully replace these builtins. can't hijack them easily\n window.createTagButton = this.createTagButton;\n config.macros.allTags.handler = this.allTagsHandler;\n config.macros.miniTag = { handler: this.miniTagHandler };\n config.shadowTiddlers["QuickOpenTagStyles"] = this.styles;\n if (store)\n store.addNotification("QuickOpenTagStyles",refreshStyles);\n else\n config.notifyTiddlers.push({name:"QuickOpenTagStyles", notify: refreshStyles});\n }\n\n}\n\nconfig.quickOpenTag.init();\n\n//}}}\n
/***\n| Name:|RenameTagsPlugin|\n| Description:|Allows you to easily rename or delete tags across multiple tiddlers|\n| Version:|6.9.3|\n| Date:|30-Sep-2006|\n| Source:||\n| Author:|Simon Baird <>|\n| CoreVersion:|2.1.x|\nRename a tag and you will be prompted to rename it in all its tagged tiddlers.\n***/\n//{{{\nconfig.renameTags = {\n\n prompts: {\n rename: "Rename the tag '%0' to '%1' in %2 tidder%3?",\n remove: "Remove the tag '%0' from %1 tidder%2?"\n },\n\n removeTag: function(tag,tiddlers) {\n for (var i=0;i<tiddlers.length;i++) {\n store.setTiddlerTag(tiddlers[i].title,false,tag);\n }\n },\n\n renameTag: function(oldTag,newTag,tiddlers) {\n for (var i=0;i<tiddlers.length;i++) {\n store.setTiddlerTag(tiddlers[i].title,false,oldTag); // remove old\n store.setTiddlerTag(tiddlers[i].title,true,newTag); // add new\n }\n },\n\n storeMethods: {\n\n saveTiddler_orig_renameTags: TiddlyWiki.prototype.saveTiddler,\n\n saveTiddler: function(title,newTitle,newBody,modifier,modified,tags,fields) {\n if (title != newTitle) {\n var tagged = this.getTaggedTiddlers(title);\n if (tagged.length > 0) {\n // then we are renaming a tag\n if (confirm(config.renameTags.prompts.rename.format([title,newTitle,tagged.length,tagged.length>1?"s":""])))\n config.renameTags.renameTag(title,newTitle,tagged);\n\n if (!this.tiddlerExists(title) && newBody == "")\n // dont create unwanted tiddler\n return null;\n }\n }\n return this.saveTiddler_orig_renameTags(title,newTitle,newBody,modifier,modified,tags,fields);\n },\n\n removeTiddler_orig_renameTags: TiddlyWiki.prototype.removeTiddler,\n\n removeTiddler: function(title) {\n var tagged = this.getTaggedTiddlers(title);\n if (tagged.length > 0)\n if (confirm(config.renameTags.prompts.remove.format([title,tagged.length,tagged.length>1?"s":""])))\n config.renameTags.removeTag(title,tagged);\n return this.removeTiddler_orig_renameTags(title);\n }\n\n },\n\n init: function() {\n merge(TiddlyWiki.prototype,this.storeMethods);\n }\n}\n\nconfig.renameTags.init();\n\n//}}}\n\n
<<search>><<collapseAll>><<expandAll>><<closeAll>><<permaview>><<newTiddler>><<saveChanges>><<upload index.html . . cambodian>><html><a href='' class='button'>download</a></html><<slider chkSliderOptionsPanel OptionsPanel 'options »' 'Change TiddlyWiki advanced options'>>
Part II of Huffman's //Cambodian System of Writing// online
Cambodian Language Exercises
/***\n\n''Inspired by [[TiddlyPom|]]''\n\n|Name|SplashScreenPlugin|\n|Created by|SaqImtiaz|\n|Location||\n|Version|0.21 |\n|Requires|~TW2.08+|\n!Description:\nProvides a simple splash screen that is visible while the TW is loading.\n\n!Installation\nCopy 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.\n\n!Customizing\nOnce 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.\n\n!History\n* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.\n* 26-06-06 : version 0.2, first release\n\n!Code\n***/\n//{{{\nvar old_lewcid_splash_restart=restart;\n\nrestart = function()\n{ if (document.getElementById("SplashScreen"))\n document.getElementById("SplashScreen").style.display = "none";\n if (document.getElementById("contentWrapper"))\n document.getElementById("contentWrapper").style.display = "block";\n \n old_lewcid_splash_restart();\n \n if (splashScreenInstall)\n {if(config.options.chkAutoSave)\n {saveChanges();}\n displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");\n }\n}\n\n\nvar oldText = store.getTiddlerText("MarkupPreHead");\nif (oldText.indexOf("SplashScreen")==-1)\n {var siteTitle = store.getTiddlerText("SiteTitle");\n var splasher='\sn\sn<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>';\n if (! store.tiddlerExists("MarkupPreHead"))\n {var myTiddler = store.createTiddler("MarkupPreHead");}\n else\n {var myTiddler = store.getTiddler("MarkupPreHead");}\n myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);\n store.setDirty(true);\n var splashScreenInstall = true;\n}\n//}}}
/*{{{*/\n* html .tiddler {\n height: 1%;\n}\n\nbody {\n font-size: .9em;\n font-family: "KhmerOS Freehand",arial,helvetica;\n margin: 0;\n padding: 0;\n}\n\nh1,h2,h3,h4,h5 {\n font-weight: bold;\n text-decoration: none;\n padding-left: 0.4em;\n}\n\nh1 {font-size: 1.35em;}\nh2 {font-size: 1.25em;}\nh3 {font-size: 1.1em;}\nh4 {font-size: 1em;}\nh5 {font-size: .9em;}\n\nhr {\n height: 1px;\n}\n\na{\n text-decoration: none;\n}\n\ndt {font-weight: bold;}\n\nol { list-style-type: decimal }\nol ol { list-style-type: lower-alpha }\nol ol ol { list-style-type: lower-roman }\nol ol ol ol { list-style-type: decimal }\nol ol ol ol ol { list-style-type: lower-alpha }\nol ol ol ol ol ol { list-style-type: lower-roman }\nol ol ol ol ol ol ol { list-style-type: decimal }\n\n.txtOptionInput {\n width: 11em;\n}\n\n#contentWrapper .chkOptionInput {\n border: 0;\n}\n\n.externalLink {\n text-decoration: underline;\n}\n\n.indent {margin-left:3em;}\n.outdent {margin-left:3em; text-indent:-3em;}\ncode.escaped {white-space:nowrap;}\n\n.tiddlyLinkExisting {\n font-weight: bold;\n}\n\n.tiddlyLinkNonExisting {\n font-style: italic;\n}\n\n/* the 'a' is required for IE, otherwise it renders the whole tiddler a bold */\na.tiddlyLinkNonExisting.shadow {\n font-weight: bold;\n}\n\n#mainMenu .tiddlyLinkExisting, \n#mainMenu .tiddlyLinkNonExisting,\n#sidebarTabs .tiddlyLinkNonExisting{\n font-weight: normal;\n font-style: normal;\n}\n\n#sidebarTabs .tiddlyLinkExisting {\n font-weight: bold;\n font-style: normal;\n}\n\n.header {\n position: relative;\n}\n\n.header a:hover {\n background: transparent;\n}\n\n.headerShadow {\n position: relative;\n padding: 4.5em 0em 1em 1em;\n left: -1px;\n top: -1px;\n}\n\n.headerForeground {\n position: absolute;\n padding: 4.5em 0em 1em 1em;\n left: 0px;\n top: 0px;\n}\n\n.siteTitle {\n font-size: 2.35em;\n}\n\n.siteSubtitle {\n font-size: 1.15em;\n}\n\n#mainMenu {\n position: absolute;\n left: 0;\n width: 10em;\n text-align: right;\n line-height: 1.6em;\n padding: 1.5em 0.5em 0.5em 0.5em;\n font-size: 1.1em;\n}\n\n#sidebar {\n position: absolute;\n right: 3px;\n width: 16em;\n font-size: .9em;\n}\n\n#sidebarOptions {\n padding-top: 0.3em;\n}\n\n#sidebarOptions a {\n margin: 0em 0.2em;\n padding: 0.2em 0.3em;\n display: block;\n}\n\n#sidebarOptions input {\n margin: 0.4em 0.5em;\n}\n\n#sidebarOptions .sliderPanel {\n margin-left: 1em;\n padding: 0.5em;\n font-size: .85em;\n}\n\n#sidebarOptions .sliderPanel a {\n font-weight: bold;\n display: inline;\n padding: 0;\n}\n\n#sidebarOptions .sliderPanel input {\n margin: 0 0 .3em 0;\n}\n\n#sidebarTabs .tabContents {\n width: 15em;\n overflow: hidden;\n}\n\n.wizard {\n padding: 0.1em 0em 0em 2em;\n}\n\n.wizard h1 {\n font-size: 2em;\n font-weight: bold;\n background: none;\n padding: 0em 0em 0em 0em;\n margin: 0.4em 0em 0.2em 0em;\n}\n\n.wizard h2 {\n font-size: 1.2em;\n font-weight: bold;\n background: none;\n padding: 0em 0em 0em 0em;\n margin: 0.2em 0em 0.2em 0em;\n}\n\n.wizardStep {\n padding: 1em 1em 1em 1em;\n}\n\n.wizard .button {\n margin: 0.5em 0em 0em 0em;\n font-size: 1.2em;\n}\n\n#messageArea {\nposition:absolute; top:0; right:0; margin: 0.5em; padding: 0.5em;\n}\n\n*[id='messageArea'] {\nposition:fixed !important; z-index:99;}\n\n.messageToolbar {\ndisplay: block;\ntext-align: right;\n}\n\n#messageArea a{\n text-decoration: underline;\n}\n\n.popup {\n font-size: .9em;\n padding: 0.2em;\n list-style: none;\n margin: 0;\n}\n\n.popup hr {\n display: block;\n height: 1px;\n width: auto;\n padding: 0;\n margin: 0.2em 0em;\n}\n\n.popup li.disabled {\n padding: 0.2em;\n}\n\n.popup li a{\n display: block;\n padding: 0.2em;\n}\n\n.tabset {\n padding: 1em 0em 0em 0.5em;\n}\n\ {\n margin: 0em 0em 0em 0.25em;\n padding: 2px;\n}\n\n.tabContents {\n padding: 0.5em;\n}\n\n.tabContents ul, .tabContents ol {\n margin: 0;\n padding: 0;\n}\n\n.txtMainTab .tabContents li {\n list-style: none;\n}\n\n.tabContents li.listLink {\n margin-left: .75em;\n}\n\n#displayArea {\n margin: 1em 17em 0em 14em;\n}\n\n\n.toolbar {\n text-align: right;\n font-size: .9em;\n visibility: hidden;\n}\n\n.selected .toolbar {\n visibility: visible;\n}\n\n.tiddler {\n padding: 1em 1em 0em 1em;\n}\n\n.missing .viewer,.missing .title {\n font-style: italic;\n}\n\n.title {\n font-size: 1.6em;\n font-weight: bold;\n}\n\n.missing .subtitle {\n display: none;\n}\n\n.subtitle {\n font-size: 1.1em;\n}\n\n.tiddler .button {\n padding: 0.2em 0.4em;\n}\n\n.tagging {\nmargin: 0.5em 0.5em 0.5em 0;\nfloat: left;\ndisplay: none;\n}\n\n.isTag .tagging {\ndisplay: block;\n}\n\n.tagged {\nmargin: 0.5em;\nfloat: right;\n}\n\n.tagging, .tagged {\nfont-size: 0.9em;\npadding: 0.25em;\n}\n\n.tagging ul, .tagged ul {\nlist-style: none;margin: 0.25em;\npadding: 0;\n}\n\n.tagClear {\nclear: both;\n}\n\n.footer {\n font-size: .9em;\n}\n\n.footer li {\ndisplay: inline;\n}\n\n* html .viewer pre {\n width: 99%;\n padding: 0 0 1em 0;\n}\n\n.viewer {\n line-height: 1.4em;\n padding-top: 0.5em;\n}\n\n.viewer .button {\n margin: 0em 0.25em;\n padding: 0em 0.25em;\n}\n\n.viewer blockquote {\n line-height: 1.5em;\n padding-left: 0.8em;\n margin-left: 2.5em;\n}\n\n.viewer ul, .viewer ol{\n margin-left: 0.5em;\n padding-left: 1.5em;\n}\n\n.viewer table {\n border-collapse: collapse;\n margin: 0.8em 1.0em;\n}\n\n.viewer th, .viewer td, .viewer tr,.viewer caption{\n padding: 3px;\n}\n\n.viewer table.listView {\n font-size: 0.85em;\n margin: 0.8em 1.0em;\n}\n\n.viewer table.listView th, .viewer table.listView td, .viewer table.listView tr {\n padding: 0px 3px 0px 3px;\n}\n\n.viewer pre {\n padding: 0.5em;\n margin-left: 0.5em;\n font-size: 1.2em;\n line-height: 1.4em;\n overflow: auto;\n}\n\n.viewer code {\n font-size: 1.2em;\n line-height: 1.4em;\n}\n\n.editor {\nfont-size: 1.1em;\n}\n\n.editor input, .editor textarea {\n display: block;\n width: 100%;\n font: inherit;\n}\n\n.editorFooter {\n padding: 0.25em 0em;\n font-size: .9em;\n}\n\n.editorFooter .button {\npadding-top: 0px; padding-bottom: 0px;}\n\n.fieldsetFix {border: 0;\npadding: 0;\nmargin: 1px 0px 1px 0px;\n}\n\n.sparkline {\n line-height: 1em;\n}\n\n.sparktick {\n outline: 0;\n}\n\n.zoomer {\n font-size: 1.1em;\n position: absolute;\n padding: 1em;\n}\n\n.cascade {\n font-size: 1.1em;\n position: absolute;\n overflow: hidden;\n}\n.viewer table.listView {\n font-size: 0.85em; margin: 0.8em 1.0em;\n}\n\n.viewer table.listView th, .viewer table.listView td, .viewer table.listView tr {\n padding: 0px 3px 0px 3px;\n\n}\n\n.wizard {\n background: [[ColorPalette::SecondaryLight]];\n padding: 0.1em 0em 0em 2em;\n border-top: 1px solid [[ColorPalette::SecondaryMid]];\n border-left: 1px solid [[ColorPalette::SecondaryMid]];\n}\n\n.wizard h1 {\n font-size: 2em; font-weight: bold;\n background: none;\n color: [[ColorPalette::SecondaryDark]];\n padding: 0em 0em 0em 0em;\n margin: 0.4em 0em 0.2em 0em;\n}\n\n.wizard h2 {\n font-size: 1.2em; font-weight: bold;\n background: none;\n color: [[ColorPalette::Foreground]];\n padding: 0em 0em 0em 0em;\n margin: 0.2em 0em 0.2em 0em;\n}\n\n.wizardStep {\n background: [[ColorPalette::Background]]; padding: 1em 1em 1em 1em;\n border-top: 1px solid [[ColorPalette::SecondaryMid]];\n border-bottom: 1px solid [[ColorPalette::SecondaryMid]];\n border-left: 1px solid [[ColorPalette::SecondaryMid]];\n}\n\n.wizard .button {\n text-align: right;\n}\n/*}}}*/
<<timeline modified 20>>
/***\n| Name:|TagglyTaggingPlugin|\n| Description:|tagglyTagging macro is a replacement for the builtin tagging macro in your ViewTemplate|\n| Version:|6.9.3|\n| Date:|30-Sep-2006|\n| Source:||\n| Author:|Simon Baird <>|\n| CoreVersion:|2.1.x|\n!Notes\nSee\n***/\n//{{{\nconfig.taggly = {\n\n // for translations\n lingo: {\n labels: {\n asc: "\su2191", // down arrow\n desc: "\su2193", // up arrow\n title: "title",\n modified: "modified",\n created: "created",\n show: "+",\n hide: "-",\n normal: "normal",\n group: "group",\n commas: "commas",\n sitemap: "sitemap",\n numCols: "cols\su00b1", // plus minus sign\n label: "Tagged as %0:"\n },\n\n tooltips: {\n title: "Click to sort by title",\n modified: "Click to sort by modified date",\n created: "Click to sort by created date",\n show: "Click to show tagging list",\n hide: "Click to hide tagging list",\n normal: "Click to show a normal ungrouped list",\n group: "Click to show list grouped by tag",\n sitemap: "Click to show a sitemap style list",\n commas: "Click to show a comma separated list",\n numCols: "Click to change number of columns"\n }\n },\n\n config: {\n showTaggingCounts: true,\n listOpts: {\n // the first one will be the default\n sortBy: ["title","modified","created"],\n sortOrder: ["asc","desc"],\n hideState: ["show","hide"],\n listMode: ["normal","group","sitemap","commas"],\n numCols: ["1","2","3","4","5","6"]\n },\n valuePrefix: "taggly."\n },\n\n getTagglyOpt: function(title,opt) {\n var val = store.getValue(title,this.config.valuePrefix+opt);\n return val ? val : this.config.listOpts[opt][0];\n },\n\n setTagglyOpt: function(title,opt,value) {\n if (!store.tiddlerExists(title))\n // create it silently\n store.saveTiddler(title,title,config.views.editor.defaultText.format([title]),config.options.txtUserName,new Date(),null);\n // if value is default then remove it to save space\n return store.setValue(title,\n this.config.valuePrefix+opt,\n value == this.config.listOpts[opt][0] ? null : value);\n },\n\n getNextValue: function(title,opt) {\n var current = this.getTagglyOpt(title,opt);\n var pos = this.config.listOpts[opt].indexOf(current);\n // a little usability enhancement. actually it doesn't work right for grouped or sitemap\n var limit = (opt == "numCols" ? store.getTaggedTiddlers(title).length : this.config.listOpts[opt].length);\n var newPos = (pos + 1) % limit;\n return this.config.listOpts[opt][newPos];\n },\n\n toggleTagglyOpt: function(title,opt) {\n var newVal = this.getNextValue(title,opt);\n this.setTagglyOpt(title,opt,newVal);\n }, \n\n createListControl: function(place,title,type) {\n var lingo = config.taggly.lingo;\n var label;\n var tooltip;\n var onclick;\n\n if ((type == "title" || type == "modified" || type == "created")) {\n // "special" controls. a little tricky. derived from sortOrder and sortBy\n label = lingo.labels[type];\n tooltip = lingo.tooltips[type];\n\n if (this.getTagglyOpt(title,"sortBy") == type) {\n label += lingo.labels[this.getTagglyOpt(title,"sortOrder")];\n onclick = function() {\n config.taggly.toggleTagglyOpt(title,"sortOrder");\n return false;\n }\n }\n else {\n onclick = function() {\n config.taggly.setTagglyOpt(title,"sortBy",type);\n config.taggly.setTagglyOpt(title,"sortOrder",config.taggly.config.listOpts.sortOrder[0]);\n return false;\n }\n }\n }\n else {\n // "regular" controls, nice and simple\n label = lingo.labels[type == "numCols" ? type : this.getNextValue(title,type)];\n tooltip = lingo.tooltips[type == "numCols" ? type : this.getNextValue(title,type)];\n onclick = function() {\n config.taggly.toggleTagglyOpt(title,type);\n return false;\n }\n }\n\n // hide button because commas don't have columns\n if (!(this.getTagglyOpt(title,"listMode") == "commas" && type == "numCols"))\n createTiddlyButton(place,label,tooltip,onclick,type == "hideState" ? "hidebutton" : "button");\n },\n\n makeColumns: function(orig,numCols) {\n var listSize = orig.length;\n var colSize = listSize/numCols;\n var remainder = listSize % numCols;\n\n var upperColsize = colSize;\n var lowerColsize = colSize;\n\n if (colSize != Math.floor(colSize)) {\n // it's not an exact fit so..\n upperColsize = Math.floor(colSize) + 1;\n lowerColsize = Math.floor(colSize);\n }\n\n var output = [];\n var c = 0;\n for (var j=0;j<numCols;j++) {\n var singleCol = [];\n var thisSize = j < remainder ? upperColsize : lowerColsize;\n for (var i=0;i<thisSize;i++) \n singleCol.push(orig[c++]);\n output.push(singleCol);\n }\n\n return output;\n },\n\n drawTable: function(place,columns,theClass) {\n var newTable = createTiddlyElement(place,"table",null,theClass);\n var newTbody = createTiddlyElement(newTable,"tbody");\n var newTr = createTiddlyElement(newTbody,"tr");\n for (var j=0;j<columns.length;j++) {\n var colOutput = "";\n for (var i=0;i<columns[j].length;i++) \n colOutput += columns[j][i];\n var newTd = createTiddlyElement(newTr,"td",null,"tagglyTagging"); // todo should not need this class\n wikify(colOutput,newTd);\n }\n return newTable;\n },\n\n createTagglyList: function(place,title) {\n switch(this.getTagglyOpt(title,"listMode")) {\n case "group": return this.createTagglyListGrouped(place,title); break;\n case "normal": return this.createTagglyListNormal(place,title,false); break;\n case "commas": return this.createTagglyListNormal(place,title,true); break;\n case "sitemap":return this.createTagglyListSiteMap(place,title); break;\n }\n },\n\n getTaggingCount: function(title) {\n // thanks to Doug Edmunds\n if (this.config.showTaggingCounts) {\n var tagCount = store.getTaggedTiddlers(title).length;\n if (tagCount > 0)\n return " ("+tagCount+")";\n }\n return "";\n },\n\n // this is for normal and commas mode\n createTagglyListNormal: function(place,title,useCommas) {\n\n var list = store.getTaggedTiddlers(title,this.getTagglyOpt(title,"sortBy"));\n\n if (this.getTagglyOpt(title,"sortOrder") == "desc")\n list = list.reverse();\n\n var output = [];\n for (var i=0;i<list.length;i++) {\n var countString = this.getTaggingCount(list[i].title);\n if (useCommas)\n output.push((i > 0 ? ", " : "") + "[[" + list[i].title + "]]" + countString);\n else\n output.push("*[[" + list[i].title + "]]" + countString + "\sn");\n }\n\n return this.drawTable(place,\n this.makeColumns(output,useCommas ? 1 : parseInt(this.getTagglyOpt(title,"numCols"))),\n useCommas ? "commas" : "normal");\n },\n\n // this is for the "grouped" mode\n createTagglyListGrouped: function(place,title) {\n var sortBy = this.getTagglyOpt(title,"sortBy");\n var sortOrder = this.getTagglyOpt(title,"sortOrder");\n\n var list = store.getTaggedTiddlers(title,sortBy);\n\n if (sortOrder == "desc")\n list = list.reverse();\n\n var leftOvers = []\n for (var i=0;i<list.length;i++)\n leftOvers.push(list[i].title);\n\n var allTagsHolder = {};\n for (var i=0;i<list.length;i++) {\n for (var j=0;j<list[i].tags.length;j++) {\n\n if (list[i].tags[j] != title) { // not this tiddler\n\n if (!allTagsHolder[list[i].tags[j]])\n allTagsHolder[list[i].tags[j]] = "";\n\n allTagsHolder[list[i].tags[j]] += "**[["+list[i].title+"]]"\n + this.getTaggingCount(list[i].title) + "\sn";\n leftOvers.setItem(list[i].title,-1); // remove from leftovers. at the end it will contain the leftovers\n }\n }\n }\n\n var allTags = [];\n for (var t in allTagsHolder)\n allTags.push(t);\n\n var sortHelper = function(a,b) {\n if (a == b) return 0;\n if (a < b) return -1;\n return 1;\n };\n\n allTags.sort(function(a,b) {\n var tidA = store.getTiddler(a);\n var tidB = store.getTiddler(b);\n if (sortBy == "title") return sortHelper(a,b);\n else if (!tidA && !tidB) return 0;\n else if (!tidA) return -1;\n else if (!tidB) return +1;\n else return sortHelper(tidA[sortBy],tidB[sortBy]);\n });\n\n var leftOverOutput = "";\n for (var i=0;i<leftOvers.length;i++)\n leftOverOutput += "*[["+leftOvers[i]+"]]" + this.getTaggingCount(leftOvers[i]) + "\sn";\n\n var output = [];\n\n if (sortOrder == "desc")\n allTags.reverse();\n else if (leftOverOutput != "")\n // leftovers first...\n output.push(leftOverOutput);\n\n for (var i=0;i<allTags.length;i++)\n output.push("*[["+allTags[i]+"]]" + this.getTaggingCount(leftOvers[i]) + "\sn" + allTagsHolder[allTags[i]]);\n\n if (sortOrder == "desc" && leftOverOutput != "")\n // leftovers last...\n output.push(leftOverOutput);\n\n return this.drawTable(place,\n this.makeColumns(output,parseInt(this.getTagglyOpt(title,"numCols"))),\n "grouped");\n\n },\n\n // used to build site map\n treeTraverse: function(title,depth,sortBy,sortOrder) {\n\n var list = store.getTaggedTiddlers(title,sortBy);\n if (sortOrder == "desc")\n list.reverse();\n\n var indent = "";\n for (var j=0;j<depth;j++)\n indent += "*"\n\n var childOutput = "";\n for (var i=0;i<list.length;i++)\n if (list[i].title != title)\n childOutput += this.treeTraverse(list[i].title,depth+1,sortBy,sortOrder);\n\n if (depth == 0)\n return childOutput;\n else\n return indent + "[["+title+"]]" + this.getTaggingCount(title) + "\sn"+childOutput;\n },\n\n // this if for the site map mode\n createTagglyListSiteMap: function(place,title) {\n var output = this.treeTraverse(title,0,this.getTagglyOpt(title,"sortBy"),this.getTagglyOpt(title,"sortOrder"));\n return this.drawTable(place,\n this.makeColumns(output.split(/(?=^\s*\s[)/m),parseInt(this.getTagglyOpt(title,"numCols"))), // regexp magic\n "sitemap"\n );\n },\n\n macros: {\n tagglyTagging: {\n handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n var refreshContainer = createTiddlyElement(place,"div");\n // do some refresh magic to make it keep the list fresh - thanks Saq\n refreshContainer.setAttribute("refresh","macro");\n refreshContainer.setAttribute("macroName",macroName);\n refreshContainer.setAttribute("title",tiddler.title);\n this.refresh(refreshContainer);\n },\n\n refresh: function(place) {\n var title = place.getAttribute("title");\n removeChildren(place);\n if (store.getTaggedTiddlers(title).length > 0) {\n var lingo = config.taggly.lingo;\n config.taggly.createListControl(place,title,"hideState");\n if (config.taggly.getTagglyOpt(title,"hideState") == "show") {\n createTiddlyElement(place,"span",null,"tagglyLabel",lingo.labels.label.format([title]));\n config.taggly.createListControl(place,title,"title");\n config.taggly.createListControl(place,title,"modified");\n config.taggly.createListControl(place,title,"created");\n config.taggly.createListControl(place,title,"listMode");\n config.taggly.createListControl(place,title,"numCols");\n config.taggly.createTagglyList(place,title);\n }\n }\n }\n }\n },\n\n // todo fix these up a bit\n styles: \n"/*{{{*/\sn"+\n"/* created by TagglyTaggingPlugin */\sn"+\n".tagglyTagging { padding-top:0.5em; }\sn"+\n".tagglyTagging li.listTitle { display:none; }\sn"+\n".tagglyTagging ul {\sn"+\n" margin-top:0px; padding-top:0.5em; padding-left:2em;\sn"+\n" margin-bottom:0px; padding-bottom:0px;\sn"+\n"}\sn"+\n".tagglyTagging { vertical-align: top; margin:0px; padding:0px; }\sn"+\n".tagglyTagging table { margin:0px; padding:0px; }\sn"+\n".tagglyTagging .button { display:none; margin-left:3px; margin-right:3px; }\sn"+\n".tagglyTagging .button, .tagglyTagging .hidebutton {\sn"+\n" color:[[ColorPalette::TertiaryLight]]; font-size:90%;\sn"+\n" border:0px; padding-left:0.3em;padding-right:0.3em;\sn"+\n"}\sn"+\n".tagglyTagging .button:hover, .hidebutton:hover {\sn"+\n" background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]];\sn"+\n"}\sn"+\n".selected .tagglyTagging .button {\sn"+\n" display:inline;\sn"+\n"}\sn"+\n".tagglyTagging .hidebutton { color:[[ColorPalette::Background]]; }\sn"+\n".selected .tagglyTagging .hidebutton { color:[[ColorPalette::TertiaryLight]] }\sn"+\n".tagglyLabel { color:[[ColorPalette::TertiaryMid]]; font-size:90%; }\sn"+\n".tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }\sn"+\n".tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}\sn"+\n".tagglyTagging ul ul li {margin-left:0.5em; }\sn"+\n".editLabel { font-size:90%; padding-top:0.5em; }\sn"+\n".tagglyTagging .commas { padding-left:1.8em; }\sn"+\n"/*}}}*/\sn"+\n "",\n\n init: function() {\n merge(config.macros,this.macros);\n config.shadowTiddlers["TagglyTaggingStyles"] = this.styles;\n if (store)\n store.addNotification("TagglyTaggingStyles",refreshStyles);\n else\n config.notifyTiddlers.push({name:"TagglyTaggingStyles", notify: refreshStyles});\n }\n};\n\nconfig.taggly.init();\n\n//}}}\n\n
@@text-align:center;font-size:120%;font-weight:bolder;Cambodian System of Writing and Beginning Reader@@\n\n@@text-align:center;font-weight:bolder;with Drills and Glossary@@\n\n@@text-align:center;font-size:120%;font-weight:bolder;by Franklin Huffman@@\n\n@@text-align:center;font-size:110%;font-weight:bolder;font-style:italic;with the assistance of ~Chhom-Rak Thong Lambert and Im Proum@@\n\n----\n\nThis site is under construction. That is to say, I'm learning the content and entering it as I go. The material is entered in a local file before being transferred to this site. You can view or download a (probably more complete) PDF version of what's been entered so far [[here|]].\n\n----\n\nChoose the entry or exercise you want to open from the drop-down menus across the top of the page, or click on the Next or Previous links.\n\nIn any exercise, "toggle" alternately collapses or expands the item (called a tiddler) and "focus" keeps the current tiddler expanded but collapses every other tiddler.\n\nThe <<tiddler NextTiddlerWithFocus with: [[About]] "About">> page contains information about what is necessary for this site to display properly, such as installing a Cambodian font.\n\n<<tiddler NextTiddlerWithFocus with: [[I Intro]] "Go to Introduction">> | <<tiddler NextTiddlerWithFocus with: [[Exercise 1]] "Go to exercise 1">>\n\n----\n\n//Cambodian System of Writing and Beginning Reader// was published originally by Yale University Press in 1970 with this statement: "Copyright is claimed until 1975. Thereafter all portions of this work will be in the public domain."\n\nThis website contains //Part Two: Programmed Reading Exercises//. The other parts consist of //Cambodian System of Writing, Beginning Reader// and //~Cambodian-English glossary.//\n\nA scanned version of both parts I and II of Huffman's text in PDF form can be downloaded from [[|]]. The complete text is still in print and available from Yale University Press.\n
/***\n| Name:|ToggleTagMacro|\n| Description:|Makes a checkbox which toggles a tag in a tiddler|\n| Version:|6.9.3|\n| Date:|30-Sep-2006|\n| Source:||\n| Author:|SimonBaird|\n| License:|[[BSD open source license]]|\n| CoreVersion:|2.1|\n!Usage\n{{{<<toggleTag }}}//{{{TagName TiddlerName LabelText}}}//{{{>>}}}\n* TagName - the tag to be toggled, default value "checked"\n* TiddlerName - the tiddler to toggle the tag in, default value the current tiddler\n* LabelText - the text (gets wikified) to put next to the check box, default value is '{{{[[TagName]]}}}' or '{{{[[TagName]] [[TiddlerName]]}}}'\n(If a parameter is '.' then the default will be used)\n\nExamples:\n\n|Code|Description|Example|h\n|{{{<<toggleTag>>}}}|Toggles the default tag (checked) in this tiddler|<<toggleTag>>|\n|{{{<<toggleTag TagName>>}}}|Toggles the TagName tag in this tiddler|<<toggleTag TagName>>|\n|{{{<<toggleTag TagName TiddlerName>>}}}|Toggles the TagName tag in the TiddlerName tiddler|<<toggleTag TagName TiddlerName>>|\n|{{{<<toggleTag TagName TiddlerName 'click me'>>}}}|Same but with custom label|<<toggleTag TagName TiddlerName 'click me'>>|\n|{{{<<toggleTag . . 'click me'>>}}}|dot means use default value|<<toggleTag . . 'click me'>>|\n(Note if TiddlerName doesn't exist it will be silently created)\n\n!Known issues\n* Doesn't smoothly handle the case where you toggle a tag in a tiddler that is current open for editing. Should it stick the tag in the edit box?\n\n***/\n//{{{\n\nmerge(config.macros,{\n\n toggleTag: {\n\n doRefreshAll: true,\n createIfRequired: true,\n shortLabel: "[[%0]]",\n longLabel: "[[%0]] [[%1]]",\n\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n var tag = (params[0] && params[0] != '.') ? params[0] : "checked";\n var title = (params[1] && params[1] != '.') ? params[1] : tiddler.title;\n var defaultLabel = (title == tiddler.title ? this.shortLabel : this.longLabel);\n var label = (params[2] && params[2] != '.') ? params[2] : defaultLabel;\n var theTiddler = title == tiddler.title ? tiddler : store.getTiddler(title);\n var cb = createTiddlyCheckbox(place, label.format([tag,title]), theTiddler && theTiddler.isTagged(tag), function(e) {\n if (!theTiddler) {\n if (config.macros.toggleTag.createIfRequired)\n store.saveTiddler(title,title,"",config.options.txtUserName,new Date(),null);\n else\n return false;\n }\n // suspendNotifications suggested by Saq\n // don't need to notify since doing a refreshDisplay\n store.suspendNotifications(); \n store.setTiddlerTag(title,this.checked,tag);\n refreshDisplay(); \n store.resumeNotifications();\n return true;\n });\n }\n }\n});\n\n//}}}\n\n
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |\n| 2/10/2006 10:24:12 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 2/10/2006 11:4:19 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 2/10/2006 11:10:2 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 2/10/2006 11:12:28 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 2/10/2006 11:32:14 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 2/10/2006 11:34:23 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 2/10/2006 11:39:6 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 2/10/2006 11:41:20 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 2/10/2006 11:42:16 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 2/10/2006 11:43:19 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/10/2006 0:35:46 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/10/2006 11:24:49 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/10/2006 11:33:19 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/10/2006 11:36:58 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/10/2006 11:58:24 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/10/2006 12:44:3 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/10/2006 13:13:21 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/10/2006 13:32:12 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/10/2006 16:16:0 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/10/2006 22:4:17 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/10/2006 23:57:23 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 0:2:54 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 0:8:2 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 0:12:1 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 7:27:55 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 7:37:4 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 7:41:18 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 10:21:35 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 11:10:32 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 11:48:59 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 11:49:33 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 11:53:33 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 13:57:4 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 13:57:52 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 14:1:38 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 14:28:9 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 16:17:22 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 16:19:55 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 16:23:55 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 16:28:30 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 16:34:38 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 16:40:11 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 16:41:52 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 16:50:48 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 17:21:31 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 19:2:45 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 19:3:8 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 19:4:25 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 19:8:25 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 19:9:21 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 19:50:48 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 4/10/2006 19:55:34 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 20:54:41 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 22:52:1 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 4/10/2006 23:13:7 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 5/10/2006 9:27:59 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 5/10/2006 9:34:4 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 5/10/2006 10:8:40 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 5/10/2006 11:36:39 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 6/10/2006 23:29:32 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 16/10/2006 23:46:58 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 28/10/2006 19:10:39 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 29/10/2006 16:34:48 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 29/10/2006 22:23:48 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 7/11/2006 6:42:40 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 30/11/2006 10:15:27 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 30/11/2006 10:15:49 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 30/11/2006 10:24:17 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 30/11/2006 10:28:25 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 6/12/2006 7:51:38 | roger | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 6/12/2006 11:32:36 | roger | [[cambodian.html|file:///C:/Documents%20and%20Settings/sperbergr/My%20Documents/personal/khmer/cambodian%20tw/cambodian.html]] | [[store.cgi|]] | . | index.html | . |\n| 6/12/2006 15:53:26 | roger | [[cambodian-cleaned.html|file:///C:/Documents%20and%20Settings/sperbergr/My%20Documents/personal/khmer/cambodian%20tw/cambodian-cleaned.html]] | [[store.cgi|]] | . | index.html | . |\n| 20/4/2007 13:8:43 | RogerS | [[/|]] | [[store.cgi|]] | . | index.html | . |
/***\n<<tiddler UploadPluginDoc>>\n!Code\n***/\n//{{{\nversion.extensions.UploadPlugin = {\n major: 3, minor: 3, revision: 3, \n date: new Date(2006,6,30),\n type: 'macro',\n source: '',\n docs: ''\n};\n//}}}\n\n////+++!![config.lib.file]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.file) config.lib.file= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\nconfig.lib.file.dirname = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(0, lastpos);\n } else {\n return filePath.substring(0, filePath.lastIndexOf("\s\s"));\n }\n};\nconfig.lib.file.basename = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("#")) != -1) \n filePath = filePath.substring(0, lastpos);\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(lastpos + 1);\n } else\n return filePath.substring(filePath.lastIndexOf("\s\s")+1);\n};\nwindow.basename = function() {return "@@deprecated@@";};\n//}}}\n////===\n\n////+++!![config.lib.log]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.log) config.lib.log= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\nconfig.lib.Log = function(tiddlerTitle, logHeader) {\n if (version.major < 2)\n this.tiddler = store.tiddlers[tiddlerTitle];\n else\n this.tiddler = store.getTiddler(tiddlerTitle);\n if (!this.tiddler) {\n this.tiddler = new Tiddler();\n this.tiddler.title = tiddlerTitle;\n this.tiddler.text = "| !date | !user | !location |" + logHeader;\n this.tiddler.created = new Date();\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[tiddlerTitle] = this.tiddler;\n else\n store.addTiddler(this.tiddler);\n }\n return this;\n};\n\nconfig.lib.Log.prototype.newLine = function (line) {\n var now = new Date();\n var newText = "| ";\n newText += now.getDate()+"/"+(now.getMonth()+1)+"/"+now.getFullYear() + " ";\n newText += now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+" | ";\n newText += config.options.txtUserName + " | ";\n var location = document.location.toString();\n var filename = config.lib.file.basename(location);\n if (!filename) filename = '/';\n newText += "[["+filename+"|"+location + "]] |";\n this.tiddler.text = this.tiddler.text + "\sn" + newText;\n this.addToLine(line);\n};\n\nconfig.lib.Log.prototype.addToLine = function (text) {\n this.tiddler.text = this.tiddler.text + text;\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[this.tiddler.tittle] = this.tiddler;\n else {\n store.addTiddler(this.tiddler);\n story.refreshTiddler(this.tiddler.title);\n store.notify(this.tiddler.title, true);\n }\n if (version.major < 2)\n store.notifyAll(); \n};\n//}}}\n////===\n\n////+++!![config.lib.options]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.options) config.lib.options = {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\n\nconfig.lib.options.init = function (name, defaultValue) {\n if (!config.options[name]) {\n config.options[name] = defaultValue;\n saveOptionCookie(name);\n }\n};\n//}}}\n////===\n\n////+++!![PasswordTweak]\n\n//{{{\nversion.extensions.PasswordTweak = {\n major: 1, minor: 0, revision: 2, date: new Date(2006,3,11),\n type: 'tweak',\n source: ''\n};\n//}}}\n/***\n!!config.macros.option\n***/\n//{{{\nconfig.macros.option.passwordCheckboxLabel = "Save this password on this computer";\nconfig.macros.option.passwordType = "password"; // password | text\n\nconfig.macros.option.onChangeOption = function(e)\n{\n var opt = this.getAttribute("option");\n var elementType,valueField;\n if(opt) {\n switch(opt.substr(0,3)) {\n case "txt":\n elementType = "input";\n valueField = "value";\n break;\n case "pas":\n elementType = "input";\n valueField = "value";\n break;\n case "chk":\n elementType = "input";\n valueField = "checked";\n break;\n }\n config.options[opt] = this[valueField];\n saveOptionCookie(opt);\n var nodes = document.getElementsByTagName(elementType);\n for(var t=0; t<nodes.length; t++) {\n var optNode = nodes[t].getAttribute("option");\n if (opt == optNode) \n nodes[t][valueField] = this[valueField];\n }\n }\n return(true);\n};\n\nconfig.macros.option.handler = function(place,macroName,params)\n{\n var opt = params[0];\n var size = 15;\n if (params[1])\n size = params[1];\n if(config.options[opt] === undefined) {\n return;}\n var c;\n switch(opt.substr(0,3)) {\n case "txt":\n c = document.createElement("input");\n c.onkeyup = this.onChangeOption;\n c.setAttribute ("option",opt);\n c.size = size;\n c.value = config.options[opt];\n place.appendChild(c);\n break;\n case "pas":\n // input password\n c = document.createElement ("input");\n c.setAttribute("type",config.macros.option.passwordType);\n c.onkeyup = this.onChangeOption;\n c.setAttribute("option",opt);\n c.size = size;\n c.value = config.options[opt];\n place.appendChild(c);\n // checkbox link with this password "save this password on this computer"\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option","chk"+opt);\n place.appendChild(c);\n c.checked = config.options["chk"+opt];\n // text savePasswordCheckboxLabel\n place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));\n break;\n case "chk":\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option",opt);\n place.appendChild(c);\n c.checked = config.options[opt];\n break;\n }\n};\n//}}}\n/***\n!! Option cookie stuff\n***/\n//{{{\nwindow.loadOptionsCookie_orig_PasswordTweak = window.loadOptionsCookie;\nwindow.loadOptionsCookie = function()\n{\n var cookies = document.cookie.split(";");\n for(var c=0; c<cookies.length; c++) {\n var p = cookies[c].indexOf("=");\n if(p != -1) {\n var name = cookies[c].substr(0,p).trim();\n var value = cookies[c].substr(p+1).trim();\n switch(name.substr(0,3)) {\n case "txt":\n config.options[name] = unescape(value);\n break;\n case "pas":\n config.options[name] = unescape(value);\n break;\n case "chk":\n config.options[name] = value == "true";\n break;\n }\n }\n }\n};\n\nwindow.saveOptionCookie_orig_PasswordTweak = window.saveOptionCookie;\nwindow.saveOptionCookie = function(name)\n{\n var c = name + "=";\n switch(name.substr(0,3)) {\n case "txt":\n c += escape(config.options[name].toString());\n break;\n case "chk":\n c += config.options[name] ? "true" : "false";\n // is there an option link with this chk ?\n if (config.options[name.substr(3)]) {\n saveOptionCookie(name.substr(3));\n }\n break;\n case "pas":\n if (config.options["chk"+name]) {\n c += escape(config.options[name].toString());\n } else {\n c += "";\n }\n break;\n }\n c += "; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";\n document.cookie = c;\n};\n//}}}\n/***\n!! Initializations\n***/\n//{{{\n// define config.options.pasPassword\nif (!config.options.pasPassword) {\n config.options.pasPassword = 'defaultPassword';\n window.saveOptionCookie('pasPassword');\n}\n// since loadCookies is first called befor password definition\n// we need to reload cookies\nwindow.loadOptionsCookie();\n//}}}\n////===\n\n////+++!![config.macros.upload]\n\n//{{{\nconfig.macros.upload = {\n accessKey: "U",\n formName: "UploadPlugin",\n contentType: "text/html;charset=UTF-8",\n defaultStoreScript: "store.php"\n};\n\n// only this two configs need to be translated\nconfig.macros.upload.messages = {\n aboutToUpload: "About to upload TiddlyWiki to %0",\n errorDownloading: "Error downloading",\n errorUploadingContent: "Error uploading content",\n fileNotFound: "file to upload not found",\n fileNotUploaded: "File %0 NOT uploaded",\n mainFileUploaded: "Main TiddlyWiki file uploaded to %0",\n urlParamMissing: "url param missing",\n rssFileNotUploaded: "RssFile %0 NOT uploaded",\n rssFileUploaded: "Rss File uploaded to %0"\n};\n\nconfig.macros.upload.label = {\n promptOption: "Save and Upload this TiddlyWiki with UploadOptions",\n promptParamMacro: "Save and Upload this TiddlyWiki in %0",\n saveLabel: "save to web", \n saveToDisk: "save to disk",\n uploadLabel: "upload" \n};\n\nconfig.macros.upload.handler = function(place,macroName,params){\n // parameters initialization\n var storeUrl = params[0];\n var toFilename = params[1];\n var backupDir = params[2];\n var uploadDir = params[3];\n var username = params[4];\n var password; // for security reason no password as macro parameter\n var label;\n if (document.location.toString().substr(0,4) == "http")\n label = this.label.saveLabel;\n else\n label = this.label.uploadLabel;\n var prompt;\n if (storeUrl) {\n prompt = this.label.promptParamMacro.toString().format([this.dirname(storeUrl)]);\n }\n else {\n prompt = this.label.promptOption;\n }\n createTiddlyButton(place, label, prompt, \n function () {\n config.macros.upload.upload(storeUrl, toFilename, uploadDir, backupDir, username, password); \n return false;}, \n null, null, this.accessKey);\n};\nconfig.macros.upload.UploadLog = function() {\n return new config.lib.Log('UploadLog', " !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |" );\n};\nconfig.macros.upload.UploadLog.prototype = config.lib.Log.prototype;\nconfig.macros.upload.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {\n var line = " [[" + config.lib.file.basename(storeUrl) + "|" + storeUrl + "]] | ";\n line += uploadDir + " | " + toFilename + " | " + backupDir + " |";\n this.newLine(line);\n};\nconfig.macros.upload.UploadLog.prototype.endUpload = function() {\n this.addToLine(" Ok |");\n};\nconfig.macros.upload.basename = config.lib.file.basename;\nconfig.macros.upload.dirname = config.lib.file.dirname;\nconfig.macros.upload.upload = function(storeUrl, toFilename, uploadDir, backupDir, username, password)\n{\n // parameters initialization\n storeUrl = (storeUrl ? storeUrl : config.options.txtUploadStoreUrl);\n toFilename = (toFilename ? toFilename : config.options.txtUploadFilename);\n backupDir = (backupDir ? backupDir : config.options.txtUploadBackupDir);\n uploadDir = (uploadDir ? uploadDir : config.options.txtUploadDir);\n username = (username ? username : config.options.txtUploadUserName);\n password = config.options.pasUploadPassword; // for security reason no password as macro parameter\n if (storeUrl === '') {\n config.macros.upload.defaultStoreScript;\n }\n if (config.lib.file.dirname(storeUrl) === '') {\n storeUrl = config.lib.file.dirname(document.location.toString())+'/'+storeUrl;\n }\n if (toFilename === '') {\n toFilename = config.lib.file.basename(document.location.toString());\n }\n\n clearMessage();\n // only for forcing the message to display\n if (version.major < 2)\n store.notifyAll();\n if (!storeUrl) {\n alert(config.macros.upload.messages.urlParamMissing);\n return;\n }\n \n var log = new this.UploadLog();\n log.startUpload(storeUrl, toFilename, uploadDir, backupDir);\n if (document.location.toString().substr(0,5) == "file:") {\n saveChanges();\n }\n displayMessage(config.macros.upload.messages.aboutToUpload.format([this.dirname(storeUrl)]), this.dirname(storeUrl));\n this.uploadChanges(storeUrl, toFilename, uploadDir, backupDir, username, password);\n if(config.options.chkGenerateAnRssFeed) {\n //var rssContent = convertUnicodeToUTF8(generateRss());\n var rssContent = generateRss();\n var rssPath = toFilename.substr(0,toFilename.lastIndexOf(".")) + ".xml";\n this.uploadContent(rssContent, storeUrl, rssPath, uploadDir, '', username, password, \n function (responseText) {\n if (responseText.substring(0,1) != '0') {\n displayMessage(config.macros.upload.messages.rssFileNotUploaded.format([rssPath]));\n }\n else {\n if (uploadDir) {\n rssPath = uploadDir + "/" + config.macros.upload.basename(rssPath);\n } else {\n rssPath = config.macros.upload.basename(rssPath);\n }\n displayMessage(config.macros.upload.messages.rssFileUploaded.format(\n [config.macros.upload.dirname(storeUrl)+"/"+rssPath]), config.macros.upload.dirname(storeUrl)+"/"+rssPath);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n });\n }\n return;\n};\n\nconfig.macros.upload.uploadChanges = function(storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var original;\n if (document.location.toString().substr(0,4) == "http") {\n original =, toFilename, uploadDir, backupDir, username, password);\n return;\n }\n else {\n // standard way : Local file\n \n original = loadFile(getLocalPath(document.location.toString()));\n if(window.Components) {\n // it's a mozilla browser\n try {\n"UniversalXPConnect");\n var converter = Components.classes[""]\n .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);\n converter.charset = "UTF-8";\n original = converter.ConvertToUnicode(original);\n }\n catch(e) {\n }\n }\n }\n //DEBUG alert(original);\n this.uploadChangesFrom(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password);\n};\n\nconfig.macros.upload.uploadChangesFrom = function(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it\n var endSaveArea = '</d' + 'iv>';\n // Locate the storeArea div's\n var posOpeningDiv = original.indexOf(startSaveArea);\n var posClosingDiv = original.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1))\n {\n alert(config.messages.invalidFileError.format([document.location.toString()]));\n return;\n }\n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n allTiddlersAsHtml() + "\sn\st\st" +\n original.substr(posClosingDiv);\n var newSiteTitle;\n if(version.major < 2){\n newSiteTitle = (getElementText("siteTitle") + " - " + getElementText("siteSubtitle")).htmlEncode();\n } else {\n newSiteTitle = (wikifyPlain ("SiteTitle") + " - " + wikifyPlain ("SiteSubtitle")).htmlEncode();\n }\n revised = revised.replace(new RegExp("<title>[^<]*</title>", "im"),"<title>"+ newSiteTitle +"</title>");\n var response = this.uploadContent(revised, storeUrl, toFilename, uploadDir, backupDir, \n username, password, function (responseText) {\n if (responseText.substring(0,1) != '0') {\n alert(responseText);\n displayMessage(config.macros.upload.messages.fileNotUploaded.format([getLocalPath(document.location.toString())]));\n }\n else {\n if (uploadDir !== '') {\n toFilename = uploadDir + "/" + config.macros.upload.basename(toFilename);\n } else {\n toFilename = config.macros.upload.basename(toFilename);\n }\n displayMessage(config.macros.upload.messages.mainFileUploaded.format(\n [config.macros.upload.dirname(storeUrl)+"/"+toFilename]), config.macros.upload.dirname(storeUrl)+"/"+toFilename);\n var log = new config.macros.upload.UploadLog();\n log.endUpload();\n store.setDirty(false);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n }\n );\n};\n\nconfig.macros.upload.uploadContent = function(content, storeUrl, toFilename, uploadDir, backupDir, \n username, password, callbackFn) {\n var boundary = "---------------------------"+"AaB03x"; \n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n if (window.netscape){\n try {\n if (document.location.toString().substr(0,4) != "http") {\n'UniversalBrowserRead');}\n }\n catch (e) { }\n } \n //DEBUG alert("user["+config.options.txtUploadUserName+"] password[" + config.options.pasUploadPassword + "]");\n // compose headers data\n var sheader = "";\n sheader += "--" + boundary + "\sr\snContent-disposition: form-data; name=\s"";\n sheader += config.macros.upload.formName +"\s"\sr\sn\sr\sn";\n sheader += "backupDir="+backupDir\n +";user=" + username \n +";password=" + password\n +";uploaddir=" + uploadDir\n + ";;\sr\sn"; \n sheader += "\sr\sn" + "--" + boundary + "\sr\sn";\n sheader += "Content-disposition: form-data; name=\s"userfile\s"; filename=\s""+toFilename+"\s"\sr\sn";\n sheader += "Content-Type: " + config.macros.upload.contentType + "\sr\sn";\n sheader += "Content-Length: " + content.length + "\sr\sn\sr\sn";\n // compose trailer data\n var strailer = new String();\n strailer = "\sr\sn--" + boundary + "--\sr\sn";\n var data;\n data = sheader + content + strailer;\n //"POST", storeUrl, true, username, password);\n"POST", storeUrl, true);\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if (request.status == 200)\n callbackFn(request.responseText);\n else\n alert(config.macros.upload.messages.errorUploadingContent);\n }\n };\n request.setRequestHeader("Content-Length",data.length);\n request.setRequestHeader("Content-Type","multipart/form-data; boundary="+boundary);\n request.send(data); \n};\n\n\ = function(uploadUrl, uploadToFilename, uploadDir, uploadBackupDir, \n username, password) {\n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n try {\n if (uploadUrl.substr(0,4) == "http") {\n"UniversalBrowserRead");\n }\n else {\n"UniversalXPConnect");\n }\n } catch (e) { }\n //"GET", document.location.toString(), true, username, password);\n"GET", document.location.toString(), true);\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if(request.status == 200) {\n config.macros.upload.uploadChangesFrom(request.responseText, uploadUrl, \n uploadToFilename, uploadDir, uploadBackupDir, username, password);\n }\n else\n alert(config.macros.upload.messages.errorDownloading.format(\n [document.location.toString()]));\n }\n };\n request.send(null);\n};\n\n//}}}\n////===\n\n////+++!![Initializations]\n\n//{{{\nconfig.lib.options.init('txtUploadStoreUrl','store.php');\nconfig.lib.options.init('txtUploadFilename','');\nconfig.lib.options.init('txtUploadDir','');\nconfig.lib.options.init('txtUploadBackupDir','');\nconfig.lib.options.init('txtUploadUserName',config.options.txtUserName);\nconfig.lib.options.init('pasUploadPassword','');\nconfig.shadowTiddlers.UploadPluginDoc = "[[Full Documentation| ]]\sn"; \n\n\n//}}}\n////===\n\n////+++!![Core Hijacking]\n\n//{{{\nconfig.macros.saveChanges.label_orig_UploadPlugin = config.macros.saveChanges.label;\nconfig.macros.saveChanges.label = config.macros.upload.label.saveToDisk;\n\nconfig.macros.saveChanges.handler_orig_UploadPlugin = config.macros.saveChanges.handler;\n\nconfig.macros.saveChanges.handler = function(place)\n{\n if ((!readOnly) && (document.location.toString().substr(0,4) != "http"))\n createTiddlyButton(place,this.label,this.prompt,this.onClick,null,null,this.accessKey);\n}\n\n//}}}\n////===
This document is a ~TiddlyWiki from A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.\n\n@@font-weight:bold;font-size:1.2em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|]] (your control panel username is //cambodian//).\n<<tiddler tiddlyspotControls>>\n@@font-weight:bold;font-size:1.2em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the "save to web" button in the column on the right.\n\n@@font-weight:bold;font-size:1.2em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click "upload" and your ~TiddlyWiki will be saved back to\n\n@@font-weight:bold;font-size:1.2em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[|]]. Also visit [[TiddlyWiki Guides|]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|]].\n\n@@font-weight:bold;font-size:1.2em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your site. Please email [[|]] with any comments or suggestions.
| tiddlyspot password:|<<option pasUploadPassword>>|\n| site management:|<<upload index.html . . cambodian>>//(requires tiddlyspot password)//<<br>>[[control panel|]], [[download (go offline)|]]|\n| links:|[[|]], [[FAQs|]], [[announcements|]], [[blog|]], email [[support|]] & [[feedback|]], [[donate|]]|