<<option chkGenerateAnRssFeed>> GenerateAnRssFeed\n<<option chkOpenInNewWindow>> OpenLinksInNewWindow\n<<option chkSaveEmptyTemplate>> SaveEmptyTemplate\n<<option chkToggleLinks>> Clicking on links to tiddlers that are already open causes them to close\n^^(override with Control or other modifier key)^^\n<<option chkHttpReadOnly>> HideEditingFeatures when viewed over HTTP\n<<option chkForceMinorUpdate>> Treat edits as MinorChanges by preserving date and time\n^^(override with Shift key when clicking 'done' or by pressing Ctrl-Shift-Enter^^\n<<option chkConfirmDelete>> ConfirmBeforeDeleting\nMaximum number of lines in a tiddler edit box: <<option txtMaxEditRows>>\nFolder name for backup files: <<option txtBackupFolder>>\n\n<<option chkSearchTitles>> Search in tiddler titles\n<<option chkSearchText>> Search in tiddler text\n<<option chkSearchTags>> Search in tiddler tags\n<<option chkSearchTitlesFirst>> Search results show title matches first\n<<option chkSearchList>> Search results show list of matching tiddlers\n<<option chkSearchIncremental>> Incremental searching\n<<option chkTOCIncludeHidden>> include hidden tiddlers in TableOfContents\n
Plusieurs alimentations sont nécessaires :\n* 3.3V pour la majorité des périphériques, ainsi que pour les IO du processeur et du FPGA,\n* 1.5V pour les coeurs du processeur et du FPGA,\n* 5V pour l'alimentation du bus USB, du bus vidéo, des LEDS, et des switchs de protection du bus d'extension.\n\nLes consommations estimées se répartissent comme indiqué dans la table ci-dessous (seuls certains périphériques 3.3V sont mentionnées) :\n\n| Tension | Device | Intensité |h\n| 3.3V | IO Stratix | 1.1 A |\n|~| IO ~SH4 | 180mA |\n|~| 2x SDRAM | 640mA |\n|~| 2x SSRAM | 325mA |\n|~| ''Total'' | ''2.245 A'' |\n| 2.5V | coeur Stratix | 2.2 A |\n|~| coeur ~SH4 | 580mA |\n|~| ''Total'' | ''2.8 A'' |\n\n La consommation du Stratix est estimée à partir des paramètres suivants :\n| Device | Conditions |h\n| Clocktree | 40.000 flip-flop à 80MHz |\n| LE | 10.000 flip-flop à 80MHz, toggle 50% |\n|~| 1.000 flip-flop à 80MHz, toggle 7%5 |\n|~| 15.000 flip-flop à 54MHz, toggle 5%0 |\n| DSP | 10 blocs à 54MHz, toggle 100% |\n| PLL | toutes en marche, 82, 54 et 27MHZ |\n| RAM | 300kb à 80Mhz |\n| IO | 100 à 80MHz, toggle 100% |\n|~| 300 à 80MHz, toggle 50% |\n|~| 200 à 54MHz, toggle 50% |\n\nCes chiffres ne représentent rien de réel, ils permettent juste d'avoir une idée de la consommation du Stratix pour un design moyen. L'alimentation doit aussi prendre en compte les périphériques 3.3V oubliés, ceux situés sur le bus d'extension, ainsi que le séquencement des power-up / power-down (voir datasheet du SH7750R).\n\nElle a donc été architecturée comme suit :\n* 3.3V : deux régulateurs à découpage LT1959 en parallèle, capables de fournir à eux deux 6A en continu. Pour éviter les problèmes des régulateurs en parallèle, l'un d'eux est maître de la régulation (compensation), l'autre est esclave. Un soft start évite les surtensions au power-up, et retarde la montée du 3.3V par rapport à celle du 1.5V conformément aux spécifications du SH7750R.\n* 1.5V : un régulateur à découpage LT1959 suivi d'un LDO 1.5V LT1587. Le profil de consommation sur le 1.5V n'étant pas maîtrisé du tout, de forts pics de consommation peuvent apparaitre, perturbant la boucle de régulation. Le 1.5V devant rester dans des marges très restreintes, j'ai préféré jouer la sécurité et réguler en deux étapes : abaissement par découpage à 2.2V environ, puis régulation linéaire 1.5V.\n* 5V : peu chargé, il est généré par un régulateur linéaire 1A.\n\nLes alimentations 3.3V et 1.5V ont été simulées (en régime continu, power-up et transient). La marge de stabilité est suffisante pour assurer leur stabilité même dans des conditions extrêmes irréalistes.\n\n
!! Arborescence, patchs, et gestion de versions\n\n!!!Description du problème\n\nLe noyau utilisé sur la carte SHiX est un noyau Linux standards auquel sont appliqués plusieurs patchs. Ses principaux composants :\n* le noyau officiel 2.6.15.1\n* les patchs pour processeurs SH\n* les patchs de la couche MTD (accès à la flash NAND)\n* le file system YAFFS (un système de fichier simple et rapide adapté aux flash NAND)\n* les patchs maison\n\nLe noyau officiel vient sous forme de tarball ou de dépôt //git//. Les autres arbes viennent sous forme de dépôts CVS, GnuArch, [[Mercurial]], et comportent un script permettant de patcher automatiquement un noyau Linux officiel.\n\nCe genre de développement pose trois problèmes :\n* les arbres de patch peuvent parfois modifier un même fichier. Or le script de patch se contente souvent de remplacer le fichier original par une version modifée, par {{{cp}}} ou {{{ln -s}}} au lieu de n'en modifier que les lignes nécessaires (comme le ferait le programme {{{patch}}}). Donc si deux arbres touchent au même fichier, seule la version du dernier arbre appliqué sera gardée. L'autre sera écrasée...\n* un autre problème vient du fait que tous ces arbres (Linux et patchs) sont dit //upstream//, c'est-à-dire développés par des gens extérieurs. Ils sont chacun mis à jour à leur rythme, à des intervalles plus ou moins réguliers. En admettant qu'on a déjà réussi à appliquer touts les différents patchs (en gérant les conflits éventuels), propager la mise à jour d'un des arbres à celle du noyau sur lequel on travaille peut être pénible : il faut identifier les modifications des sources, puis appliquer ces modifications (en court-circuitant les scripts normaux de patch) à notre copie privée... Pour peu que les mises-à-jour soient fréquentes (comme c'est le cas pour la MTD ou YAFFS), c'est pénible.\n* Enfin, certains patchs sont buggés, et il vaut mieux pouvoir revenir en arrière facilement. \n\nPour résoudre ces problèmes, la stratégie suivante a été choisie : chaque arbre de patch est appliqué à sa propre copie privée du noyau. De là un diff par rapport à la version précédente est extrait, puis appliqué à un autre arbre, l'arbre de développement. De plus, chaque arbre Linux est versionné.\n\nLe système de versionnement choisi est [[Mercurial]], pour sa simplicité, sa rapidité, et sa facilité à gérer les patchs et les dépôts (repository) multiples.\n\n!!!Arborescence\n\nTous les fichiers nécessaires à la compilation du noyau sont rassemblés sous une même racine {{{kernel}}}. \n\n{{{\nkernel\n|-- kernel/downloads\n|-- kernel/repositories\n| |-- kernel/repositories/linux\n| |-- kernel/repositories/mtd\n| | |-- kernel/repositories/mtd/linux\n| | `-- kernel/repositories/mtd/mtd\n| |-- kernel/repositories/sh_linux\n| | |-- kernel/repositories/sh_linux/linux\n| | `-- kernel/repositories/sh_linux/sh_kernel\n| `-- kernel/repositories/yaffs2\n| |-- kernel/repositories/yaffs2/linux\n| `-- kernel/repositories/yaffs2/yaffs2\n`-- kernel/linux_work\n}}}\n\n* {{{downloads}}} contient les sources compressées des noyaux Linux officiels. \n* {{{repositories}}} contient les différents arbres de patch //upstream// : MTD, YAFFS, SH-Linux, ainsi qu'un noyau Linux officiel pur (non patché), décompressé. Ce noyau Linux est un repository Mercurial à part entière, qui sert de repository de base à tous les autres.\n* Chaque sous-répertoire ({{{mts}}}, {{{yaffs2}}}, {{{sh_linux}}}) contient deux répertoire : \n** l'arbre de patch, récupéré par CVS, GnuArch, ...\n** une copie privée du noyau Linux officiel sur laquelle on applique les patchs de l'arbre de question. Chaque copie privée est un repository Mercurial à part entière (on appele ça une //branch// en jargon Mercurial), clonée à partir de la copie de base {{{repositories/linux}}}.\n* {{{linux_work}}} : la copie de travail. C'est aussi un repository Mercurial, dans lequel on a importé tous les patchs des autres repositories. On y fait aussi tous les développements qu'on souhaite. Bien entendu, chaque application de patch ou chaque développement terminé donne lieu à un {{{commit}}}.\n\nPour la mise en place de l'arborescence de développement, on a deux possibilités : [[importer une arborescence existante|Import Arborescence]], ou la [[créer de toutes pièces|Creation Arborescence From Scratch]].\n\n\n\n
/***\n''Attach File Plugin for TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#AttachFilePlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nStore binary files (such as jpg, gif, pdf or even mp3) directly in your TiddlyWiki document, and then use them as embedded images or links in your tiddlers. Let's you create truly self-contained documents!\n!!!!!Inline interface (live)\n<<<\n<<attach inline>>\n<<<\n!!!!!Usage\n<<<\n# select ''attach file'' sidebar menu\n# press "Browse..." on the attach file control panel\n# select a file from the system-specific 'file picker' dialog and press OK\n# MIME type //(see below)// is automatically selected based on the filename\n# optionally, change the suggested MIME type\n# optionally, enter tiddler tags to add to the attachment\n# press OK\n\nAn 'attachment tiddler' is created, using the filename of the attachment as it's title. The contents of this tidder includes a standard header with a clickable link to the attachment as well as an embedded image of the attachment (if applicable). Below the attachment header are the MIME type and "base64" declarations for the attached file, followed by a base64 text-encoded block of binary data.\n\nAlthough you can edit an attachment tiddler, ''don't change any of the encoded content below the attachment header'', as it has been prepared for use in the rest of your document, and even changing a single character can make it unusable by the browser. //If needed, you ''can'' edit the MIME type declaration in the attachment data, but be very careful not to change anything else, including punctuation!//\n<<<\n!!!!!Known Limitations\nNote: ''This feature does not currently work with Internet Explorer... sorry.''\n*''problem #1:'' while it is easy to read text files, reading binary files is not supported by IE's FileSystemObject (FSO) methods, and other file I/O techniques are subject to security barriers or require additional MS proprietary technologies (like ASP or VB) that make implementation more difficult.\n*''problem #2:'' IE does not support the data: URI scheme, and cannot render the embedded images or links. This would seem to be an insurmountable shortcoming in the browser. Let's hope it is added in the next version...\n!!!!!Example\n<<<\nTo embed attached files as images or link to them from other tiddlers, use the standard TiddlyWiki image syntax or //external// link syntax, substituting a tiddler attachment title in place of the filename or URL that is normally entered.\n# Attachment as an embedded image:^^\n[img[Meow|AttachFileSample]]^^\n# Attachment as an external link:^^\n[[click here to view attachment|AttachFileSample]]^^\n# Regular TiddlyWiki link to an attachment tiddler:^^\n[[AttachFileSample]]^^\n<<<\n!!!!!MIME Types\n<<<\nThe following ''[[MIME|http://en.wikipedia.org/wiki/MIME]]'' file types are automatically suggested (based on filename extension) when using the [[Attach File|AttachFileHelp]] plug-in:\n|>|!text|\n|^^TXT TEXT JS VBS ASP CGI PL^^|text/plain|\n|^^HTM HTML HTA HTX MHT^^|text/html|\n|^^CSV^^|text/comma-separated-values|\n|^^JS^^|text/javascript|\n|^^CSS^^|text/css|\n|^^XML XSL XSLT^^|text/xml|\n|>|!images|\n|^^GIF^^|image/gif|\n|^^JPG JPE JPEG^^|image/jpeg|\n|^^PNG^^|image/png|\n|^^BMP^^|image/bmp|\n|^^TIF TIFF^^|image/tiff|\n|>|!sounds|\n|^^AU SND^^|audio/basic|\n|^^WAV^^|audio/wav|\n|^^RA RM RAM^^|audio/x-pn-realaudio|\n|^^MID MIDI^^|audio/x-midi|\n|^^MP3^^|audio/mp3|\n|^^M3U^^|audio/m3u|\n|>|!video|\n|^^ASF^^|video/x-ms-asf|\n|^^AVI^^|video/avi|\n|^^MPG MPEG^^|video/mpeg|\n|^^QT MOV QTVR^^|video/quicktime|\n|>|!formatted documents|\n|^^PDF^^|application/pdf|\n|^^RTF^^|application/rtf|\n|^^AI EPS PS^^|application/postscript|\n|^^WPD^^|application/wordperfect|\n|^^WRI^^|application/mswrite|\n|^^XLS XLS3 XLS4 XLS5 XLW^^|application/msexcel|\n|^^DOC^^|application/msword|\n|^^PPT PPS^^|application/mspowerpoint|\n|^^SWA^^|application/x-director|\n|^^SWF^^|application/x-shockwave-flash|\n|>|!compressed storage/download|\n|^^ZIP^^|application/x-zip-compressed|\n|^^GZ^^|application/x-gzip|\n|^^RAR^^|application/x-rar-compressed|\n|>|!programs|\n|^^COM EXE DLL OCX^^|application/octet-stream|\n|>|!WAP enabled content|\n|^^WML^^|text/vnd.wap.wml|\n|^^WMLS^^|text/vnd.wap.wmlscript|\n|^^WBMP^^|image/vnd.wap.wbmp|\n|^^WMLC^^|application/vnd.wap.wmlc|\n|^^WMLSC^^|application/vnd.wap.wmlscriptc|\n<<<\n!!!!!Installation\n<<<\nImport (or copy/paste) the following tiddlers into your document:\n''AttachFilePlugin'' (tagged with <<tag systemConfig>>)\n''AttachFileSample'' //(sample attachment tiddler containing an image file)//\n\ncreate/edit ''SideBarOptions'': (sidebar menu items) \n^^Add {{{<<attach>>}}} macro^^\n<<<\n!!!!!Revision History\n<<<\n''2006.02.05 [3.0.1]''\nwrapped wikifier hijacks in initAttachmentFormatters() function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals\n''2005.12.27 [3.0.0]''\nUpdate for TW2.0\nAutomatically add 'excludeMissing' tag to attachments\n''2005.12.16 [2.2.0]''\nDynamically create/remove attachPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding.\n''2005.11.20 [2.1.0]''\nadded wikifier handler extensions for "image" and "prettyLink" to render tiddler attachments\n''2005.11.09 [2.0.0]''\nbegin port from old ELS Design plugin/adaptation hybrid based on ~TW1.2.33\n''2005.08.05 [1.1.0]''\nmoved CSS and HTML definitions into plugin code tiddler instead of using separate tiddlers\n''2005.07.27 [1.0.2]''\ncore update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet()\n''2005.07.23 [1.0.1]''\nadded parameter checks and corrected addNotification() usage\n''2005.07.20 [1.0.0]''\nInitial Release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n// // +++[version]\n//{{{\nversion.extensions.attach = {major: 3, minor: 0, revision: 1, date: new Date(2006,2,5)};\n//}}}\n// // ===\n\n// // +++[1.2.x compatibility]\n//{{{\nif (!window.story) window.story=window; // for v1.2.x\nif (!store.getTiddler) store.getTiddler=function(title){return store.tiddlers[title]}\nif (!store.addTiddler) store.addTiddler=function(tiddler){store.tiddlers[tiddler.title]=tiddler}\nif (!store.deleteTiddler) store.deleteTiddler=function(title){delete store.tiddlers[title]}\n//}}}\n// // ===\n\n// // +++[messages and macro definition]\n//{{{\nconfig.messages.attachmentLinkTooltip="Attachment: ";\nconfig.macros.attach = { label: "attach file", prompt: "Attach a file to this document" };\nconfig.macros.attach.handler = function(place,macroName,params) {\n if (params[0]!="inline")\n { createTiddlyButton(place,this.label,this.prompt,onClickAttachMenu); return; }\n createAttachPanel(place);\n document.getElementById("attachPanel").style.position="static";\n document.getElementById("attachPanel").style.display="block";\n}\n\nfunction createAttachPanel(place) {\n var panel=document.getElementById("attachPanel");\n if (panel) { panel.parentNode.removeChild(panel); }\n setStylesheet(config.macros.attach.css,"attachFile");\n panel=createTiddlyElement(place,"span","attachPanel",null,null)\n panel.innerHTML=config.macros.attach.html;\n var theList = document.getElementById("attachMIMEType");\n if (theList) for (var i=0;i<config.MIMETypes.length; i++)\n theList.options[i] = new Option(config.MIMETypes[i][1],config.MIMETypes[i][1],false,false);\n return panel;\n}\n\nfunction onClickAttachMenu(e)\n{\n if (!e) var e = window.event;\n var parent=resolveTarget(e).parentNode;\n var panel = document.getElementById("attachPanel");\n if (panel==undefined || panel.parentNode!=parent)\n panel=createAttachPanel(parent);\n var isOpen = panel.style.display=="block";\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n panel.style.display = isOpen ? "none" : "block" ;\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n//}}}\n// //===\n\n// // +++[CSS for attach file control panel]\n//{{{\nconfig.macros.attach.css = '\s\n#attachPanel {\s\n display: none; position:absolute; z-index:10; width:30em; right:105%; top:0em;\s\n background-color: #eeeeee; color:#000000; font-size: 8pt; line-height:110%;\s\n border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\s\n padding: 0.5em; margin:0em;\s\n -moz-border-radius:1em;\s\n}\s\n#attachPanel select { width:100%;margin:0px;font-size:8pt;line-height:110%;}\s\n#attachPanel input { width:100%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\s\n#attachPanel .btn { width:auto; }\s\n#attachPanel .btn1 { width:98%; }\s\n#attachPanel .btn2 { width:48%; }\s\n#attachPanel .btn3 { width:32%; }\s\n#attachPanel .btn4 { width:24%; }\s\n#attachPanel .btn5 { width:19%; }\s\n';\n//}}}\n// // ===\n\n// // +++[HTML for attach file control panel]\n//{{{\nconfig.macros.attach.html = '\s\nattach from source file:\s\n<input type="file" id="attachSource" size=45 onChange="onChangeAttachSource()">\s\n<select size=1 id="attachMIMEType"></select>\s\nadd tags:\s\n<input type=text id="attachTags" size=15 autocomplete=off>\s\n<div style="text-align:center">\s\n <input type=button style="width:30%" value="ok" onclick="onClickAttachOK()">\s\n <input type=button style="width:30%" value="cancel" onclick="onClickAttachCancel()">\s\n</div>\s\n';\n//}}}\n// // ===\n\n// // +++[wikifiers for rendering attachments as images or links]\n//{{{\ninitAttachmentFormatters();\nfunction initAttachmentFormatters() {\n // find the formatter for "image" and replace the handler\n for (var i=0; i<config.formatters.length && config.formatters[i].name!="image"; i++);\n if (i<config.formatters.length) config.formatters[i].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) // Simple bracketted link\n {\n var e = w.output;\n if(lookaheadMatch[5])\n {\n if(store.tiddlerExists(lookaheadMatch[5]))\n e = createTiddlyLink(w.output,lookaheadMatch[5],false);\n else\n e = createExternalLink(w.output,lookaheadMatch[5]);\n }\n var img = createTiddlyElement(e,"img");\n if(lookaheadMatch[1])\n img.align = "left";\n else if(lookaheadMatch[2])\n img.align = "right";\n if(lookaheadMatch[3])\n img.title = lookaheadMatch[3];\n img.src = lookaheadMatch[4];\n // ELS: ADDED\n if (isAttachment(lookaheadMatch[4])) img.src=getAttachment(lookaheadMatch[4]);\n // ELS: END\n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n }\n }\n\n // find the formatter for "prettyLink" and replace the handler\n for (var i=0; i<config.formatters.length && config.formatters[i].name!="prettyLink"; i++);\n if (i<config.formatters.length) config.formatters[i].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 && lookaheadMatch[2])\n { // Simple bracketted link\n var link = createTiddlyLink(w.output,lookaheadMatch[1],false);\n w.outputText(link,w.nextMatch,w.nextMatch + lookaheadMatch[1].length);\n w.nextMatch += lookaheadMatch[1].length + 2;\n }\n else if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[3])\n { // Pretty bracketted link\n var e;\n if(store.tiddlerExists(lookaheadMatch[4]))\n // ELS: ADDED\n if (isAttachment(lookaheadMatch[4]))\n {\n e = createExternalLink(w.output,lookaheadMatch[4]);\n e.href=getAttachment(lookaheadMatch[4]);\n e.title = config.messages.attachmentLinkTooltip + lookaheadMatch[4];\n }\n else\n // ELS: END\n e = createTiddlyLink(w.output,lookaheadMatch[4],false);\n else\n e = createExternalLink(w.output,lookaheadMatch[4]);\n w.outputText(e,w.nextMatch,w.nextMatch + lookaheadMatch[1].length);\n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n }\n }\n}\n//}}}\n// // ===\n\n// // +++[Utility API]\n//{{{\nfunction isAttachment(title)\n{\n var tiddler = store.getTiddler(title);\n if (tiddler==undefined || tiddler.tags==undefined) return false;\n return (tiddler.tags.find("attachment")!=null);\n}\n\nfunction getAttachment(title)\n{\n var theData = store.getTiddlerText(title);\n // remove header and embedded newlines from attachment text\n return "data:"+(theData.split('\sn----\sn'))[1].replace(/\s\sn/,'');\n}\n//}}}\n// // ===\n\n// // +++[explict global scoping for IE]\n//{{{\n// for functions/vars called from browser events\nwindow.onChangeAttachSource=onChangeAttachSource;\nwindow.onClickAttachCancel=onClickAttachCancel;\nwindow.onClickAttachOK=onClickAttachOK;\nwindow.isAttachment=isAttachment;\nwindow.getAttachment=getAttachment;\n//}}}\n// // ===\n\n// // +++[MIME Types]\n//{{{\nconfig.MIMETypes = [\n [" ", ""],\n [" txt text js vbs asp cgi pl ","text/plain"],\n [" htm html hta htx mht ", "text/html"],\n [" csv ", "text/comma-separated-values"],\n [" js ", "text/javascript"],\n [" css ", "text/css"],\n [" xml xsl xslt ", "text/xml"],\n [" ", ""],\n [" gif ", "image/gif"],\n [" jpg jpe jpeg ", "image/jpeg"],\n [" png ", "image/png"],\n [" bmp ", "image/bmp"],\n [" tif tiff ", "image/tiff"],\n [" ", ""],\n [" au snd ", "audio/basic"],\n [" wav ", "audio/wav"],\n [" ra rm ram ", "audio/x-pn-realaudio"],\n [" mid midi ", "audio/x-midi"],\n [" mp3 ", "audio/mp3"],\n [" m3u ", "audio/m3u"],\n [" ", ""],\n [" asf ", "video/x-ms-asf"],\n [" avi ", "video/avi"],\n [" mpg mpeg ", "video/mpeg"],\n [" qt mov qtvr ", "video/quicktime"],\n [" ", ""],\n [" pdf ", "application/pdf"],\n [" rtf ", "application/rtf"],\n [" ai eps ps ", "application/postscript"],\n [" ", ""],\n [" wpd ", "application/wordperfect"],\n [" wri ", "application/mswrite"],\n [" xls xls3 xls4 xls5 xlw ", "application/msexcel"],\n [" doc ", "application/msword"],\n [" ppt pps ", "application/mspowerpoint"],\n [" swa ", "application/x-director"],\n [" swf ", "application/x-shockwave-flash"],\n [" ", ""],\n [" zip ", "application/x-zip-compressed"],\n [" gz ", "application/x-gzip"],\n [" rar ", "application/x-rar-compressed"],\n [" com exe dll ocx ", "application/octet-stream"],\n [" ", ""],\n [" wml ", "text/vnd.wap.wml"],\n [" wmls ", "text/vnd.wap.wmlscript"],\n [" wbmp ", "image/vnd.wap.wbmp"],\n [" wmlc ", "application/vnd.wap.wmlc"],\n [" wmlsc ", "application/vnd.wap.wmlscriptc"]];\n//}}}\n// // ===\n\n// // +++[control panel interaction]\n//{{{\nfunction onChangeAttachSource()\n{\n var theFilename = document.getElementById("attachSource").value;\n var theExtension = theFilename.substr(theFilename.lastIndexOf('.')+1).toLowerCase();\n for (var i=0; i<config.MIMETypes.length; i++)\n if (config.MIMETypes[i][0].indexOf(theExtension)!=-1)\n {\n document.getElementById("attachMIMEType").value = config.MIMETypes[i][1];\n document.getElementById("attachMIMEType").selectedIndex = i;\n break;\n }\n}\n\nfunction onClickAttachCancel()\n{\n document.getElementById("attachPanel").style.display="none";\n}\n\nfunction onClickAttachOK()\n{\n var theSource = document.getElementById("attachSource").value;\n var theTags = "attachment excludeMissing "+document.getElementById("attachTags").value;\n var theMIMEType = document.getElementById("attachMIMEType").value;\n if (theMIMEType=="") return;\n var theData = loadBinaryFile(theSource); if (!theData) return;\n var theEncoded = encodeBase64(theData);\n var theTiddler = new Tiddler();\n var theTitle = theSource.replace(/\s\s/g,"/");\n var theTitle = theTitle.substr(theTitle.lastIndexOf('/')+1);\n var theText = "";\n if (theMIMEType.substr(0,5)=="image") theText+='[img['+theTitle+'|'+theTitle+']]\sn';\n theText += 'attachment: [['+theTitle+'|'+theTitle+']]\sn';\n theText += 'original size: '+theData.length+' bytes, encoded size: '+theEncoded.length+' bytes\sn';\n theText += '//{{{\sn';\n theText += '\sn----\sn';\n theText += theMIMEType + ";base64,\sn" + theEncoded;\n theText += '\sn----\sn';\n theText += '\sn//}}}\sn';\n theTiddler.set(theTitle,theText,config.options.txtUserName,new Date(),theTags);\n store.addTiddler(theTiddler);\n store.setDirty(true)\n clearMessage(); displayMessage('Attached '+theTitle);\n document.getElementById("attachPanel").style.display="none";\n story.displayTiddler(null,theTiddler.title,1,null,null,false);\n store.notifyAll();\n}\n//}}}\n// // ===\n\n// // +++[Binary to text encoding]\n//{{{\nfunction encodeBase64(theData)\n{\n if (!theData) return null;\n // encode as base64\n var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";\n var out = ""; //This is the output\n var chr1, chr2, chr3 = ""; //These are the 3 bytes to be encoded\n var enc1, enc2, enc3, enc4 = ""; //These are the 4 encoded bytes\n for (var count=0,i=0; i<theData.length; )\n {\n chr1 = theData.charCodeAt(i++); //Grab the first byte\n chr2 = theData.charCodeAt(i++); //Grab the second byte\n chr3 = theData.charCodeAt(i++); //Grab the third byte\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n if (isNaN(chr2))\n enc3 = enc4 = 64;\n else if (isNaN(chr3))\n enc4 = 64;\n out += keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4);\n chr1 = chr2 = chr3 = "";\n enc1 = enc2 = enc3 = enc4 = "";\n count+=4; if (count>60) { out+='\sn'; count=0; } // add line break every 60 chars for readability\n }\n return out;\n}\n//}}}\n// // ===\n\n// // +++[Binary File I/O]\n//{{{\nfunction loadBinaryFile(fileUrl)\n{\n var r = mozillaLoadBinaryFile(fileUrl);\n if((r == null) || (r == false))\n r = ieLoadBinaryFile(fileUrl);\n return(r);\n}\n\nfunction mozillaLoadBinaryFile(filePath)\n{\n if(window.Components)\n try \n {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);\n file.initWithPath(filePath);\n if (!file.exists())\n return(null);\n var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);\n inputStream.init(file, 0x01, 00004, null);\n var bInputStream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);\n bInputStream.setInputStream(inputStream);\n return(bInputStream.readBytes(inputStream.available()));\n }\n catch(e)\n {\n alert("Exception while attempting to attach\sn\sn" + e);\n return(false);\n }\n return(null);\n}\n\nfunction ieLoadBinaryFile(filePath)\n{\n // TBD: load BINARY, not TEXT file\n // return(ieLoadFile(filePath));\n // alert("ieLoadBinaryFile(): not yet implemented...sorry");\n // return(null);\n try\n {\n var stream = new ActiveXObject("ADODB.Stream");\n }\n catch(e)\n {\n alert("Exception while attempting to attach\sn\sn" + e.toString());\n return(null);\n }\n stream.Type = 'adTypeBinary';\n stream.Open();\n stream.LoadFromFile(filePath);\n var content = stream.Read();\n stream.Close();\n return(content);\n\n}\n//}}}\n// // ===\n
/***\n''Auto Tagger Plugin for TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#AutoTaggerPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nAutomatically tag tiddlers with their original creation date and author and optionally scan the tiddler content for any tags that are embedded as text. Makes cross-referencing your tiddlers a snap!\n\n!!!!!Usage\n<<<\nWhen ~AutoTagger is present, it automatically ''generates 'creation date' and 'creator' tag values'' for all newly created tiddlers, so that this information is retained even after a tiddler has been updated many times. In addition, if you enter ''//auto//'' as a tiddler tag value, ~AutoTagger ''scans the tiddler content'' (including title) for all existing tags, and ''automatically adds any embedded tags that it finds''.\n\nAfter they have been added to the tiddler, the new tags are treated just as if you had entered them by hand and can be edited to make any changes you want. Of course, as long as the "auto" tag is still present on a tiddler, ~AutoTagger will re-scan that tiddler's content each time it is edited. If you DO edit the generated tags, you can remove the "auto" tag from the tiddler to prevent it from being re-scanned when you press 'done' to finish editing.\n\n//Note: the special-purpose ''"systemConfig" and "systemTiddler" tags are not added automatically, even if matched in the tiddler content'', since these tags should be added manually to ensure they are always used appropriately)//\n\n//Note: if you have set the "auto" tag on a tiddler, and then add several tags to your document, those tags will ''not'' be automatically added to the tiddler until you actually edit that tiddler and press 'done' to trigger an AutoTagger scan.//\n<<<\n!!!!!Configuration\n<<<\nThe ~AutoTagger plugin comes with a ''self-contained control panel''. Use these controls to enable or disable automatic 'creation date' or 'creator' tagging, modify the default date formatting, or redefine the special 'scan trigger' tag value (so you can use "auto" as a normal tag value in your document).\n\n<<option chkAutoTagAuthor>> add 'created by' tag //(when a tiddler is first created)//\n<<option chkAutoTagDate>> add 'creation date' tag, using date format: <<option txtAutoTagFormat>>\n<<option chkAutoTagEditor>> add 'edited by' tag //(when a tiddler is updated)//\nscan tiddler content for new tags when tagged with: <<option txtAutoTagTrigger>>\n----\n//date formatting syntax://\n^^//''DDD'' - day of week in full (eg, "Monday"), ''DD'' - day of month, ''0DD'' - adds leading zero//^^\n^^//''MMM'' - month in full (eg, "July"), ''MM'' - month number, ''0MM'' - adds leading zero//^^\n^^//''YYYY'' - full year, ''YY'' - two digit year//^^\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''AutoTaggerPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2005.10.09 [1.3.0]''\nAdded 'edited by' tagging\nCombined documentation and code into a single tiddler\n''2005.08.16 [1.2.0]''\nAdded optional scanning for tags in tiddler content (based on suggestion from Jacques Turbé)\n''2005.08.15 [1.1.0]''\nAdded 'created by' tag generation (based on suggestion from Elise Springer)\nRenamed from DateTag to AutoTagger\n''2005.08.15 [1.0.0]''\nInitial Release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].\n<<<\n!!!!!Code\n***/\n// // 1.2.x compatibility\n//{{{\nif (!window.story) window.story=window;\nif (!store.getTiddler) store.getTiddler=function(title){return store.tiddlers[title]}\nif (!store.addTiddler) store.addTiddler=function(tiddler){store.tiddlers[tiddler.title]=tiddler}\nif (!store.deleteTiddler) store.deleteTiddler=function(title){delete store.tiddlers[title]}\n//}}}\n\n//{{{\nversion.extensions.autoTagger = {major: 1, minor: 3, revision: 0, date: new Date(2005,10,9)};\n\nif (config.options.chkAutoTagDate==undefined)\n config.options.chkAutoTagDate=false;\nif (config.options.chkAutoTagEditor==undefined)\n config.options.chkAutoTagEditor=false;\nif (config.options.chkAutoTagAuthor==undefined)\n config.options.chkAutoTagAuthor=false;\nif (config.options.txtAutoTagTrigger==undefined)\n config.options.txtAutoTagTrigger="auto";\nif (config.options.txtAutoTagFormat==undefined)\n config.options.txtAutoTagFormat="YYYY.0MM.0DD";\n\n// hijack store.saveTiddler()\nstore.coreSaveTiddler = store.saveTiddler;\nstore.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags)\n{\n // get the tags as passed from the tiddler editor\n var newTags = [];\n if (tags) newTags = (typeof tags == "string") ? tags.readBracketedList() : tags;\n\n // if saving a new tiddler, add 'creation date' tag\n if (config.options.chkAutoTagDate && (store.getTiddler(title)==undefined))\n newTags.pushUnique(new Date().formatString(config.options.txtAutoTagFormat));\n // if saving a new tiddler, add 'created by' tag\n if (config.options.chkAutoTagAuthor && (store.getTiddler(title)==undefined))\n newTags.pushUnique(config.options.txtUserName);\n // if saving an existing tiddler, add 'edited by' tag\n if (config.options.chkAutoTagEditor && (store.getTiddler(title)))\n newTags.pushUnique(config.options.txtUserName);\n\n // if tagged for scanning, find tags embedded in text of tiddler title/body\n var allTags = store.getTags();\n if ((config.options.txtAutoTagTrigger!="") && (newTags.find(config.options.txtAutoTagTrigger)!=null))\n for (var t=0; t<allTags.length; t++)\n {\n // note: don't automatically tag a tiddler with 'systemConfig' or 'systemTiddler'\n if ((allTags[t][0]=='systemConfig') || (allTags[t][0]=='systemTiddler'))\n continue;\n if ((newBody.indexOf(allTags[t][0])!=-1) || (newTitle.indexOf(allTags[t][0])!=-1))\n newTags.pushUnique(allTags[t][0]);\n }\n\n // pass it all on to the core TW to be saved in the data store.\n return store.coreSaveTiddler(title,newTitle,newBody,modifier,modified,newTags);\n}\n//}}}
!! En bref\nLe bios a pour rôle de :\n* faire l’initialisation du processeur, des SDRAM, et du bus externe.\n* lire les premiers blocs de la FLASH contenant le bootloader, les charger en RAM, et lancer ce bootloader.\nIl pourra éventuellement à terme contenir les stubs gdb de sh-ipl-g+, permettant un debug interactif du noyau...\n\nCe bios n’a de bios que le nom : il est appelé ainsi pour éviter d’avoir à distinguer entre bootloader de niveau 1 (dans le Stratix) et bootloader de niveau 2 (en flash). Ses possibilités étant fortement limitées, il peut ainsi garder une taille négligeable (moins de 1ko : 796 octets).\n\nLe bios peut aussi être compilé dans un mode spécial, auquel cas il contient aussi le bootloader. Cela permet de flasher le bootloader en flash lors de la première utilisation d'une carte vierge. Plus de détail à la fin de la rubrique...\n\n!! Internals\n\n!!! Initialisation basique\n\nLe [[Bios]] commence par positionner le pointeur de pile (par convention {{{r15}}}) à la valeur du symbole {{{top_stack}}} définit dans le script de link (cf mapping mémoire). Puis il saute à la routine de configuration du bus externe. Une fois cette routine exécutée, on peut alors sauter à la fonction {{{main}}}. Attention, le BSS n'est pas mis à zéro, le segment de data n'est pas recopié (cf mapping mémoire).\n{{{\n_start:\n ! Init Stack\n mov.l stackend,r15\n \n ! Init SHIX hardware\n mov.l initbus_addr,r1\n jsr @r1\n nop\n\n ! from now on, we can use C (yesss!)\n ! Call program entry point\n mov.l main_addr,r1\n jsr @r1\n nop\n}}}\n\n!!! Initialisation du bus\n* {{{BCR1}}} = {{{0x8000000C}}} : little-endian, master, pull-up sur toutes les lignes, aucune zone en byte-control, refresh prioritaire sur DMA, Area0, Area5, Area6 en SRAM, Area2 et Area3 en SDRAM\n* {{{BCR2}}} = {{{0xFFFD}}} : toutes les zones sont en 32bits, et port[32:51] en GPIO\n* {{{BCR3}}} = {{{0x0001}}} : Area1 et Area4 en SRAM, Burst length = 4 pour la SDRAM\n* {{{BCR4}}} = {{{0x0000}}} : toutes les lignes sont synchrones\n* {{{WCR1}}} = {{{0x11111110}}} : 1 cycle de wait-state lors du passage de {{{read}}} à {{{write}}}, sauf pour Area0 (0 cycle).\n* {{{WCR2}}} = {{{0x24924449}}} : toutes les zones SRAM en 1 wait-state + ping {{{RDY_n}}}, CAS latency=2 pour la SDRAM\n* {{{WCR3}}} = {{{0x00000000}}} : pas de setup ni hold time additionnel pour les zones en SRAM\n\n\n!!! Mapping mémoire\n\nLe bios réside en {{{0xa000_0000}}}. Le kernel réside en {{{0xa800_0000}}} (RAM0). Le [[bootloader|BootLoader]] doit donc résider en {{{0xac00_0000}}} (RAM1). Le chargement de l'exécutable ([[bootloader|BootLoader]]) a donc lieu de la flash vers {{{0xac00_0000}}}.\n\nLe bios réside donc en {{{0xa000_0000}}} (P2, non cachée) qui est l'adresse de reset. \n\nLe pointeur de pile est à la fin de la RAM0 ({{{0xa8fffffc}}}). Il est positioné par le symbole {{{top_stack}}} définit par [[ld|LD]] au moment du link.\n\nPour avoir une ROM la plus petite possible, on supprime les segments {{{bss}}} et {{{data}}} (voir la page sur [[ld|LD]] pour plus de détails sur les sections). Pour cela, on n'utilise que des variables locales et non statiques (qui seront sur la pile, sauf les constantes qui seront dans {{{rodata}}}). Le script de link ci-dessous s'assure que les sections {{{bss}}} et {{{data}}} sont bien vides et définit le symbole {{{top_stack}}} pour le positionnement du pointeur de pile :\n{{{\n/*OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")\n\nOUTPUT_ARCH(sh)*/\n\nMEMORY\n{\n ROM (rx): ORIGIN = 0xa0000000, LENGTH = 24k\n RAM0 (rw): ORIGIN = 0xa8000000, LENGTH = 16M\n RAM1 (rw): ORIGIN = 0xac000000, LENGTH = 16M\n\n /* fake bss region to ensure bss is empty */\n BSS (w): ORIGIN = 0, LENGTH = 0\n\n /* fake data region to ensure data is empty */\n DATA (w): ORIGIN = 0, LENGTH = 0 \n}\n\nSECTIONS\n{\n\n .text :\n {\n init.o(.text)\n *(.text)\n *(.*rodata*)\n } > ROM\n\n\n /* data and bss should be empty... */\n .data : { *(.data) } > DATA\n .bss : { *(.bss) } > BSS\n \n /* stack : on met la pile en RAM0 */\n top_stack = ORIGIN(RAM0) + LENGTH(RAM0) - 4;\n\n .stab :\n {\n *(.stab)\n }\n .comment :\n {\n *(.comment)\n }\n .stabstr :\n {\n *(.stabstr)\n }\n}\n}}}\n\n\n!!! Chargement et exécution\n\nPour lire et charger le noyau Linux, on lit en fait les deux premières partitions :\n* la première (1bloc = 32 pages = 16ko) contient les données critiques (arguments du noyau, table de partition éventuelle, ...)\n* la deuxième ( 39 blocs = 1248 pages = 624ko) contient le bootloader.\nOn recopie le tout linéairement en RAM, on se retrouvera donc en RAM avec le mapping suivant :\n* {{{0xac00_0000 - 0xac00_3FFF}}} : données de la partition 0\n* {{{0xac00_4000 - 0xac09-BFFF}}} : données de la partition 1 (bootloader)\n\nLe premier bloc est garanti sans fautes, donc tout va bien. Pour le bootloader (partition 1), on ne lit que les blocs marqués valides. Pour garder le [[bootloader|BootLoader]] à une taille minimale, on ignore les ECC. Ce sera lors du flashage du [[bootloader|BootLoader]] qu'on écrira et relira les ECC pour vérifier que les blocs sont non-défectueux.\n\nUne fois qu'on a recopié les deux partitions en RAM, on saute en {{{0xac00_4000}}}, qui est l'adresse de {{{start}}} du [[bootloader|BootLoader]].\n\n!!! Mode first-flash\n\nLors de la première utilisation d'une carte, la flash est vierge. Or le flashage du noyau et des autres partitions est effectué par le [[bootloader|BootLoader]], qui est normalement lu en flash par le [[bios|Bios]] ! Il y a donc un problème d'oeuf et de poule (pour écrire le [[bootloader|BootLoader]] en flash on a justement besoin de lire le [[bootloader|BootLoader]] en flash).\nPour résoudre ce problème, le [[bios|Bios]] peut être compilé dans un mode spécial, en lui passant le flag //FLASH// : {{{make FLASH=1 && make FLASH=1 copy}}}. Il embarque alors une copie du [[bootloader|BootLoader]], qu'il va recopier en RAM et exécuter. \n\n''Note'' : la ROM dans le Stratix doit alors être suffisament grande pour accueillir le bios plus le bootloader, soit 32k minimum...\nLa manipulation est la suivante :\n# compilation du bios en mode "premier flash" : {{{make clean && make FLASH=1 && make FLASH=1 copy}}} (penser à changer au besoin les chemins dans le {{{Makefile}}}).\n# compilation de la ROM du Stratix avec le bios spécial : lancer {{{Quartus}}}, modifier la taille de la ROM pour qu'elle fasse au moins 8k x 32 (penser à changer aussi le nombre de lignes d'adresses dans {{{top.v}}}). Pour plus d'informations sur comment compiler, cf. la rubrique [[Configuration Stratix]]. On peut aussi utiliser le fichier de programmation {{{first_flash.pof}}}, disponible dans l'archive de départ (cf. rubrique [[Configuration Stratix]]), qui contient déjà le [[bios|Bios]] en mode "first-flash". Flashage de l'EPC8 puis reboot (off / on).\n# utilisation du [[bootloader|BootLoader]] pour flasher :\n** le bootloader : {{{lr}}} puis {{{flash 1}}} \n** le noyau Linux : {{{lr}}} puis {{{flash 2}}} \n** le root filesystem YAFFS : {{{lr}}} puis {{{flash -raw 3}}} \n# recompilation du bios en mode normal : {{{make clean && make && make copy}}}\n# modification inverse de la ROM dans le Stratix, puis flash de l'~EPC8.\n\n''Note'' : Pour les personnes ne disposant pas de moyens de recompilation, les différents fichiers (bootloader, kernel et rootfs sont disponibles ici :\n* kernel : http://perso.enst.fr/~polti/realisations/shix20/zImage\n* bootloader : http://perso.enst.fr/~polti/realisations/shix20/bootloader.bin\n* root FS : http://perso.enst.fr/~polti/realisations/shix20/rootfs_2.6.15.1-sh.img.yaffs\n* modules : si on met à jour noyau, il faut généralement mettre aussi à jour les modules. Plutôt que reflasher entièrement un file-system, on peut juste récupérer les modules ici (à décompresser dans {{{/lib}}}) : http://perso.enst.fr/~polti/realisations/shix20/modules.tgz\n* {{{.config}}} utilisé pour la génération du kernel et des modules ci-dessus : http://perso.enst.fr/~polti/realisations/shix20/.config\n\n
!Boot du processeur\n\nLa flash branchée sur le bus GPIO du SH4 étant une flash NAND, le SH4 ne peut pas booter directement dessus. Une ROM de boot est donc instanciée dans le Stratix : elle contient le minimum de code pour initialiser le processeur, les SDRAM, et accéder à la flash. Pour éviter de gâcher de la place dans le Stratix, il est nécessaire de garder cette ROM la plus petite possible.\n\nPour cela, le boot se décompose en deux étapes : la ROM instanciée dans le Stratix contient un bios minimal, qui fait l’initialisation du processeur, puis va lire les premières pages de la flash contenant un bootloader plus évolué, et l’exécute. Dans la suite de ce document, on appelera [[bios|Bios]] le code contenu dans la ROM instanciée dans le Stratix, et [[bootloader|BootLoader]] celui (plus évolué) stocké en flash.\n\nLe [[bios|Bios]] a pour rôle de :\n* faire l’initialisation du processeur, des SDRAM, du bus externe,\n* lire les premiers blocs de la FLASH contenant le bootloader, les charger en RAM, et lancer ce bootloader.\n* Il a aussi la possibilité de recevoir un exécutable par le port série et de l’exécuter.\nIl pourra éventuellement à terme contenir les stubs gdb de sh-ipl-g+, permettant un debug interactif du noyau...\n\nCe [[bios|Bios]] n’a de bios que le nom : il est appelé ainsi pour éviter d’avoir à distinguer entre bootloader de niveau 1 (dans le Stratix) et bootloader de niveau 2 (en flash). Ses possibilités étant fortement limitées, il peut ainsi garder une taille négligeable (moins de 2ko).\n\nLe [[bootloader|BootLoader]] a un rôle plus complexe :\n* initialisation des ports série\n* lancement du noyau Linux :\n** lecture du noyau en flash, et recopie en RAM,\n** lecture en flash des arguments pour le noyau, et donner à l’utilisateur la possibilité de les modifier de façon interactive,\n** lancement du noyau avec les bons paramètres,\n* maintenance des flashs (scan des bad blocks, reset de leur statut, effacement de partitions, . . . )\n* maintenance des fichiers (récupération d’images de partition, flashage du root file system, ajout/suppression de fichiers, mise à jour du bootloader, . . . )\n* ...
!! Rôle\nLe [[bootloader|BootLoader]] a un rôle plus complexe que celui du [[bios|Bios]] :\n* lancement du noyau Linux:\n** lecture du noyau en flash, et recopie en RAM,\n** lecture en flash des arguments pour le noyau, et donner à l’utilisateur la possibilité de les modifier de façon interactive,\n** lancement du noyau avec les bons paramètres,\n* maintenance des flashs\n** scan des bad blocks,\n** reset de leur statut, \n** effacement de partitions,\n* maintenance des fichiers \n** récupération d’images de partition par la ligne série,\n** flashage d'une image de partition,\n** ...\n\n!! Utilisation\n\nAu lancement, le bootloader affiche un message de bienvenue et un prompt : \n{{{\nBootloader v2.0\n>\n}}}\n\nSi on tape un caractère à la ligne série dans les deux secondes environ, on prend la main et le bootloader attend des commandes de la part de l'utilisateur. Sinon, il recherche la partition du noyau, charge le noyau en RAM, et le lance en lui passant les arguments qui ont été sauvegardés.\n\nLe mode interactif supporte la quasi-totalité des facilités du clavier (flèches, home, suppr, back, etc.). Il supporte aussi les échappements typiques des xterm : {{{CTRL+b}}}, {{{CTRL+f}}}, {{{CTRL+k}}}, ... \n\nLes commandes disponibles sont résumés en tapant {{{help}}} (ou n'importe quel mot invalide) :\n* {{{help}}} : affiche l'aide du bootloader\n* {{{lrz}}} : réceptionne un fichier sur la ligne série SCI en mode zmodem. Pour l'instant, non implémenté.\n* {{{lr}}} : réceptionne un fichier sur la ligne série en mode //raw binary// (binaire pur, sans protocole). Le fichier reçu est stocké dans un tampon en RAM.\n* {{{flash [-raw] n}}} : flash le fichier précédement reçu dans la partition dont on passe le numéro {{{n}}}en argument. Les OOB (ECC, ...) sont automatiquement insérés au bon endroit. L'option {{{-raw}}} permet de ne pas les insérer, au cas où on flashe une image qui le contient déjà. Le flashage saute automatiquement les blocs défectueux. On a la possibilité de reflasher manuellement le MBR et la partition du bootloader. Pour éviter les erreurs de manipulations, l'accès aux partitions MBR ({{{0}}}) et bootloader ({{{1}}}) demande confirmation de l'utilisateur (avec un message suffisament compliqué pour forcer à réfléchir...).\n* {{{scan}}} : scan manuel des flash pour avoir la liste des blocs défectueux.\n* {{{erase [-f] n}}} : efface la partition dont on passe le numéro {{{n}}} en argument. L'option {{{-f}}} permet de remettre les marqueurs de validité des blocs à zéro, dans le cas où un bloc aurait été marqué invalide par erreur. Attention, cette option n'est à utiliser que si on sait précisément ce qu'on fait...\n* {{{cmd}}} : permet d'éditer la ligne de commande qui sera passée au noyau. On a la possibilité de la sauver aussi en flash, elle devient alors la ligne de commande par défaut. Si on se trompe dans la ligne de commande, {{{CTRL+c}}} permet de quitter l'éditeur sans rien modifier.\n* {{{boot}}} : boote le kernel. ''A compléter''\n* {{{part}}} : liste les partitions de la flash\n* {{{edpart}}} : lance l'éditeur de partitions. C'est un éditeur basique qui permet de modifier / supprimer / ajouter des partitions. Il est configuré pour ne pas pouvoir modifier ni la taille ni le type des deux premières partitions (MBR et bootloader). Il vérifie automatiquement la validité des partitions créées (non superposition, taille correcte, ...). En cas d'erreur, la commande {{{q}}} permet d'en sortir sans sauvegarder les changements. Chaque partition dispose d'un type, qui est ignoré : il n'a qu'une valeur informative, sauf pour la partition contenant le noyau. Lors du boot, le bootloader cherche le noyau sur la première partition de type {{{Kernel}}}.\n* {{{dump -[nb] n}}} : commande de debug pour dumper les {{{nb}}} premiers octets d'une partition. Si {{{nb}}} n'est pas spécifié, il vaut 128 par défaut.\n\n!! Flashage d'un nouveau noyau\n\nLes noyaux Linux se présentent généralement sous deux formats : \n* le noyau exécutable ({{{vmlinux}}}), généralement de grosse taille, surtout s'il contient les symboles de débuggage\n* une image compressée ({{{zImage}}}), qui se décompresse seule au moment du boot.\nLe noyau doit être compilé pour être chargé en {{{0x88000000}}} et s'exécuter en {{{0x88002000}}} :\n* {{{CONFIG_MEMORY_START=0x08000000}}}\n* {{{CONFIG_ZERO_PAGE_OFFSET=0x00001000}}} (ce n'est pas une erreur de frappe : à ce chiffre est ajouté un offset supplémentaire de {{{0x1000}}}, d'où l'adresse d'exécution).\nL'image compressée ({{{zImage}}}), elle, doit être compilée pour être chargée et exécutée en {{{0x88800000}}} :\n* {{{CONFIG_BOOT_LINK_OFFSET=0x00800000}}}\n\nLe bootloader différencie le type d'image par la convention suivante :\n* un fichier au format ELF est un noyau pur,\n* un fichier binaire plat est une image compressée.\nAutrement dit, pour flasher un noyau non compressé, on flashera directement le noyau ELF ({{{linux-2.6.15.1/vmlinux}}}), tandis que pour flasher une image compressée, on ira flasher l'image binaire compressée {{{linux-2.6.15.1/arch/sh/boot/zImage}}}.\n\nLe fichier {{{arch/sh/boot/compressed/vmlinux}}} ''ne doit pas'' être utilisé ! C'est une image compressée mais au format ELF, elle serait donc mal interprété par le bootloader, et chargée à la mauvaise adresse...\n\n!! Architecture\n\nCette section décrit l'architecture interne du bootloader, ce qu'il fait, pourquoi, et comment... \n\n!!!Initialisation\n\nLe bios effectue une initialisation sommaire du hardware. Le bootloader initialise le reste.\nIl commence par re-positionner le pointeur de pile. Comme on ne reviendra jamais au bios, pas besoin de perdre de la place. Le pointeur de pile est donc remis à sa position d'origine.\nPuis le bootloader initialise les caches, de la façon suivante :\n* le [[bios|Bios]] exécute le bootloader à partir de l'adresse {{{0xac000000}}} qui se situe en zone P2, non cachée. \n* les première instructions du bootloader initialisent le cache (cache I et D, 32k, copy-back). Puis délai de 4 {{{nop}}}.\n* enfin, l'ensemble du code du bootloader étant linké à l'adresse {{{0x8C000000}}}, tous les sauts successifs se font en une zone cachée (P0).\n* le saut à la fonction {{{main}}} aboutit donc dans une zone cachée.\n\nLa fonction {{{main}}} initialise les ports série, reset les flashs, reconstruit (silencieusement) la table des bad blocks, puis lance l'interpéteur de commande si on a reçu un caractère sur SCI dans la seconde. Sinon, il boote le noyau, en lui passant en argument la ligne de commande stockée dans le MDR (partition 0) de la flash.\n\n!!! Paramètres en flash\nLe premier bloc de la flash contient des paramètres, tels que la table de partition, la ligne de commande du noyau, ... Au lancement du bootloader, le [[bios|Bios]] a déjà chargé ce bloc en RAM. On a donc au lancement du bootloader l'état suivant de la RAM :\n* {{{0xac000000-0xac003fff}}} : premier bloc de la flash (MBR)\n* {{{0xac004000-0xac0xxxxx}}} : bootloader\nLe botloader possède une variable interne ({{{data_flash}}}, de la même taille que le premier bloc de la flash, située en {{{0xac000000}}} par les instructions {{{u8 data_flash[512*32] __attribute__ ((section (".flash_part0"))) = { 0 }; }}}. Au lancement du bootloader, elle contient donc une image du premier bloc de la flash. Le bootloader n'a donc pas besoin de lire le premier bloc de la flash. \n\nLes paramètres en flash :\n* page 0\n** magic number (0xbabebabe)\n** table des partitions\n** magic numer (0xdeadbeef)\n** garbage...\n* page 1\n** magic number (0xfeedbabe)\n** ligne de commande par défaut du noyau (terminée par un {{{0}}})\n** magic number (0xbabefeed)\n\nOn pourra stocker d'autres paramètres plus tard (historique, quand il sera implémenté, ...).\n\n!!! Boot Linux\nLe noyau Linux admet le passage d'arguments par deux moyens : précompilés et en ligne de commande du bootloader.\nOn a dans {{{include/asm/setup.h}}} la taille maximum de la ligne de commande (256). Le fichier {{{arch/sh/kernel/setup.c}}} est en charge de traiter la ligne de commande.\nOn a ceci :\n{{{\n#define PARAM ((unsigned char *)empty_zero_page)\n\n#define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000))\n#define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004))\n#define ORIG_ROOT_DEV (*(unsigned long *) (PARAM+0x008))\n#define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c))\n#define INITRD_START (*(unsigned long *) (PARAM+0x010))\n#define INITRD_SIZE (*(unsigned long *) (PARAM+0x014))\n/* ... */\n#define COMMAND_LINE ((char *) (PARAM+0x100))\n\n#define RAMDISK_IMAGE_START_MASK 0x07FF\n#define RAMDISK_PROMPT_FLAG 0x8000\n#define RAMDISK_LOAD_FLAG 0x4000 \n\nstatic char command_line[COMMAND_LINE_SIZE] = { 0, };\n}}}\n\nLa fonction {{{void __init setup_arch(char **cmdline_p)}}} :\n* prend en argument un pointeur qui contiendra l'adresse de la ligne de commande une fois parsée (pour {{{/proc/cmdline)}}}\n* effectue éventuellement la recopie dans {{{COMMAND_LINE}}} de la ligne précompilée, si on l'a demandé lors de la compilation du noyau : {{{strcpy(COMMAND_LINE, CONFIG_CMDLINE);}}}\n* appelle {{{parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable);}}}\n\nLa fonction {{{parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable);}}} : ''A compléter''\n\n\n\n
! Le bus ~SH4\n\nLe bus mémoire du processeur est un point critique du design. Il comporte 26 lignes d'adresse, de 8 à 64 lignes de données, des signaux de contôle, et des signaux d'arbitration. \n\nLes 32 lignes de données de poids fort sont partagées avec les {{{GPIO}}} du ~SH4. Il a donc fallu choisir entre {{{GPIO}}} et bus 64 bits. J'ai préféré utiliser les {{{GPIO}}} pour des LED et la flash NAND, et restreindre le bus données à 32 bits.\n\nL'étude du bus doit être séparée en deux parties :\n* son [[fonctionnement électrique|BusElectrique]]\n* son [[fonctionnement logique|BusLogique]]\n
! Fonctionnement électrique du bus ~SH4\nLe bus externe du ~SH4 ne peut fonctionner à fréquence maximale (80Mhz) que si sa charge est limitée. Les timings donnés dans la datasheet portent sur un bus chargé à 30pF, pouvant alors atteindre\nsa fréquence max. Une charge plus grande augmente les timings d'environ 1.5ns pour 25pF, et ralentit donc le bus, sans compter les 1.5nS de délai supplémentaires du au boîtier QFP.\n\nIl y a donc un compromis à faire entre le nombre de périphériques branchés directement sur le bus du ~SH4, et sa fréquence maximale. J'ai choisi arbitrairement de maximiser la fréquence du bus, et donc de limiter les périphériques y étant reliés aux deux SDRAM et au Stratix. Les autres périphériques (USB, ...) sont donc reliés au Stratix. Il est nécessaire d'implémenter un pont dans le Stratix pour que le ~SH4 puisse y accéder. \n\nLa charge du bus se répartit donc comme suit :\n* ~SH4 : 10pF par pin\n* Stratix : \n** bancs 1, 2, 5 et 6 : 8.2pF \n** bancs 3, 4, 7 et 8 : 11.5pF\n** horloges : de 4.4 à 11.5pF.\n* SDRAM : de 4.0 à 6.5pF selon le type de la pin.\n* PCB : 3pF environ.\n\nDes contraintes de placement ont fait que le banc 7 était le plus adpaté à la connexion avec le ~SH4, aboutissant ainsi à une charge d'environ 30.5pF. Le bus peut donc fonctionner à fréquence maximale\n(80MHz). Toutes les lignes du bus, horloge, données, adresses et contrôle, ont été simulées : temps de propagation, round trip délai, overshoot, undershoot, crosstalk, ... en se basant sur les modèles IBIS des constructeurs, garantissant ainsi le fonctionnement du bus, même à fréquence maximale.\n\n
! Fonctionnement logique du bus ~SH4\n\nLes adresses présentes sur le bus comportent 26 bits, représentant les 26 bits de poids faible de l'adresse physique de l'accès en cours. Pour un descriptif précis et complet de l'espage mémoire du SH4,\non se rapportera à sa datasheet.\n\nL'espace mémoire du SH4 est séparé en plusieurs niveaux : l'espace virtuel, propre à chaque processus, l'espace physique interne, et l'espace externe :\n* espace virtuel : il comporte 32 bits d'adresses. La MMU se charge de traduire les adresses virtuelles en des adresses physiques internes sur 32 bits aussi. Lorsque la MMU n'est pas utilisée, l'espace virtuel est le même que l'espace physique interne.\n* espace physique interne : séparé en plusieurs zones, appelées zones physiques ou zones internes : P0 à P4 en mode superviseur, et U0 en mode utilisateur. Ces zones diffèrent par le fait qu'elles sont ou non cachées : P2 et P4 sont non cachables, P1, P3 et U0 sont cachables. L'espace physique interne est ensuite mappé sur l'espace externe en supprimant les 3 bits de poids fort des adresses.\n* espace physique externe : séparé lui aussi en 8 zones, appelées zones externes, de même taille : Area0 à Area7, et disposant chacune de 26 bits d'adresse et son propre chip select. Le bus du ~SH4 sort donc 26 lignes d'adresse, et 7 chip select (le 8^^ème^^ n'est pas disponible).\n\nA partir d'une adresse virtuelle, on obtient donc\n* une adresse physique interne, par l'intermédiaire de la MMU,\n* puis une adresse physique externe par suppression de 3 + 3 bits de poids fort. Les premiers trois bits déterminent la zone physique (et l'accès ou non au cache), les derniers trois bits donnent la zone externe et donc le chip select.\n\nChaque zone externe est donc mappée dans plusieurs zones internes. Par exemple, Area0 est accessible dans la zone P0 (cachée), P1 (cachée), P2 (non-cachée), P3 (cachée), P4 (non cachée) et U0 (cachée). La zone Area7 étant réservée aux registres, un trou apparait donc dans chaque zone P0 à P4 / U0.\n\nOn a donc, pour les zones internes, en mode privilégié :\n| Adresse | Zone interne |h\n| 0x0000 0000 - 0x7FFF FFFF | P0 area, cachable |\n| 0x8000 0000 - 0x9FFF FFFF | P1 area, cachable |\n| 0xA000 0000 - 0xBFFF FFFF | P2 area, non-cachable |\n| 0xC000 0000 - 0xDFFF FFFF | P3 area, cachable |\n| 0xE000 0000 - 0xFFFF FFFF | P4 area, non-cachable |\n''Note'' : en mode utilisateur (non privilégié), le mapping des zones est différent. On se reportera à la datasheet du 7750 pour plus de précisions.\n\nEt chaque zone interne permet d'accéder aux zones externes, décrites ci-dessous (les adresses sont données ici pour un accès à partir de la zone interne P0) :\n| Adresse | Zone externe |h\n| 0x0000 0000 - 0x03FF FFFF | Area 0 (boot, ROM) |\n| 0x0400 0000 - 0x07FF FFFF | Area 1 (FPGA) |\n| 0x0800 0000 - 0x08FF FFFF | Area 2 (SDRAM 1, 16M) |\n| 0x0C00 0000 - 0x0CFF FFFF | Area 3 (SDRAM 2, 16M) |\n| 0x1000 0000 - 0x13FF FFFF | Area 4 (FPGA) |\n| 0x1400 0000 - 0x17FF FFFF | Area 5 (FPGA) |\n| 0x1800 0000 - 0x1BFF FFFF | Area 6 (FPGA) |\n| 0x1C00 0000 - 0x1FFF FFFF | Area 7 (reserved) |\n\nLe bus peut être configuré de différentes manières pour chaque zone externe, en terme de\n* type d'accès : SRAM, Burst ROM, byte controlled SRAM, multiplexé, SDRAM, PCMCIA,\n* nombre de wait state,\n* largeur de bus de données : 8, 16, 32 ou 64 bits.\nLa configuration de la zone 0 (celle de boot) est données par les lignes {{{MD[8:0]}}} lors d'un reset manuel.\nLa configuration des autres zones est déterminée par des registres internes, qui sont programmés par le boot loader. La configuration actuelle choisie est la suivante :\n* CS2 et CS3 : SDRAM, Cas latency 2, 32 bits\n* CS0, CS1, CS4, CS5, CS6 : 32 bits, SRAM, 1 wait state interne (+ autant qu'on veut supplémentaires par la pin {{{RDY_n}}})
/***\n''Name:'' Calendar plugin\n''Version:'' <<getversion calendar>> (<<getversiondate calendar "DD MMM YYYY">>)\n''Author:'' SteveRumsby\n\n''Configuration:''\n\n|''First day of week:''|<<option txtCalFirstDay>>|(Monday = 0, Sunday = 6)|\n|''First day of weekend:''|<<option txtCalStartOfWeekend>>|(Monday = 0, Sunday = 6)|\n\n''Syntax:'' \n|{{{<<calendar>>}}}|Produce a full-year calendar for the current year|\n|{{{<<calendar year>>}}}|Produce a full-year calendar for the given year|\n|{{{<<calendar year month>>}}}|Produce a one-month calendar for the given month and year|\n|{{{<<calendar thismonth>>}}}|Produce a one-month calendar for the current month|\n|{{{<<calendar lastmonth>>}}}|Produce a one-month calendar for last month|\n|{{{<<calendar nextmonth>>}}}|Produce a one-month calendar for next month|\n\n***/\n// //Modify this section to change the text displayed for the month and day names, to a different language for example. You can also change the format of the tiddler names linked to from each date, and the colours used.\n\n// // ''Changes by ELS 2005.10.30:''\n// // config.macros.calendar.handler()\n// // ^^use "tbody" element for IE compatibility^^\n// // ^^IE returns 2005 for current year, FF returns 105... fix year adjustment accordingly^^\n// // createCalendarDays()\n// // ^^use showDate() function (if defined) to render autostyled date with linked popup^^\n// // calendar stylesheet definition\n// // ^^use .calendar class-specific selectors, add text centering and margin settings^^\n\n//{{{\nconfig.macros.calendar = {};\n\nconfig.macros.calendar.monthnames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];\nconfig.macros.calendar.daynames = ["M", "T", "W", "T", "F", "S", "S"];\n\nconfig.macros.calendar.weekendbg = "#c0c0c0";\nconfig.macros.calendar.monthbg = "#e0e0e0";\nconfig.macros.calendar.holidaybg = "#ffc0c0";\n\n//}}}\n// //''Code section:''\n// (you should not need to alter anything below here)//\n//{{{\nif(config.options.txtCalFirstDay == undefined)\n config.options.txtCalFirstDay = 0;\nif(config.options.txtCalStartOfWeekend == undefined)\n config.options.txtCalStartOfWeekend = 5;\n\nconfig.macros.calendar.tiddlerformat = "0DD/0MM/YYYY"; // This used to be changeable - for now, it isn't// <<smiley :-(>> \n\nversion.extensions.calendar = { major: 0, minor: 6, revision: 0, date: new Date(2006, 1, 22)};\nconfig.macros.calendar.monthdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nconfig.macros.calendar.holidays = [ ]; // Not sure this is required anymore - use reminders instead\n//}}}\n\n// //Is the given date a holiday?\n//{{{\nfunction calendarIsHoliday(date)\n{\n var longHoliday = date.formatString("0DD/0MM/YYYY");\n var shortHoliday = date.formatString("0DD/0MM");\n\n for(var i = 0; i < config.macros.calendar.holidays.length; i++) {\n if(config.macros.calendar.holidays[i] == longHoliday || config.macros.calendar.holidays[i] == shortHoliday) {\n return true;\n }\n }\n return false;\n}\n//}}}\n\n// //The main entry point - the macro handler.\n// //Decide what sort of calendar we are creating (month or year, and which month or year)\n// // Create the main calendar container and pass that to sub-ordinate functions to create the structure.\n// ELS 2005.10.30: added creation and use of "tbody" for IE compatibility and fixup for year >1900//\n// ELS 2005.10.30: fix year calculation for IE's getYear() function (which returns '2005' instead of '105')//\n//{{{\nconfig.macros.calendar.handler = function(place,macroName,params)\n{\n var calendar = createTiddlyElement(place, "table", null, "calendar", null);\n var tbody = createTiddlyElement(calendar, "tbody", null, null, null);\n var today = new Date();\n var year = today.getYear();\n if (year<1900) year+=1900;\n if (params[0] == "thismonth")\n createCalendarOneMonth(tbody, year, today.getMonth());\n else if (params[0] == "lastmonth") {\n var month = today.getMonth()-1; if (month==-1) { month=11; year--; }\n createCalendarOneMonth(tbody, year, month);\n }\n else if (params[0] == "nextmonth") {\n var month = today.getMonth()+1; if (month>11) { month=0; year++; }\n createCalendarOneMonth(tbody, year, month);\n }\n else {\n if (params[0]) year = params[0];\n if(params[1])\n createCalendarOneMonth(tbody, year, params[1]-1);\n else\n createCalendarYear(tbody, year);\n }\n}\n//}}}\n\n//{{{\nfunction createCalendarOneMonth(calendar, year, mon)\n{\n var row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, true, year, mon);\n row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarDayHeader(row, 1);\n createCalendarDayRowsSingle(calendar, year, mon);\n}\n//}}}\n\n//{{{\nfunction createCalendarMonth(calendar, year, mon)\n{\n var row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, false, year, mon);\n row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarDayHeader(row, 1);\n createCalendarDayRowsSingle(calendar, year, mon);\n}\n//}}}\n\n//{{{\nfunction createCalendarYear(calendar, year)\n{\n var row;\n row = createTiddlyElement(calendar, "tr", null, null, null);\n var back = createTiddlyElement(row, "td", null, null, null);\n var backHandler = function() {\n removeChildren(calendar);\n createCalendarYear(calendar, year-1);\n };\n createTiddlyButton(back, "<", "Previous year", backHandler);\n back.align = "center";\n\n var yearHeader = createTiddlyElement(row, "td", null, "calendarYear", year);\n yearHeader.align = "center";\n yearHeader.setAttribute("colSpan", 19);\n\n var fwd = createTiddlyElement(row, "td", null, null, null);\n var fwdHandler = function() {\n removeChildren(calendar);\n createCalendarYear(calendar, year+1);\n };\n createTiddlyButton(fwd, ">", "Next year", fwdHandler);\n fwd.align = "center";\n\n createCalendarMonthRow(calendar, year, 0);\n createCalendarMonthRow(calendar, year, 3);\n createCalendarMonthRow(calendar, year, 6);\n createCalendarMonthRow(calendar, year, 9);\n}\n//}}}\n\n//{{{\nfunction createCalendarMonthRow(cal, year, mon)\n{\n var row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon], false, year, mon);\n createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+1], false, year, mon);\n createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+2], false, year, mon);\n row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarDayHeader(row, 3);\n createCalendarDayRows(cal, year, mon);\n}\n//}}}\n\n//{{{\nfunction createCalendarMonthHeader(cal, row, name, nav, year, mon)\n{\n var month;\n if(nav) {\n var back = createTiddlyElement(row, "td", null, null, null);\n back.align = "center";\n back.style.background = config.macros.calendar.monthbg;\n\n/*\n back.setAttribute("colSpan", 2);\n\n var backYearHandler = function() {\n var newyear = year-1;\n removeChildren(cal);\n createCalendarOneMonth(cal, newyear, mon);\n };\n createTiddlyButton(back, "<<", "Previous year", backYearHandler);\n*/\n var backMonHandler = function() {\n var newyear = year;\n var newmon = mon-1;\n if(newmon == -1) { newmon = 11; newyear = newyear-1;}\n removeChildren(cal);\n createCalendarOneMonth(cal, newyear, newmon);\n };\n createTiddlyButton(back, "<", "Previous month", backMonHandler);\n\n\n month = createTiddlyElement(row, "td", null, "calendarMonthname", name)\n// month.setAttribute("colSpan", 3);\n month.setAttribute("colSpan", 5);\n\n var fwd = createTiddlyElement(row, "td", null, null, null);\n fwd.align = "center";\n fwd.style.background = config.macros.calendar.monthbg; \n\n// fwd.setAttribute("colSpan", 2);\n var fwdMonHandler = function() {\n var newyear = year;\n var newmon = mon+1;\n if(newmon == 12) { newmon = 0; newyear = newyear+1;}\n removeChildren(cal);\n createCalendarOneMonth(cal, newyear, newmon);\n };\n createTiddlyButton(fwd, ">", "Next month", fwdMonHandler);\n/*\n var fwdYear = createTiddlyElement(row, "td", null, null, null);\n var fwdYearHandler = function() {\n var newyear = year+1;\n removeChildren(cal);\n createCalendarOneMonth(cal, newyear, mon);\n };\n createTiddlyButton(fwd, ">>", "Next year", fwdYearHandler);\n*/\n } else {\n month = createTiddlyElement(row, "td", null, "calendarMonthname", name)\n month.setAttribute("colSpan", 7);\n }\n month.align = "center";\n month.style.background = config.macros.calendar.monthbg;\n}\n//}}}\n\n//{{{\nfunction createCalendarDayHeader(row, num)\n{\n var cell;\n for(var i = 0; i < num; i++) {\n for(var j = 0; j < 7; j++) {\n var d = j + (config.options.txtCalFirstDay - 0);\n if(d > 6) d = d - 7;\n cell = createTiddlyElement(row, "td", null, null, config.macros.calendar.daynames[d]);\n\n if(d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))\n cell.style.background = config.macros.calendar.weekendbg;\n }\n }\n}\n//}}}\n\n//{{{\nfunction createCalendarDays(row, col, first, max, year, mon)\n{\n var i;\n for(i = 0; i < col; i++) {\n createTiddlyElement(row, "td", null, null, null);\n }\n var day = first;\n for(i = col; i < 7; i++) {\n var d = i + (config.options.txtCalFirstDay - 0);\n if(d > 6) d = d - 7;\n var daycell = createTiddlyElement(row, "td", null, null, null);\n var isaWeekend = ((d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))? true:false);\n\n if(day > 0 && day <= max) {\n var celldate = new Date(year, mon, day);\n // ELS 2005.10.30: use <<date>> macro's showDate() function to create popup\n if (window.showDate) {\n showDate(daycell,celldate,"popup","DD","DD-MMM-YYYY",true, isaWeekend); \n } else {\n if(isaWeekend) daycell.style.background = config.macros.calendar.weekendbg;\n var title = celldate.formatString(config.macros.calendar.tiddlerformat);\n if(calendarIsHoliday(celldate)) {\n daycell.style.background = config.macros.calendar.holidaybg;\n }\n if(window.findTiddlersWithReminders == null) {\n var link = createTiddlyLink(daycell, title, false);\n link.appendChild(document.createTextNode(day));\n } else {\n var button = createTiddlyButton(daycell, day, title, onClickCalendarDate);\n }\n }\n }\n day++;\n }\n}\n//}}}\n\n// //We've clicked on a day in a calendar - create a suitable pop-up of options.\n// //The pop-up should contain:\n// // * a link to create a new entry for that date\n// // * a link to create a new reminder for that date\n// // * an <hr>\n// // * the list of reminders for that date\n//{{{\nfunction onClickCalendarDate(e)\n{\n var button = this;\n var date = button.getAttribute("title");\n var dat = new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0, 2));\n\n date = dat.formatString(config.macros.calendar.tiddlerformat);\n var popup = createTiddlerPopup(this);\n popup.appendChild(document.createTextNode(date));\n var newReminder = function() {\n var t = store.getTiddlers(date);\n displayTiddler(null, date, 2, null, null, false, false);\n if(t) {\n document.getElementById("editorBody" + date).value += "\sn<<reminder day:" + dat.getDate() +\n " month:" + (dat.getMonth()+1) +\n " year:" + (dat.getYear()+1900) + " title: >>";\n } else {\n document.getElementById("editorBody" + date).value = "<<reminder day:" + dat.getDate() +\n " month:" + (dat.getMonth()+1) +\n " year:" + (dat.getYear()+1900) + " title: >>";\n }\n };\n var link = createTiddlyButton(popup, "New reminder", null, newReminder); \n popup.appendChild(document.createElement("hr"));\n\n var t = findTiddlersWithReminders(dat, 0, null, null);\n for(var i = 0; i < t.length; i++) {\n link = createTiddlyLink(popup, t[i].tiddler, false);\n link.appendChild(document.createTextNode(t[i].tiddler));\n }\n}\n//}}}\n\n//{{{\nfunction calendarMaxDays(year, mon)\n{\n var max = config.macros.calendar.monthdays[mon];\n if(mon == 1 && (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) {\n max++;\n }\n return max;\n}\n//}}}\n\n//{{{\nfunction createCalendarDayRows(cal, year, mon)\n{\n var row = createTiddlyElement(cal, "tr", null, null, null);\n\n var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);\n if(first1 < 0) first1 = first1 + 7;\n var day1 = -first1 + 1;\n var first2 = (new Date(year, mon+1, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);\n if(first2 < 0) first2 = first2 + 7;\n var day2 = -first2 + 1;\n var first3 = (new Date(year, mon+2, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);\n if(first3 < 0) first3 = first3 + 7;\n var day3 = -first3 + 1;\n\n var max1 = calendarMaxDays(year, mon);\n var max2 = calendarMaxDays(year, mon+1);\n var max3 = calendarMaxDays(year, mon+2);\n\n while(day1 <= max1 || day2 <= max2 || day3 <= max3) {\n row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;\n createCalendarDays(row, 0, day2, max2, year, mon+1); day2 += 7;\n createCalendarDays(row, 0, day3, max3, year, mon+2); day3 += 7;\n }\n}\n//}}}\n\n//{{{\nfunction createCalendarDayRowsSingle(cal, year, mon)\n{\n var row = createTiddlyElement(cal, "tr", null, null, null);\n\n var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);\n if(first1 < 0) first1 = first1+ 7;\n var day1 = -first1 + 1;\n var max1 = calendarMaxDays(year, mon);\n\n while(day1 <= max1) {\n row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;\n }\n}\n//}}}\n\n// //ELS 2005.10.30: added styles\n//{{{\nsetStylesheet(".calendar, .calendar table, .calendar th, .calendar tr, .calendar td { font-size:10pt; text-align:center; } .calendar { margin:0px !important; }", "calendarStyles");\n//}}}\n
!!!Liste des tiddlers relatifs à la compilation pour la carte SHiX (compilation toolchain, noyau, applications)\n
!!! Crosstools\n\n''Attention, cette méthode de compilation ne fonctionne qu'avec zsh (et probablement les autres shells bourne). tcsh and co provoquent des crashs !''\n\n* récupérer crosstool 0.38 sur http://kegel.com/crosstool/crosstool-0.38.tar.gz\n* créer le script {{{sh4-main.sh}}}, comme indiqué ci-dessous. Ce fichier contient les chemins avec le répertoire de download, ainsi que l'endroit où la chaîne sera installée. Il exécute ensuite les différents scripts pour la compilation de la chaîne. On pourrait aussi construire {{{busybox}}} et {{{ncurses}}} avec crosstool, en passant l'option {{{--builduserland}}}, mais pour l'instant elle crashe...) :\n{{{\n#!/bin/sh\n\nset -ex\nTARBALLS_DIR=~/Recherche/shix/sh4/build_toolchain/downloads\nPREFIX=/opt/tools_sh4 ; sudo mkdir -p ${PREFIX} ; sudo chown -R alexis ${PREFIX}\nexport TARBALLS_DIR PREFIX\nexport GCC_LANGUAGES="c,c++,ada"\n\neval `cat sh4-sw.dat sh4-vars.dat` sh all.sh --notest \n\necho Done.\n}}}\n* créer le fichier {{{sh4-vars.dat}}} contenant les données suivantes :\n{{{\nTARGET=sh4-unknown-linux-gnu\nTARGET_CFLAGS="-O2 -m4 -ml"\nGLIBC_CONFIGPARMS="no-z-defs=yes"\nGLIBC_EXTRA_CONFIG="--without-fp"\nUSE_SYSROOT=1\n}}}\n* créer le fichier {{{sh4-sw.dat}}} contenant les version des différentes parties de la toolchain à récupérer. On utilise une ancienne version de gcc pour compatibilité avec le compilateur Ada. La GlibC est la 2.3.5, car la 2.3.6 ne compile avec crosstool. Cela donne le fichier suivant :\n{{{\nBINUTILS_DIR=binutils-2.16.1\nGCC_DIR=gcc-3.4.4\nGLIBC_DIR=glibc-2.3.5\nLINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0\nGLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.5\n}}}\n* lancer le script {{{sh4-main}}} : {{{ ./sh4-main.sh }}}. La compilation se lance, et la chaîne est installée. Il suffit ensuite d'inclure {{{$PREFIX/bin}}} dans le {{{PATH}}}.\n\n!!! Utilisation\n\nIl est nécessaire de passer certaines options au compilateur ainsi créé pour que le code généré soit correct : {{{sh4-unknown-linux-gnu-gcc -m4 -ml}}}. Le support du FPU est automatique, malgré l'option passée à la GLIBC lors de la compilation de la chaîne. \n\n''Attention'' :\n* ne jamais utiliser l'option {{{-m4-no-fpu}}} car le code ainsi généré est en fait du code pour SH3, dont l'ABI n'est pas compatible.\n* de même, on évitera les compilations en {{{-Os}}} car le code généré est invalide (problème d'alignement des structures)...\n
\n!! Compilation du noyau Linux pour carte SHiX v2.0\n\nLa compilation du noyau pour la carte SHiX se passe comme pour toutes les compilations de noyau : on commence par choisir les composants qu'on souhaite inclure dans les noyau (par {{{make menuconfig}}} ou {{{make xconfig}}}), puis on lance la compilation proprement dite par {{{make}}}.\n\n!!! Choix des composants à inclure\n\n!!!! Modules ou noyau ?\n\nLe noyau Linux est modulaire : on peut choisir d'y inclure le support pour différents sous-systèmes (flash, réseau, ...) ou non. La plupart de ces composants peuvent être compilés directement dans le noyau, ou sous forme de modules. L'inclusion dans le noyau permet d'utiliser directement ces composants, au détriment d'un noyau plus gros. S'ils sont compilés sous forme de modules, le noyau est plus petit mais il faut charger les modules en question en mémoire avant de pouvoir les utiliser (par {{{modprobe}}} ou {{{insmod}}}).\nIl existe cependant tout un ensemble d'outils pour charger automatiquement les modules au moment où on en a besoin...\n\nLe choix de compiler des composants dans le noyau ou sous forme de modules est principalement une question de goût. Il existe cependant quelques contraintes :\n* on doit compiler dans le noyau tout ce qui est nécessaire pour accéder au root file system. Comme le bootloader ne supporte pas les mécanisme d'{{{initrd}}}, pour des questions d'utilisation de la flash, le noyau doit comporter tout ce dont il a besoin pour accéder à la flash. Cela inclut :\n** la couche MTD\n** le système de fichier root (yaffs)\n* la place en flash réservée au noyau (partition 1) est relativement grande. On peut sans peine y écrire un gros noyau (éventuellement compressé). Par contre, ce noyau prendra beaucoup de place en RAM. Il vaut donc mieux passer le plus possible par des modules qu'on ne chargera que si on en a besoin, et qu'on déchargera après utilisation. Ainsi on évitera de gâcher de la RAM.\n\nPour choisir les options, le noyau Linux propose trois mécanismes :\n* {{{make oldconfig}}} : cela permet d'importer le fichier de configuration ({{{.config}}}) d'une version précédente du noyau. Le système regarde alors si des options ont été rajoutées ou modifiées, et demande à l'utilisateur ce qu'il souhaite faire (les rajouter ou non, et si oui sous quelle forme). On n'utilisera que rarement ce système.\n* {{{make menuconfig}}} : ce système propose à l'utilisateur de choisir les composants du noyau à l'aide d'une interface conviviale, basée sur des menus, et textuelle. Chaque option dispose d'une aide, expliquant à quoi elle sert et s'il est conseillé de la choisir ou non. Ce mécanisme est purement textuel, et peut donc être utilisé avec un terminal texte.\n* {{{make xconfig}}} : c'est le même système que le précédent, mais sous forme graphique. \n\n!!!! Les options nécessaires\n\nComme indiqué précédemment, certaines options sont ''nécessaires'' :\n* Dans {{{System type}}} :\n** {{{SuperH system type}}} : {{{SHIX}}}\n** {{{Processor selection}}} : {{{7750R}}}\n** {{{ Memory management options}}} : {{{Support for memory management hardware}}}\n** {{{Physical memory start address}}} : c'est l'adresse de base de la mémoire. Mettre {{{0x08000000}}} (CS1)\n** {{{Physical memory size}}} : {{{0x01000000}}} (16 Mo). Linux pour SH ne supporte pas encore les espaces mémoires morcelés.\n** {{{Processor features}}} : {{{Little endian}}} et {{{FPU support}}}\n** {{{Timer support}}} : oui\n** {{{Peripheral clock frequency}}} : {{{60000000}}}. Si on change la fréquence bus, ajuster ce paramètre en conséquence.\n** {{{Heartbeat LED}}} : oui\n* {{{Boot option}}}\n** {{{Zero page offset}}} : c'est la taille de la page zéro, et le début de la zone de passage de paramètres au noyau par le bootoader. Mettre {{{0x00001000}}}.\n** {{{Link address offset for booting}}} : c'est l'adresse de départ de l'image compressée. Mettre {{{0x00800000}}}, comme le demande le bootoader.\n** {{{Default bootloader kernel arguments}}} : non coché. C'est le bootloader qui transmet la ligne de commande au noyau.\n* {{{Device Drivers}}}\n** {{{Memory Technology Devices (MTD)}}} : en noyau (pas en module)\n*** {{{MTD concatenating support}}} : oui\n*** {{{MTD partitioning support}}} : oui\n*** {{{Command line partition table parsing}}} : oui\n*** {{{Direct char device access to MTD devices}}} : oui\n*** {{{Caching block device access to MTD devices}}} : oui\n*** {{{ NAND Flash Device Drivers}}} : \n**** {{{NAND Device Support}}} : dans le noyau\n**** {{{Verify NAND page writes}}} : non\n**** {{{Nand Flash TC58128AFT driver for SHiX 2.0 board}}} : oui\n* {{{File systems}}}\n** {{{Miscellaneous filesystems}}}\n*** {{{YAFFS2 file system support}}} : dans le noyau\n*** {{{Lets Yaffs do its own ECC}}} : oui\n*** {{{Use the same ecc byte order as Steven Hill's nand_ecc.c}}} : oui\n\n!!!! Les options optionnelles (!)\n\nLes composants qui peuvent être intéressants :\n* la couche réseau, accompagnée de la couche USB maître, pour brancher une carte USB-Ethernet\n* le système de fichier VFAT (avec les modules de langues associés), la couche USB maître et le module USB-storage pour brancher une clef USB\n* les modules maisons\n* les modules I2C\n\n\n!!! Compilation\n\nAvant de compiler, il est nécessaire d'indiquer au {{{Makefile}}} qu'on souhaite utiliser un cross-compilateur. Cela est fait en modifiant ainsi les deux lignes 197 et 198 :\n{{{\nARCH ?= sh \nCROSS_COMPILE ?= sh4-unknown-linux-gnu- \n}}}\nSi on a importé une arborescence existante, le Makefile est déjà à jour.\n\nOn prendra aussi soin d'avoir dans son {{{PATH}}} le chemin vers la chaîne de cross-compilation ({{{sh4-unknown-linux-gnu-gcc}}} ...).\n\nPuis il suffit de lancer {{{make}}}, avec éventuellement l'option {{{make -j 4}}} pour accélérer la compilation. Une fois le noyau compilé, on récupère \n* un noyau contenant les symboles de debug dans la racine : {{{vmlinux}}}\n* une image compressée : {{{arch/sh/boot/zImage}}}\n\nOn pourra flasher l'image compressée, ou le noyau normal s'il est suffisament petit pour entrer dans la partition 1.\n
var txtDAVURL = "xxxx";
! Configuration du Stratix\n\nLa configuration du Stratix au power up peut s'effectuer de deux façons : par sa flash de configuration, une ~EPC8, ou par l'interface ~ByteBlaster. \nLe jumper J29 permet de choisir l'interface utilisée :\n* si J29 est en position ~ByteBlaster, le connecteur J20 est relié directement au Stratix, permettant de le reprogrammer par ~ByteBlaster,\n* si J29 est en position ~EPC8, le connecteur J20 est relié à l'interface JTAG de l'~EPC8, et le Stratix est configuré automatiquement au boot par l'~EPC8 avec le dernier programme qui y a été flashé.\n\nLa led rouge D22, située à côté du connecteur de programmation J20, est allumée si le Stratix est correctement configuré.\n\nUn même câble permet de relier J20 à un PC, et sert, selon la configuration de Quartus et de J20, soit d'interface ~ByteBlaster, soit d'interface JTAG. \n\n''Bug'' : à cause d'une inversion de pistes sur le PCB, l'ordre des signaux est inversé quand on est en mode ~ByteBlaster. Il faut donc, soit patcher la carte entre U47 et U44 pour décroiser les signaux (ainsi le même câble est utilisé que ce soit en ~ByteBlaster ou en JTAG), soit utiliser une carte d'adaptation du câble quand on est en mode ~ByteBlaster si la carte SH4 n'est pas patchée.\n\n!!!Configuration par ~EPC8\nPour configurer le Stratix par sa flash ~EPC8 automatiquement au power-up, il faut avoir au préalable programmé l'EPC avec le fichier de programmation idoine. L'~EPC8 est configurée en mode JTAG, par le même connecteur (J20) que l'interface ~ByteBlaster. Quartus génère par défaut un fichier de programmation {{{.sof}}} destiné au Stratix en mode ~ByteBlaster. Il faut donc convertir ce fichier en un fichier de programmation pour l'~EPC8. Cela est fait par le menu ''File / Convert Programming File...'' , et en utilisant les options suivantes :\n* Configuration device : ~EPC8\n* Mode : 1-bit Passive Serial\n* Soft Data / Page 0 : ''Add File...'', puis choisir le fichier {{{.sof}}}\n* Options / Compression Mode : coché\n* Options / Clock source : internal\n* Options / Clock frequency : 10MHz\n* Options / Divide clock frequency by : 1,0\n* Options / Disable nCS and OE... : non coché\n* File name : choisir un fichier de sortie {{{.pof}}}\npuis en cliquant sur OK.\n\nOn peut aussi cliquer sur ''Open Conversion Setup Data'' et choisir le fichier {{{to_~EPC8Q100_10MHz_compression.cof}}} qui positionne automatiquement les options à leurs valeurs correctes. Puis ouvrir la fenêtre de programmation (''Tools / Programmer''), choisir le mode JTAG, choisir le fichier {{{.pof}}} généré, cocher ''Program / Configure'' et ''Verify'' et cliquer sur ''Start'' (après avoir mis la carte sous tension, et déplacé J20 en position ~EPC8).\n\n!!!Configuration directe du Stratix en ~ByteBlaster\nQuartus génère directement un fichier {{{.sof}}} adapté à la configuration du Stratix en ~ByteBlaster. Il suffit d'ouvrir la fenêtre du programmateur (''Tools / Programmer''), choisir ''Passive Serial'', puis ''Add File...'' du fichier {{{.sof}}}, et cliquer sur ''Start'' après avoir mis la carte sous tension et positionné J20 sur ~ByteBlaster ({{{BB}}}).\n\nSi la configuration s'est effectuée correctement, la led rouge D20 doit s'allumer. Il est parfois nécessaire de faire plusieurs tentatives de programmation, la longueur des câbles générant des parasites.\n\n! Fichiers de départ\n\nL'archive {{{shix_bare}}} fournit un bon point de départ pour travailler. Il contient les fichiers nécessaire pour construire un FPGA minimal, contenant :\n* la ROM de boot, \n* la génération des horloges nécessaires au SH4 et des reset\n* la gestion des LEDs et des boutons poussoir / switchs\n* la gestion de 4 bus I2C, dont 3 sont câblés en externe (1 n'aboutit nulle part)\n* le pont USB\nL'archive contient aussi un fichier de projet avec les contraintes de brochage et de timing nécessaires... Il contient aussi une image de programmation {{{first_flash.pof}}}, dans laquelle la ROM contient le [[bios|Bios]] en mode "first-flash" (embarquant le [[bootloader|BootLoader]]).\n\nCette archive est disponible ici : http://perso.enst.fr/~polti/realisations/shix20/shix_bare.tgz\n\n
!! Création d'une arborescence from scratch\n\nOn commence par créer une partie de l'arborescence à la main à l'aide de {{{mkdir}}} : \n{{{\nmkdir kernel kernel/downloads kernel/repositories \nmkdir kernel/repositories/yaffs2 kernel/repositories/mtd kernel/repositories/sh_linux\n}}}\n\n!!! MTD\n\nPour récupérer la couche MTD, on procède comme indiqué sur [[la homepage du projet MTD|http://www.linux-mtd.infradead.org/source.html]] : \n{{{\ncd kernel/repositories/mtd\ncvs -d :pserver:anoncvs@cvs.infradead.org:/home/cvs login (password: anoncvs)\ncvs -d :pserver:anoncvs@cvs.infradead.org:/home/cvs co mtd \n}}}\n\n\n!!! YAFFS\nLa version récupérée est en fait YAFFS2. On la récupère comme le MTD (et ''pas'' comme indiqué sur la [[homepage de Yaffs|http://www.aleph1.co.uk/yaffs/]]) :\n{{{\ncd ../yaffs2\ncvs -d :pserver:anonymous@cvs.aleph1.co.uk:/home/aleph1/cvs login\ncvs -d :pserver:anonymous@cvs.aleph1.co.uk:/home/aleph1/cvs co yaffs2\n}}}\n\n!!!kernel SH\n\nOn procède comme indiqué sur [[le wiki Linux-SH|http://www.linux-sh.org/shwiki/Getting_source]] :\n{{{\ncd ../sh_linux\ntla register-archive http://www.stampede.org/~lethal/{archive}/linux\ntla get lethal@linux-sh.org--linux/sh--stable--2.6 sh_kernel\n}}}\nAprès un {{{ls sh_kernel}}}, on s'aperçoit que l'arbre de patch pour sh4 actuel est conçu pour s'appliquer à un noyau 2.6.15. On récupère donc aussi un noyau 2.6.15 :\n{{{\ncd ../../downloads\nwget http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.15.1.tar.bz2\n}}}\n\n!!! Extraction du noyau officiel, et mise en place du repository de base\n{{{\ncd ../repositories\ntar jvxf ../downloads/linux-2.6.15.1.tar.bz2\n}}}\n\nPuis création du repository [[Mercurial]] dans le noyau Linux qu'on vient d'extraire. Ce repository sera le repository source : tous les autres dépôts Linux seront créés à partir de lui. On aura ainsi un parent commun à tous les dépôts :\n{{{\nmv linux-2.6.15.1 linux\ncd linux\nhg init\nhg add\nhg commit -m"Initial official Linux kernel"\n}}}\n\n!!! Création des dépôts Linux pour chaque arbre\nOn va cloner le repository maître dans chaque sous-répertoire d'arbre de patch. Ainsi tous les dépôts auront un même parent ce qui facilitera les imports de patchs dans le repository de travail...\n{{{\ncd ../mtd\nhg clone ../linux linux\ncd ../yaffs2\nhg clone ../linux linux\ncd ../sh_kernel\nhg clone ../linux linux\n}}}\nEnfin on le clone aussi pour créér le noyau de travail :\n{{{\ncd ../..\nhg clone repositories/linux linux_work\n}}}\n\n\n!!! Patchs couche MTD\nOn va maintenant appliquer les patch MTD à leur repository Linux. A la fin du patch, on commit les changements.\n{{{\ncd repositories/mtd/mtd\n./patchkernel.sh -c -2 ../linux\ncd ../linux\nhg addremove\nhg commit -m"MTD patch"\n}}}\n\n!!! Patchs couche YAFFS\nOn refait la même chose avec l'arbre YAFFS.\n{{{\ncd ../../yaffs2/yaffs2\n./patch-ker.sh ../linux\ncd ../linux\nhg addremove\nhg commit -m"YAFFS2 patch"\n}}}\n\n!!! Patchs noyau SH\nOn refait la même chose avec l'arbre SH. Sa procédure de patch doit être modifiée car elle crée des liens symboliques. Pour cela, éditer le fichier {{{script/treelink.sh}}} et remplacer la ligne {{{ln -s $LDIR/$file $file}}} par {{{cp $LDIR/$file $file}}}.\n{{{\ncd ../../sh_linux/sh_kernel/scripts\nvi treelink.sh\n[édition du fichier]\n./treelink.sh .. ../../linux\ncd ../../linux\nhg addremove\nhg commit -m"SH-specific patch"\n}}}\n\n!!! Import des patch dans l'arbre de travail\nOn applique maintenant les patchs à l'arbre de travail, en réglant manuellement les conflits. Il faut pour cela qu'un outil graphique de résolution de conflit (//merge//) soit installé. Parmis les outils supportés par Mercurial :\n* {{{tkdiff}}}\n* {{{kdiff3}}}\n* {{{meld}}}\n{{{\ncd ../../../linux_work\nhg pull ../repositories/sh_kernel/sh_linux\nhg update \nhg pull ../repositories/yaffs2/yaffs2\nhg update -m\nhg commit -m"Import des patchs YAFFS"\nhg pull ../repositories/mtd/mtd\nhg update -m\nhg commit -m"Import des patchs MTD"\n}}}\n\nOuf, c'est fini ! Après cela, on peut essayer une compilation par {{{make menuconfig}}} ou {{{make xconfig}}}, puis {{{make}}}. Mais bien sûr, dans ce cas, le noyau ne dispose pas des patchs "maisons" (ENST)...\n\n
/***\n''Date Plugin for TiddlyWiki version 2.x''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#DatePlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n^^last update: <<date tiddler "DDD, MMM DDth, YYYY hh:0mm:0ss">>^^\n\nThere are quite a few calendar generators, reminders, to-do lists, 'dated tiddlers' journals, blog-makers and GTD-like schedule managers that have been built around TW. While they all have different purposes, and vary in format, interaction, and style, in one way or another each of these plugins displays and/or uses date-based information to make finding, accessing and managing relevant tiddlers easier. This plugin provides a general approach to embedding dates and date-based links/menus within tiddler content.\n\nYou can ''specify a date using a combination of year, month, and day number values or mathematical expressions (such as "Y+1" or "D+30")'', and then just display it as formatted date text, or create a ''link to a 'dated tiddler''' for quick blogging, or create a ''popup menu'' containing the dated tiddler link plus links to ''tiddlers that were changed'' as well as any ''scheduled reminders'' for that date.\n!!!!!Usage\n<<<\nWhen installed, this plugin defines a macro: {{{<<date [mode] [date] [format] [linkformat]>>}}}. All of the macro parameters are optional and, in it's simplest form, {{{<<date>>}}}, it is equivalent to the ~TiddlyWiki core macro, {{{<<today>>}}}.\n\nHowever, where {{{<<today>>}}} simply inserts the current date/time in a predefined format (or custom format, using {{{<<today [format]>>}}}), the {{{<<date>>}}} macro's parameters take it much further than that:\n* [mode] is either ''display'', ''link'' or ''popup''. If omitted, it defaults to ''display''. This param let's you select between simply displaying a formatted date, or creating a link to a specific 'date titled' tiddler or a popup menu containing a dated tiddler link, plus links to changes and reminders.\n* [date] lets you enter ANY date (not just today) as ''year, month, and day values or simple mathematical expressions'' using pre-defined variables, Y, M, and D for the current year, month and day, repectively. You can display the modification date of the current tiddler by using the keyword: ''tiddler'' in place of the year, month and day parameters. Use ''tiddler://name-of-tiddler//'' to display the modification date of a specific tiddler. You can also use keywords ''today'' or ''filedate'' to refer to these //dynamically changing// date/time values. \n* [format] and [linkformat] uses standard ~TiddlyWiki date formatting syntax. The default is "YYYY.0MM.0DD"\n>^^''DDD'' - day of week in full (eg, "Monday"), ''DD'' - day of month, ''0DD'' - adds leading zero^^\n>^^''MMM'' - month in full (eg, "July"), ''MM'' - month number, ''0MM'' - adds leading zero^^\n>^^''YYYY'' - full year, ''YY'' - two digit year, ''hh'' - hours, ''mm'' - minutes, ''ss'' - seconds^^\n>^^//note: use of hh, mm or ss format codes is only supported with ''tiddler'', ''today'' or ''filedate'' values//^^\n* [linkformat] - specify an alternative date format so that the title of a 'dated tiddler' link can have a format that differs from the date's displayed format\n\nIn addition to the macro syntax, DatePlugin also provides a public javascript API so that other plugins that work with dates (such as calendar generators, etc.) can quickly incorporate date formatted links or popups into their output:\n\n''{{{showDate(place, date, mode, format, linkformat, autostyle, weekend)}}}'' \n\nNote that in addition to the parameters provided by the macro interface, the javascript API also supports two optional true/false parameters:\n* [autostyle] - when true, the font/background styles of formatted dates are automatically adjusted to show the date's status: 'today' is boxed, 'changes' are bold, 'reminders' are underlined, while weekends and holidays (as well as changes and reminders) can each have a different background color to make them more visibly distinct from each other.\n* [weekend] - true indicates a weekend, false indicates a weekday. When this parameter is omitted, the plugin uses internal defaults to automatically determine when a given date falls on a weekend.\n<<<\n!!!!!Examples\n<<<\nThe current date: <<date>>\nThe current time: <<date today "0hh:0mm:0ss">>\nToday's blog: <<date link today "DDD, MMM DDth, YYYY">>\nRecent blogs/changes/reminders: <<date popup Y M D-1 "yesterday">> <<date popup today "today">> <<date popup Y M D+1 "tomorrow">>\nThe first day of next month will be a <<date Y M+1 1 "DDD">>\nThis tiddler (DatePlugin) was last updated on: <<date tiddler "DDD, MMM DDth, YYYY">>\nThe SiteUrl was last updated on: <<date tiddler:SiteUrl "DDD, MMM DDth, YYYY">>\nThis document was last saved on <<date filedate "DDD, MMM DDth, YYYY at 0hh:0mm:0ss">>\n<<date 2006 07 24 "MMM DDth, YYYY">> will be a <<date 2006 07 24 "DDD">>\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''DatePlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2006.02.14 [2.0.5]''\nwhen readOnly is set (by TW core), omit "new reminders..." popup menu item and, if a "dated tiddler" does not already exist, display the date as simple text instead of a link.\n''2006.02.05 [2.0.4]''\nadded var to variables that were unintentionally global. Avoids FireFox 1.5.0.1 crash bug when referencing global variables\n''2006.01.18 [2.0.3]''\nIn 1.2.x the tiddler editor's text area control was given an element ID=("tiddlerBody"+title), so that it was easy to locate this field and programmatically modify its content. With the addition of configuration templates in 2.x, the textarea no longer has an ID assigned. To find this control we now look through all the child nodes of the tiddler editor to locate a "textarea" control where attribute("edit") equals "text", and then append the new reminder to the contents of that control.\n''2006.01.11 [2.0.2]''\ncorrect 'weekend' override detection logic in showDate()\n''2006.01.10 [2.0.1]''\nallow custom-defined weekend days (default defined in config.macros.date.weekend[] array)\nadded flag param to showDate() API to override internal weekend[] array\n''2005.12.27 [2.0.0]''\nUpdate for TW2.0\nAdded parameter handling for 'linkformat'\n''2005.12.21 [1.2.2]''\nFF's date.getYear() function returns 105 (for the current year, 2005). When calculating a date value from Y M and D expressions, the plugin adds 1900 to the returned year value get the current year number. But IE's date.getYear() already returns 2005. As a result, plugin calculated date values on IE were incorrect (e.g., 3905 instead of 2005). Adding +1900 is now conditional so the values will be correct on both browsers.\n''2005.11.07 [1.2.1]''\nadded support for "tiddler" dynamic date parameter\n''2005.11.06 [1.2.0]''\nadded support for "tiddler:title" dynamic date parameter\n''2005.11.03 [1.1.2]''\nwhen a reminder doesn't have a specified title parameter, use the title of the tiddler that contains the reminder as "fallback" text in the popup menu. Based on a suggestion from BenjaminKudria.\n''2005.11.03 [1.1.1]''\nTemporarily bypass hasReminders() logic to avoid excessive overhead from generating the indexReminders() cache. While reminders can still appear in the popup menu, they just won't be indicated by auto-styling the date number that is displayed. This single change saves approx. 60% overhead (5 second delay reduced to under 2 seconds).\n''2005.11.01 [1.1.0]''\ncorrected logic in hasModifieds() and hasReminders() so caching of indexed modifieds and reminders is done just once, as intended. This should hopefully speed up calendar generators and other plugins that render multiple dates...\n''2005.10.31 [1.0.1]''\ndocumentation and code cleanup\n''2005.10.31 [1.0.0]''\ninitial public release\n''2005.10.30 [0.9.0]''\npre-release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.date = {major: 2, minor: 0, revision: 5, date: new Date(2006,2,14)};\n//}}}\n\n//{{{\n// 1.2.x compatibility\nif (!window.story) window.story=window;\nif (!store.getTiddler) store.getTiddler=function(title){return store.tiddlers[title]}\nif (!store.addTiddler) store.addTiddler=function(tiddler){store.tiddlers[tiddler.title]=tiddler}\nif (!store.deleteTiddler) store.deleteTiddler=function(title){delete store.tiddlers[title]}\n//}}}\n\n//{{{\nconfig.macros.date = {\n format: "YYYY.0MM.0DD", // default date display format\n linkformat: "YYYY.0MM.0DD", // 'dated tiddler' link format\n weekendbg: "#c0c0c0", // "cocoa"\n holidaybg: "#c0ffee", // "coffee"\n modifiedsbg: "#bbeeff", // "beef"\n remindersbg: "#ffaace", // "face"\n holidays: [ "01/01", "07/04", "07/24", "11/24" ], // NewYearsDay, IndependenceDay(US), Eric's Birthday (hooray!), Thanksgiving(US)\n weekend: [ 1,0,0,0,0,0,1 ] // [ day index values: sun=0, mon=1, tue=2, wed=3, thu=4, fri=5, sat=6 ]\n};\n//}}}\n\n//{{{\nconfig.macros.date.handler = function(place,macroName,params)\n{\n // do we want to see a link, a popup, or just a formatted date?\n var mode="display";\n if (params[0]=="display") { mode=params[0]; params.shift(); }\n if (params[0]=="popup") { mode=params[0]; params.shift(); }\n if (params[0]=="link") { mode=params[0]; params.shift(); }\n // get the date\n var now = new Date();\n var date = now;\n if (!params[0] || params[0]=="today")\n { params.shift(); }\n else if (params[0]=="filedate")\n { date=new Date(document.lastModified); params.shift(); }\n else if (params[0]=="tiddler")\n { date=store.getTiddler(story.findContainingTiddler(place).id.substr(7)).modified; params.shift(); }\n else if (params[0].substr(0,8)=="tiddler:")\n { var t; if ((t=store.getTiddler(params[0].substr(8)))) date=t.modified; params.shift(); }\n else {\n var y = eval(params.shift().replace(/Y/ig,(now.getYear()<1900)?now.getYear()+1900:now.getYear()));\n var m = eval(params.shift().replace(/M/ig,now.getMonth()+1));\n var d = eval(params.shift().replace(/D/ig,now.getDate()+0));\n date = new Date(y,m-1,d);\n }\n // date format with optional custom override\n var format=this.format; if (params[0]) format=params.shift();\n var linkformat=this.linkformat; if (params[0]) linkformat=params.shift();\n showDate(place,date,mode,format,linkformat);\n}\n//}}}\n\n//{{{\nwindow.showDate=showDate;\nfunction showDate(place,date,mode,format,linkformat,autostyle,weekend)\n{\n if (!mode) mode="display";\n if (!format) format=config.macros.date.format;\n if (!linkformat) linkformat=config.macros.date.linkformat;\n if (!autostyle) autostyle=false;\n\n // format the date output\n var title = date.formatString(format);\n var linkto = date.formatString(linkformat);\n\n // just show the formatted output\n if (mode=="display") { place.appendChild(document.createTextNode(title)); return; }\n\n // link to a 'dated tiddler'\n var link = createTiddlyLink(place, linkto, false);\n link.appendChild(document.createTextNode(title));\n link.title = linkto;\n link.date = date;\n link.format = format;\n link.linkformat = linkformat;\n\n // if using a popup menu, replace click handler for dated tiddler link\n // with handler for popup and make link text non-italic (i.e., an 'existing link' look)\n if (mode=="popup") {\n link.onclick = onClickDatePopup;\n link.style.fontStyle="normal";\n }\n\n // format the popup link to show what kind of info it contains (for use with calendar generators)\n if (!autostyle) return;\n if (hasModifieds(date))\n { link.style.fontStyle="normal"; link.style.fontWeight="bold"; }\n if (hasReminders(date))\n { link.style.textDecoration="underline"; }\n if(isToday(date))\n { link.style.border="1px solid black"; }\n\n if( (weekend!=undefined?weekend:isWeekend(date)) && (config.macros.date.weekendbg!="") )\n { place.style.background = config.macros.date.weekendbg; }\n if(isHoliday(date)&&(config.macros.date.holidaybg!=""))\n { place.style.background = config.macros.date.holidaybg; }\n if (hasModifieds(date)&&(config.macros.date.modifiedsbg!=""))\n { place.style.background = config.macros.date.modifiedsbg; }\n if (hasReminders(date)&&(config.macros.date.remindersbg!=""))\n { place.style.background = config.macros.date.remindersbg; }\n}\n//}}}\n\n//{{{\nfunction isToday(date) // returns true if date is today\n { var now=new Date(); return ((now-date>=0) && (now-date<86400000)); }\n\nfunction isWeekend(date) // returns true if date is a weekend\n { return (config.macros.date.weekend[date.getDay()]); }\n\nfunction isHoliday(date) // returns true if date is a holiday\n{\n var longHoliday = date.formatString("0MM/0DD/YYYY");\n var shortHoliday = date.formatString("0MM/0DD");\n for(var i = 0; i < config.macros.date.holidays.length; i++) {\n var holiday=config.macros.date.holidays[i];\n if (holiday==longHoliday||holiday==shortHoliday) return true;\n }\n return false;\n}\n//}}}\n\n//{{{\n// Event handler for clicking on a day popup\nfunction onClickDatePopup(e)\n{\n if (!e) var e = window.event;\n var theTarget = resolveTarget(e);\n var popup = createTiddlerPopup(this);\n if(popup) {\n // always show dated tiddler link (or just date, if readOnly) at the top...\n if (!readOnly || store.tiddlerExists(this.date.formatString(this.linkformat)))\n createTiddlyLink(popup,this.date.formatString(this.linkformat),true);\n else\n createTiddlyText(popup,this.date.formatString(this.linkformat));\n addModifiedsToPopup(popup,this.date,this.format);\n addRemindersToPopup(popup,this.date,this.linkformat);\n }\n scrollToTiddlerPopup(popup,false);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n//}}}\n\n//{{{\nfunction indexModifieds() // build list of tiddlers, hash indexed by modification date\n{\n var modifieds= { };\n var tiddlers = store.getTiddlers("title");\n for (var t = 0; t < tiddlers.length; t++) {\n var date = tiddlers[t].modified.formatString("YYYY0MM0DD")\n if (!modifieds[date])\n modifieds[date]=new Array();\n modifieds[date].push(tiddlers[t].title);\n }\n return modifieds;\n}\nfunction hasModifieds(date) // returns true if date has modified tiddlers\n{\n if (!config.macros.date.modifieds) config.macros.date.modifieds = indexModifieds();\n return (config.macros.date.modifieds[date.formatString("YYYY0MM0DD")]!=undefined);\n}\n\nfunction addModifiedsToPopup(popup,when,format)\n{\n if (!config.macros.date.modifieds) config.macros.date.modifieds = indexModifieds();\n var indent=String.fromCharCode(160)+String.fromCharCode(160);\n var mods = config.macros.date.modifieds[when.formatString("YYYY0MM0DD")];\n if (mods) {\n mods.sort();\n var e=createTiddlyElement(popup,"div",null,null,"changes:");\n for(var t=0; t<mods.length; t++) {\n var link=createTiddlyLink(popup,mods[t],false);\n link.appendChild(document.createTextNode(indent+mods[t]));\n createTiddlyElement(popup,"br",null,null,null);\n }\n }\n}\n//}}}\n\n//{{{\nfunction indexReminders() // build list of tiddlers with reminders, hash indexed by reminder date\n{\n var reminders = { };\n\n if(window.findTiddlersWithReminders==undefined) return; // reminder plugin not installed\n\n var matches = store.search("reminder",false,false,"title","excludeSearch");\n var macroPattern = "<<([^>\s\ss]+)(?:\s\ss*)([^>]*)>>";\n var macroRegExp = new RegExp(macroPattern,"mg");\n var arr = [];\n for(var t=matches.length-1; t>=0; t--)\n {\n var targetText = matches[t].text;\n do {\n // Get the next formatting match\n var formatMatch = macroRegExp.exec(targetText);\n if(formatMatch)\n {\n if (formatMatch[1] != null && formatMatch[1].toLowerCase() == "reminder")\n {\n //Find the matching date.\n var params = formatMatch[2].readMacroParams();\n var dateHash = getParamsForReminder(params);\n var date = findDateForReminder(dateHash);\n if (date != null)\n {\n var dateindex = date.formatString("YYYY0MM0DD")\n if (!reminders[dateindex])\n reminders[dateindex]=new Array();\n reminders[dateindex].pushUnique(t);\n }\n }\n }\n } while(formatMatch);\n }\n return reminders;\n}\n\nfunction hasReminders(date) // returns true if date has reminders\n{\n return false; // ELS 2005.11.03: BYPASS due to performance issues\n if (!config.macros.date.reminders) config.macros.date.reminders = indexReminders();\n return (config.macros.date.reminders[date.formatString("YYYY0MM0DD")]!=undefined);\n}\n\nfunction addRemindersToPopup(popup,when,format)\n{\n if(window.findTiddlersWithReminders==undefined) return; // reminder plugin not installed\n\n var indent = String.fromCharCode(160)+String.fromCharCode(160);\n var e=createTiddlyElement(popup,"div",null,null,"reminders:");\n var reminders=findTiddlersWithReminders(when, [0,31],null,null);\n for(var t=0; t<reminders.length; t++) {\n link = createTiddlyLink(popup,reminders[t].tiddler,false);\n var diff=reminders[t].diff;\n diff=(!diff)?"Today":((diff==1)?"Tomorrow":diff+" days");\n var txt=(reminders[t].params["title"])?reminders[t].params["title"]:reminders[t].tiddler;\n link.appendChild(document.createTextNode(indent+diff+" - "+txt));\n createTiddlyElement(popup,"br",null,null,null);\n }\n if (readOnly) return; // omit "new reminder..." link\n var link = createTiddlyLink(popup,indent+"new reminder...",true); createTiddlyElement(popup,"br");\n var title = when.formatString(format);\n link.title="add a reminder to '"+title+"'";\n link.onclick = function() {\n // show tiddler editor\n story.displayTiddler(null, title, 2, null, null, false, false);\n // find body 'textarea'\n var c =document.getElementById("tiddler" + title).getElementsByTagName("*");\n for (var i=0; i<c.length; i++) if ((c[i].tagName.toLowerCase()=="textarea") && (c[i].getAttribute("edit")=="text")) break;\n // append reminder macro to tiddler content\n if (i<c.length) {\n if (store.tiddlerExists(title)) c[i].value+="\sn"; else c[i].value="";\n c[i].value += "<<reminder day:"+when.getDate()+" month:"+(when.getMonth()+1)+" year:"+(when.getYear()+1900)+" title: >>";\n }\n };\n}\n//}}}\n
[[Introduction]]
/***\n''DisableWikiLinksPlugin for TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#DisableWikiLinksPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nThis plugin allows you to disable TiddlyWiki's automatic WikiWord linking behavior, so that WikiWords embedded in tiddler content will be rendered as regular text, instead of being automatically converted to tiddler links. To create a tiddler link when automatic linking is disabled, you must enclose the link text within {{{[[}}} and {{{]]}}}.\n\n!!!!!Configuration\n<<<\nSelf-contained control panel:\n<<option chkDisableWikiLinks>> Disable automatic WikiWord tiddler links\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''DisableWikiLinksPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2006.02.05 [1.0.1]''\nwrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals\n''2005.12.09 [1.0.0]''\ninitial release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.disableWikiLinks= {major: 1, minor: 0, revision: 0, date: new Date(2005,12,9)};\n\nif (config.options.chkDisableWikiLinks==undefined) config.options.chkDisableWikiLinks= false;\n\n// find the formatter for wikiLink and replace handler with 'pass-thru' rendering\ninitDisableWikiLinksFormatter();\nfunction initDisableWikiLinksFormatter() {\n for (var i=0; i<config.formatters.length && config.formatters[i].name!="wikiLink"; i++);\n config.formatters[i].coreHandler=config.formatters[i].handler;\n config.formatters[i].handler=function(w) {\n // if not enabled, just do standard WikiWord link formatting\n if (!config.options.chkDisableWikiLinks) return this.coreHandler(w);\n // supress any leading "~" (if present)\n var skip=(w.matchText.substr(0,1)==config.textPrimitives.unWikiLink)?1:0;\n w.outputText(w.output,w.matchStart+skip,w.nextMatch)\n }\n}\n//}}}\n
<!---\n| Name:|~TagglyTaggingEditTemplate |\n| Version:|1.1 (12-Jan-2006)|\n| Source:|http://simonbaird.com/mptw/#TagglyTaggingEditTemplate|\n| Purpose:|See TagglyTagging for more info|\n| Requires:|You need the CSS in TagglyTaggingStyles to make it look right|\n--->\n<!--{{{-->\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<br/>\n<!--}}}-->
/***\n''Export Tiddlers Plugin for TiddlyWiki version 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#ExportTiddlersPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nWhen many people edit copies of the same TiddlyWiki document, the ability to easily copy and share these changes so they can then be redistributed to the entire group is very important. This ability is also very useful when moving your own tiddlers from document to document (e.g., when upgrading to the latest version of TiddlyWiki, or 'pre-loading' your favorite stylesheets into a new 'empty' TiddlyWiki document.)\n\nExportTiddlersPlugin let you ''select and extract tiddlers from your ~TiddlyWiki documents and save them to a local file'' or a remote server (requires installation of compatible server-side scripting, still under development...). An interactive control panel lets you specify a destination, and then select which tiddlers to export. A convenient 'selection filter' helps you pick desired tiddlers by specifying a combination of modification dates, tags, or tiddler text to be matched or excluded. ''Tiddler data can be output as ~TiddlyWiki "storeArea ~DIVs" that can be imported into another ~TiddlyWiki or as ~RSS-compatible XML that can be published for RSS syndication.''\n\n!!!!!Inline interface (live)\n<<<\n<<exportTiddlers inline>>\n<<<\n!!!!!Usage\n<<<\nOptional "special tiddlers" used by this plugin:\n* SiteUrl^^\nURL for official server-published version of document being viewed\ndefault: //none//^^\n* SiteHost^^\nhost name/address for remote server (e.g., "www.server.com" or "192.168.1.27")\ndefault: //none//^^\n* SitePost^^\nremote path/filename for submitting changes (e.g., "/cgi-bin/submit.cgi")\ndefault: //none//^^\n* SiteParams^^\narguments (if any) for server-side receiving script\ndefault: //none//^^\n* SiteID^^\nusername or other authorization identifier for login-controlled access to remote server\ndefault: current TiddlyWiki username (e.g., "YourName")^^\n* SiteDate^^\nstored date/time stamp for most recent published version of document\ndefault: current document.modified value (i.e., the 'file date')^^\n<<<\n!!!!!Example\n<<<\n<<exportTiddlers>>\n<<<\n!!!!!Installation\n<<<\nImport (or copy/paste) the following tiddlers into your document:\n''ExportTiddlersPlugin'' (tagged with <<tag systemConfig>>)\n\ncreate/edit ''SideBarOptions'': (sidebar menu items) \n^^Add "< < exportTiddlers > >" macro^^\n<<<\n!!!!!Revision History\n<<<\n''2006.02.12 [2.1.2]''^^\nadded var to unintended global 'tags' in matchTags(). Avoids FF1501 bug when filtering by tags. (based on report by TedPavlic)\n''2006.02.04 [2.1.1]''^^\nadded var to variables that were unintentionally global. Avoids FireFox 1.5.0.1 crash bug when referencing global variables\n''2006.02.02 [2.1.0]''^^\nAdded support for output of complete TiddlyWiki documents. Let's you use ExportTiddlers to generate 'starter' documents from selected tiddlers.^^\n''2006.01.21 [2.0.1]''^^\nDefer initial panel creation and only register a notification function when panel first is created\nin saveChanges 'hijack', create panel as needed. Note: if window.event is not available to identify the click location, the export panel is positioned relative to the 'tiddlerDisplay' element of the TW document.\n^^\n''2005.12.27 [2.0.0]''^^\nUpdate for TW2.0\nDefer initial panel creation and only register a notification function when panel first is created\n^^\n''2005.12.24 [0.9.5]''^^\nMinor adjustments to CSS to force correct link colors regardless of TW stylesheet selection\n^^\n''2005.12.16 [0.9.4]''^^\nDynamically create/remove exportPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding.\n^^\n''2005.11.15 [0.9.2]''^^\nadded non-Ajax post function to bypass javascript security restrictions on cross-domain I/O. Moved AJAX functions to separate tiddler (no longer needed here). Generalized HTTP server to support UnaWiki servers\n^^\n+++[previous releases...]\n''2005.11.08 [0.9.1]''^^\nmoved HTML, CSS and control initialization into exportInit() function and call from macro handler instead of at load time. This allows exportPanel to be placed within the same containing element as the "export tiddlers" button, so that relative positioning can be achieved.\n^^\n''2005.10.28 [0.9.0]''^^\nadded 'select opened tiddlers' feature\nBased on a suggestion by Geoff Slocock\n^^\n''2005.10.24 [0.8.3]''^^\nCorrected hijack of 'save changes' when using http:\n^^\n''2005.10.18 [0.8.2]''^^\nadded AJAX functions\n^^\n''2005.10.18 [0.8.1]''^^\nCorrected timezone handling when filtering for date ranges.\nImproved error checking/reporting for invalid filter values and filters that don't match any tiddlers.\nExporting localfile-to-localfile is working for IE and FF\nExporting server-to-localfile works in IE (after ActiveX warnings), but has security issues in FF\nCross-domain exporting (localfile/server-to-server) is under development\nCookies to remember filter settings - coming soon\nMore style tweaks, minor text changes and some assorted layout cleanup.\n^^\n''2005.10.17 [0.8.0]''^^\nFirst pre-release.\n^^\n''2005.10.16 [0.7.0]''^^\nfilter by tags\n^^\n''2005.10.15 [0.6.0]''^^\nfilter by title/text\n^^\n''2005.10.14 [0.5.0]''^^\nexport to local file (DIV or XML)\n^^\n''2005.10.14 [0.4.0]''^^\nfilter by start/end date\n^^\n''2005.10.13 [0.3.0]''^^\npanel interaction\n^^\n''2005.10.11 [0.2.0]''^^\npanel layout\n^^\n''2005.10.10 [0.1.0]''^^\ncode framework\n^^\n''2005.10.09 [0.0.0]''^^\ndevelopment started\n^^\n===\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n// // +++[version]\n//{{{\nversion.extensions.exportTiddlers = {major: 2, minor: 1, revision: 2, date: new Date(2006,2,12)};\n//}}}\n// //===\n\n// // +++[macro handler]\n//{{{\nconfig.macros.exportTiddlers = {\n label: "export tiddlers",\n prompt: "Copy selected tiddlers to an export document",\n datetimefmt: "0MM/0DD/YYYY 0hh:0mm:0ss" // for "filter date/time" edit fields\n};\n\nconfig.macros.exportTiddlers.handler = function(place,macroName,params) {\n if (params[0]!="inline")\n { createTiddlyButton(place,this.label,this.prompt,onClickExportMenu); return; }\n var panel=createExportPanel(place);\n panel.style.position="static";\n panel.style.display="block";\n}\n\nfunction createExportPanel(place) {\n var panel=document.getElementById("exportPanel");\n if (panel) { panel.parentNode.removeChild(panel); }\n setStylesheet(config.macros.exportTiddlers.css,"exportTiddlers");\n panel=createTiddlyElement(place,"span","exportPanel",null,null)\n panel.innerHTML=config.macros.exportTiddlers.html;\n exportShowPanel(document.location.protocol);\n exportInitFilter();\n refreshExportList(0);\n store.addNotification(null,refreshExportList); // refresh listbox after every tiddler change\n return panel;\n}\n\nfunction onClickExportMenu(e)\n{\n if (!e) var e = window.event;\n var parent=resolveTarget(e).parentNode;\n var panel = document.getElementById("exportPanel");\n if (panel==undefined || panel.parentNode!=parent)\n panel=createExportPanel(parent);\n var isOpen = panel.style.display=="block";\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n panel.style.display = isOpen ? "none" : "block" ;\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n//}}}\n// //===\n\n// // +++[Hijack saveChanges] diverts 'notFileUrlError' to display export control panel instead\n//{{{\nwindow.coreSaveChanges=window.saveChanges;\nwindow.saveChanges = function()\n{\n if (document.location.protocol=="file:") { coreSaveChanges(); return; }\n var e = window.event;\n var parent=e?resolveTarget(e).parentNode:document.body;\n var panel = document.getElementById("exportPanel");\n if (panel==undefined || panel.parentNode!=parent) panel=createExportPanel(parent);\n exportShowPanel(document.location.protocol);\n if (parent==document.body) { panel.style.left="30%"; panel.style.top="30%"; }\n panel.style.display = "block" ;\n}\n//}}}\n// //===\n\n// // +++[IE needs explicit scoping] for functions called by browser events\n//{{{\nwindow.onClickExportMenu=onClickExportMenu;\nwindow.onClickExportButton=onClickExportButton;\nwindow.exportShowPanel=exportShowPanel;\nwindow.exportShowFilterFields=exportShowFilterFields;\nwindow.refreshExportList=refreshExportList;\n//}}}\n// //===\n\n// // +++[CSS] for floating export control panel\n//{{{\nconfig.macros.exportTiddlers.css = '\s\n#exportPanel {\s\n display: none; position:absolute; z-index:12; width:35em; right:105%; top:6em;\s\n background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\s\n border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\s\n padding: 0.5em; margin:0em; -moz-border-radius:1em;\s\n}\s\n#exportPanel a, #exportPanel td a { color:#009; display:inline; margin:0px; padding:1px; }\s\n#exportPanel table { width:100%;border:0px;padding:0px;margin:0px; font-size:8pt;line-height:110%}\s\n#exportPanel tr { border:0px;padding:0px;margin:0px; }\s\n#exportPanel td { border:0px;padding:0px;margin:0px; }\s\n#exportPanel select { width:98%;margin:0px;font-size:8pt;line-height:110%;}\s\n#exportPanel input { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\s\n#exportPanel .box { border:1px solid black; padding:3px; margin-bottom:5px; background:#f8f8f8; -moz-border-radius:5px;}\s\n#exportPanel .topline { border-top:2px solid black; padding-top:3px; margin-bottom:5px; }\s\n#exportPanel .rad { width:auto; }\s\n#exportPanel .chk { width:auto; }\s\n#exportPanel .btn { width:auto; }\s\n#exportPanel .btn1 { width:98%; }\s\n#exportPanel .btn2 { width:48%; }\s\n#exportPanel .btn3 { width:32%; }\s\n#exportPanel .btn4 { width:24%; }\s\n#exportPanel .btn5 { width:19%; }\s\n';\n//}}}\n// //===\n\n// // +++[HTML] for export control panel interface\n//{{{\nconfig.macros.exportTiddlers.html = '\s\n<!-- output target and format -->\s\n<table cellpadding="0" cellspacing="0"><tr><td width=50%>\s\n export to\s\n <select size=1 id="exportTo" onchange="exportShowPanel(this.value);">\s\n <option value="file:" SELECTED>this computer</option>\s\n <option value="http:">web server (http)</option>\s\n <option value="https:">secure web server (https)</option>\s\n <option value="ftp:">file server (ftp)</option>\s\n </select>\s\n</td><td width=50%>\s\n output format\s\n <select id="exportFormat" size=1>\s\n <option value="DIV">TiddlyWiki export file</option>\s\n <option value="TW">TiddlyWiki document</option>\s\n <option value="XML">RSS feed (XML)</option>\s\n </select>\s\n</td></tr></table>\s\n\s\n<!-- export to local file -->\s\n<div id="exportLocalPanel" style="margin-bottom:5px;margin-top:5px;">\s\nlocal path/filename<br>\s\n<input type="file" id="exportFilename" size=56 style="width:100%"><br>\s\n</div><!--panel-->\s\n\s\n<!-- export to http server -->\s\n<div id="exportHTTPPanel" style="display:none;margin-bottom:5px;margin-top:5px;">\s\ndocument URL<br>\s\n<input type="text" id="exportHTTPSiteURL" onfocus="this.select()"><br>\s\nserver script / parameters<br>\s\n<input type="text" id="exportHTTPServerURL" onfocus="this.select()"><br>\s\n</div><!--panel-->\s\n\s\n<!-- export to ftp server -->\s\n<div id="exportFTPPanel" style="display:none;margin-bottom:5px;margin-top:5px;">\s\n<table cellpadding="0" cellspacing="0" width="33%"><tr valign="top"><td>\s\n host server<br>\s\n <input type="text" id="exportFTPHost" onfocus="this.select()"><br>\s\n</td><td width="33%">\s\n username<br>\s\n <input type="text" id="exportFTPID" onfocus="this.select()"><br>\s\n</td><td width="33%">\s\n password<br>\s\n <input type="password" id="exportFTPPW" onfocus="this.select()"><br>\s\n</td></tr></table>\s\nFTP path/filename<br>\s\n<input type="text" id="exportFTPFilename" onfocus="this.select()"><br>\s\n</div><!--panel-->\s\n\s\n<!-- list of tiddlers -->\s\n<table><tr align="left"><td>\s\n select:\s\n <a href="JavaScript:;" id="exportSelectAll"\s\n onclick="onClickExportButton(this)" title="select all tiddlers">\s\n all </a>\s\n <a href="JavaScript:;" id="exportSelectChanges"\s\n onclick="onClickExportButton(this)" title="select tiddlers changed since last save">\s\n changes </a> \s\n <a href="JavaScript:;" id="exportSelectOpened"\s\n onclick="onClickExportButton(this)" title="select tiddlers currently being displayed">\s\n opened </a> \s\n <a href="JavaScript:;" id="exportToggleFilter"\s\n onclick="onClickExportButton(this)" title="show/hide selection filter">\s\n filter </a> \s\n</td><td align="right">\s\n <a href="JavaScript:;" id="exportListSmaller"\s\n onclick="onClickExportButton(this)" title="reduce list size">\s\n – </a>\s\n <a href="JavaScript:;" id="exportListLarger"\s\n onclick="onClickExportButton(this)" title="increase list size">\s\n + </a>\s\n</td></tr></table>\s\n<select id="exportList" multiple size="10" style="margin-bottom:5px;"\s\n onchange="refreshExportList(this.selectedIndex)">\s\n</select><br>\s\n\s\n<!-- selection filter -->\s\n<div id="exportFilterPanel" style="display:none">\s\n<table><tr align="left"><td>\s\n selection filter\s\n</td><td align="right">\s\n <a href="JavaScript:;" id="exportHideFilter"\s\n onclick="onClickExportButton(this)" title="hide selection filter">hide</a>\s\n</td></tr></table>\s\n<div class="box">\s\n<input type="checkbox" class="chk" id="exportFilterStart" value="1"\s\n onclick="exportShowFilterFields(this)"> starting date/time<br>\s\n<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">\s\n <select size=1 id="exportFilterStartBy" onchange="exportShowFilterFields(this);">\s\n <option value="0">today</option>\s\n <option value="1">yesterday</option>\s\n <option value="7">a week ago</option>\s\n <option value="30">a month ago</option>\s\n <option value="site">SiteDate</option>\s\n <option value="file">file date</option>\s\n <option value="other">other (mm/dd/yyyy hh:mm)</option>\s\n </select>\s\n</td><td width="50%">\s\n <input type="text" id="exportStartDate" onfocus="this.select()"\s\n onchange="document.getElementById(\s'exportFilterStartBy\s').value=\s'other\s';">\s\n</td></tr></table>\s\n<input type="checkbox" class="chk" id="exportFilterEnd" value="1"\s\n onclick="exportShowFilterFields(this)"> ending date/time<br>\s\n<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">\s\n <select size=1 id="exportFilterEndBy" onchange="exportShowFilterFields(this);">\s\n <option value="0">today</option>\s\n <option value="1">yesterday</option>\s\n <option value="7">a week ago</option>\s\n <option value="30">a month ago</option>\s\n <option value="site">SiteDate</option>\s\n <option value="file">file date</option>\s\n <option value="other">other (mm/dd/yyyy hh:mm)</option>\s\n </select>\s\n</td><td width="50%">\s\n <input type="text" id="exportEndDate" onfocus="this.select()"\s\n onchange="document.getElementById(\s'exportFilterEndBy\s').value=\s'other\s';">\s\n</td></tr></table>\s\n<input type="checkbox" class="chk" id=exportFilterTags value="1"\s\n onclick="exportShowFilterFields(this)"> match tags<br>\s\n<input type="text" id="exportTags" onfocus="this.select()">\s\n<input type="checkbox" class="chk" id=exportFilterText value="1"\s\n onclick="exportShowFilterFields(this)"> match titles/tiddler text<br>\s\n<input type="text" id="exportText" onfocus="this.select()">\s\n</div> <!--box-->\s\n</div> <!--panel-->\s\n\s\n<!-- action buttons -->\s\n<div style="text-align:center">\s\n<input type=button class="btn3" onclick="onClickExportButton(this)"\s\n id="exportFilter" value="apply filter">\s\n<input type=button class="btn3" onclick="onClickExportButton(this)"\s\n id="exportStart" value="export tiddlers">\s\n<input type=button class="btn3" onclick="onClickExportButton(this)"\s\n id="exportClose" value="close">\s\n</div><!--center-->\s\n';\n//}}}\n// //===\n\n// // +++[initialize interface]>\n// // +++[exportShowPanel(which)]\n//{{{\nfunction exportShowPanel(which) {\n var index=0; var panel='exportLocalPanel';\n switch (which) {\n case 'file:':\n case undefined:\n index=0; panel='exportLocalPanel'; break;\n case 'http:':\n index=1; panel='exportHTTPPanel'; break;\n case 'https:':\n index=2; panel='exportHTTPPanel'; break;\n case 'ftp:':\n index=3; panel='exportFTPPanel'; break;\n default:\n alert("Sorry, export to "+which+" is not yet available");\n break;\n }\n exportInitPanel(which);\n document.getElementById('exportTo').selectedIndex=index;\n document.getElementById('exportLocalPanel').style.display='none';\n document.getElementById('exportHTTPPanel').style.display='none';\n document.getElementById('exportFTPPanel').style.display='none';\n document.getElementById(panel).style.display='block';\n}\n//}}}\n// //===\n\n// // +++[exportInitPanel(which)]\n//{{{\nfunction exportInitPanel(which) {\n switch (which) {\n case "file:": // LOCAL EXPORT PANEL: file/path:\n // ** no init - security issues in IE **\n break;\n case "http:": // WEB EXPORT PANEL\n case "https:": // SECURE WEB EXPORT PANEL\n // url\n var siteURL=store.getTiddlerText("SiteUrl");\n if (store.tiddlerExists("unawiki_download")) {\n var theURL=store.getTiddlerText("unawiki_download");\n theURL=theURL.replace(/\s[\s[download\s|/,'').replace(/\s]\s]/,'');\n var title=(store.tiddlerExists("unawiki_host"))?"unawiki_host":"SiteHost";\n var theHost=store.getTiddlerText(title);\n if (!theHost || !theHost.length) theHost=document.location.host;\n if (!theHost || !theHost.length) theHost=title;\n siteURL=which+"//"+theHost+theURL\n }\n if (!siteURL) siteURL="SiteUrl";\n document.getElementById("exportHTTPSiteURL").value=siteURL;;\n // server script/params\n var title=(store.tiddlerExists("unawiki_host"))?"unawiki_host":"SiteHost";\n var theHost=store.getTiddlerText(title);\n if (!theHost || !theHost.length) theHost=document.location.host;\n if (!theHost || !theHost.length) theHost=title;\n // get POST\n var title=(store.tiddlerExists("unawiki_post"))?"unawiki_post":"SitePost";\n var thePost=store.getTiddlerText(title);\n if (!thePost || !thePost.length) thePost="/"+title;\n // get PARAMS\n var title=(store.tiddlerExists("unawiki_params"))?"unawiki_params":"SiteParams";\n var theParams=store.getTiddlerText(title);\n if (!theParams|| !theParams.length) theParams=title;\n var serverURL = which+"//"+theHost+thePost+"?"+theParams;\n document.getElementById("exportHTTPServerURL").value=serverURL;\n break;\n case "ftp:": // FTP EXPORT PANEL\n // host\n var siteHost=store.getTiddlerText("SiteHost");\n if (!siteHost || !siteHost.length) siteHost=document.location.host;\n if (!siteHost || !siteHost.length) siteHost="SiteHost";\n document.getElementById("exportFTPHost").value=siteHost;\n // username\n var siteID=store.getTiddlerText("SiteID");\n if (!siteID || !siteID.length) siteID=config.options.txtUserName;\n document.getElementById("exportFTPID").value=siteID;\n // password\n document.getElementById("exportFTPPW").value="";\n // file/path\n document.getElementById("exportFTPFilename").value="";\n break;\n }\n}\n//}}}\n// //===\n\n// // +++[exportInitFilter()]\n//{{{\nfunction exportInitFilter() {\n // TBD: persistent settings via local cookies\n // start date\n document.getElementById("exportFilterStart").checked=false;\n document.getElementById("exportStartDate").value="";\n // end date\n document.getElementById("exportFilterEnd").checked=false;\n document.getElementById("exportEndDate").value="";\n // tags\n document.getElementById("exportFilterTags").checked=false;\n document.getElementById("exportTags").value="not excludeExport";\n // text\n document.getElementById("exportFilterText").checked=false;\n document.getElementById("exportText").value="";\n // show/hide filter input fields\n exportShowFilterFields();\n}\n//}}}\n// //===\n\n// // +++[exportShowFilterFields(which)]\n//{{{\nfunction exportShowFilterFields(which) {\n var show;\n\n show=document.getElementById('exportFilterStart').checked;\n document.getElementById('exportFilterStartBy').style.display=show?"block":"none";\n document.getElementById('exportStartDate').style.display=show?"block":"none";\n var val=document.getElementById('exportFilterStartBy').value;\n document.getElementById('exportStartDate').value\n =getFilterDate(val,'exportStartDate').formatString(config.macros.exportTiddlers.datetimefmt);\n if (which && (which.id=='exportFilterStartBy') && (val=='other'))\n document.getElementById('exportStartDate').focus();\n\n show=document.getElementById('exportFilterEnd').checked;\n document.getElementById('exportFilterEndBy').style.display=show?"block":"none";\n document.getElementById('exportEndDate').style.display=show?"block":"none";\n var val=document.getElementById('exportFilterEndBy').value;\n document.getElementById('exportEndDate').value\n =getFilterDate(val,'exportEndDate').formatString(config.macros.exportTiddlers.datetimefmt);\n if (which && (which.id=='exportFilterEndBy') && (val=='other'))\n document.getElementById('exportEndDate').focus();\n\n show=document.getElementById('exportFilterTags').checked;\n document.getElementById('exportTags').style.display=show?"block":"none";\n\n show=document.getElementById('exportFilterText').checked;\n document.getElementById('exportText').style.display=show?"block":"none";\n}\n//}}}\n// //===\n// //===\n\n// // +++[onClickExportButton(which): control interactions]\n//{{{\nfunction onClickExportButton(which)\n{\n // DEBUG alert(which.id);\n var theList=document.getElementById('exportList'); if (!theList) return;\n var count = 0;\n var total = store.getTiddlers('title').length;\n switch (which.id)\n {\n case 'exportFilter':\n count=filterExportList();\n var panel=document.getElementById('exportFilterPanel');\n if (count==-1) { panel.style.display='block'; break; }\n theList.options[0].text=formatExportListHeader(count,total);\n document.getElementById("exportStart").disabled=(count==0);\n clearMessage(); displayMessage("filtered "+theList.options[0].text);\n if (count==0) { alert("No tiddlers were selected"); panel.style.display='block'; }\n break;\n case 'exportStart':\n exportTiddlers();\n break;\n case 'exportHideFilter':\n case 'exportToggleFilter':\n var panel=document.getElementById('exportFilterPanel')\n panel.style.display=(panel.style.display=='block')?'none':'block';\n break;\n case 'exportSelectChanges':\n var lastmod=new Date(document.lastModified);\n for (var t = 0; t < theList.options.length; t++) {\n if (theList.options[t].value=="") continue;\n var tiddler=store.getTiddler(theList.options[t].value); if (!tiddler) continue;\n theList.options[t].selected=(tiddler.modified>lastmod);\n count += (tiddler.modified>lastmod)?1:0;\n }\n theList.options[0].text=formatExportListHeader(count,total);\n document.getElementById("exportStart").disabled=(count==0);\n clearMessage(); displayMessage(theList.options[0].text);\n if (count==0) alert("There are no unsaved changes");\n break;\n case 'exportSelectAll':\n for (var t = 0; t < theList.options.length; t++) {\n if (theList.options[t].value=="") continue;\n theList.options[t].selected=true;\n count += 1;\n }\n theList.options[0].text=formatExportListHeader(count,count);\n document.getElementById("exportStart").disabled=(count==0);\n clearMessage(); displayMessage(theList.options[0].text);\n break;\n case 'exportSelectOpened':\n for (var t = 0; t < theList.options.length; t++) theList.options[t].selected=false;\n var tiddlerDisplay = document.getElementById("tiddlerDisplay");\n for (var t=0;t<tiddlerDisplay.childNodes.length;t++) {\n var tiddler=tiddlerDisplay.childNodes[t].id.substr(7);\n for (var i = 0; i < theList.options.length; i++) {\n if (theList.options[i].value!=tiddler) continue;\n theList.options[i].selected=true; count++; break;\n }\n }\n theList.options[0].text=formatExportListHeader(count,total);\n document.getElementById("exportStart").disabled=(count==0);\n clearMessage(); displayMessage(theList.options[0].text);\n if (count==0) alert("There are no tiddlers currently opened");\n break;\n case 'exportListSmaller': // decrease current listbox size\n var min=5;\n theList.size-=(theList.size>min)?1:0;\n break;\n case 'exportListLarger': // increase current listbox size\n var max=(theList.options.length>25)?theList.options.length:25;\n theList.size+=(theList.size<max)?1:0;\n break;\n case 'exportClose':\n document.getElementById('exportPanel').style.display='none';\n break;\n }\n}\n//}}}\n// //===\n\n// // +++[list display]\n//{{{\nfunction formatExportListHeader(count,total)\n{\n var txt=total+' tiddler'+((total!=1)?'s':'')+" - ";\n txt += (count==0)?"none":(count==total)?"all":count;\n txt += " selected for export";\n return txt;\n}\n\nfunction refreshExportList(selectedIndex)\n{\n var theList = document.getElementById("exportList");\n var sort;\n if (!theList) return;\n // get the sort order\n if (!selectedIndex) selectedIndex=0;\n if (selectedIndex==0) sort='modified';\n if (selectedIndex==1) sort='title';\n if (selectedIndex==2) sort='modified';\n if (selectedIndex==3) sort='modifier';\n\n // get the alphasorted list of tiddlers\n var tiddlers = store.getTiddlers('title');\n // unselect headings and count number of tiddlers actually selected\n var count=0;\n for (var i=0; i<theList.options.length; i++) {\n if (theList.options[i].value=="") theList.options[i].selected=false;\n count+=theList.options[i].selected?1:0;\n }\n // disable "export" button if no tiddlers selected\n document.getElementById("exportStart").disabled=(count==0);\n // update listbox heading to show selection count\n if (theList.options.length)\n theList.options[0].text=formatExportListHeader(count,tiddlers.length);\n\n // if a [command] item, reload list... otherwise, no further refresh needed\n if (selectedIndex>3) return;\n\n // clear current list contents\n while (theList.length > 0) { theList.options[0] = null; }\n // add heading and control items to list\n var i=0;\n var indent=String.fromCharCode(160)+String.fromCharCode(160);\n theList.options[i++]=\n new Option(formatExportListHeader(0,tiddlers.length), "",false,false);\n theList.options[i++]=\n new Option(((sort=="title" )?">":indent)+' [by title]', "",false,false);\n theList.options[i++]=\n new Option(((sort=="modified")?">":indent)+' [by date]', "",false,false);\n theList.options[i++]=\n new Option(((sort=="modifier")?">":indent)+' [by author]', "",false,false);\n // output the tiddler list\n switch(sort)\n {\n case "title":\n for(var t = 0; t < tiddlers.length; t++)\n theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);\n break;\n case "modifier":\n case "modified":\n var tiddlers = store.getTiddlers(sort);\n // sort descending for newest date first\n tiddlers.sort(function (a,b) {if(a[sort] == b[sort]) return(0); else return (a[sort] > b[sort]) ? -1 : +1; });\n var lastSection = "";\n for(var t = 0; t < tiddlers.length; t++)\n {\n var tiddler = tiddlers[t];\n var theSection = "";\n if (sort=="modified") theSection=tiddler.modified.toLocaleDateString();\n if (sort=="modifier") theSection=tiddler.modifier;\n if (theSection != lastSection)\n {\n theList.options[i++] = new Option(theSection,"",false,false);\n lastSection = theSection;\n }\n theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);\n }\n break;\n }\n theList.selectedIndex=selectedIndex; // select current control item\n}\n//}}}\n// //===\n\n// // +++[list filtering]\n//{{{\nfunction getFilterDate(val,id)\n{\n var result=0;\n switch (val) {\n case 'site':\n var timestamp=store.getTiddlerText("SiteDate");\n if (!timestamp) timestamp=document.lastModified;\n result=new Date(timestamp);\n break;\n case 'file':\n result=new Date(document.lastModified);\n break;\n case 'other':\n result=new Date(document.getElementById(id).value);\n break;\n default: // today=0, yesterday=1, one week=7, two weeks=14, a month=31\n var now=new Date(); var tz=now.getTimezoneOffset()*60000; now-=tz;\n var oneday=86400000;\n if (id=='exportStartDate')\n result=new Date((Math.floor(now/oneday)-val)*oneday+tz);\n else\n result=new Date((Math.floor(now/oneday)-val+1)*oneday+tz-1);\n break;\n }\n // DEBUG alert('getFilterDate('+val+','+id+')=='+result+"\snnow="+now);\n return result;\n}\n\nfunction filterExportList()\n{\n var theList = document.getElementById("exportList"); if (!theList) return -1;\n\n var filterStart=document.getElementById("exportFilterStart").checked;\n var val=document.getElementById("exportFilterStartBy").value;\n var startDate=getFilterDate(val,'exportStartDate');\n\n var filterEnd=document.getElementById("exportFilterEnd").checked;\n var val=document.getElementById("exportFilterEndBy").value;\n var endDate=getFilterDate(val,'exportEndDate');\n\n var filterTags=document.getElementById("exportFilterTags").checked;\n var tags=document.getElementById("exportTags").value;\n\n var filterText=document.getElementById("exportFilterText").checked;\n var text=document.getElementById("exportText").value;\n\n if (!(filterStart||filterEnd||filterTags||filterText)) {\n alert("Please set the selection filter");\n document.getElementById('exportFilterPanel').style.display="block";\n return -1;\n }\n if (filterStart&&filterEnd&&(startDate>endDate)) {\n var msg="starting date/time:\sn"\n msg+=startDate.toLocaleString()+"\sn";\n msg+="is later than ending date/time:\sn"\n msg+=endDate.toLocaleString()\n alert(msg);\n return -1;\n }\n\n // scan list and select tiddlers that match all applicable criteria\n var total=0;\n var count=0;\n for (var i=0; i<theList.options.length; i++) {\n // get item, skip non-tiddler list items (section headings)\n var opt=theList.options[i]; if (opt.value=="") continue;\n // get tiddler, skip missing tiddlers (this should NOT happen)\n var tiddler=store.getTiddler(opt.value); if (!tiddler) continue; \n var sel=true;\n if ( (filterStart && tiddler.modified<startDate)\n || (filterEnd && tiddler.modified>endDate)\n || (filterTags && !matchTags(tiddler,tags))\n || (filterText && (tiddler.text.indexOf(text)==-1) && (tiddler.title.indexOf(text)==-1)))\n sel=false;\n opt.selected=sel;\n count+=sel?1:0;\n total++;\n }\n return count;\n}\n//}}}\n\n//{{{\nfunction matchTags(tiddler,cond)\n{\n if (!cond||!cond.trim().length) return false;\n\n // build a regex of all tags as a big-old regex that \n // OR's the tags together (tag1|tag2|tag3...) in length order\n var tgs = store.getTags();\n if ( tgs.length == 0 ) return results ;\n var tags = tgs.sort( function(a,b){return (a[0].length<b[0].length)-(a[0].length>b[0].length);});\n var exp = "(" + tags.join("|") + ")" ;\n exp = exp.replace( /(,[\sd]+)/g, "" ) ;\n var regex = new RegExp( exp, "ig" );\n\n // build a string such that an expression that looks like this: tag1 AND tag2 OR NOT tag3\n // turns into : /tag1/.test(...) && /tag2/.test(...) || ! /tag2/.test(...)\n cond = cond.replace( regex, "/$1\s\s|/.test(tiddlerTags)" );\n cond = cond.replace( /\ssand\ss/ig, " && " ) ;\n cond = cond.replace( /\ssor\ss/ig, " || " ) ;\n cond = cond.replace( /\ss?not\ss/ig, " ! " ) ;\n\n // if a boolean uses a tag that doesn't exist - it will get left alone \n // (we only turn existing tags into actual tests).\n // replace anything that wasn't found as a tag, AND, OR, or NOT with the string "false"\n // if the tag doesn't exist then /tag/.test(...) will always return false.\n cond = cond.replace( /(\ss|^)+[^\s/\s|&!][^\ss]*/g, "false" ) ;\n\n // make a string of the tags in the tiddler and eval the 'cond' string against that string \n // if it's TRUE then the tiddler qualifies!\n var tiddlerTags = (tiddler.tags?tiddler.tags.join("|"):"")+"|" ;\n try { if ( eval( cond ) ) return true; }\n catch( e ) { displayMessage("Error in tag filter '" + e + "'" ); }\n return false;\n}\n//}}}\n// //===\n\n// // +++[output data formatting]>\n// // +++[exportHeader(format)]\n//{{{\nfunction exportHeader(format)\n{\n switch (format) {\n case "TW": return exportTWHeader();\n case "DIV": return exportDIVHeader();\n case "XML": return exportXMLHeader();\n }\n}\n//}}}\n// //===\n\n// // +++[exportFooter(format)]\n//{{{\nfunction exportFooter(format)\n{\n switch (format) {\n case "TW": return exportDIVFooter();\n case "DIV": return exportDIVFooter();\n case "XML": return exportXMLFooter();\n }\n}\n//}}}\n// //===\n\n// // +++[exportTWHeader()]\n//{{{\nfunction exportTWHeader()\n{\n // Get the URL of the document\n var originalPath = document.location.toString();\n // Check we were loaded from a file URL\n if(originalPath.substr(0,5) != "file:")\n { alert(config.messages.notFileUrlError); return; }\n // Remove any location part of the URL\n var hashPos = originalPath.indexOf("#"); if(hashPos != -1) originalPath = originalPath.substr(0,hashPos);\n // Convert to a native file format assuming\n // "file:///x:/path/path/path..." - pc local file --> "x:\spath\spath\spath..."\n // "file://///server/share/path/path/path..." - FireFox pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n // "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."\n // "file://server/share/path/path/path..." - pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n var localPath;\n if(originalPath.charAt(9) == ":") // pc local file\n localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file://///") == 0) // FireFox pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file:///") == 0) // mac/unix local file\n localPath = unescape(originalPath.substr(7));\n else if(originalPath.indexOf("file:/") == 0) // mac/unix local file\n localPath = unescape(originalPath.substr(5));\n else // pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\s\s");\n // Load the original file\n var original = loadFile(localPath);\n if(original == null)\n { alert(config.messages.cantSaveError); return; }\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 { alert(config.messages.invalidFileError.format([localPath])); return; }\n return original.substr(0,posOpeningDiv+startSaveArea.length)\n}\n//}}}\n// //===\n\n// // +++[exportDIVHeader()]\n//{{{\nfunction exportDIVHeader()\n{\n var out=[];\n var now = new Date();\n var u = store.getTiddlerText("SiteUrl",null);\n var title = wikifyPlain("SiteTitle").htmlEncode();\n var subtitle = wikifyPlain("SiteSubtitle").htmlEncode();\n var user = config.options.txtUserName.htmlEncode();\n var twver = version.major+"."+version.minor+"."+version.revision;\n var pver = version.extensions.exportTiddlers.major+"."\n +version.extensions.exportTiddlers.minor+"."+version.extensions.exportTiddlers.revision;\n out.push("<html><body>");\n out.push("<style type=\s"text/css\s">");\n out.push("#storeArea {display:block;margin:1em;}");\n out.push("#storeArea div");\n out.push("{padding:0.5em;margin:1em;border:2px solid black;height:10em;overflow:auto;}");\n out.push("#javascriptWarning");\n out.push("{width:100%;text-align:left;background-color:#eeeeee;padding:1em;}");\n out.push("</style>");\n out.push("<div id=\s"javascriptWarning\s">");\n out.push("TiddlyWiki export file<br>");\n out.push("Source: <b>"+document.location+"</b><br>");\n out.push("Title: <b>"+title+"</b><br>");\n out.push("Subtitle: <b>"+subtitle+"</b><br>");\n out.push("Created: <b>"+now.toLocaleString()+"</b> by <b>"+user+"</b><br>");\n out.push("TiddlyWiki "+twver+" / "+"ExportTiddlersPlugin "+pver+"<br>");\n out.push("</div>");\n out.push("<div id=\s"storeArea\s">");\n return out;\n}\n//}}}\n// //===\n\n// // +++[exportDIVFooter()]\n//{{{\nfunction exportDIVFooter()\n{\n var out=[];\n out.push("</div></body></html>");\n return out;\n}\n//}}}\n// //===\n\n// // +++[exportXMLHeader()]\n//{{{\nfunction exportXMLHeader()\n{\n var out=[];\n var now = new Date();\n var u = store.getTiddlerText("SiteUrl",null);\n var title = wikifyPlain("SiteTitle").htmlEncode();\n var subtitle = wikifyPlain("SiteSubtitle").htmlEncode();\n var user = config.options.txtUserName.htmlEncode();\n var twver = version.major+"."+version.minor+"."+version.revision;\n var pver = version.extensions.exportTiddlers.major+"."\n +version.extensions.exportTiddlers.minor+"."+version.extensions.exportTiddlers.revision;\n out.push("<" + "?xml version=\s"1.0\s"?" + ">");\n out.push("<rss version=\s"2.0\s">");\n out.push("<channel>");\n out.push("<title>" + title + "</title>");\n if(u) out.push("<link>" + u.htmlEncode() + "</link>");\n out.push("<description>" + subtitle + "</description>");\n out.push("<language>en-us</language>");\n out.push("<copyright>Copyright " + now.getFullYear() + " " + user + "</copyright>");\n out.push("<pubDate>" + now.toGMTString() + "</pubDate>");\n out.push("<lastBuildDate>" + now.toGMTString() + "</lastBuildDate>");\n out.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");\n out.push("<generator>TiddlyWiki "+twver+" plus ExportTiddlersPlugin "+pver+"</generator>");\n return out;\n}\n//}}}\n// //===\n\n// // +++[exportXMLFooter()]\n//{{{\nfunction exportXMLFooter()\n{\n var out=[];\n out.push("</channel></rss>");\n return out;\n}\n//}}}\n// //===\n\n// // +++[exportData()]\n//{{{\nfunction exportData(theList,theFormat)\n{\n // scan export listbox and collect DIVs or XML for selected tiddler content\n var out=[];\n for (var i=0; i<theList.options.length; i++) {\n // get item, skip non-selected items and section headings\n var opt=theList.options[i]; if (!opt.selected||(opt.value=="")) continue;\n // get tiddler, skip missing tiddlers (this should NOT happen)\n var thisTiddler=store.getTiddler(opt.value); if (!thisTiddler) continue; \n if (theFormat=="TW") out.push(thisTiddler.saveToDiv());\n if (theFormat=="DIV") out.push(thisTiddler.title+"\sn"+thisTiddler.saveToDiv());\n if (theFormat=="XML") out.push(thisTiddler.saveToRss());\n }\n return out;\n}\n//}}}\n// //===\n// //===\n\n// // +++[exportTiddlers(): output selected data to local or server]\n//{{{\nfunction exportTiddlers()\n{\n var theList = document.getElementById("exportList"); if (!theList) return;\n\n // get the export settings\n var theProtocol = document.getElementById("exportTo").value;\n var theFormat = document.getElementById("exportFormat").value;\n\n // assemble output: header + tiddlers + footer\n var theData=exportData(theList,theFormat);\n var count=theData.length;\n var out=[]; var txt=out.concat(exportHeader(theFormat),theData,exportFooter(theFormat)).join("\sn");\n var msg="";\n switch (theProtocol) {\n case "file:":\n var theTarget = document.getElementById("exportFilename").value.trim();\n if (!theTarget.length) msg = "A local path/filename is required\sn";\n if (!msg && saveFile(theTarget,txt))\n msg=count+" tiddler"+((count!=1)?"s":"")+" exported to local file";\n else if (!msg)\n msg+="An error occurred while saving to "+theTarget;\n break;\n case "http:":\n case "https:":\n var theTarget = document.getElementById("exportHTTPServerURL").value.trim();\n if (!theTarget.length) msg = "A server URL is required\sn";\n if (!msg && exportPost(theTarget+encodeURIComponent(txt)))\n msg=count+" tiddler"+((count!=1)?"s":"")+" exported to "+theProtocol+" server";\n else if (!msg)\n msg+="An error occurred while saving to "+theTarget;\n break;\n case "ftp:":\n default:\n msg="Sorry, export to "+theLocation+" is not yet available";\n break;\n }\n clearMessage(); displayMessage(msg,theTarget);\n}\n//}}}\n// //===\n\n// // +++[exportPost(url): cross-domain post] uses hidden iframe to submit url and capture responses\n//{{{\nfunction exportPost(url)\n{\n var f=document.getElementById("exportFrame"); if (f) document.body.removeChild(f);\n f=document.createElement("iframe"); f.id="exportFrame";\n f.style.width="0px"; f.style.height="0px"; f.style.border="0px";\n document.body.appendChild(f);\n var d=f.document;\n if (f.contentDocument) d=f.contentDocument; // For NS6\n else if (f.contentWindow) d=f.contentWindow.document; // For IE5.5 and IE6\n d.location.replace(url);\n return true;\n}\n//}}}\n// //===\n
! Introduction\n\nLes flash NAND sont des flashs de grande capacité, mais dont l'interface est spéciale, et qui possèdent des contraintes d'utilisation particulières.\nLeur fonctionnement, ainsi que leur formatage, sont décrits en détail dans la rubrique qui leur est consacrée ([[FonctionnementFlashNAND]]), et le système de fichier racine (//root FS//) est décrit dans la rubrique sur [[YAFFS|YAFFS2]].
!!!!Réflexions sur les interfaces\n\nQuelle interface choisir pour l'arbitre ? Il y a plusieurs façons d'aborder le problème : \n* on peut partir sur un arbitre prenant en entrée une interface DTL (ou DTL-like), c'est-à-dire traitant directement des requêtes agrégées. On a donc quelque part un multiplexeur d'adresse choisissant une source parmi N+1 (N sources externes, et 1 supplémentaire qui est l'adresse actuelle + 1 quand on est dans un burst).\n* on peut assi partir sur un arbitre prenant directement des requêtes élémentaires en entrée, plus une interface DTL qui se charge d'exploser les requêtes agrégées en requêtes élémentaires. On diminue alors le nombre de sources du multiplexeur, au détriment de fifos plus grandes. Comme les fifos sont implémentées à base de SRAM internes, et qu'on n'est pas vraiment contraint en terme SRAM dans le FPGA, il est préférable de partir sur cette options. En effet, le chemin critique de l'arbitre est justement la chaîne de multiplexeurs de sélection d'adresses. Moins il y aura de sources possible, plus on ira vite.\n\nEstimons le nombre de bits nécessaires pour les fifos dans chaque cas, avec {{{ BS_MAX = taille maximal d'un bloc en burst }}} et {{{ NREQ_MAX = nombre maximal de requêtes agrégées pipe-linables }}}.\n* Cas requêtes explosées :\n** Write : {{{ (25+32).BS_MAX.NREQ_MAX }}}\n** Read : {{{ (25+32+1).BS_MAX.NREQ_MAX }}}\n* Cas requêtes agrégées :\n** Write : {{{ (25+8).NREQ_MAX + 32.BS_MAX.NREQ_MAX}}}\n** Read : {{{ (25+8).NREQ_MAX + (32+1).BS_MAX.NREQ_MAX}}}\n\n\n\n\n\n\n\n
!!Fonctionnement\n{{{ADSCn = 0}}} et {{{ADSPn = 1}}}. Comme cela, la sélection / déselection de la RAM se fait exclusivement par {{{CE0n}}}. \nLes SSRAM sont single-cycle deselect, ce qui veut dire qu'un petit délai après un front montant qui voit {{{CE0n=1}}} et {{{ADCSn=0}}}, la RAM passe en haute-impédance.\n\n!!!Mode FT\n\nOpérations :\n* Read : on présente AD. La RAM passe en basse-impédance au cycle suivant (ie un petit délai après le front de clock) et sort la donnée.\n* Write : on présente AD et DATA en même temps\n\nEnchaînement des opérations :\n* Write -> Read : directement (une opération par cycle)\n* Read -> Write : un cycle d'attente (celui où on récupère la donnée du Read).\n\nDouble banc :\n* Comme la déselection se fait au cycle qui suit (ie, un petit délai après le front d'horloge qui voit {{{CE0n=1}}} et {{{ADSCn=0}}}), on peut enchaîner les opérations sur deux RAM comme s'il n'y en avait qu'une seule. \n* Il faut juste s'assurer que les chip select ne sont jamais actifs en même temps. En prenant {{{CE0nA = ~CE0nB}}}, on a en permanence une RAM sélectionnée et une déselectionée. Donc pas de conflits.\n\n!!!Mode Pipeline\n\nOpérations :\n* Read : on présente AD. La RAM passe en basse-impédance 2 cycles après et sort la donnée.\n* Write : on présente AD et DATA en même temps\n
!!Introduction\n\nLa flash est une flash de type NAND. Elle diffère des flashs classiques (NOR) par :\n* sa densité, plus grande que les flash NOR, grâce à des points mémoire plus petits,\n* son coût, qui à capacité égale est donc plus faible,\n* sa rapidité, plus grande que celle des flashs NOR,\n* son type d’interface, différente des interfaces type SRAM des flashs habituelles,\n* la présence autorisée et fréquente (5%) de blocs défectueux,\n* son layout : chaque page comporte des données habituelles, plus quelques octets dits Out Of Band (OOB) permettant entre autres d’implémenter de l’ECC.\n\nLes deux caractéristiques les plus importantes ici sont l’interface et le layout (OOB). L’interface ne comporte ni bus d’adresse ni bus de données, mais un bus de commande bidirectionnel et des lignes de contrôle. Chaque accès se compose d’une phase d’envoi de commande (lecture, écriture, eacement, reset, ...), puis d’une ou plusieurs phases d’exécution proprement dite. En d’autres termes, il n’est pas possible de connecter cette flash directement au bus processeur du SH4. C’est pour cela qu’elle a été connectée aux GPIO du SH4.\n\nChacune des deux flashs de la carte Stratix comporte 1024 blocs de 32 pages de (512+16) octets.\n\n!!!!Bloc \nUn bloc est la plus petite partie qu’on puisse effacer. Autrement dit, pour effacer 20 octets, on doit lire le bloc qui les contient, effacer ce bloc, puis ré-écrire tout le bloc, sauf les 20 octets en question. \nLes flashs de la carte Stratix comportent chacune 1024 blocs.\n\n!!!!Pages \nUne page est la plus petite section qu’on puisse écrire. Il ne faut pas confondre écriture et effacement. Une écriture ne peut mettre des bits qu’à 0, un effacement qu’à 1. Une flash vierge ne contient que des 1. Quand on écrit, on programme des 0 aux endroits où il faut. On peut programmer une page sans avoir à effacer le bloc qui la contient si on ne fait que passer des bits à 0, et si on se limite à 3 écritures. Au delà de trois écritures, le bloc doit être effacé pour être ré-écrit. Les flashs de la carte Stratix comportent chacune 32 pages par bloc, et chaque page comporte (512+16) octets.\n\n!!!!Données et OOB \nChaque page comporte 512 octets de données, situés à des adresses consécutives, plus 16 octets dits Out Of Band (OOB). Ces 16 octets sont réservés à l’ECC, ainsi qu’à différents marquages. La plupart des file-systems spécifiques aux flashs NAND les utilisent comme marqueurs d’inode. Un de ces octets est important, c’est le numéro 517 (le 6ème des OOB) : le nombre de bits à 0 dans cet octet est le nombre de bit défectueux dans la page.\n* Une page correcte contient donc 0xFF en 517.\n* Une page avec un bit défectueux contiendra par exemple 0xFE (ou 0xEF, ou. . . ).\n* Une page avec deux bits défectueux contiendra par exemple 0xFC (ou 0x3F, ou. . . ).\n\nLes OOB comportent aussi six octets d’ECC : 520-521-522, qui portent sur les derniers 256 octets de data de la page, et 525-526-527 qui portent sur les 256 premiers octets de data de la page. Chaque triplet permet de corriger un bit défectueux.\nUne page contenant plus d’un bit défectueux sera donc généralement non récupérable (sauf si chaque bit est dans une moitié diérente de la page). On n’admet donc qu’un seul bit à 0 dans l’octet de statut\n(517).\nSi une page comporte plus d’un bit défectueux, le bloc qui la contient en entier est marqué comme défectueux. La façon d’effectuer ce marquage dépend des file-systems et conventions utilisées, mais généralement soit on marque toutes les pages du bloc comme défectueuses, soit on ne marque que la page en question ainsi que la première du bloc.\nDe plus, certains flash NAND (les Disk On Chip par exemple) maintiennent une table des blocs défectueux. Ce n’est pas notre cas, la table des blocs est construite au boot en scannant la flash, et maintenue seulement en RAM par le système de fichier (YAFFS).\n\n!!!!ECC \nUne flash NAND peut comporter jusqu’à 5% de blocs défectueux. Il est donc important d’utiliser l’ECC et de détecter et marquer les blocs défectueux. Normalement cela est géré de façon transparente par le système de fichier et l’OS, mais dans le cas du bootloader c’est à faire manuellement. En d’autres termes, l’écriture d’un fichier en flash par le bootloader (indépendament de tout système de fichier) se décompose ainsi :\n* tronçonnage du fichier en pages de 512 octets,\n* calcul de l’ECC pour chaque page, ajout de 16 octets à ce fichier à la fin de chaque blocs de 512,\n* écriture du nouveau fichier (data + OOB), mais seulement sur les blocs marqués valides.\n\n\n!!File system\nLa flash doit contenir, au minimum, le noyau Linux (vmlinuzx) et le root file-system. Elle peut aussi stocker un file-system additionnel (utilisateur), d’autres noyaux, etc. . . Le choix du file-system est crucial : les flash NAND peuvent avoir des secteurs défectueux, et sont limitées en termes de ré-écriture. Il faut donc choisir un file-system adapté à leur fonctionnement. A ce jour, il en existe deux : JFFS2 et [[YAFFS|YAFFS2]].\n* JFFS2 : file-system compressé. Nécessite un parsing entier des secteurs de la flash au boot, pouvant être long. La génération d’une image (pour le formatage de la flash et la première écriture du root file-system) est compliquée.\n* [[YAFFS|YAFFS2]] : file-system non compressé. Simple et rapide. Génération d’une image simplissime.\nC’est donc [[YAFFS|YAFFS2]] qui a été retenu.\n\n[[YAFFS|YAFFS2]] existe en deux versions. \n* La première, utilisée dans les premières versions de la carte, est maintenant obsolète. Elle n’est plus maintenue, et son utilisation est fortement déconseillée. \n* La deuxième version de [[YAFFS|YAFFS2]] est principalement orientée vers les flashs aux pages de 2ko, mais il est possible de la faire fonctionner dans un mode dit de compatibilité pour les flashs de 512o par page. Cette deuxième version de [[YAFFS|YAFFS2]] connaît certains problèmes nécessitant de patcher la couche MTD de Linux. En effet, la couche MTD a fait des choix architecturaux orientés vers l’utilisation de JFFS2, notamment en ce qui concerne le placement des octets OOB. Elle ne permet actuellement pas au filesystem de spécifier lui-même l’emplacement de ses OOB, en tous cas pas dans l’intégralité des fonctions de son API. Des modifications de la couche MTD sont en cours de façon à rendre [[YAFFS|YAFFS2]] et MTD compatibles sans nécessiter de patchs particuliers. La version finale est toujours attendue. En attendant, les modifications effectuées pour interfacer MTD et [[YAFFS|YAFFS2]] sont décrites dans la [[rubrique sur YAFFS|YAFFS2]].\n\n!!Partitionnement\nLa flash est partagée en un certain nombre de partitions :\n\n| Numéro | Offset (bloc) | Longueur | FileSystem | Contenu |\n| 0 | 0 | 1 bloc (16ko) | none (data+ECC) | Data pour le bootloader |\n| 1 | 1 | 39 blocs (624ko) | none (data+ECC) | Bootloader |\n| 2 | 40 | 128 blocs (2Mo) | none (data+ECC) | Linux kernel |\n| 3 | 168 | 1680 blocs (26.25Mo) | YAFFS2 | RootFS |\n| 4 | 1848 | 200 blocs (3.12 Mo) | YAFFS2, JFFS2, ... | Partition de test |\n\nLes trois première partitions contiennent des données brutes, sans système de fichiers. Cependant les OOB contiennent quand même les marqueurs de validité ainsi que les ECC. L’avant-dernière dernière partition contient le système de fichiers racine de la carte, au format [[YAFFS|YAFFS2]]. Le premier bloc des flashs est garanti sans fautes : il peut donc accueillir sans problème les données critiques du bootloader (arguments pour le noyau, ...). Les autres partitions (1 et 2) ont été choisies suffisament grandes pour pouvoir accueilir ce qui leur revient (bootloader2 et kernel respectivement) même en cas de taux de blocs défectueux maximum (5%). La dernière partition est temporaire, pour tester [[YAFFS|YAFFS2]], JFFS2, . . .\n\n!!!Formatage et première écriture\n\nAvant de pouvoir booter Linux, il est nécessaire d’avoir écrit un noyau en flash ainsi qu’un root filesystem minimal. Cela est effectué au moyen du bootloader : le [[bios|Bios]] en ROM charge le [[bootloader|BootLoader]] par la ligne série, puis il l’exécute. C’est lui qui se charge de scanner les flash pour détecter d’éventuels blocs défectueux, de n’effacer que les blocs valides, et de programmer au bon endroit les différentes partitions. Le partage des tâches entre [[bios|Bios]] et [[bootloader|BootLoader]] est [[décrit ici|Boot]].\n\nIl y a quand même un problème avec les cartes vierges : le [[bootloader|BootLoader]], utiliser pour flasher la flash, doit justement être lu en flash par le [[bios|Bios]]. Si rien n'est écrit en flash, comme c'est le cas pour une carte vierge, le [[bios|Bios]] ne trouve pas le [[bootloader|BootLoader]] et on ne peut donc rien flasher ! C'est le problème du bootstrap (appelé aussi de l'oeuf et de la poule). Pour le résoudre, le [[bios|Bios]] peut être compilé dans un mode spécial, auquel cas il embarque une copie du [[bootloader|BootLoader]]. Au lacement, il recopie cette image en RAM, et l'exécute. On peut alors tranquilement flasher la carte. La compilation du [[bios|Bios]] dans ce mode et le premier flash de la carte sont décrit dans la [[rubrique sur le bios|Bios]].\n\n\n\n
config.macros.getversion = {}\nconfig.macros.getversion.handler = function(place,macroName,params)\n{\nvar versionData = version.extensions[params].major + "." + version.extensions[params].minor + "." + version.extensions[params].revision;\ncreateTiddlyElement(place,"span",null,null,versionData);\n}\n\nconfig.macros.getversiondate = {}\nconfig.macros.getversiondate.handler = function(place,macroName,params)\n{\nvar versionDate = version.extensions[params[0]].date.formatString(params[1].trim());\ncreateTiddlyElement(place,"span",null,null,versionDate);\n}\n
/***\n''HTML Formatting Plugin for TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#HTMLFormattingPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nThe shorthand Wiki-style formatting syntax of ~TiddlyWiki is very convenient and enables most content to be reasonably well presented. However, there are times when tried-and-true HTML formatting syntax allows more more precise control of the content display.\n\nWhen HTML formatting syntax is embedded within a tiddler (in between {{{<}}}{{{html>}}} and {{{<}}}{{{/html>}}} markers) TiddlyWiki passes this content to the browser for processing as 'native' HTML. However, TiddlyWiki does not also process the HTML source content for any embedded wiki-formatting syntax it may contain. This means that while you can use HTML formatted content, you cannot mix wiki-formatted content within the HTML formatting.\n!!!!!Usage\n<<<\nThe ~HTMLFormatting plugin allows you to freely ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.\n\nWhen a tiddler is about to be displayed, ~TiddlyWiki looks for tiddler content contained within ''<{{{html}}}>'' and ''<{{{/html}}}>'' HTML tags. This content (if any) is passed directly to the browser's internal "rendering engine" to process as ~HTML-formatted content. Once the HTML formatting has been processed, all the pieces of text occuring in between the HTML formatting are then processed by the ~TiddlyWiki rendering engine, one piece at a time, so that normal wiki-style formatting can be applied to the individual text pieces.\n<<<\n!!!!!Line breaks\n<<<\nOne major difference between Wiki formatting and HTML formatting is how "line breaks" are processed. Wiki formatting treats all line breaks as literal content to be displayed //as-is//. However, because HTML normally ignores line breaks and actually processes them as simple "word separators" instead, many people who write HTML include extra line breaks in their documents, just to make the "source code" easier to read.\n\nEven though you can use HTML tags within your tiddler content, the default treatment for line breaks still follows the Wiki-style rule (i.e., all new lines are displayed as-is). When adding HTML content to a tiddler (especially if you cut-and-paste it from another web page), you should take care to avoid adding extra line breaks to the text.\n\nIf removing all the extra line breaks from your HTML content would be a big hassle, you can quickly //override the default Wiki-style line break rule// so that the line breaks use the standard HTML rules instead. Placing a ''<{{{hide linebreaks}}}>'' tag within the tiddler's HTML content changes all line breaks to spaces before rendering the content, so that the literal line breaks will be processed as simple word-breaks instead.\n\nNote: this does //not// alter the actual tiddler content that is stored in the document, just the manner in which it is displayed. Any line breaks contained in the tiddler will still be there when you edit its content. Also, to include a literal line break when the ''<{{{hide linebreaks}}}>'' tag is present, you will need to use a ''<{{{br}}}>'' or ''<{{{p}}}>'' HTML tag instead of simply typing a line break.\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''HTMLFormattingPlugin'' (tagged with <<tag systemConfig>>)\n^^documentation and javascript for HTMLFormatting handling^^\n<<<\n!!!!!Revision History\n<<<\n''2006.02.05 [2.1.1]''\nwrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals\n''2005.12.01 [2.1.0]''\ndon't wikify #TEXT nodes inside SELECT and TEXTAREA elements\n''2005.11.06 [2.0.1]''\ncode cleanup\n''2005.10.31 [2.0.0]''\nreplaced hijack wikify() with hijack config.formatters["html"] and simplified recursive WikifyTextNodes() code\n''2005.10.09 [1.0.2]''\ncombined documentation and code into a single tiddler\n''2005.08.05 [1.0.1]''\nmoved HTML and CSS definitions into plugin code instead of using separate tiddlers\n''2005.07.26 [1.0.1]''\nRe-released as a plugin.\nAdded <{{{html}}}>...</{{{nohtml}}}> and <{{{hide newlines}}}> handling\n''2005.07.20 [1.0.0]''\nInitial Release (as code adaptation)\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.HTMLFormatting = {major: 2, minor: 1, revision: 0, date: new Date(2005,12,1)};\n\n// find the formatter for HTML and replace the handler\ninitHTMLFormatter();\nfunction initHTMLFormatter()\n{\n for (var i=0; i<config.formatters.length && config.formatters[i].name!="html"; i++);\n if (i<config.formatters.length) config.formatters[i].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 var html=lookaheadMatch[1];\n // optionally suppress wiki-style literal handling of newlines\n // strip any carriage returns added by Internet Explorer's textarea edit field\n // encode newlines as \sn so Internet Explorer's HTML parser won't eat them\n // encode macro brackets (<< and >>) so HTML parser won't eat them\n if (html.indexOf('<hide linebreaks>')!=-1) html=html.replace(regexpNewLine,' ');\n html=html.replace(regexpCarriageReturn,'');\n html=html.replace(regexpNewLine,'\s\sn');\n html=html.replace(/<</g,'%%(').replace(/>>/g,')%%');\n // create span to hold HTML\n // parse HTML and normalize the results\n // walk node tree and call wikify() on each text node\n var e = createTiddlyElement(w.output,"span");\n e.innerHTML=html;\n e.normalize(); \n wikifyTextNodes(e);\n // advance to next parse position\n w.nextMatch=lookaheadMatch.index + lookaheadMatch[0].length;\n }\n }\n}\n\n// wikify text nodes remaining after HTML content is processed (pre-order recursion)\nfunction wikifyTextNodes(theNode)\n{\n for (var i=0;i<theNode.childNodes.length;i++) {\n var theChild=theNode.childNodes.item(i);\n if (theChild.nodeName.toLowerCase()=='option') continue;\n if (theChild.nodeName.toLowerCase()=='select') continue;\n wikifyTextNodes(theChild);\n if (theChild.nodeName=='#text') {\n var txt=theChild.nodeValue;\n // decode macro brackets and newlines\n txt=txt.replace(/\s%%\s(/g,'<<').replace(/\s)\s%%/g,'>>').replace(regexpBackSlashEn,'\sn');\n // replace text node with wikified() span\n var newNode=createTiddlyElement(null,"span");\n wikify(txt,newNode);\n theNode.replaceChild(newNode,theChild);\n }\n }\n}\n//}}}\n
To upload a TiddlyWiki on your web server :\n\n#Import all tiddlers tagged with Upload from http://TiddlyWiki.bidix.info/#Upload\n#Install UploadPlugin //as usual//\n#Configure and upload [[store.php]] on your webserver\n#set a {{{<<upload>>}}} button for example in your SideBarOptions\n#Set UploadOptions in conformity with [[store.php]]\n#click on <<upload>> button\n
!! Import de l'arborescence à partir des archives d'Alexis\n\n''Note'' : on appelera {{{$SOURCE}}} l'endroit où se trouve l'arborescence existante. Typiquement, c'est {{{ssh://shix@vega.enst.fr/sh4/kernel}}}. Avant de pouvoir y accéder, il faut fournir au responsable du dépôt une clef ssh publique...\n\nPlutôt que se [[construire son arborescence from scratch|Creation Arborescence From Scratch]], on peut récupérer celle d'Alexis. Toute l'arborescence de développement est versionnée, et, pour des raisons pratiques, séparée en plusieurs repository Mercurial :\n* un repository pour le répertoire principal Linux (contenant tous les patchs des autres arbres ainsi que les modifications maison)\n* un repository pour chaque arbre de patch (MTD, YAFFS, SH_LINUX)\n* un repository pour les sources officielles du noyau\n\nLe scénario présenté ici consiste à ne récupérer que le répertoire principal, à travailler dedans, et à récupérer de temps à autres (si on le souhaite) les patchs appliqués par Alexis dans l'archive //officielle//.\nSi on souhaite aussi disposer des dépôts annexes, on peut bien entendu les récupérer aussi (même endroit).\n\nLe répertoire principal, qui peut servir de répertoire de travail courant, se trouve dans {{{kernel/linux_work}}}. Pour le récupérer à partir du repository d'Alexis : \n{{{\n> cd kernel\n> hg clone $SOURCE\n}}}\n\nPar la suite, pour récupérer les nouvelles modifications effectuées dans cet arbre :\n{{{\n> hg pull\n> hg update\n# éventuellement hg update -m s'il y a besoin d'un merge manuel...\n}}}\n\n
/***\n''Import Tiddlers Plugin for TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#ImportTiddlersPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nWhen many people share and edit copies of the same TiddlyWiki document, the ability to quickly collect all these changes back into a single, updated document that can then be redistributed to the entire group is very important. This plugin lets you selectively combine tiddlers from any two TiddlyWiki documents. It can also be very useful when moving your own tiddlers from document to document (e.g., when upgrading to the latest version of TiddlyWiki, or 'pre-loading' your favorite stylesheets into a new 'empty' TiddlyWiki document.)\n\n!!!!!Inline interface (live)\n<<<\n<<importTiddlers inline>>\n<<<\n!!!!!Macro Syntax\n<<<\n{{{<<importTiddlers>>}}}\ncreates "import tiddlers" link. click to show/hide import control panel\n\n{{{<<importTiddlers inline>>}}}\ncreates import control panel directly in tiddler content\n\n{{{<<importTiddlers filter source quiet ask>>}}}\nnon-interactive 'automatic' import.\n''filter'' determines which tiddlers will be automatically selected for importing. Use one of the following keywords:\n>''"new"'' retrieves only tiddlers that are found in the import source document, but do not yet exist in the destination document\n>''"changes"'' retrieves only tiddlers that exist in both documents for which the import source tiddler is newer than the existing tiddler\n>''"updates"'' retrieves both ''new'' and ''changed'' tiddlers (this is the default action when none is specified)\n>''"all"'' retrieves ALL tiddlers from the import source document, even if they have not been changed.\n''source'' is the location of the imported document. It can be either a local document or an URL:\n>filename is any local path/file, in whatever format your system requires\n>URL is any remote web location that starts with "http://" or "https://"\n''"quiet"'' (optional)\n>supresses all status message during the import processing (e.g., "opening local file...", "found NN tiddlers..." etc). Note that if ANY tiddlers are actualy imported, a final information message will still be displayed (along with the ImportedTiddlers report), even when 'quiet' is specified. This ensures that changes to your document cannot occur without any visible indication at all.\n''"ask"'' (optional)\n>adds interactive confirmation. A browser message box (OK/Cancel) is displayed for each tiddler that will be imported, so that you can manually bypass any tiddlers that you do not want to import.\n\n''Special tag values: importReplace and importPublic''\n\nBy adding these special tags to an existing tiddler, you can precisely control whether or not to allow updates to that tiddler as well as decide which tiddlers in your document can be automatically imported by others.\n*''For maximum safety, the default action is to prevent existing tiddlers from being unintentionally overwritten by incoming tiddlers.'' To allow an existing tiddler to be overwritten by an imported tiddler, you must tag the existing tiddler with ''<<tag importReplace>>''\n*''For maximum privacy, the default action for //outgoing// tiddlers is to NOT automatically share your tiddlers with others.'' To allow a tiddler in your document to be shared via auto-import actions by others, you must tag it with ''<<tag importPublic>>''\n//Note: these tags are only applied when using the auto-import processing. When using the interactive control panel, all tiddlers in the imported document are available in the listbox, regardless of their tag values.//\n<<<\n!!!!!Interactive Usage\n<<<\nWhen used interactively, a control panel is displayed consisting of an "import source document" filename input (text field plus a ''[Browse...]'' button), a listbox of available tiddlers, a "differences only" checkbox, an "add tags" input field and four push buttons: ''[open]'', ''[select all]'', ''[import]'' and ''[close]''.\n\nPress ''[browse]'' to select a TiddlyWiki document file to import. You can also type in the path/filename or a remote document URL (starting with http://)and press ''[open]''. //Note: There may be some delay to permit the browser time to access and load the document before updating the listbox with the titles of all tiddlers that are available to be imported.//\n\nSelect one or more titles from the listbox (hold CTRL or SHIFT while clicking to add/remove the highlight from individual list items). You can press ''[select all]'' to quickly highlight all tiddler titles in the list. Use the ''[-]'', ''[+]'', or ''[=]'' links to adjust the listbox size so you can view more (or less) tiddler titles at one time. When you have chosen the tiddlers you want to import and entered any extra tags, press ''[import]'' to begin copying them to the current TiddlyWiki document.\n\n''select: all, new, changes, or differences''\n\nYou can click on ''all'', ''new'', ''changes'', or ''differences'' to automatically select a subset of tiddlers from the list. This makes it very quick and easy to find and import just the updated tiddlers you are interested in:\n>''"all"'' selects ALL tiddlers from the import source document, even if they have not been changed.\n>''"new"'' selects only tiddlers that are found in the import source document, but do not yet exist in the destination document\n>''"changes"'' selects only tiddlers that exist in both documents but that are newer in the source document\n>''"differences"'' selects all new and existing tiddlers that are different from the destination document (even if destination tiddler is newer)\n\n''Import Tagging:''\n\nTiddlers that have been imported can be automatically tagged, so they will be easier to find later on, after they have been added to your document. New tags are entered into the "add tags" input field, and then //added// to the existing tags for each tiddler as it is imported.\n\n''Skip, Rename, Merge, or Replace:''\n\nWhen importing a tiddler whose title is identical to one that already exists, the import process pauses and the tiddler title is displayed in an input field, along with four push buttons: ''[skip]'', ''[rename]'', ''[merge]'' and ''[replace]''.\n\nTo bypass importing this tiddler, press ''[skip]''. To import the tiddler with a different name (so that both the tiddlers will exist when the import is done), enter a new title in the input field and then press ''[rename]''. Press ''[merge]'' to combine the content from both tiddlers into a single tiddler. Press ''[replace]'' to overwrite the existing tiddler with the imported one, discarding the previous tiddler content.\n\n//Note: if both the title ''and'' modification date/////time match, the imported tiddler is assumed to be identical to the existing one, and will be automatically skipped (i.e., not imported) without asking.//\n\n''Import Report History''\n\nWhen tiddlers are imported, a report is generated into ImportedTiddlers, indicating when the latest import was performed, the number of tiddlers successfully imported, from what location, and by whom. It also includes a list with the title, date and author of each tiddler that was imported.\n\nWhen the import process is completed, the ImportedTiddlers report is automatically displayed for your review. If more tiddlers are subsequently imported, a new report is //added// to ImportedTiddlers, above the previous report (i.e., at the top of the tiddler), so that a reverse-chronological history of imports is maintained.\n\nIf a cumulative record is not desired, the ImportedTiddlers report may be deleted at any time. A new ImportedTiddlers report will be created the next time tiddlers are imported.\n\nNote: You can prevent the ImportedTiddlers report from being generated for any given import activity by clearing the "create a report" checkbox before beginning the import processing.\n\n<<<\n!!!!!Installation\n<<<\ncopy/paste the following tiddlers into your document:\n''ImportTiddlersPlugin'' (tagged with <<tag systemConfig>>)\n\ncreate/edit ''SideBarOptions'': (sidebar menu items) \n^^Add "< < ImportTiddlers > >" macro^^\n\n''Quick Installation Tip #1:''\nIf you are using an unmodified version of TiddlyWiki (core release version <<version>>), you can get a new, empty TiddlyWiki with the Import Tiddlers plugin pre-installed (''[[download from here|TW+ImportExport.html]]''), and then simply import all your content from your old document into this new, empty document.\n<<<\n!!!!!Revision History\n<<<\n''2006.02.21 [2.7.1]''\nClean up layout problems with IE. (Use tables for alignment instead of SPANs styled with float:left and float:right)\n''2006.02.21 [2.7.0]''\nAdded "local file" and "web server" radio buttons for selecting dynamic import source controls in ImportPanel. Default file control is replaced with URL text input field when "web server" is selected. Default remote document URL is defined in SiteURL tiddler. Also, added option for prepending SiteProxy URL as prefix to remote URL to mask cross-domain document access (requires compatible server-side script)\n''2006.02.17 [2.6.0]''\nRemoved "differences only" listbox display mode, replaced with selection filter 'presets': all/new/changes/differences. Also fixed initialization handling for "add new tags" so that checkbox state is correctly tracked when panel is first displayed.\n''2006.02.16 [2.5.4]''\nadded checkbox options to control "import remote tags" and "keep existing tags" behavior, in addition to existing "add new tags" functionality.\n''2006.02.14 [2.5.3]''\nFF1501 corrected unintended global 't' (loop index) in importReport() and autoImportTiddlers()\n''2006.02.10 [2.5.2]''\ncorrected unintended global variable in importReport().\n''2006.02.05 [2.5.1]''\nmoved globals from window.* to config.macros.importTiddlers.* to avoid FireFox 1.5.0.1 crash bug when referencing globals\n''2006.01.18 [2.5.0]''\nadded checkbox for "create a report". Default is to create/update the ImportedTiddlers report. Clear the checkbox to skip this step.\n''2006.01.15 [2.4.1]''\nadded "importPublic" tag and inverted default so that auto sharing is NOT done unless tagged with importPublic\n''2006.01.15 [2.4.0]''\nAdded support for tagging individual tiddlers with importSkip, importReplace, and/or importPrivate to control which tiddlers can be overwritten or shared with others when using auto-import macro syntax. Defaults are to SKIP overwriting existing tiddlers with imported tiddlers, and ALLOW your tiddlers to be auto-imported by others.\n''2006.01.15 [2.3.2]''\nAdded "ask" parameter to confirm each tiddler before importing (for use with auto-importing)\n''2006.01.15 [2.3.1]''\nStrip TW core scripts from import source content and load just the storeArea into the hidden IFRAME. Makes loading more efficient by reducing the document size and by preventing the import document from executing its TW initialization (including plugins). Seems to resolve the "Found 0 tiddlers" problem. Also, when importing local documents, use convertUTF8ToUnicode() to convert the file contents so support international characters sets.\n''2006.01.12 [2.3.0]''\nReorganized code to use callback function for loading import files to support event-driven I/O via an ASYNCHRONOUS XMLHttpRequest. Let's processing continue while waiting for remote hosts to respond to URL requests. Added non-interactive 'batch' macro mode, using parameters to specify which tiddlers to import, and from what document source. Improved error messages and diagnostics, plus an optional 'quiet' switch for batch mode to eliminate //most// feedback.\n''2006.01.11 [2.2.0]''\nAdded "[by tags]" to list of tiddlers, based on code submitted by BradleyMeck\n''2006.01.09 [2.1.1]''\nWhen a URL is typed in, and then the "open" button is pressed, it generates both an onChange event for the file input and a click event for open button. This results in multiple XMLHttpRequest()'s which seem to jam things up quite a bit. I removed the onChange handling for file input field. To open a file (local or URL), you must now explicitly press the "open" button in the control panel.\n''2006.01.08 [2.1.0]''\nIMPORT FROM ANYWHERE!!! re-write getImportedTiddlers() logic to either read a local file (using local I/O), OR... read a remote file, using a combination of XML and an iframe to permit cross-domain reading of DOM elements. Adapted from example code and techniques courtesy of Jonny LeRoy.\n''2006.01.06 [2.0.2]''\nWhen refreshing list contents, fixed check for tiddlerExists() when "show differences only" is selected, so that imported tiddlers that don't exist in the current file will be recognized as differences and included in the list.\n''2006.01.04 [2.0.1]''\nWhen "show differences only" is NOT checked, import all tiddlers that have been selected even when they have a matching title and date.\n''2005.12.27 [2.0.0]''\nUpdate for TW2.0\nDefer initial panel creation and only register a notification function when panel first is created\n''2005.12.22 [1.3.1]''\ntweak formatting in importReport() and add 'discard report' link to output\n''2005.12.03 [1.3.0]''\nDynamically create/remove importPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding. Also, dynamically create/recreate importFrame each time an external TW document is loaded for importation (reduces DOM overhead and ensures a 'fresh' frame for each document)\n''2005.11.29 [1.2.1]''\nfixed formatting of 'detail info' in importReport()\n''2005.11.11 [1.2.0]''\nadded 'inline' param to embed controls in a tiddler\n''2005.11.09 [1.1.0]''\nonly load HTML and CSS the first time the macro handler is called. Allows for redundant placement of the macro without creating multiple instances of controls with the same ID's.\n''2005.10.25 [1.0.5]''\nfixed typo in importReport() that prevented reports from being generated\n''2005.10.09 [1.0.4]''\ncombined documentation with plugin code instead of using separate tiddlers\n''2005.08.05 [1.0.3]''\nmoved CSS and HTML definitions into plugin code instead of using separate tiddlers\n''2005.07.27 [1.0.2]''\ncore update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet()\n''2005.07.23 [1.0.1]''\nadded parameter checks and corrected addNotification() usage\n''2005.07.20 [1.0.0]''\nInitial Release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n\n// // Version\n//{{{\nversion.extensions.importTiddlers = {major: 2, minor: 7, revision: 1, date: new Date(2006,2,21)};\n//}}}\n\n// // 1.2.x compatibility\n//{{{\nif (!window.story) window.story=window;\nif (!store.getTiddler) store.getTiddler=function(title){return store.tiddlers[title]}\nif (!store.addTiddler) store.addTiddler=function(tiddler){store.tiddlers[tiddler.title]=tiddler}\nif (!store.deleteTiddler) store.deleteTiddler=function(title){delete store.tiddlers[title]}\n//}}}\n\n// // IE needs explicit global scoping for functions/vars called from browser events\n//{{{\nwindow.onClickImportButton=onClickImportButton;\nwindow.loadImportFile=loadImportFile;\nwindow.refreshImportList=refreshImportList;\n//}}}\n\n// // default cookie/option values\n//{{{\nif (!config.options.chkImportReport) config.options.chkImportReport=true;\n//}}}\n\n\n// // ''MACRO DEFINITION''\n\n//{{{\nconfig.macros.importTiddlers = { };\nconfig.macros.importTiddlers = {\n label: "import tiddlers",\n prompt: "Copy tiddlers from another document",\n countMsg: "%0 tiddlers selected for import",\n src: "", // path/filename or URL of document to import (retrieved from SiteUrl tiddler)\n proxy: "", // URL for remote proxy script (retrieved from SiteProxy tiddler)\n useProxy: false, // use specific proxy script in front of remote URL\n inbound: null, // hash-indexed array of tiddlers from other document\n newTags: "", // text of tags added to imported tiddlers\n addTags: true, // add new tags to imported tiddlers\n listsize: 8, // # of lines to show in imported tiddler list\n importTags: true, // include tags from remote source document when importing a tiddler\n keepTags: true, // retain existing tags when replacing a tiddler\n index: 0, // current processing index in import list\n sort: "" // sort order for imported tiddler listbox\n};\n\nconfig.macros.importTiddlers.handler = function(place,macroName,params) {\n // LINK WITH FLOATING PANEL\n if (!params[0]) {\n createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);\n return;\n }\n // INLINE TIDDLER CONTENT\n if (params[0]=="inline") {\n createImportPanel(place);\n document.getElementById("importPanel").style.position="static";\n document.getElementById("importPanel").style.display="block";\n return;\n }\n // NON-INTERACTIVE BATCH MODE\n switch (params[0]) {\n case 'all':\n case 'new':\n case 'changes':\n case 'updates':\n var filter=params.shift();\n break;\n default:\n var filter="updates";\n break;\n } \n if (!params[0]||!params[0].length) return; // filename is required\n config.macros.importTiddlers.src=params.shift();\n var quiet=(params[0]=="quiet"); if (quiet) params.shift();\n var ask=(params[0]=="ask"); if (ask) params.shift();\n config.macros.importTiddlers.inbound=null; // clear the imported tiddler buffer\n // load storeArea from a hidden IFRAME, then apply import rules and add/replace tiddlers\n loadImportFile(config.macros.importTiddlers.src,filter,quiet,ask,autoImportTiddlers);\n}\n//}}}\n\n// // ''READ TIDDLERS FROM ANOTHER DOCUMENT''\n\n//{{{\nfunction loadImportFile(src,filter,quiet,ask,callback) {\n if (!quiet) clearMessage();\n // LOCAL FILE\n if ((src.substr(0,7)!="http://")&&(src.substr(0,8)!="https://")) {\n if (!quiet) displayMessage("Opening local document: "+ src);\n var txt=loadFile(src);\n if(!txt) { if (!quiet) displayMessage("Could not open local document: "+src); }\n else {\n var s="<html><body>"+txt.substr(txt.indexOf('<div id="storeArea">'));\n if (!quiet) displayMessage(txt.length+" bytes in document. ("+s.length+" bytes used for tiddler storage)");\n config.macros.importTiddlers.inbound = readImportedTiddlers(convertUTF8ToUnicode(s));\n var count=config.macros.importTiddlers.inbound?config.macros.importTiddlers.inbound.length:0;\n if (!quiet) displayMessage("Found "+count+" tiddlers in "+src);\n if (callback) callback(src,filter,quiet,ask);\n }\n return;\n }\n // REMOTE FILE\n var x; // XML object\n try {x = new XMLHttpRequest()}\n catch(e) {\n try {x = new ActiveXObject("Msxml2.XMLHTTP")}\n catch (e) {\n try {x = new ActiveXObject("Microsoft.XMLHTTP")}\n catch (e) { return }\n }\n }\n x.onreadystatechange = function() {\n if (x.readyState == 4) {\n if (x.status == 200) {\n var sa="<html><body>"+x.responseText.substr(x.responseText.indexOf('<div id="storeArea">'));\n if (!quiet) displayMessage(x.responseText.length+" bytes in document. ("+sa.length+" bytes used for tiddler storage)");\n config.macros.importTiddlers.inbound = readImportedTiddlers(sa);\n var count=config.macros.importTiddlers.inbound?config.macros.importTiddlers.inbound.length:0;\n if (!quiet) displayMessage("Found "+count+" tiddlers in "+src);\n if (callback) callback(src,filter,quiet,ask);\n }\n else\n if (!quiet) displayMessage("Could not open remote document:"+ src+" (error="+x.status+")");\n }\n }\n if (document.location.protocol=="file:") { // UniversalBrowserRead only works from a local file context\n try {netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead')}\n catch (e) { if (!quiet) displayMessage(e.description?e.description:e.toString()); }\n }\n if (config.macros.importTiddlers.useProxy) src=config.macros.importTiddlers.proxy+src;\n if (!quiet) displayMessage("Opening remote document: "+ src);\n try {\n var url=src+(src.indexOf('?')<0?'?':'&')+'nocache='+Math.random();\n x.open("GET",url,true);\n x.overrideMimeType('text/html');\n x.send(null);\n }\n catch (e) {\n if (!quiet) {\n displayMessage("Could not open remote document: "+src);\n displayMessage(e.description?e.description:e.toString());\n }\n }\n}\n\nfunction readImportedTiddlers(txt)\n{\n var importedTiddlers = [];\n // create frame\n var f=document.getElementById("importFrame");\n if (f) document.body.removeChild(f);\n f=document.createElement("iframe");\n f.id="importFrame";\n f.style.width="0px"; f.style.height="0px"; f.style.border="0px";\n document.body.appendChild(f);\n // get document\n var d=f.document;\n if (f.contentDocument) d=f.contentDocument; // For NS6\n else if (f.contentWindow) d=f.contentWindow.document; // For IE5.5 and IE6\n // load source into document\n d.open(); d.writeln(txt); d.close();\n // read tiddler DIVs from storeArea DOM element \n var importStore = [];\n var importStoreArea = d.getElementById("storeArea");\n if (!importStoreArea || !(importStore=importStoreArea.childNodes) || (importStore.length==0)) { return null; }\n importStoreArea.normalize();\n for(var t = 0; t < importStore.length; t++) {\n var e = importStore[t];\n var title = null;\n if(e.getAttribute)\n title = e.getAttribute("tiddler");\n if(!title && e.id && (e.id.substr(0,5) == "store"))\n title = e.id.substr(5);\n if(title && title != "") {\n var theImported = new Tiddler();\n theImported.loadFromDiv(e,title);\n importedTiddlers.push(theImported);\n }\n }\n return importedTiddlers;\n}\n//}}}\n\n// // ''NON-INTERACTIVE IMPORT''\n\n// // import all/new/changed tiddlers into store, replacing or adding tiddlers as needed\n//{{{\nfunction autoImportTiddlers(src,filter,quiet,ask)\n{\n var count=0;\n if (config.macros.importTiddlers.inbound) for (var t=0;t<config.macros.importTiddlers.inbound.length;t++) {\n var theImported = config.macros.importTiddlers.inbound[t];\n var theExisting = store.getTiddler(theImported.title);\n\n // only import tiddlers if tagged with "importPublic"\n if (theImported.tags && theImported.tags.find("importPublic")==null)\n { config.macros.importTiddlers.inbound[t].status=""; continue; } // status=="" means don't show in report\n\n // never import the "ImportedTiddlers" history from the other document...\n if (theImported.title=='ImportedTiddlers')\n { config.macros.importTiddlers.inbound[t].status=""; continue; } // status=="" means don't show in report\n\n // check existing tiddler for importReplace, or systemConfig tags\n config.macros.importTiddlers.inbound[t].status="added"; // default - add any tiddlers not filtered out\n if (store.tiddlerExists(theImported.title)) {\n config.macros.importTiddlers.inbound[t].status="replaced";\n if (!theExisting.tags||(theExisting.tags.find("importReplace")==null))\n { config.macros.importTiddlers.inbound[t].status="not imported - tiddler already exists (use importReplace to allow changes)"; continue; }\n if ((theExisting.tags.find("systemConfig")!=null)||(theImported.tags.find("systemConfig")!=null))\n config.macros.importTiddlers.inbound[t].status+=" - WARNING: an active systemConfig plugin has been added or updated";\n }\n\n // apply the all/new/changes/updates filter \n if (filter!="all") {\n if ((filter=="new") && store.tiddlerExists(theImported.title))\n { config.macros.importTiddlers.inbound[t].status="not imported - tiddler already exists"; continue; }\n if ((filter=="changes") && !store.tiddlerExists(theImported.title))\n { config.macros.importTiddlers.inbound[t].status="not imported - new tiddler"; continue; }\n if (store.tiddlerExists(theImported.title) && ((theExisting.modified.getTime()-theImported.modified.getTime())>=0))\n { config.macros.importTiddlers.inbound[t].status="not imported - tiddler is unchanged"; continue; }\n }\n\n // get confirmation if required\n if (ask && !confirm("Import "+(theExisting?"updated":"new")+" tiddler '"+theImported.title+"'\snfrom "+src))\n { config.macros.importTiddlers.inbound[t].status="skipped - cancelled by user"; continue; }\n\n // DO THE IMPORT!!\n store.addTiddler(theImported); count++;\n }\n importReport(quiet); // generate a report (as needed) and display it if not 'quiet'\n if (count) store.setDirty(true); \n // always show final message when tiddlers were actually imported\n if (!quiet||count) displayMessage("Imported "+count+" tiddler"+(count!=1?"s":"")+" from "+src);\n}\n//}}}\n\n// // ''REPORT GENERATOR''\n\n//{{{\nfunction importReport(quiet)\n{\n if (!config.macros.importTiddlers.inbound) return;\n // DEBUG alert('importReport: start');\n\n // if import was not completed, the Ask panel will still be open... close it now.\n var askpanel=document.getElementById('importAskPanel'); if (askpanel) askpanel.style.display='none'; \n // get the alphasorted list of tiddlers\n var tiddlers = config.macros.importTiddlers.inbound;\n tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });\n // gather the statistics\n var count=tiddlers.length;\n var added=0; var replaced=0; var renamed=0; var skipped=0; var merged=0;\n for (var t=0; t<count; t++)\n if (tiddlers[t].status)\n {\n if (tiddlers[t].status=='added') added++;\n if (tiddlers[t].status.substr(0,7)=='skipped') skipped++;\n if (tiddlers[t].status.substr(0,6)=='rename') renamed++;\n if (tiddlers[t].status.substr(0,7)=='replace') replaced++;\n if (tiddlers[t].status.substr(0,6)=='merged') merged++;\n }\n var omitted=count-(added+replaced+renamed+skipped+merged);\n // DEBUG alert('stats done: '+count+' total, '+added+' added, '+skipped+' skipped, '+renamed+' renamed, '+replaced+' replaced, '+merged+' merged');\n // skip the report if nothing was imported\n if (added+replaced+renamed+merged==0) return;\n // skip the report if not desired by user\n if (!config.options.chkImportReport) {\n // reset status flags\n for (var t=0; t<count; t++) config.macros.importTiddlers.inbound[t].status="";\n // refresh display since tiddlers have been imported\n store.notifyAll();\n // quick message area summary report\n var msg=(added+replaced+renamed+merged)+' of '+count+' tiddler'+((count!=1)?'s':"");\n msg+=' imported from '+config.macros.importTiddlers.src.replace(/\s\s/g,'/')\n displayMessage(msg);\n return;\n }\n // create the report tiddler (if not already present)\n var tiddler = store.getTiddler('ImportedTiddlers');\n if (!tiddler) // create new report tiddler if it doesn't exist\n {\n tiddler = new Tiddler();\n tiddler.title = 'ImportedTiddlers';\n tiddler.text = "";\n }\n // format the report header\n var now = new Date();\n var newText = "";\n newText += "On "+now.toLocaleString()+", "+config.options.txtUserName+" imported tiddlers from\sn";\n newText += "[["+config.macros.importTiddlers.src+"|"+config.macros.importTiddlers.src+"]]:\sn";\n newText += "<"+"<"+"<\sn";\n newText += "Out of "+count+" tiddler"+((count!=1)?"s ":" ")+" in {{{"+config.macros.importTiddlers.src.replace(/\s\s/g,'/')+"}}}:\sn";\n if (added+renamed>0)\n newText += (added+renamed)+" new tiddler"+(((added+renamed)!=1)?"s were":" was")+" added to your document.\sn";\n if (merged>0)\n newText += merged+" tiddler"+((merged!=1)?"s were":" was")+" merged with "+((merged!=1)?"":"an ")+"existing tiddler"+((merged!=1)?"s":"")+".\sn"; \n if (replaced>0)\n newText += replaced+" existing tiddler"+((replaced!=1)?"s were":" was")+" replaced.\sn"; \n if (skipped>0)\n newText += skipped+" tiddler"+((skipped!=1)?"s were":" was")+" skipped after asking.\sn"; \n if (omitted>0)\n newText += omitted+" tiddler"+((omitted!=1)?"s":"")+((omitted!=1)?" were":" was")+" not imported.\sn";\n if (config.macros.importTiddlers.addTags && config.macros.importTiddlers.newTags.trim().length)\n newText += "imported tiddlers were tagged with: \s""+config.macros.importTiddlers.newTags+"\s"\sn";\n // output the tiddler detail and reset status flags\n for (var t=0; t<count; t++)\n if (tiddlers[t].status!="")\n {\n newText += "#["+"["+tiddlers[t].title+"]"+"]";\n newText += ((tiddlers[t].status!="added")?("^^\sn"+tiddlers[t].status+"^^"):"")+"\sn";\n config.macros.importTiddlers.inbound[t].status="";\n }\n newText += "<"+"<"+"<\sn";\n // output 'discard report' link\n newText += "<html><input type=\s"button\s" href=\s"javascript:;\s" ";\n newText += "onclick=\s"story.closeTiddler('"+tiddler.title+"'); store.deleteTiddler('"+tiddler.title+"');\s" ";\n newText += "value=\s"discard report\s"></html>";\n // update the ImportedTiddlers content and show the tiddler\n tiddler.text = newText+((tiddler.text!="")?'\sn----\sn':"")+tiddler.text;\n tiddler.modifier = config.options.txtUserName;\n tiddler.modified = new Date();\n store.addTiddler(tiddler);\n if (!quiet) story.displayTiddler(null,"ImportedTiddlers",1,null,null,false);\n story.refreshTiddler("ImportedTiddlers",1,true);\n // refresh the display\n store.notifyAll();\n}\n//}}}\n\n// // ''INTERFACE DEFINITION''\n\n// // Handle link click to create/show/hide control panel\n//{{{\nfunction onClickImportMenu(e)\n{\n if (!e) var e = window.event;\n var parent=resolveTarget(e).parentNode;\n var panel = document.getElementById("importPanel");\n if (panel==undefined || panel.parentNode!=parent)\n panel=createImportPanel(parent);\n var isOpen = panel.style.display=="block";\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n panel.style.display = isOpen ? "none" : "block" ;\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n//}}}\n\n// // Create control panel: HTML, CSS, register for notification\n//{{{\nfunction createImportPanel(place) {\n var panel=document.getElementById("importPanel");\n if (panel) { panel.parentNode.removeChild(panel); }\n setStylesheet(config.macros.importTiddlers.css,"importTiddlers");\n panel=createTiddlyElement(place,"span","importPanel",null,null)\n panel.innerHTML=config.macros.importTiddlers.html;\n store.addNotification(null,refreshImportList); // refresh listbox after every tiddler change\n refreshImportList();\n var siteURL=store.getTiddlerText("SiteUrl"); if (!siteURL) siteURL="";\n document.getElementById("importSourceURL").value=siteURL;\n config.macros.importTiddlers.src=siteURL;\n var siteProxy=store.getTiddlerText("SiteProxy"); if (!siteProxy) siteProxy="SiteProxy";\n document.getElementById("importSiteProxy").value=siteProxy;\n config.macros.importTiddlers.proxy=siteProxy;\n return panel;\n}\n//}}}\n\n// // CSS\n//{{{\nconfig.macros.importTiddlers.css = '\s\n#importPanel {\s\n display: none; position:absolute; z-index:11; width:35em; right:105%; top:3em;\s\n background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\s\n border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\s\n padding: 0.5em; margin:0em; -moz-border-radius:1em;\s\n}\s\n#importPanel a, #importPanel td a { color:#009; display:inline; margin:0px; padding:1px; }\s\n#importPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }\s\n#importPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }\s\n#importPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }\s\n#importPanel select { width:98%;margin:0px;font-size:8pt;line-height:110%;}\s\n#importPanel input { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\s\n#importPanel .box { border:1px solid black; padding:3px; margin-bottom:5px; background:#f8f8f8; -moz-border-radius:5px;}\s\n#importPanel .topline { border-top:2px solid black; padding-top:3px; margin-bottom:5px; }\s\n#importPanel .rad { width:auto; }\s\n#importPanel .chk { width:auto; margin:1px; }\s\n#importPanel .btn { width:auto; }\s\n#importPanel .btn1 { width:98%; }\s\n#importPanel .btn2 { width:48%; }\s\n#importPanel .btn3 { width:32%; }\s\n#importPanel .btn4 { width:24%; }\s\n#importPanel .btn5 { width:19%; }\s\n#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }\s\n#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; display:inline }\s\n#importAskPanel { display:none; margin:0.5em 0em 0em 0em; }\s\n';\n//}}}\n\n// // HTML \n//{{{\nconfig.macros.importTiddlers.html = '\s\n<!-- source and report -->\s\n<table><tr><td align=left>\s\n import from\s\n <input type="radio" class="rad" name="importFrom" value="file" CHECKED\s\n onClick="document.getElementById(\s'importLocalPanel\s').style.display=this.checked?\s'block\s':\s'none\s';\s\n document.getElementById(\s'importHTTPPanel\s').style.display=!this.checked?\s'block\s':\s'none\s'"> local file\s\n <input type="radio" class="rad" name="importFrom" value="http"\s\n onClick="document.getElementById(\s'importLocalPanel\s').style.display=!this.checked?\s'block\s':\s'none\s';\s\n document.getElementById(\s'importHTTPPanel\s').style.display=this.checked?\s'block\s':\s'none\s'"> web server\s\n</td><td align=right>\s\n <input type=checkbox class="chk" id="chkImportReport" checked\s\n onClick="config.options[\s'chkImportReport\s']=this.checked;"> create a report\s\n</td></tr></table>\s\n<!-- import from local file -->\s\n<div id="importLocalPanel" style="display:block;margin-bottom:5px;margin-top:5px;padding-top:3px;border-top:1px solid #999">\s\nlocal document path/filename:<br>\s\n<input type="file" id="fileImportSource" size=57 style="width:100%"\s\n onKeyUp="config.macros.importTiddlers.src=this.value"\s\n onChange="config.macros.importTiddlers.src=this.value;">\s\n</div><!--panel-->\s\n\s\n<!-- import from http server -->\s\n<div id="importHTTPPanel" style="display:none;margin-bottom:5px;margin-top:5px;padding-top:3px;border-top:1px solid #999">\s\n<table><tr><td align=left>\s\n remote document URL:<br>\s\n</td><td align=right>\s\n <input type="checkbox" class="chk" id="importUseProxy"\s\n onClick="config.macros.importTiddlers.useProxy=this.checked;\s\n document.getElementById(\s'importSiteProxy\s').style.display=this.checked?\s'block\s':\s'none\s'"> use a proxy script\s\n</td></tr></table>\s\n<input type="text" id="importSiteProxy" style="display:none;margin-bottom:1px" onfocus="this.select()" value="SiteProxy"\s\n onKeyUp="config.macros.importTiddlers.proxy=this.value"\s\n onChange="config.macros.importTiddlers.proxy=this.value;">\s\n<input type="text" id="importSourceURL" onfocus="this.select()" value="SiteUrl"\s\n onKeyUp="config.macros.importTiddlers.src=this.value"\s\n onChange="config.macros.importTiddlers.src=this.value;">\s\n</div><!--panel-->\s\n\s\n<table><tr><td align=left>\s\n select:\s\n <a href="JavaScript:;" id="importSelectAll"\s\n onclick="onClickImportButton(this)" title="select all tiddlers">\s\n all </a>\s\n <a href="JavaScript:;" id="importSelectNew"\s\n onclick="onClickImportButton(this)" title="select tiddlers not already in destination document">\s\n added </a> \s\n <a href="JavaScript:;" id="importSelectChanges"\s\n onclick="onClickImportButton(this)" title="select tiddlers that have been updated in source document">\s\n changes </a> \s\n <a href="JavaScript:;" id="importSelectDifferences"\s\n onclick="onClickImportButton(this)" title="select tiddlers that have been added or are different from existing tiddlers">\s\n differences </a> \s\n <a href="JavaScript:;" id="importToggleFilter"\s\n onclick="onClickImportButton(this)" title="show/hide selection filter">\s\n filter </a> \s\n</td><td align=right>\s\n <a href="JavaScript:;" id="importListSmaller"\s\n onclick="onClickImportButton(this)" title="reduce list size">\s\n – </a>\s\n <a href="JavaScript:;" id="importListLarger"\s\n onclick="onClickImportButton(this)" title="increase list size">\s\n + </a>\s\n <a href="JavaScript:;" id="importListMaximize"\s\n onclick="onClickImportButton(this)" title="maximize/restore list size">\s\n = </a>\s\n</td></tr></table>\s\n<select id="importList" size=8 multiple\s\n onchange="setTimeout(\s'refreshImportList(\s'+this.selectedIndex+\s')\s',1)">\s\n <!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->\s\n</select>\s\n<input type=checkbox class="chk" id="chkAddTags" checked\s\n onClick="config.macros.importTiddlers.addTags=this.checked;">add new tags \s\n<input type=checkbox class="chk" id="chkImportTags" checked\s\n onClick="config.macros.importTiddlers.importTags=this.checked;">import source tags \s\n<input type=checkbox class="chk" id="chkKeepTags" checked\s\n onClick="config.macros.importTiddlers.keepTags=this.checked;">keep existing tags<br>\s\n<input type=text id="txtNewTags" size=15 onKeyUp="config.macros.importTiddlers.newTags=this.value" autocomplete=off>\s\n<div align=center>\s\n <input type=button id="importOpen" class="importButton" style="width:32%" value="open"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importStart" class="importButton" style="width:32%" value="import"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importClose" class="importButton" style="width:32%" value="close"\s\n onclick="onClickImportButton(this)">\s\n</div>\s\n<div id="importAskPanel">\s\n tiddler already exists:\s\n <input type=text id="importNewTitle" size=15 autocomplete=off">\s\n <div align=center>\s\n <input type=button id="importSkip" class="importButton" style="width:23%" value="skip"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importRename" class="importButton" style="width:23%" value="rename"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importMerge" class="importButton" style="width:23%" value="merge"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importReplace" class="importButton" style="width:23%" value="replace"\s\n onclick="onClickImportButton(this)">\s\n </div>\s\n</div>\s\n';\n//}}}\n\n// // refresh listbox\n//{{{\nfunction refreshImportList(selectedIndex)\n{\n var theList = document.getElementById("importList");\n if (!theList) return;\n // if nothing to show, reset list content and size\n if (!config.macros.importTiddlers.inbound) \n {\n while (theList.length > 0) { theList.options[0] = null; }\n theList.options[0]=new Option('please open a document...',"",false,false);\n theList.size=config.macros.importTiddlers.listsize;\n return;\n }\n // get the sort order\n if (!selectedIndex) selectedIndex=0;\n if (selectedIndex==0) config.macros.importTiddlers.sort='title'; // heading\n if (selectedIndex==1) config.macros.importTiddlers.sort='title';\n if (selectedIndex==2) config.macros.importTiddlers.sort='modified';\n if (selectedIndex==3) config.macros.importTiddlers.sort='tags';\n if (selectedIndex>3) {\n // display selected tiddler count\n for (var t=0,count=0; t < theList.options.length; t++) count+=(theList.options[t].selected&&theList.options[t].value!="")?1:0;\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n return; // no refresh needed\n }\n\n // get the alphasorted list of tiddlers (optionally, filter out unchanged tiddlers)\n var tiddlers=config.macros.importTiddlers.inbound;\n tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });\n // clear current list contents\n while (theList.length > 0) { theList.options[0] = null; }\n // add heading and control items to list\n var i=0;\n var indent=String.fromCharCode(160)+String.fromCharCode(160);\n theList.options[i++]=new Option(tiddlers.length+' tiddler'+((tiddlers.length!=1)?'s are':' is')+' in the document',"",false,false);\n theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="title" )?">":indent)+' [by title]',"",false,false);\n theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="modified")?">":indent)+' [by date]',"",false,false);\n theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="tags")?">":indent)+' [by tags]',"",false,false);\n // output the tiddler list\n switch(config.macros.importTiddlers.sort)\n {\n case "title":\n for(var t = 0; t < tiddlers.length; t++)\n theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);\n break;\n case "modified":\n // sort descending for newest date first\n tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });\n var lastSection = "";\n for(var t = 0; t < tiddlers.length; t++) {\n var tiddler = tiddlers[t];\n var theSection = tiddler.modified.toLocaleDateString();\n if (theSection != lastSection) {\n theList.options[i++] = new Option(theSection,"",false,false);\n lastSection = theSection;\n }\n theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);\n }\n break;\n case "tags":\n var theTitles = {}; // all tiddler titles, hash indexed by tag value\n var theTags = new Array();\n for(var t=0; t<tiddlers.length; t++) {\n var title=tiddlers[t].title;\n var tags=tiddlers[t].tags;\n for(var s=0; s<tags.length; s++) {\n if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }\n theTitles[tags[s]].push(title);\n }\n }\n theTags.sort();\n for(var tagindex=0; tagindex<theTags.length; tagindex++) {\n var theTag=theTags[tagindex];\n theList.options[i++]=new Option(theTag,"",false,false);\n for(var t=0; t<theTitles[theTag].length; t++)\n theList.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);\n }\n break;\n }\n theList.selectedIndex=selectedIndex; // select current control item\n if (theList.size<config.macros.importTiddlers.listsize) theList.size=config.macros.importTiddlers.listsize;\n if (theList.size>theList.options.length) theList.size=theList.options.length;\n}\n//}}}\n\n// // Control interactions\n//{{{\nfunction onClickImportButton(which)\n{\n // DEBUG alert(which.id);\n var theList = document.getElementById('importList');\n if (!theList) return;\n var thePanel = document.getElementById('importPanel');\n var theAskPanel = document.getElementById('importAskPanel');\n var theNewTitle = document.getElementById('importNewTitle');\n var count=0;\n switch (which.id)\n {\n case 'fileImportSource':\n case 'importOpen': // load import source into hidden frame\n importReport(); // if an import was in progress, generate a report\n config.macros.importTiddlers.inbound=null; // clear the imported tiddler buffer\n refreshImportList(); // reset/resize the listbox\n if (config.macros.importTiddlers.src=="") break;\n // Load document into hidden iframe so we can read it's DOM and fill the list\n loadImportFile(config.macros.importTiddlers.src,"all",null,null,function(src,filter,quiet,ask){window.refreshImportList(0);});\n break;\n case 'importSelectAll': // select all tiddler list items (i.e., not headings)\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n if (theList.options[t].value=="") continue;\n theList.options[t].selected=true;\n count++;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importSelectNew': // select tiddlers not in current document\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n theList.options[t].selected=false;\n if (theList.options[t].value=="") continue;\n theList.options[t].selected=!store.tiddlerExists(theList.options[t].value);\n count+=theList.options[t].selected?1:0;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importSelectChanges': // select tiddlers that are updated from existing tiddlers\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n theList.options[t].selected=false;\n if (theList.options[t].value==""||!store.tiddlerExists(theList.options[t].value)) continue;\n for (var i=0; i<config.macros.importTiddlers.inbound.length; i++) // find matching inbound tiddler\n { var inbound=config.macros.importTiddlers.inbound[i]; if (inbound.title==theList.options[t].value) break; }\n theList.options[t].selected=(inbound.modified-store.getTiddler(theList.options[t].value).modified>0); // updated tiddler\n count+=theList.options[t].selected?1:0;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importSelectDifferences': // select tiddlers that are new or different from existing tiddlers\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n theList.options[t].selected=false;\n if (theList.options[t].value=="") continue;\n if (!store.tiddlerExists(theList.options[t].value)) { theList.options[t].selected=true; count++; continue; }\n for (var i=0; i<config.macros.importTiddlers.inbound.length; i++) // find matching inbound tiddler\n { var inbound=config.macros.importTiddlers.inbound[i]; if (inbound.title==theList.options[t].value) break; }\n theList.options[t].selected=(inbound.modified-store.getTiddler(theList.options[t].value).modified!=0); // changed tiddler\n count+=theList.options[t].selected?1:0;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importToggleFilter': // show/hide filter\n case 'importFilter': // apply filter\n alert("coming soon!");\n break;\n case 'importStart': // initiate the import processing\n importReport(); // if an import was in progress, generate a report\n config.macros.importTiddlers.index=0;\n config.macros.importTiddlers.index=importTiddlers(0);\n importStopped();\n break;\n case 'importClose': // unload imported tiddlers or hide the import control panel\n // if imported tiddlers not loaded, close the import control panel\n if (!config.macros.importTiddlers.inbound) { thePanel.style.display='none'; break; }\n importReport(); // if an import was in progress, generate a report\n config.macros.importTiddlers.inbound=null; // clear the imported tiddler buffer\n refreshImportList(); // reset/resize the listbox\n break;\n case 'importSkip': // don't import the tiddler\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n theImported.status='skipped after asking'; // mark item as skipped\n theAskPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index+1); // resume with NEXT item\n importStopped();\n break;\n case 'importRename': // change name of imported tiddler\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n theImported.status = 'renamed from '+theImported.title; // mark item as renamed\n theImported.set(theNewTitle.value,null,null,null,null); // change the tiddler title\n theItem.value = theNewTitle.value; // change the listbox item text\n theItem.text = theNewTitle.value; // change the listbox item text\n theAskPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index); // resume with THIS item\n importStopped();\n break;\n case 'importMerge': // join existing and imported tiddler content\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n var theExisting = store.getTiddler(theItem.value);\n var theText = theExisting.text+'\sn----\sn^^merged from: [['+config.macros.importTiddlers.src+'#'+theItem.value+'|'+config.macros.importTiddlers.src+'#'+theItem.value+']]^^\sn^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\sn'+theImported.text;\n var theDate = new Date();\n var theTags = theExisting.getTags()+' '+theImported.getTags();\n theImported.set(null,theText,null,theDate,theTags);\n theImported.status = 'merged with '+theExisting.title; // mark item as merged\n theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY hh:mm:ss");\n theImported.status += ' by '+theExisting.modifier;\n theAskPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index); // resume with this item\n importStopped();\n break;\n case 'importReplace': // substitute imported tiddler for existing tiddler\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n var theExisting = store.getTiddler(theItem.value);\n theImported.status = 'replaces '+theExisting.title; // mark item for replace\n theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY hh:mm:ss");\n theImported.status += ' by '+theExisting.modifier;\n theAskPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index); // resume with THIS item\n importStopped();\n break;\n case 'importListSmaller': // decrease current listbox size, minimum=5\n if (theList.options.length==1) break;\n theList.size-=(theList.size>5)?1:0;\n config.macros.importTiddlers.listsize=theList.size;\n break;\n case 'importListLarger': // increase current listbox size, maximum=number of items in list\n if (theList.options.length==1) break;\n theList.size+=(theList.size<theList.options.length)?1:0;\n config.macros.importTiddlers.listsize=theList.size;\n break;\n case 'importListMaximize': // toggle listbox size between current and maximum\n if (theList.options.length==1) break;\n theList.size=(theList.size==theList.options.length)?config.macros.importTiddlers.listsize:theList.options.length;\n break;\n }\n}\n//}}}\n\n// // re-entrant processing for handling import with interactive collision prompting\n//{{{\nfunction importTiddlers(startIndex)\n{\n if (!config.macros.importTiddlers.inbound) return -1;\n\n var theList = document.getElementById('importList');\n if (!theList) return;\n var t;\n // if starting new import, reset import status flags\n if (startIndex==0)\n for (var t=0;t<config.macros.importTiddlers.inbound.length;t++)\n config.macros.importTiddlers.inbound[t].status="";\n for (var i=startIndex; i<theList.options.length; i++)\n {\n // if list item is not selected or is a heading (i.e., has no value), skip it\n if ((!theList.options[i].selected) || ((t=theList.options[i].value)==""))\n continue;\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==t) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n var theExisting = store.getTiddler(theImported.title);\n // avoid redundant import for tiddlers that are listed multiple times (when 'by tags')\n if (theImported.status=="added")\n continue;\n // don't import the "ImportedTiddlers" history from the other document...\n if (theImported.title=='ImportedTiddlers')\n continue;\n // if tiddler exists and import not marked for replace or merge, stop importing\n if (theExisting && (theImported.status.substr(0,7)!="replace") && (theImported.status.substr(0,5)!="merge"))\n return i;\n // assemble tags (remote + existing + added)\n var newTags = "";\n if (config.macros.importTiddlers.importTags)\n newTags+=theImported.getTags() // import remote tags\n if (config.macros.importTiddlers.keepTags && theExisting)\n newTags+=" "+theExisting.getTags(); // keep existing tags\n if (config.macros.importTiddlers.addTags && config.macros.importTiddlers.newTags.trim().length)\n newTags+=" "+config.macros.importTiddlers.newTags; // add new tags\n theImported.set(null,null,null,null,newTags.trim());\n // set the status to 'added' (if not already set by the 'ask the user' UI)\n theImported.status=(theImported.status=="")?'added':theImported.status;\n // do the import!\n store.addTiddler(theImported);\n store.setDirty(true);\n }\n return(-1); // signals that we really finished the entire list\n}\n//}}}\n\n//{{{\nfunction importStopped()\n{\n var theList = document.getElementById('importList');\n var theNewTitle = document.getElementById('importNewTitle');\n if (!theList) return;\n if (config.macros.importTiddlers.index==-1)\n importReport(); // import finished... generate the report\n else\n {\n // DEBUG alert('import stopped at: '+config.macros.importTiddlers.index);\n // import collision... show the ask panel and set the title edit field\n document.getElementById('importAskPanel').style.display='block';\n theNewTitle.value=theList.options[config.macros.importTiddlers.index].value;\n }\n}\n//}}}\n
/***\n''InlineJavascriptPlugin for ~TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#InlineJavascriptPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\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''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<<<\nan "alert" message box:\n{{{\n<script>alert('InlineJavascriptPlugin: this is a demonstration message');</script>\n}}}\n\n\ndynamic output:\n{{{\n<script>return (new Date()).toString();</script>\n}}}\n\n\nwikified dynamic output:\n{{{\n<script>return "link to current user: [["+config.options.txtUserName+"]]";</script>\n}}}\n\n\ndynamic output using 'place' to get size information for current tiddler\n{{{\n<script>\n if (!window.story) window.story=window;\n var title=story.findContainingTiddler(place).id.substr(7);\n return title+" is using "+store.getTiddlerText(title).length+" bytes";\n</script>\n}}}\n\ncreating an 'onclick' button/link that runs a script\n{{{\n<script label="click here">\n if (!window.story) window.story=window;\n alert("Hello World!\snlinktext='"+place.firstChild.data+"'\sntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");\n</script>\n}}}\n\nloading a script from a source url\n{{{\n<script src="demo.js">return "loading demo.js..."</script>\n<script>return window.demo()</script>\n}}}\nwhere http://www.TiddlyTools.com/demo.js contains:\n>^^window.demo = function()^^\n>^^ { return 'this output is from demo(), defined in demo.js'; }^^\n>^^alert('InlineJavascriptPlugin: demo.js has been loaded');^^\n\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.01.05 [1.4.0]''\nadded 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]''\nwhen 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]''\nfor '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\nBased on a suggestion by BradleyMeck\n''2005.11.08 [1.2.0]''\nhandle loading of javascript from an external URL via src="..." syntax\n''2005.11.08 [1.1.0]''\npass 'place' param into scripts to provide direct DOM access \n''2005.11.08 [1.0.0]''\ninitial release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.inlineJavascript= {major: 1, minor: 4, revision: 0, date: new Date(2006,1,5)};\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")?\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[2] && lookaheadMatch[3]) { // 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[3]+"};_out(this);"\n link.setAttribute("href","javascript:;"); link.setAttribute("title",""); link.style.cursor="pointer";\n }\n else if (lookaheadMatch[3]) { // run inline script code\n var code="function _out(place){"+lookaheadMatch[3]+"};_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);\n }\n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n }\n }\n} )\n//}}}\n
!Gestion des interruptions\n\n!!Introduction\nLe processeur ~SH4 possède 4 lignes d'interruptions externes ({{{IRL[3:0]}}}, plus une, {{{NMI}}}, qui n'est pas gérée par Linux). Ces lignes peuvent être configurées de deux façons :\n* {{{IRL}}} multiplexées : les lignes {{{IRL}}} indiquent alors seulement un niveau de priorité. Il n'y a pas possiblité de masquage autrement que par l'{{{IMASK}}} du registre {{{SR}}} : on masque un niveau, et les requêtes de niveau inférieur sont alors masquées (cela inclut les périphériques on-chip). Il faut donc réserver ce genre de requêtes à la communications avec un contrôleur d'interruption externe, qui contient lui-même de quoi masquer les interruptions.\n* {{{IRL}}} non multiplexées : on a alors droit (sur le SH7750R) à 4 interruptions normales, qui peuvent être masquées indépendament les unes des autres par le registre {{{IPRD}}}.\n\n!! Gestion par Linux\nQuelle que soit la configuration des lignes {{{IRL}}} :\n* {{{setup.c}}} doit positionner le bit {{{IRLM}}} du registre {{{ICR}}} correctement de façon à choisir multiplexées ou non mutliplexées.\n* Si on n'est pas multiplexé, il faut ajouter les 4 {{{IRL}}} à la liste des interruptions gérées par Linux grâce à la fonction {{{make_ipr_irq}}}. Sinon, il faut se déclarer un contrôleur externe.\n* le numéro des interruptions ({{{irq}}} dans le code Linux) est défini ainsi : {{{irq = (EVT/32) - 16}}}. Autrement dit, la {{{NMI}}} n'est actuellement pas supportée.\n\nLa configuration actuelle consiste à fonctionner en mode non multiplexé. La fonction {{{init_shix_IRQ}}} se charge de configurer le registre {{{ICR}}} et d'inscrire les vecteurs dans la table des interruptions gérables par Linux. C'est quand même aux drivers qui ont besoin de ces lignes de déclarer le handler associé au vecteur idoine...\n{{{\nvoid __init \ninit_shix_IRQ(void)\n{\n /* enable IRL pins as 4 independant IRQ sources */\n ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);\n \n printk("Setup SHiX IRQ/IPR ...\sn");\n \n make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);\n make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);\n make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);\n make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);\n}\n}}}\n\nLes constantes utilisées ici sont déclarées dans {{{include/asm/irq.h}}}.\n\nIl est possible de passer à une gestion non multiplexée des IRQ externes, en implémentant un contôleur d'interruption dans le Stratix. Ce contrôleur doitpouvoir masquer ou non les interruptions externes, gérer leur priorités, etc. On pourra s'inspirer des différentes plateformes SH existantes... Mais pour l'instant, 4 sources semblent suffisantes.\n
!! Introduction\n\nCe wiki sert de support à la documentation de la carte Stratix, appelée aussi SHiX, version 2.0. Il couvre les aspects matériels et logiciels. Il est complété au fur et à mesure de l'écriture du code, que ce soit le code pour le FPGA ou pour le noyau Linux. Sa dernière version peut être trouvée sur http://perso.enst.fr/~polti/realisations/shix20/doc/index.html.\n\n!! Organisation\n\nComme pour tous les wiki, il n'y a pas d'ordre linéaire de lecture, ce qui peut dérouter au premier abord...\n\nChaque rubrique (appelée ''tiddler'' en jargon wiki) contient des tags, indiquant sur quoi porte son contenu. \n* La liste des tags de la rubrique en cours est affichée au dessus du titre de la rubrique, avec un menu déroulant permettant d'accéder rapidement aux autre rubriques portant le même tag. \n* La liste de tous les tags du wiki est disponible dans le menu de droite, dans la rubrique //lists//. \nAinsi, tous les tiddlers relatifs à la carte SHiX portent le tag SHiX. Tous ceux relatifs à la compilation du noyau Linux portent aussi le tag [[Compilation]], etc...\n\nDans le menu en haut à droite d'une rubrique (s'il n'est pas visible, passer la souris sur la rubrique en question), on trouve aussi la commande //references// qui donne la liste des rubriques contenant un lien vers la rubrique actuelle...\n\nPour ceux que la navigation par tag dérouterait, une [[table des matière commentée|TableDesMatières]] est quand même disponible. Elle n'est cependant pas mise à jour à chaque modification du wiki...\n\n!! La carte\nLa carte SHiX 2.0 est un système embarqué, conçu originellement à des fins d'enseignement et de recherche. Elle associe un microprocesseur Super-H (SH4 7750R d'Hitachi) à un FPGA Stratix EP1S25\nd'Altera, ainsi qu'un certain nombre de périphériques. Sa conception a été dictée par la puissance de calcul, la reconfigurabilité et le prix de revient.\n\nCe document décrit son architecture, ainsi que les développements qui ont éffectués dessus, tant du point de vue matériel que logiciel.\n\nBien entendu, les développements avançant rapidement, ce document ne prétend pas être à jour, mais il devrait fournir un bon point de départ pour toute personne cherchant de la documentation sur cette carte.\n\n
!Introduction\n\nCes rubriques parlent du noyau Linux exécuté sur la carte SHiX v2.0. C'est un noyau Linux standard, récent (2.6.15.1 actuellement), auquel sont appliqués un certains nombres de patchs.\nVu la quantité d'informations au sujet du noyau, il est nécessaire d'organiser un peu les choses :\n* avant de compiler un noyau, il faut avoir récupéré les sources (noyau et éventuellement arbres de patchs). Pour cela on se rapportera à la rubrique [[Arbres Patch Kernel]].\n* une fois l'arborescence en place, ou au moins l'aborescence principale, on pourra compiler un premier noyau, en consultant la rubrique [[Compilation noyau Linux pour SH4]]\n
Linux a été porté sur la plateforme SHiX 2.0, même si son utilisation n'est pas imposée. Mais qu'il soit utilisé ou non, il est important de connaître certains points clefs comme\n* l'organisation mémoire de la carte,\n* l'odre d'exécution des différents modules,\n* l'organisation des systèmes de fichiers,\n* ...\n\nC'est l'objectif de cette partie.
<<gradient horiz #ddeeff #ffffff>>\n\n<<today>>\n----\n[[Introduction]]\n[[Table des matières|TableDesMatières]]\n----\n![[Matériel]]\n[[Alimentations]]\n[[Processeur|ProcesseurHorlogesResets]]\n[[Bus processeur|Bus]]\n[[UART]]\n[[SSRAM, arbitre|SSRAM]]\n----\n![[Logiciel]]\n[[Flash NAND|FlashNand]]\n[[Boot]]\n[[Organisation Mémoire]]\n[[Interruptions]]\n----\n!Utilisation\n[[Configuration FPGA|Configuration Stratix]]\n[[Toolchain|Compilation Toolchain SH4]]\n[[Kernel]]\n----\n<<newTiddler>>\n----\n[[Configuration|MenuConfiguration]]\n[[MainMenu]]\n[[Syntaxe|Syntaxe]]\n\n~~[[tiddlywiki.com|http://www.tiddlywiki.com/]] (<<version>>)~~\n
! Présentation matérielle de la carte SHiX\nLa carte SHiX 2.0 comporte, comme indiqué sur la figure ci-dessous :\n[img[http://perso.enst.fr/~polti/realisations/shix20/doc/archi_globale.png]]\n\n* un microprocesseur Super-H d'Hitachi : SH4 7750R,\n* un Stratix EP1S25 d'Altera, disposant de sa propre flash de configuration EPC8,\n* 32Mo de SDRAM,\n* 32Mo de mémoire flash NAND,\n* un circuit d'acquisition vidéo (décodeur multistandard SAA7113 de Philips),\n* un circuit de restitution vidéo (encodeur CS4954 de Cirrus Logic),\n* 36 Mbits de SSRAM, dédiée au FPGA,\n* un contrôleur USB 1.1 hôte, SL811 de Cypress,\n* un contrôleur USB 2.0 esclave CY7C68001,\n* deux Uarts\n** l'un sans fifo ni signaux de contrôle (console),\n** l'autre avec fifo de 16 octets et signaux de contrôle (CTS / DTR),\n* divers afficheurs (LEDs, afficheur 7 segments), et quelques switchs,\n* un générateur d'horloge non programmable CY22392,\n* trois ports d'extension\n** un port d'extension general purpose 32 bits 3.3V et compatible 5V (protégé),\n** deux ports I2C,\n* une alimentation à découpage,\n* un capteur de la température du FPGA.\nLe PCB comporte 8 couches, dont 4 de signaux. Le stackup a été soigneusement choisi, et toutes les lignes critiques du point de vue intégrité du signal ont été simulées.
!!!!Menus et Titres\n* [[Titre wiki|SiteTitle]]\n* [[Sous-titre wiki|SiteSubtitle]]\n* [[Edit Main Menu|MainMenu]]\n* [[Edit Options Menu|SideBarOptions]]\n\n!!!!Divers\n* [[Tiddlers par défaut|DefaultTiddlers]]\n\n
/***\n''NestedSlidersPlugin for TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman\nsource: http://www.TiddlyTools.com/#NestedSlidersPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nQuickly make any tiddler content into an expandable 'slider' panel, without needing to create a separate tiddler to contain the slider content. Optional syntax allows ''default to open'', ''custom button label/tooltip'' and ''automatic blockquote formatting.''\n\nYou can also 'nest' these sliders as deep as you like (see complex nesting example below), so that expandable 'tree-like' hierarchical displays can be created. This is most useful when converting existing in-line text content to create in-line annotations, footnotes, context-sensitive help, or other subordinate information displays.\n\nFor more details, please click on a section headline below:\n++++!!!!![Configuration]>\nDebugging messages for 'lazy sliders' deferred rendering:\n<<option chkDebugLazySliderDefer>> show debugging alert when deferring slider rendering\n<<option chkDebugLazySliderRender>> show debugging alert when deferred slider is actually rendered\n===\n++++!!!!![Usage]>\nWhen installed, this plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content. Use {{{+++}}} and {{{===}}} to delimit the slider content. Additional optional syntax elements let you specify\n*default to open\n*cookiename\n*heading level\n*floater\n*rollover\n*custom label/tooltip\n*automatic blockquote\n*deferred rendering\nThe complete syntax, using all options, is:\n//{{{\n++++(cookiename)!!!!!^*[label|tooltip]>...\ncontent goes here\n===\n//}}}\nwhere:\n* {{{+++}}} (or {{{++++}}}) and {{{===}}}^^\nmarks the start and end of the slider definition, respectively. When the extra {{{+}}} is used, the slider will be open when initially displayed.^^\n* {{{(cookiename)}}}^^\nsaves the slider opened/closed state, and restores this state whenever the slider is re-rendered.^^\n* {{{!}}} through {{{!!!!!}}}^^\ndisplays the slider label using a formatted headline (Hn) style instead of a button/link style^^\n* {{{"^"}}} //(without the quotes)//^^\nmakes the slider 'float' on top of other content rather than shifting that content downward^^\n* {{{"*"}}} //(without the quotes)//^^\nautomatically opens/closes slider on "rollover" as well as when clicked^^\n* {{{[label]}}} or {{{[label|tooltip]}}}^^\nuses custom label/tooltip. (defaults are: ">" (more) and "<" (less)^^\n* {{{">"}}} //(without the quotes)//^^\nautomatically adds blockquote formatting to slider content^^\n* {{{"..."}}} //(without the quotes)//^^\ndefers rendering of closed sliders until the first time they are opened. //Note: deferred rendering may produce unexpected results in some cases. Use with care.//^^\n\n//Note: to make slider definitions easier to read and recognize when editing a tiddler, newlines immediately following the {{{+++}}} 'start slider' or preceding the {{{===}}} 'end slider' sequence are automatically supressed so that excess whitespace is eliminated from the output.//\n===\n++++!!!!![Examples]>\nsimple in-line slider: \n{{{\n+++\n content\n===\n}}}\n+++\n content\n===\n----\nuse a custom label and tooltip: \n{{{\n+++[label|tooltip]\n content\n===\n}}}\n+++[label|tooltip]\n content\n===\n----\ncontent automatically blockquoted: \n{{{\n+++>\n content\n===\n}}}\n+++>\n content\n===\n----\nall options combined //(default open, cookie, heading, floater, rollover, label/tooltip, blockquoted, deferred)//\n{{{\n++++(testcookie)!!!^*[label|tooltip]>...\n content\n===\n}}}\n++++(testcookie)!!!^*[label|tooltip]>...\n content\n===\n----\ncomplex nesting example:\n{{{\n+++^[get info...|click for information]\n put some general information here, plus a floating slider with more specific info:\n +++^[view details...|click for details]\n put some detail here, which could include a rollover with a +++^*[glossary definition]explaining technical terms===\n ===\n===\n}}}\n+++^[get info...|click for information]\n put some general information here, plus a floating slider with more specific info:\n +++^[view details...|click for details]\n put some detail here, which could include a rollover with a +++^*[glossary definition]explaining technical terms===\n ===\n===\n----\nnested floaters\n>menu: <<tiddler NestedSlidersExample>>\n(see [[NestedSlidersExample]] for definition)\n----\n===\n+++!!!!![Installation]>\nimport (or copy/paste) the following tiddlers into your document:\n''NestedSlidersPlugin'' (tagged with <<tag systemConfig>>)\n===\n+++!!!!![Revision History]>\n\n++++[2006.02.16 - 1.7.7]\ncorrected deferred rendering to account for use-case where show/hide state is tracked in a cookie\n===\n\n++++[2006.02.15 - 1.7.6]\nin adjustSliderPos(), ensure that floating panel is positioned completely within the browser window (i.e., does not go beyond the right edge of the browser window)\n===\n\n++++[2006.02.04 - 1.7.5]\nadd 'var' to unintended global variable declarations to avoid FireFox 1.5.0.1 crash bug when assigning to globals\n===\n\n++++[2006.01.18 - 1.7.4]\nonly define adjustSliderPos() function if it has not already been provided by another plugin. This lets other plugins 'hijack' the function even when they are loaded first.\n===\n\n++++[2006.01.16 - 1.7.3]\nadded adjustSliderPos(place,btn,panel,panelClass) function to permit specialized logic for placement of floating panels. While it provides improved placement for many uses of floating panels, it exhibits a relative offset positioning error when used within *nested* floating panels. Short-term workaround is to only adjust the position for 'top-level' floaters.\n===\n\n++++[2006.01.16 - 1.7.2]\nadded button property to slider panel elements so that slider panel can tell which button it belongs to. Also, re-activated and corrected animation handling so that nested sliders aren't clipped by hijacking Slider.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends\n===\n\n++++[2006.01.14 - 1.7.1]\nadded optional "^" syntax for floating panels. Defines new CSS class, ".floatingPanel", as an alternative for standard in-line ".sliderPanel" styles.\n===\n\n++++[2006.01.14 - 1.7.0]\nadded optional "*" syntax for rollover handling to show/hide slider without requiring a click (Based on a suggestion by tw4efl)\n===\n\n+++[2006.01.03 - 1.6.2]\nWhen using optional "!" heading style, instead of creating a clickable "Hn" element, create an "A" element inside the "Hn" element. (allows click-through in SlideShowPlugin, which captures nearly all click events, except for hyperlinks)\n===\n\n+++[2005.12.15 - 1.6.1]\nadded optional "..." syntax to invoke deferred ('lazy') rendering for initially hidden sliders\nremoved checkbox option for 'global' application of lazy sliders\n===\n\n+++[2005.11.25 - 1.6.0]\nadded optional handling for 'lazy sliders' (deferred rendering for initially hidden sliders)\n===\n\n+++[2005.11.21 - 1.5.1]\nrevised regular expressions: if present, a single newline //preceding// and/or //following// a slider definition will be suppressed so start/end syntax can be place on separate lines in the tiddler 'source' for improved readability. Similarly, any whitespace (newlines, tabs, spaces, etc.) trailing the 'start slider' syntax or preceding the 'end slider' syntax is also suppressed.\n===\n\n+++[2005.11.20 - 1.5.0]\n added (cookiename) syntax for optional tracking and restoring of slider open/close state\n===\n\n+++[2005.11.11 - 1.4.0]\n added !!!!! syntax to render slider label as a header (Hn) style instead of a button/link style\n===\n\n+++[2005.11.07 - 1.3.0]\n removed alternative syntax {{{(((}}} and {{{)))}}} (so they can be used by other\n formatting extensions) and simplified/improved regular expressions to trim multiple excess newlines\n===\n\n+++[2005.11.05 - 1.2.1]\n changed name to NestedSlidersPlugin\n more documentation\n===\n\n+++[2005.11.04 - 1.2.0]\n added alternative character-mode syntax {{{(((}}} and {{{)))}}}\n tweaked "eat newlines" logic for line-mode {{{+++}}} and {{{===}}} syntax\n===\n\n+++[2005.11.03 - 1.1.1]\n fixed toggling of default tooltips ("more..." and "less...") when a non-default button label is used\n code cleanup, added documentation\n===\n\n+++[2005.11.03 - 1.1.0]\n changed delimiter syntax from {{{(((}}} and {{{)))}}} to {{{+++}}} and {{{===}}}\n changed name to EasySlidersPlugin\n===\n\n+++[2005.11.03 - 1.0.0]\n initial public release\n===\n\n===\n+++!!!!![Credits]>\nThis feature was implemented by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]] with research, programming and suggestions from RodneyGomes, GeoffSlocock, and PaulPetterson\n===\n***/\n// //+++!!!!![Code]\n//{{{\nversion.extensions.nestedSliders = {major: 1, minor: 7, revision: 7, date: new Date(2006,2,16)};\n//}}}\n\n//{{{\n// options for deferred rendering of sliders that are not initially displayed\nif (config.options.chkDebugLazySliderDefer==undefined) config.options.chkDebugLazySliderDefer=false;\nif (config.options.chkDebugLazySliderRender==undefined) config.options.chkDebugLazySliderRender=false;\n\n// default styles for 'floating' class\nsetStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \s\n background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");\n//}}}\n\n//{{{\nconfig.formatters.push( {\n name: "nestedSliders",\n match: "\s\sn?\s\s+{3}",\n terminator: "\s\ss*\s\s={3}\s\sn?",\n lookahead: "\s\sn?\s\s+{3}(\s\s+)?(\s\s([^\s\s)]*\s\s))?(\s\s!*)?(\s\s^)?(\s\s*)?(\s\s[[^\s\s]]*\s\s])?(\s\s>)?(\s\s.\s\s.\s\s.)?\s\ss*",\n handler: function(w)\n {\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 {\n // location for rendering button and panel\n var place=w.output;\n\n // default to closed, no cookie\n var show="none"; var title=">"; var tooltip="show"; var cookie="";\n\n // extra "+", default to open\n if (lookaheadMatch[1])\n { show="block"; title="<"; tooltip="hide"; }\n\n // cookie, use saved open/closed state\n if (lookaheadMatch[2]) {\n cookie=lookaheadMatch[2].trim().substr(1,lookaheadMatch[2].length-2);\n cookie="chkSlider"+cookie;\n if (config.options[cookie]==undefined)\n { config.options[cookie] = (show=="block") }\n if (config.options[cookie])\n { show="block"; title="<"; tooltip="hide"; }\n else\n { show="none"; title=">"; tooltip="show"; }\n }\n\n // custom label/tooltip\n if (lookaheadMatch[6]) {\n title = lookaheadMatch[6].trim().substr(1,lookaheadMatch[6].length-2);\n var pos=title.indexOf("|");\n if (pos!=-1)\n { tooltip = title.substr(pos+1,title.length); title = title.substr(0,pos); }\n else\n { tooltip += " "+title; }\n }\n\n // create the button\n if (lookaheadMatch[3]) { // use "Hn" header format instead of button/link\n var lvl=(lookaheadMatch[3].length>6)?6:lookaheadMatch[3].length;\n var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,null,title);\n btn.onclick=onClickNestedSlider;\n btn.setAttribute("href","javascript:;");\n btn.setAttribute("title",tooltip);\n }\n else\n var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider);\n btn.sliderCookie = cookie; // save the cookiename (if any) in the button object\n\n // "non-click" MouseOver open/close slider\n if (lookaheadMatch[5]) btn.onmouseover=onClickNestedSlider;\n\n // create slider panel\n var panelClass=lookaheadMatch[4]?"floatingPanel":"sliderPanel";\n var panel=createTiddlyElement(place,"div",null,panelClass,null);\n panel.style.display = show;\n panel.button = btn; // so the slider panel know which button it belongs to\n btn.sliderPanel=panel;\n\n // render slider (or defer until shown) \n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n if ((show=="block")||!lookaheadMatch[8]) {\n // render now if panel is supposed to be shown or NOT deferred rendering\n w.subWikify(lookaheadMatch[7]?createTiddlyElement(panel,"blockquote"):panel,this.terminator);\n // align slider/floater position with button\n adjustSliderPos(place,btn,panel,panelClass);\n }\n else {\n var src = w.source.substr(w.nextMatch);\n var endpos=findMatchingDelimiter(src,"+++","===");\n panel.setAttribute("raw",src.substr(0,endpos));\n panel.setAttribute("blockquote",lookaheadMatch[7]?"true":"false");\n panel.setAttribute("rendered","false");\n w.nextMatch += endpos+3;\n if (w.source.substr(w.nextMatch,1)=="\sn") w.nextMatch++;\n if (config.options.chkDebugLazySliderDefer) alert("deferred '"+title+"':\sn\sn"+panel.getAttribute("raw"));\n }\n }\n }\n }\n)\n\n// TBD: ignore 'quoted' delimiters (e.g., "{{{+++foo===}}}" isn't really a slider)\nfunction findMatchingDelimiter(src,starttext,endtext) {\n var startpos = 0;\n var endpos = src.indexOf(endtext);\n // check for nested delimiters\n while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {\n // count number of nested 'starts'\n var startcount=0;\n var temp = src.substring(startpos,endpos-1);\n var pos=temp.indexOf(starttext);\n while (pos!=-1) { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }\n // set up to check for additional 'starts' after adjusting endpos\n startpos=endpos+endtext.length;\n // find endpos for corresponding number of matching 'ends'\n while (startcount && endpos!=-1) {\n endpos = src.indexOf(endtext,endpos+endtext.length);\n startcount--;\n }\n }\n return (endpos==-1)?src.length:endpos;\n}\n//}}}\n\n//{{{\nfunction onClickNestedSlider(e)\n{\n if (!e) var e = window.event;\n var theTarget = resolveTarget(e);\n var theLabel = theTarget.firstChild.data;\n var theSlider = theTarget.sliderPanel\n var isOpen = theSlider.style.display!="none";\n // if using default button labels, toggle labels\n if (theLabel==">") theTarget.firstChild.data = "<";\n else if (theLabel=="<") theTarget.firstChild.data = ">";\n // if using default tooltips, toggle tooltips\n if (theTarget.getAttribute("title")=="show")\n theTarget.setAttribute("title","hide");\n else if (theTarget.getAttribute("title")=="hide")\n theTarget.setAttribute("title","show");\n if (theTarget.getAttribute("title")=="show "+theLabel)\n theTarget.setAttribute("title","hide "+theLabel);\n else if (theTarget.getAttribute("title")=="hide "+theLabel)\n theTarget.setAttribute("title","show "+theLabel);\n // deferred rendering (if needed)\n if (theSlider.getAttribute("rendered")=="false") {\n if (config.options.chkDebugLazySliderRender)\n alert("rendering '"+theLabel+"':\sn\sn"+theSlider.getAttribute("raw"));\n var place=theSlider;\n if (theSlider.getAttribute("blockquote")=="true")\n place=createTiddlyElement(place,"blockquote");\n wikify(theSlider.getAttribute("raw"),place);\n theSlider.setAttribute("rendered","true");\n }\n // show/hide the slider\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n theSlider.style.display = isOpen ? "none" : "block";\n if (this.sliderCookie && this.sliderCookie.length)\n { config.options[this.sliderCookie]=!isOpen; saveOptionCookie(this.sliderCookie); }\n // align slider/floater position with target button\n adjustSliderPos(theSlider.parentNode,theTarget,theSlider,theSlider.className);\n return false;\n}\n\n// hijack animation handler 'stop' handler so overflow is visible after animation has completed\nSlider.prototype.coreStop = Slider.prototype.stop;\nSlider.prototype.stop = function() { this.coreStop(); this.element.style.overflow = "visible"; }\n\n// adjust panel position based on button position\nif (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel,panelClass) {\n ///////////////////////////////////////////////////////////////////////////////\n /// EXPERIMENTAL HACK - WORKS IN SOME CASES, NOT IN OTHERS\n ///////////////////////////////////////////////////////////////////////////////\n // "if this panel is floating and the parent is not also a floating panel"...\n if (panelClass=="floatingPanel" && place.className!="floatingPanel") {\n var left=0; var top=btn.offsetHeight;\n if (place.style.position!="relative") { left+=findPosX(btn); top+=findPosY(btn); }\n if (left+panel.offsetWidth > getWindowWidth()) left=getWindowWidth()-panel.offsetWidth;\n panel.style.left=left+"px"; panel.style.top=top+"px";\n }\n}\n\nfunction getWindowWidth() {\n if(document.width!=undefined)\n return document.width; // moz (FF)\n if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )\n return document.documentElement.clientWidth; // IE6\n if(document.body && ( document.body.clientWidth || document.body.clientHeight ) )\n return document.body.clientWidth; // IE4\n if(window.innerWidth!=undefined)\n return window.innerWidth; // IE - general\n return 0; // unknown\n}\n//}}}\n// //===
/***\n''NewDocumentPlugin for TiddlyWiki version 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#NewDocumentPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nQuickly create new TiddlyWiki documents from your existing document, with just one click! Use the {{{<<newDocument>>}}} macro to place a "new document" link into your sidebar/mainmenu/any tiddler (wherever you like). Select this command to automatically create a "new.html" document containing a specific set of tagged tiddlers. Optional parameters let you specify an alternate path/filename for the new file, or different combinations of tags to match (using AND, OR, NOT and parentheses to form complex matches). You can also indicate "ask" for either parameter, which will trigger a prompt for input when the command is selected.\n\n!!!!!Usage\n<<<\n{{{<<newDocument filename tags>>}}}\n where:\n* ''filename'' is any local path-and-filename. If no parameters are provided, the default is to create the file "new.htm" in the current directory. If a filename is provided without a path (i.e., there is no "/" in the input), then the current directory is also assumed. Otherwise, this parameter is expected to contain the complete path and filename needed to write the file to your local hard disk.\n* ''tags'' an //expression// that can be a single tag value, a space-separated list of tags, or a logical formula using AND, OR, NOT and parentheses to create complex matches. The default tag expression includes only tiddlers tagged with <<tag includeNew>>or<<tag systemTiddlers>>. If the special keyword "ask" is used in place of either parameter then, when the command link is selected, a browser prompt() message box will be automatically displayed so you can input the parameter value(s) "on-the-fly".\n\n<<<\n!!!!!Examples:\n<<<\n{{{<<newDocument>>}}}\nequivalent to {{{<<newDocument new.htm includeNew systemTiddlers>>}}}\ncreates default "new.htm" containing tiddlers tagged with either<<tag includeNew>>or<<tag systemTiddlers>>\ntry it: <<newDocument>>\n\n{{{<<newDocument empty.html systemTiddlers>>}}}\ncreates "empty.html" containing only tiddlers tagged with<<tag systemTiddlers>>\n//(reproduces old-style (pre 2.0.2) empty file)//\ntry it: <<newDocument empty.html systemTiddlers>>\n\n{{{<<newDocument ask ask>>}}}\nprompts for path/file, prompts for tags to match\ntry it: <<newDocument ask ask>>\n<<<\n!!!!!Installation\n<<<\nImport (or copy/paste) the following tiddlers into your document:\n''NewDocumentPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2006.02.03 [1.1.1]''^^\nconcatentate 'extra' params so that tag expressions don't have to be quoted\nmoved all text to 'formatted' string definitions for easier translation.\neven better documentation and some minor code cleanup^^\n''2006.02.03 [1.1.0]''^^\nadded support for tag EXPRESSIONS\nplus improved documentation and code cleanup^^\n''2006.02.03 [1.0.0]''^^\nCreated.^^\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.newDocument = {major: 1, minor: 1, revision: 1, date: new Date(2006,2,3)};\n\nconfig.macros.newDocument = {\n label: "new document",\n prompt: "create a new TiddlyWiki 'starter' document",\n newtag: "includeNew OR systemTiddlers",\n newfile: "new.htm",\n fileprompt: "Enter a new filename",\n tagprompt: "Enter tag(s) to match (use AND, OR, NOT)",\n okmsg: "%0 tiddlers written to %1",\n failmsg: "An error occurred while creating '%0'",\n tagerrmsg: "Error in tag filter '%0'"\n};\n\nconfig.macros.newDocument.handler = function(place,macroName,params) {\n var btn=createTiddlyButton(place,this.label,this.prompt,onClickNewDocument);\n btn.newfile=config.macros.newDocument.newfile;\n if (params[0]) btn.newfile=params.shift();\n btn.newtag=config.macros.newDocument.newtag;\n if (params[0]) btn.newtag=params.join(" ");\n}\n\n// IE needs explicit global scoping for functions called by browser events\nwindow.onClickNewDocument=function(e)\n{\n if (!e) var e = window.event;\n\n // get the TiddlyWiki core code source\n var path=getLocalPath();\n var filename=getLocalFilename();\n var sourcefile=path+((path.indexOf("\s\s")==-1)?"/":"\s\s")+filename;\n var source=loadFile(sourcefile);\n if(source==null) { alert(config.messages.cantSaveError); return null; }\n var posOpeningDiv=source.indexOf(startSaveArea);\n var posClosingDiv=source.lastIndexOf(endSaveArea);\n if((posOpeningDiv==-1)||(posClosingDiv==-1)) { alert(config.messages.invalidFileError.format([localPath])); return; }\n\n // get output path/filename\n var newfile=resolveTarget(e).newfile;\n if (newfile=="ask") newfile=prompt(config.macros.newDocument.fileprompt, config.macros.newDocument.newfile);\n if (!newfile) return; // cancelled by user\n // if specified file does not include a path, assemble fully qualified path and filename\n var slashpos=newfile.lastIndexOf("/"); if (slashpos==-1) slashpos=newfile.lastIndexOf("\s\s");\n if (slashpos==-1) newfile=getLocalPath()+(config.browser.isWindows?"\s\s":"/")+newfile;\n\n // get the tiddler divs\n var match=resolveTarget(e).newtag;\n if (match=="ask")\n match=prompt(config.macros.newDocument.tagprompt,config.macros.newDocument.newtag);\n if (!match) return; // cancelled by user\n var storeAreaDivs=[];\n var tiddlers=store.getTiddlers('title');\n for (var i=0; i<tiddlers.length; i++)\n if (matchTags(tiddlers[i],match))\n storeAreaDivs.push(tiddlers[i].saveToDiv());\n\n // construct and write the file output\n var out=source.substr(0,posOpeningDiv+startSaveArea.length)+storeAreaDivs.join("\sn")+"\sn\st\st"+source.substr(posClosingDiv);\n if (saveFile(newfile,out))\n var msg=config.macros.newDocument.okmsg.format([storeAreaDivs.length,newfile]);\n else\n var msg=config.macros.newDocument.failmsg.format([newfile]);\n clearMessage(); displayMessage(msg);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n//}}}\n\n//{{{\nfunction getLocalPath()\n{\n // Get the URL of the document\n var originalPath = document.location.toString();\n var hashPos=originalPath.indexOf("#"); if(hashPos != -1) originalPath=originalPath.substr(0,hashPos);\n // Check we were loaded from a file URL\n if(originalPath.substr(0,5) != "file:")\n { alert(config.messages.notFileUrlError); return null; }\n // Convert to a native file format assuming\n // "file:///x:/path/path/path..." - pc local file --> "x:\spath\spath\spath..."\n // "file://///server/share/path/path/path..." - FireFox pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n // "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."\n // "file://server/share/path/path/path..." - pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n var localPath;\n if(originalPath.charAt(9) == ":") // pc local file\n localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file://///") == 0) // FireFox pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file:///") == 0) // mac/unix local file\n localPath = unescape(originalPath.substr(7));\n else if(originalPath.indexOf("file:/") == 0) // mac/unix local file\n localPath = unescape(originalPath.substr(5));\n else // pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\s\s");\n var slashpos=localPath.lastIndexOf("/"); if (slashpos==-1) slashpos=localPath.lastIndexOf("\s\s"); \n return localPath.substr(0,slashpos);\n}\n\nfunction getLocalFilename()\n{\n var path=document.location.toString();\n var hashPos=path.indexOf("#"); if(hashPos != -1) path=path.substr(0,hashPos);\n var slashpos=path.lastIndexOf("/"); if (slashpos==-1) slashpos=path.lastIndexOf("\s\s");\n return path.substr(slashpos+1);\n}\n//}}}\n\n//{{{\nif (!window.matchTags) window.matchTags=function(tiddler,cond)\n{\n if (!cond||!cond.trim().length) return false;\n\n // build a regex of all tags as a big-old regex that \n // OR's the tags together (tag1|tag2|tag3...) in length order\n var tgs = store.getTags();\n if ( tgs.length == 0 ) return results ;\n tags = tgs.sort( function(a,b){return (a[0].length<b[0].length)-(a[0].length>b[0].length);});\n var exp = "(" + tags.join("|") + ")" ;\n exp = exp.replace( /(,[\sd]+)/g, "" ) ;\n var regex = new RegExp( exp, "ig" );\n\n // build a string such that an expression that looks like this: tag1 AND tag2 OR NOT tag3\n // turns into : /tag1/.test(...) && /tag2/.test(...) || ! /tag2/.test(...)\n cond = cond.replace( regex, "/$1\s\s|/.test(tiddlerTags)" );\n cond = cond.replace( /\ssand\ss/ig, " && " ) ;\n cond = cond.replace( /\ssor\ss/ig, " || " ) ;\n cond = cond.replace( /\ss?not\ss/ig, " ! " ) ;\n\n // if a boolean uses a tag that doesn't exist - it will get left alone \n // (we only turn existing tags into actual tests).\n // replace anything that wasn't found as a tag, AND, OR, or NOT with the string "false"\n // if the tag doesn't exist then /tag/.test(...) will always return false.\n cond = cond.replace( /(\ss|^)+[^\s/\s|&!][^\ss]*/g, "false" ) ;\n\n // make a string of the tags in the tiddler and eval the 'cond' string against that string \n // if it's TRUE then the tiddler qualifies!\n var tiddlerTags = (tiddler.tags?tiddler.tags.join("|"):"")+"|" ;\n try { if ( eval( cond ) ) return true; }\n catch( e ) { displayMessage(config.macros.newDocument.tagerrmsg.format([e])); }\n return false;\n}\n//}}}
/***\n|Name|NewHereCommand|\n|Source|http://simonbaird.com/mptw/#NewHereCommand|\n|Version|1.0|\n\nCode originally by ArphenLin. Small tweak by SimonBaird\nhttp://aiddlywiki.sourceforge.net/NewHere_demo.html#NewHereCommand\nTo use this you must edit your ViewTemplate and add newHere to the toolbar div, eg\n{{{<div class='toolbar' macro='toolbar ... newHere'></div>}}}\n***/\n\n//{{{\n\nconfig.commands.newHere = {\n text: 'new here',\n tooltip: 'Create a new tiddler tagged as this tiddler',\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");\n return false;\n }\n }\n};\n\n//}}}
! Organisation logicielle de la mémoire\n\n!!Zones mémoire\nL'organisation mémoire a déjà été abordée à la section sur le [[fonctionnement logique du bus|fonctionnement logique]]. \nL'espace mémoire physique est partagé en 8 zones, disposant chacune de son chip select ({{{SH4_CSxn}}}). Pour chacune de ces zones, le comportement du bus est configurable, en type (ROM, SRAM, multiplexé, SDRAM, PCMCIA), en nombre de wait state à l'intérieur de chaque accès, en nombre de wait state entre chaque accès, etc.\n\nL'organisation choisie actuellement est la suivante :\n\n| Zone | Description | Adresse | Type | Wait state internes |h\n| CS0 | Zone de boot | {{{0xA0000000-0xA3FFFFFF}}} | SRAM | 1 + {{{SH4_RDYn}}} |\n| CS1 | Zone utilisateur (stratix) | {{{0xA4000000-0xA7FFFFFF}}} | SRAM | 1 + {{{SH4_RDYn}}} |\n| CS2 | SDRAM 0 (U5) | {{{0xA8000000-0xABFFFFFF}}} | SRAM | 0 |\n| CS3 | SDRAM 1 (U37) | {{{0xAC000000-0xAFFFFFFF}}} | SRAM | 0 |\n| CS4 | Zone utilisateur (stratix) | {{{0xB0000000-0xB3FFFFFF}}} | SRAM | 1 + {{{SH4_RDYn}}} |\n| CS5 | Zone utilisateur (stratix) | {{{0xB4000000-0xB7FFFFFF}}} | SRAM | 1 + {{{SH4_RDYn}}} |\n| CS6 | Zone utilisateur (stratix) | {{{0xB8000000-0xBBFFFFFF}}} | SRAM | 1 + {{{SH4_RDYn}}} |\n| CS7 | reservé | non accessible | - | - |\n\n''Note'' : les adresses sont données ici à partir de la zone physique interne P2 ({{{0xA...-0xB...}}})\n\nLe SH4 boot à partir de l'adresse 0 (0xA0000000). Mais le bus, malgré les nombreuses configurations qu'il possède, ne sait pas accéder de lui-même à une flash NAND. Il n'est pas donc pas possible de booter directement sur la flash NAND. Une ROM est donc instanciée dans le FPGA, qui contient un bootloader minimal, appelé [[bios|Bios]].\n\n!!Emplacement des exécutables\nLe [[bios|Bios]] en ROM est logé en {{{0xA0000000}}} (adresse 0, de boot). Il va lire un bootloader dans la flash NAND, et l'exécuter. Le [[bootloader|BootLoader]] à son tour va (en temps normal) lire le noyau Linux dans la flash NAND, et le lance.\n\nLe [[bios|Bios]] est prévu pour s'exécuter à partir de {{{0xA0000000}}}, et n'utilise que des variables locales stockées sur la pile, située dans la ~RAM0 ({{{0x0xA8000000}}}).\nLe noyau Linux s'exécute à partir de {{{0x88000000}}} (~RAM0 / ~CS2, zone cachée), donc le [[bootloader|BootLoader]] doit s'exécuter en {{{0xac000000}}}. Pour des raisons expliquées dans la [[rubrique sur le bootloader|BootLoader]], il s'exécute en fait en {{{0xac004000}}}.\n\n!!Emplacement des périphériques\nLe Stratix est vu par le SH4 comme un périphérique mappé en mémoire, accessible à partir des zones externes 0, 1, 4, 5 et 6. Chaque application hardware va définir ses propres périphériques dans les\ndifférentes zones, et donc son propre mapping mémoire. Dans un soucis d'organisation, et de partage de code, il est important de respecter certaines règles.\nCertaines adresses sont allouées de façon globale, et personne n'a le droit de les modifier sans accord du responsable principal du code (actuellement Alexis). D'autres adresses sont libres, et utilisables à\nvolonté :\n* Les adresses figées :\n** CS0, pour le boot,\n** CS1, pour des registres divers\n* Les adresses libres :\n** CS4, (utilisé pour la vidéo),\n** CS5,\n** CS6.\n\nSi on souhaite ajouter un périphérique ou un registre dans une zone réservée, il convient de prévenir le responsable de l'archive code pour éviter tout conflit (immédiat ou futur).\n\nLes périphériques actuellement définis sont donnés dans le fichier Verilog {{{top.v}}}, et récapitulés ci-dessous :\n{{{\nCS0 :\n 0xA0000000 Internal boot ROM (contains bootloader)\nCS1 :\n \n}}}\n\n''A compléter !!!''\n\n''Attention'' : il est primordial qu'aucun driver ne change les settings d'accès au bus !!! Les settings, en terme de format et de wait states (registres {{{BCR1}}}, {{{BCR2}}}, {{{BCR3}}}, {{{WCR1}}}, {{{WCR2}}} et {{{WCR3}}}), sont programmés par le [[bios|Bios]], et uniquement par celui-ci. Toute tentative de les modifier ailleurs risquerait de rendre un périphérique inutilisable et son débug impossible.
<div class='header'>\n<div class='headerShadow'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span> \n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n<div class='headerForeground'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span> \n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n</div>\n<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>\n<div id='sidebar'>\n<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>\n</div>\n<div id='displayArea'>\n<div id='messageArea'></div>\n<div id='tiddlerDisplay'></div>\n</div>
!Processeur\nLe processeur est un SH4 7750R d'Hitachi. Il a été choisi pour ses performances (430 MIPS à 240 MHz, 1.7GFlops), sa faible consommation (0.9W en crête), sa disponibilité et son coût. C'est un RISC\n32bits superscalaire (2 instructions en parallèle), possédant 2 caches internes (16kB instructions et 32kB données), une MMU et divers périphérique intégrés, pour lequel la suite de compilation GNU C( gcc et binutils) a été portée. Il possède un bus externe 64 bits, utilisé ici en 32 bits, multi-protocoles.\n\n!Horloges, resets\n!!!Horloges\nSon horloge principale ({{{clk_sh4}}}) est générée par le FPGA, à partir du générateur d'horloge Cypress. Une première PLL interne multiplie cette horloge par 6 ou 12. Puis des diviseurs se chargent de générer les différentes horloges (coeur, modules et bus). Une deuxième PLL spécifique au bus externe assure la génération d'une horloge bus ({{{sh4_ckio}}}) propre et stable.\n\nPar défaut sur les cartes actuelles, on a :\n* horloge entrée ({{{clk_sh4}}}) : 20MHz,\n* horloge coeur : 240Mhz,\n* horloge modules : 60MHz,\n* horloge bus ({{{sh4_ckio}}}) : 60MHz.\n\n''Attention'' : si on modifie ces valeurs (par les switchs de configuration), il faut penser à recompiler le noyau Linux avec la bonne valeur de fréquence modules, sinon les UART ne fonctionneront pas !\n\nLe processeur dispose aussi d'une RTC, pilotée par un quartz de 32.768kHz.\n\n!!! Resets\nLe processeur dispose de deux types de reset : manuel (power-up reset), et soft. Ils diffèrent entre eux par la façon dont ils sont générés, et par les parties du processeur qui sont affectées. De façon grossière, un reset manuel remet le processeur entier à zéro, alors que le reset soft n'affecte que son coeur. C'est l'état de la ligne {{{SH4_SCK2_MRESETn}}} quand {{{SH4_RESETn}}} est bas qui détermine si le reset est manuel ou soft.\n\nUn reset manuel (power-up reset) déclenche aussi la lecture de certaines lignes ({{{MD[8:0]}}}), qui déterminent alors la configuration du processeur. Après le reset, ces lignes prennent éventuellement une autre fonction (UART, . . . ). \nUn buffer 3 états ({{{U41}}}) assure l'indépendance des lignes {{{MD[8:0]}}} après la phase de reset.\n\nLa configuration par défaut, sur laquelle se basent la chaîne de compilation ainsi que les différents modules du FPGA déjà écrits, est la suivante :\n* horloge module : 60MHz, horloge bus 60MHz, horloge d'entrée externe,\n* zone de boot (Area 0) en 32 bits, type SRAM,\n* processeur en little-endian, seul maître du bus.\n\n
/***\n| Name:|QuickOpenTagPlugin|\n| Purpose:|Makes tag links into a Taggly style open tag plus a normal style drop down menu|\n| Creator:|SimonBaird|\n| Source:|http://simonbaird.com/mptw/#QuickOpenTagPlugin|\n| Requires:|TW 2.x|\n| Version|1.1 (7-Feb-06)|\n\n!History\n* Version 1.1 (07/02/2006)\n** Fix Firefox 1.5.0.1 crashes\n** Updated by ~BidiX[at]~BidiX.info\n* Version 1.0 (?/01/2006)\n** First release\n\n***/\n//{{{\n\n//⊻ ⊽ ⋁ ▼ \n\nwindow.createTagButton_orig_mptw = createTagButton;\nwindow.createTagButton = function(place,tag,excludeTiddler) {\n var sp = createTiddlyElement(place,"span",null,"quickopentag");\n createTiddlyLink(sp,tag,true,"button");\n var theTag = createTiddlyButton(sp,config.macros.miniTag.dropdownchar,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\nconfig.macros.miniTag = {handler: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.macros.miniTag.dropdownchar,config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);\n theTag.setAttribute("tag",tiddler.title);\n theTag.className = "miniTag";\n }\n}};\n\nconfig.macros.miniTag.dropdownchar = (document.all?"▼":"▾"); // the fat one is the only one that works in IE\n\nconfig.macros.allTags.handler = function(place,macroName,params)\n{\n var tags = store.getTags();\n var theDateList = createTiddlyElement(place,"ul",null,null,null);\n if(tags.length === 0)\n createTiddlyElement(theDateList,"li",null,"listTitle",this.noTags);\n for (var t=0; t<tags.length; t++)\n {\n var theListItem =createTiddlyElement(theDateList,"li",null,null,null);\n var theLink = createTiddlyLink(theListItem,tags[t][0],true);\n var theCount = " (" + tags[t][1] + ")";\n theLink.appendChild(document.createTextNode(theCount));\n\n var theDropDownBtn = createTiddlyButton(theListItem," "+config.macros.miniTag.dropdownchar,this.tooltip.format([tags[t][0]]),onClickTag);\n theDropDownBtn.setAttribute("tag",tags[t][0]);\n }\n};\n\n\nsetStylesheet(\n ".quickopentag { 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 "a.miniTag {font-size:150%;}\sn"+\n "",\n"QuickOpenTagStyles");\n\n//}}}\n\n/***\n<html>⊻ ⊽ ⋁ ▼ ▾</html>\n***/\n
/***\n|''Name:''|ReminderPlugin|\n|''Version:''|2.3.3 (Feb 2, 2006)|\n|''Source:''|http://www.geocities.com/allredfaq/reminderMacros.html|\n|''Author:''|Jeremy Sheeley(pop1280 [at] excite [dot] com)|\n|''Licence:''|[[BSD open source license]]|\n|''Macros:''|reminder, showreminders, displayTiddlersWithReminders, newReminder|\n|''TiddlyWiki:''|2.0+|\n|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|\n\n!HACKS BY OTHERS\n''ELS 2006.02.05:''\nadded 'var' to loop indices and other temporary variables to avoid FF1.5.0.1 global crash bug (search for """"// ELS"""" to find all changes)\n\n!Description\nThis plugin provides macros for tagging a date with a reminder. Use the {{{reminder}}} macro to do this. The {{{showReminders}}} and {{{displayTiddlersWithReminder}}} macros automatically search through all available tiddlers looking for upcoming reminders.\n\n!Installation\n* Create a new tiddler in your tiddlywiki titled ReminderPlugin and give it the {{{systemConfig}}} tag. The tag is important because it tells TW that this is executable code.\n* Double click this tiddler, and copy all the text from the tiddler's body.\n* Paste the text into the body of the new tiddler in your TW.\n* Save and reload your TW.\n* You can copy some examples into your TW as well. See [[Simple examples]], [[Holidays]], [[showReminders]] and [[Personal Reminders]]\n\n!Syntax:\n|>|See [[ReminderSyntax]] and [[showRemindersSyntax]]|\n\n!Revision history\n* v2.3.3 (Jan 21, 2006)\n**Feature: newReminder now has drop down lists instead of text boxes.\n**Bug fix: A trailing space in a title would trigger an infinite loop.\n**Bug fix: using tag:"birthday !reminder" would filter differently than tag:"!reminder birthday"\n* v2.3.2 (Jan 21, 2006)\n**Feature: newReminder macro, which will let you easily add a reminder to a tiddler. Thanks to Eric Shulman (http://www.elsdesign.com) for the code to do this.\n** Bug fix: offsetday was not working sometimes\n** Bug fix: when upgrading to 2.0, I included a bit to exclude tiddlers tagged with excludeSearch. I've reverted back to searching through all tiddlers\n* v2.3.1 (Jan 7, 2006)\n**Feature: 2.0 compatibility\n**Feature AlanH sent some code to make sure that showReminders prints a message if no reminders are found.\n* v2.3.0 (Jan 3, 2006)\n** Bug Fix: Using "Last Sunday (-0)" as a offsetdayofweek wasn't working.\n** Bug Fix: Daylight Savings time broke offset based reminders (for example year:2005 month:8 day:23 recurdays:7 would match Monday instead of Tuesday during DST.\n\n!Code\n***/\n//{{{\n\n//============================================================================\n//============================================================================\n// ReminderPlugin\n//============================================================================\n//============================================================================\n\nversion.extensions.ReminderPlugin = {major: 2, minor: 3, revision: 3, date: new Date(2006,2,2), source: "http://www.geocities.com/allredfaq/reminderMacros.html"};\n\n//============================================================================\n// Configuration\n// Modify this section to change the defaults for \n// leadtime and display strings\n//============================================================================\n\nconfig.macros.reminders = {};\nconfig.macros["reminder"] = {};\nconfig.macros["newReminder"] = {};\nconfig.macros["showReminders"] = {};\nconfig.macros["displayTiddlersWithReminders"] = {};\n\nconfig.macros.reminders["defaultLeadTime"] = [0,6000];\nconfig.macros.reminders["defaultReminderMessage"] = "DIFF: TITLE on DATE ANNIVERSARY";\nconfig.macros.reminders["defaultShowReminderMessage"] = "DIFF: TITLE on DATE ANNIVERSARY -- TIDDLER";\nconfig.macros.reminders["defaultAnniversaryMessage"] = "(DIFF)";\nconfig.macros.reminders["untitledReminder"] = "Untitled Reminder";\nconfig.macros.reminders["noReminderFound"] = "Couldn't find a match for TITLE in the next LEADTIMEUPPER days."\nconfig.macros.reminders["todayString"] = "Today";\nconfig.macros.reminders["tomorrowString"] = "Tomorrow";\nconfig.macros.reminders["ndaysString"] = "DIFF days";\nconfig.macros.reminders["emtpyShowRemindersString"] = "There are no upcoming events";\n\n\n//============================================================================\n// Code\n// You should not need to edit anything \n// below this. Make sure to edit this tiddler and copy \n// the code from the text box, to make sure that \n// tiddler rendering doesn't interfere with the copy \n// and paste.\n//============================================================================\n\n// This line is to preserve 1.2 compatibility\n if (!story) var story=window; \nconfig.macros.showReminders.handler = function(place,macroName,params)\n{\n var now = new Date().getMidnight();\n var paramHash = {};\n var type = "";\n var num = 0;\n var leadtime = [0,14];\n var paramHash = getParamsForReminder(params);\n var bProvidedDate = (paramHash["year"] != null) \n || (paramHash["month"] != null) \n || (paramHash["day"] != null) \n || (paramHash["dayofweek"] != null)\n if (paramHash["leadtime"] != null)\n {\n leadtime = paramHash["leadtime"];\n if (bProvidedDate)\n //If they've entered a day, we need to make \n //sure to find it. We'll reset the \n //leadtime a few lines down.\n paramHash["leadtime"] = [-10000, 10000]\n }\n var matchedDate = now;\n if (bProvidedDate)\n {\n matchedDate = findDateForReminder(paramHash); \n }\n\n var arr = findTiddlersWithReminders(matchedDate, leadtime, paramHash["tag"], paramHash["limit"]);\n var elem = createTiddlyElement(place,"span",null,null, null);\n var mess = "";\n if (arr.length == 0)\n mess += config.macros.reminders.emtpyShowRemindersString; \n for (var j = 0; j < arr.length; j++) // ELS 2006.02.05: added 'var' to avoid FF1.5.0.1 global crash bug\n {\n if (paramHash["format"] != null)\n arr[j]["params"]["format"] = paramHash["format"];\n else\n arr[j]["params"]["format"] = config.macros.reminders["defaultShowReminderMessage"];\n mess += getReminderMessageForDisplay(arr[j]["diff"], arr[j]["params"], arr[j]["matchedDate"], arr[j]["tiddler"]);\n mess += "\sn";\n }\n wikify(mess, elem, null, null);\n}\n\n\nconfig.macros.displayTiddlersWithReminders.handler = function(place,macroName,params)\n{\n var now = new Date().getMidnight();\n var paramHash = {};\n var type = "";\n var num = 0;\n var leadtime = [0,14];\n var paramHash = getParamsForReminder(params);\n var bProvidedDate = (paramHash["year"] != null) \n || (paramHash["month"] != null) \n || (paramHash["day"] != null) \n || (paramHash["dayofweek"] != null)\n if (paramHash["leadtime"] != null)\n {\n leadtime = paramHash["leadtime"];\n if (bProvidedDate)\n //If they've entered a day, we need to make \n //sure to find it. We'll reset the leadtime \n //a few lines down.\n paramHash["leadtime"] = [-10000,10000];\n }\n var matchedDate = now;\n if (bProvidedDate)\n {\n matchedDate = findDateForReminder(paramHash); \n }\n var arr = findTiddlersWithReminders(matchedDate, leadtime, paramHash["tag"], paramHash["limit"]);\n for (j = 0; j < arr.length; j++)\n {\n displayTiddler(null, arr[j]["tiddler"], 0, null, false, false, false)\n }\n}\n\nconfig.macros.reminder.handler = function(place,macroName,params)\n{\n var dateHash = getParamsForReminder(params);\n if (dateHash["hidden"] != null)\n return;\n var matchedDate = findDateForReminder(dateHash);\n var leadTime = dateHash["leadtime"];\n if (leadTime == null)\n leadTime = config.macros.reminders["defaultLeadTime"]; \n\n if (matchedDate != null)\n {\n var diff = matchedDate.getDifferenceInDays(new Date())\n var elem = createTiddlyElement(place,"span",null,null, null);\n var mess = getReminderMessageForDisplay(diff, dateHash, matchedDate);\n wikify(mess, elem, null, null);\n }\n else\n createTiddlyElement(place,"span",null,null, config.macros.reminders["noReminderFound"].replace("TITLE", dateHash["title"]).replace("LEADTIMEUPPER", leadTime[1]).replace("LEADTIMELOWER", leadTime[0]) );\n}\n\nconfig.macros.newReminder.handler = function(place,macroName,params)\n{\n var today=new Date();\n var formstring = '<html><form>Year: <select name="year"><option value="">Every year</option>';\n for (var i = 0; i < 5; i++) // ELS 2006.02.05: added 'var' to avoid FF1.5.0.1 global crash bug\n formstring += '<option' + ((i == 0) ? ' selected' : '') + '>' + (today.getFullYear() + i) + '</option>';\n formstring += '</select> Month:<select name="month"><option value="">Every month</option>';\n for (var i = 0; i < 12; i++) // ELS 2006.02.05: added 'var' to avoid FF1.5.0.1 global crash bug\n formstring += '<option' + ((i == today.getMonth()) ? ' selected' : '') + ' value="' + (i+1) + '">' + config.messages.dates.months[i] + '</option>';\n formstring += '</select> Day:<select name="day"><option value="">Every day</option>';\n for (var i = 1; i < 32; i++) // ELS 2006.02.05: added 'var' to avoid FF1.5.0.1 global crash bug\n formstring += '<option' + ((i == (today.getDate() )) ? ' selected' : '') + '>' + i + '</option>';\n\nformstring += '</select> Reminder Title:<input type="text" size="40" name="title" value="please enter a title" onfocus="this.select();"><input type="button" value="ok" onclick="addReminderToTiddler(this.form)"></form></html>';\n\n var panel = config.macros.slider.createSlider(place,null,"New Reminder","Open a form to add a new reminder to this tiddler");\n wikify(formstring ,panel,null,store.getTiddler(params[1]));\n}\n\n// onclick: process input and insert reminder at 'marker'\nwindow.addReminderToTiddler = function(form) {\n if (!window.story) window.story=window; if (!store.getTiddler) store.getTiddler=function(title) {return this.tiddlers[title]}\n var title = story.findContainingTiddler(form).id.substr(7);\n var tiddler=store.getTiddler(title);\n pos=tiddler.text.length;\n var txt='\sn<<reminder year:'+form.year.value+' month:'+form.month.value+' day:'+form.day.value+' title:"'+form.title.value+'">>';\n tiddler.set(null,tiddler.text + txt);\n story.refreshTiddler(title,1,true);\n store.setDirty(true);\n}\n\nhasTag = function(tiddlerTags, tagFilters)\n{\n //Make sure we respond well to empty tiddlerTaglists or tagFilterlists\n if (tagFilters.length==0 || tiddlerTags.length==0)\n return true;\n\n var bHasTag = false;\n \n /*bNoPos says: "'till now there has been no check using a positive filter"\n Imagine a filterlist consisting of 1 negative filter:\n If the filter isn't matched, we want hasTag to be true.\n Yet bHasTag is still false ('cause only positive filters cause bHasTag to change)\n \n If no positive filters are present bNoPos is true, and no negative filters are matched so we have not returned false\n Thus: hasTag returns true.\n \n If at any time a positive filter is encountered, we want at least one of the tags to match it, so we turn bNoPos to false, which\n means bHasTag must be true for hasTag to return true*/\n var bNoPos=true;\n \nfor (var t3 = 0; t3 < tagFilters.length; t3++)\n {\n for(var t2=0; t2<tiddlerTags.length; t2++)\n {\n if (tagFilters[t3].length > 1 && tagFilters[t3].charAt(0) == '!') {\n if (tiddlerTags[t2] == tagFilters[t3].substring(1))\n //If at any time a negative filter is matched, we return false\n return false;\n }\n else {\n if (bNoPos)\n //We encountered the first positive filter\n bNoPos=false;\n if (tiddlerTags[t2] == tagFilters[t3])\n //A positive filter is matched. As long as no negative filter is matched, hasTag will return true\n bHasTag=true;\n }\n }\n }\n return (bNoPos || bHasTag);\n}\n\n//This function searches all tiddlers for the reminder //macro. It is intended that other plugins (like //calendar) will use this function to query for \n//upcoming reminders.\n//The arguments to this function filter out reminders //based on when they will fire.\n//\n//ARGUMENTS:\n//baseDate is the date that is used as "now". \n//leadtime is a two element int array, with leadtime[0] \n// as the lower bound and leadtime[1] as the\n// upper bound. A reasonable default is [0,14]\n//tags is a space-separated list of tags to use to filter \n// tiddlers. If a tag name begins with an !, then \n// only tiddlers which do not have that tag will \n// be considered. For example "examples holidays" \n// will search for reminders in any tiddlers that \n// are tagged with examples or holidays and \n// "!examples !holidays" will search for reminders \n// in any tiddlers that are not tagged with \n// examples or holidays. Pass in null to search \n// all tiddlers.\n//limit. If limit is null, individual reminders can \n// override the leadtime specified earlier. \n// Pass in 1 in order to override that behavior.\n\nfindTiddlersWithReminders = function(baseDate, leadtime, tags, limit)\n{\n//function(searchRegExp,sortField,excludeTag)\n// var macroPattern = "<<([^>\s\s]+)(?:\s\s*)([^>]*)>>";\n var macroPattern = "<<(reminder)(.*)>>";\n var macroRegExp = new RegExp(macroPattern,"mg");\n var matches = store.search(macroRegExp,"title","");\n var arr = [];\n var tagsArray = null;\n if (tags != null)\n tagsArray = tags.split(" ");\n for(var t=matches.length-1; t>=0; t--)\n {\n if (tagsArray != null)\n {\n //If they specified tags to filter on, and this tiddler doesn't \n //match, skip it entirely.\n if ( ! hasTag(matches[t].tags, tagsArray))\n continue;\n }\n\n var targetText = matches[t].text;\n do {\n // Get the next formatting match\n var formatMatch = macroRegExp.exec(targetText);\n var matchPos = formatMatch ? formatMatch.index : targetText.length;\n var level;\n var theBlockquote;\n if(formatMatch && formatMatch[1] != null && formatMatch[1].toLowerCase() == "reminder")\n {\n //Find the matching date.\n \n var params = formatMatch[2] != null ? formatMatch[2].readMacroParams() : {};\n var dateHash = getParamsForReminder(params);\n if (limit != null || dateHash["leadtime"] == null)\n dateHash["leadtime"] = leadtime;\n\n var matchedDate = findDateForReminder(dateHash, baseDate);\n if (matchedDate != null)\n {\n var hash = {};\n hash["diff"] = matchedDate.getDifferenceInDays(baseDate);\n hash["matchedDate"] = matchedDate;\n hash["params"] = dateHash;\n hash["tiddler"] = matches[t].title;\n hash["tags"] = matches[t].tags;\n arr.pushUnique(hash);\n }\n }\n }while(formatMatch);\n }\n if(arr.length > 1) //Sort the array by number of days remaining.\n arr.sort(function (a,b) {if(a["diff"] == b["diff"]) return(0); else return (a["diff"] < b["diff"]) ? -1 : +1; });\n return arr;\n}\n\n//This function takes the reminder macro parameters and\n//generates the string that is used for display.\n//This function is not intended to be called by \n//other plugins.\ngetReminderMessageForDisplay = function(diff, params, matchedDate, tiddlerTitle)\n{\n var anniversaryString = "";\n var reminderTitle = params["title"];\n if (reminderTitle == null)\n reminderTitle = config.macros.reminders["untitledReminder"];\n if (params["firstyear"] != null)\n anniversaryString = config.macros.reminders["defaultAnniversaryMessage"].replace("DIFF", (matchedDate.getFullYear() - params["firstyear"]));\n var mess = "";\n if (diff == 0)\n diffString = config.macros.reminders["todayString"];\n else if (diff == 1)\n diffString = config.macros.reminders["tomorrowString"];\n else\n diffString = config.macros.reminders["ndaysString"].replace("DIFF", diff);\n var format = config.macros.reminders["defaultReminderMessage"];\n if (params["format"] != null)\n format = params["format"];\n mess = format;\n//HACK! -- Avoid replacing DD in TIDDLER with the date\n mess = mess.replace("TIDDLER", "TIDELER");\n mess = matchedDate.formatStringDateOnly(mess);\n mess = mess.replace("TIDELER", "TIDDLER");\n if (tiddlerTitle != null)\n mess = mess.replace("TIDDLER", "[[" + tiddlerTitle + "]]");\n \n mess = mess.replace("DIFF", diffString).replace("TITLE", reminderTitle).replace("DATE", matchedDate.formatString("DDD MMM DD, YYYY")).replace("ANNIVERSARY", anniversaryString);\n return mess;\n}\n\n// Parse out the macro parameters into a hashtable. This\n// handles the arguments for reminder, showReminders and \n// displayTiddlersWithReminders.\ngetParamsForReminder = function(params)\n{\n var dateHash = {};\n var type = "";\n var num = 0;\n var title = "";\n for(var t=0; t<params.length; t++)\n {\n var split = params[t].split(":"); // ELS 2006.02.05: added 'var' to avoid FF1.5.0.1 global crash bug\n type = split[0].toLowerCase();\n var value = split[1];\n for (var i=2; i < split.length; i++) // ELS 2006.02.05: added 'var' to avoid FF1.5.0.1 global crash bug\n value += ":" + split[i];\n if (type == "nolinks" || type == "limit" || type == "hidden")\n num = 1;\n else if (type == "leadtime")\n {\n leads = value.split("...");\n if (leads.length == 1)\n {\n leads[1]= leads[0];\n leads[0] = 0;\n }\n leads[0] = parseInt(leads[0]);\n leads[1] = parseInt(leads[1]);\n num = leads;\n }\n else if (type == "offsetdayofweek")\n {\n if (value.substr(0,1) == "-")\n {\n dateHash["negativeOffsetDayOfWeek"] = 1;\n }\n num = parseInt(value);\n }\n else if (type != "title" && type != "tag" && type != "format")\n num = parseInt(value);\n else\n {\n title = value;\n t++;\n while (title.substr(0,1) == '"' && title.substr(title.length - 1,1) != '"' && params[t] != undefined)\n {\n title += " " + params[t++];\n }\n //Trim off the leading and trailing quotes\n if (title.substr(0,1) == "\s"" && title.substr(title.length - 1,1)== "\s"")\n title = title.substr(1, title.length - 2);\n num = title;\n }\n dateHash[type] = num;\n }\n //date is synonymous with day\n if (dateHash["day"] == null)\n dateHash["day"] = dateHash["date"];\n return dateHash;\n}\n\n//This function finds the date specified in the reminder \n//parameters. It will return null if no match can be\n//found. This function is not intended to be used by\n//other plugins.\nfindDateForReminder = function( dateHash, baseDate)\n{\n if (baseDate == null)\n baseDate = new Date().getMidnight();\n var leadTime = dateHash["leadtime"];\n var bOffsetSpecified = dateHash["offsetyear"] != null \n || dateHash["offsetmonth"] != null\n || dateHash["offsetday"] != null\n || dateHash["offsetdayofweek"] != null\n || dateHash["recurdays"] != null;\n \n if (leadTime == null)\n leadTime = config.macros.reminders["defaultLeadTime"]; \n//HACK!\n if (dateHash["offsetdayofweek"] != null && dateHash["day"] != null && dateHash["month"] == null && dateHash["year"] == null)\n {\n if ((baseDate.getDate() - dateHash["day"]) < 7 && (baseDate.getDate() - dateHash["day"]) >= 0 \n && dateHash["offsetdayofweek"] >= baseDate.getDay())\n {\n //They've seleceted an offsetdayofweek that is greater than or equal to today.\n //We need to use today as the first matched date\n for (var i=0; i < 7; i++) // ELS 2006.02.05: added 'var' to avoid FF1.5.0.1 global crash bug\n {\n var testDate = baseDate.addDays(i);\n if (testDate.getDay() == dateHash["offsetdayofweek"])\n {\n var diff3 = testDate.getDifferenceInDays(baseDate);\n if (diff3 <= leadTime[1] && diff3 >= leadTime[0])\n return testDate;\n else\n return null;\n }\n }\n }\n }\n\n var matchedDate = baseDate.findMatch(dateHash, bOffsetSpecified ? [0, 6000] : leadTime);\n if (matchedDate != null)\n {\n var newMatchedDate = matchedDate;\n if (dateHash["recurdays"] != null)\n {\n while (newMatchedDate.getTime() < baseDate.getTime())\n {\n newMatchedDate = newMatchedDate.addDays(dateHash["recurdays"]);\n }\n }\n else if (dateHash["offsetyear"] != null \n || dateHash["offsetmonth"] != null\n || dateHash["offsetday"] != null\n || dateHash["offsetdayofweek"] != null)\n {\n dateHash["year"] = dateHash["offsetyear"];\n dateHash["month"] = dateHash["offsetmonth"];\n dateHash["day"] = dateHash["offsetday"];\n dateHash["dayofweek"] = dateHash["offsetdayofweek"];\n newMatchedDate = matchedDate.findMatch(dateHash, leadTime);\n //The offset couldn't be matched. return null.\n if (newMatchedDate == null)\n return null;\n }\n var diff2 = newMatchedDate.getDifferenceInDays(baseDate);\n if (diff2 <= leadTime[1] && diff2 >= leadTime[0])\n return newMatchedDate;\n }\n return null;\n}\n\n//This does much the same job as findDateForReminder, but\n//this one doesn't deal with offsets or recurring \n//reminders.\nDate.prototype.findMatch = function(dateHash, leadTime)\n{\n var bSpecifiedYear = (dateHash["year"] != null);\n var bSpecifiedMonth = (dateHash["month"] != null);\n var bSpecifiedDay = (dateHash["day"] != null);\n var bSpecifiedDayOfWeek = (dateHash["dayofweek"] != null);\n if (bSpecifiedYear && bSpecifiedMonth && bSpecifiedDay)\n return Date.convertFromYYYYMMDDHHMM("" + dateHash["year"] + String.zeroPad(dateHash["month"],2) + String.zeroPad(dateHash["day"],2) + "0000");\n var bMatchedYear = !bSpecifiedYear;\n var bMatchedMonth = !bSpecifiedMonth;\n var bMatchedDay = !bSpecifiedDay;\n var bMatchedDayOfWeek = !bSpecifiedDayOfWeek;\n var searchInterval = 1;\n if ((bSpecifiedDayOfWeek && dateHash["dayofweek"] < 0)\n || dateHash["negativeOffsetDayOfWeek"] != null)\n {\n dateHash["dayofweek"] = dateHash["dayofweek"] * -1;\n searchInterval = -1;\n }\n if (bSpecifiedDay && bSpecifiedMonth && !bSpecifiedYear && !bSpecifiedDayOfWeek)\n {\n\n //Shortcut -- First try this year. If it's too small, try next year.\n var tmpMidnight = this.getMidnight();\n var tmpLeadTime = this.addDays(leadTime[0]).getMidnight();\n var tmpDate = Date.convertFromYYYYMMDDHHMM("" + this.getFullYear() + String.zeroPad(dateHash["month"],2) + String.zeroPad(dateHash["day"],2) + "0000");\n if (tmpDate.getTime() < tmpLeadTime.getTime())\n tmpDate = Date.convertFromYYYYMMDDHHMM("" + (this.getFullYear() + 1) + String.zeroPad(dateHash["month"],2) + String.zeroPad(dateHash["day"],2) + "0000");\n var diff2 = tmpDate.getDifferenceInDays(tmpMidnight);\n\n if (diff2 <= leadTime[1] && diff2 >= leadTime[0])\n return tmpDate;\n else\n return null;\n }\n\n for (var i = 0; i <= leadTime[1]; i+=searchInterval) // ELS 2006.02.05: added 'var' to avoid FF1.5.0.1 global crash bug\n {\n var newDate = this.addDays(i);\n if (bSpecifiedYear)\n bMatchedYear = ((dateHash["year"] - 1900) == newDate.getYear());\n if (bSpecifiedMonth)\n bMatchedMonth = ((dateHash["month"] - 1) == newDate.getMonth() );\n if (bSpecifiedDay)\n bMatchedDay = (dateHash["day"] == newDate.getDate());\n if (bSpecifiedDayOfWeek)\n bMatchedDayOfWeek = (dateHash["dayofweek"] == newDate.getDay());\n\n if (bMatchedYear && bMatchedMonth && bMatchedDay && bMatchedDayOfWeek)\n return newDate;\n }\n//Only search backwards if we're not just trying to match the dayofweek\nif (leadTime[0] < 0 && (bSpecifiedYear || bSpecifiedMonth || bSpecifiedDay))\n for (var i = 0; i >= leadTime[0]; i+=(searchInterval * -1)) // ELS 2006.02.05: added 'var' to avoid FF1.5.0.1 global crash bug\n {\n var newDate = this.addDays(i);\n if (bSpecifiedYear)\n bMatchedYear = ((dateHash["year"] - 1900) == newDate.getYear());\n if (bSpecifiedMonth)\n bMatchedMonth = ((dateHash["month"] - 1) == newDate.getMonth() );\n if (bSpecifiedDay)\n bMatchedDay = (dateHash["day"] == newDate.getDate());\n if (bSpecifiedDayOfWeek)\n bMatchedDayOfWeek = (dateHash["dayofweek"] == newDate.getDay());\n\n if (bMatchedYear && bMatchedMonth && bMatchedDay && bMatchedDayOfWeek)\n return newDate;\n }\n}\n\n//Return a new date, with the time set to midnight (0000)\nDate.prototype.getMidnight = function()\n{\n return Date.convertFromYYYYMMDDHHMM("" + this.getFullYear() + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2) + "0000");\n}\n// Add the specified number of days to a date.\nDate.prototype.addDays = function(numberOfDays)\n{\n return( Date.convertFromYYYYMMDDHHMM(this.formatStringDateOnly("YYYY0MM") + String.zeroPad(this.getDate() + numberOfDays,2) + "0000"));\n}\n//Return the number of days between two dates.\nDate.prototype.getDifferenceInDays = function(otherDate)\n{\n return Math.floor((this.getMidnight().getTime() - otherDate.getMidnight().getTime()) / 86400000);\n \n}\n\n// Substitute date components into a string\nDate.prototype.formatStringDateOnly = function(template)\n{\n template = template.replace("YYYY",this.getFullYear());\n template = template.replace("YY",String.zeroPad(this.getFullYear()-2000,2));\n template = template.replace("MMM",config.messages.dates.months[this.getMonth()]);\n template = template.replace("0MM",String.zeroPad(this.getMonth()+1,2));\n template = template.replace("MM",this.getMonth()+1);\n template = template.replace("DDD",config.messages.dates.days[this.getDay()]);\n template = template.replace("0DD",String.zeroPad(this.getDate(),2));\n template = template.replace("DD",this.getDate());\n return template;\n}\n//}}}
!!!Liste des tiddlers se rapportant à la carte Stratix version 2.0 (SHiX 2.0)\nVoir aussi les sections relatives à la [[Compilation]].\n
Ces rubriques décrivent le fonctionnement du bloc SSRAM (RAM statique dédié au Stratix) :\n* [[Fonctionnement des SSRAM|Fonctionnement SSRAM]]\n* [[Fonctionnement de l'arbitre d'accès aux SSRAM|Fonctionnement Arbitre SSRAM]]\n
// //''Name:'' Save Changes To DAV plugin\n// //''Version:'' <<getversion saveChangesToDAV>> (<<getversiondate calendar "DD MMM YYYY">>)\n// //''Depends on:'' YATWA http://www.rumsby.org/yatwa/\n// //''Author:'' PeterSuschlik <peter-tiddly //at// suschlik //dot// de>\n\n// //''Syntax:'' \n// //<< {{{saveChangesToDAV}}} >>\n\n// //''Description:'' \n// //This plugin allows you to upload your changes to a webserver via WebDAV (at the moment only the methods {{{GET}}} and {{{PUT}}} are implemented)\n// //It should be add to SideBarOptions.\n// //Addionally, add << {{{option txtDAVURL 50}}} >> to AdvancedOptions.\n\n// //''WebDAV Apache Setup Example''\n// // Wiki-URL: http://{{{host}}}/wiki/\n// // DAV-URL: http://{{{host}}}/wiki/dav/index.html\n// // * setup WebDAV for {{{host}}} as usual\n// // * symlink /wiki/index.html to /wiki/dav/index.html\n\n// //''Notes on XMLHttpRequest restrictions''\n// //Due to security reasons there are some restrictions on connection to a webserver via XMLHttpRequest\n// //The wiki and the upload WebDAV directory must live on the same host\n\n// //''TODO''\n// // * some documentation/comments\n\n\n// //''Configuration:''\n// //Add a tiddler named DavUrl, tagged as systemConfig, containing the URL to upload to : {{{txtDAVURL="http://mysite/index.html";}}}\n// //For setup see above.\n\n// //''Code section:''\n// (you should not need to alter anything below here)//\n\n/*\n{{{\n*/\n\nvar txtDAVURL;\n\nfunction isHttp() {\n return document.location.toString().search(/https?:\s/\s//) != -1;\n}\n\nfunction DAVSaver() {\n this.uploading = false;\n}\n\nDAVSaver.prototype = {\n xmlhttprequest: function() {\n try {\n return new XMLHttpRequest();\n return new ActiveXObject("Msxml2.XMLHTTP");\n return new ActiveXObject("Microsoft.XMLHTTP");\n } catch(e) {}\n alert("Could not construct XmlHttpRequest Object!");\n },\n reset: function() {\n this.uploading = false;\n return null;\n },\n loadLocal: function() {\n var originalPath = document.location.toString();\n var hashPos = originalPath.indexOf("#");\n if(hashPos != -1) originalPath = originalPath.substr(0,hashPos);\n var localPath;\n if(originalPath.charAt(9) == ":") // pc local file\n localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file://///") == 0) // FireFox pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file:///") == 0) // mac/unix local file\n localPath = unescape(originalPath.substr(7));\n else if(originalPath.indexOf("file:/") == 0) // mac/unix local file\n localPath = unescape(originalPath.substr(5));\n else // pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\s\s");\n displayMessage('Loading locally: ' + localPath, localPath);\n var original = loadFile(localPath);\n if (original == null) {\n displayMessage('Loading locally failed: ' + localPath, localPath);\n return;\n }\n this.doUpload(original);\n },\n loadRemote: function() {\n var xml = this.xmlhttprequest();\n xml._uploader = this;\n displayMessage('Updating remotely : ' + this.url, this.url);\n xml.onreadystatechange = function() {\n //if (xml.readyState != 3)\n // displayMessage("Download-State " + xml.readyState);\n if (xml.readyState == 4) {\n if (xml.status == 200) {\n //displayMessage('Downloaded ' + xml.responseText.length + ' bytes');\n xml._uploader.doUpload(xml.responseText);\n } else {\n displayMessage('Upload failed (during download) ' + xml.status, xml._uploader.url);1\n xml._uploader.reset();\n }\n }\n }\n xml.open('GET', this.url, true);\n xml.send('');\n },\n loadAndUpload: function() {\n if (isHttp()) {\n this.loadRemote();\n } else {\n this.loadLocal();\n }\n },\n upload: function() {\n if (readOnly) return;\n if (this.uploading) {\n displayMessage("Upload in progress - please wait");\n return;\n }\n this.url = txtDAVURL;\n if (this.url == null || this.url == "") {\n alert("No DAV URL specified !\sn\sn" +\n"Maybe you need to add a tiddler with the correct txtDAVURL:\sn");\n return;\n }\n this.uploading = true;\n this.loadAndUpload();\n },\n doUpload: function(content) {\n if (content == null) return;\n content = this.reviseStore(content);\n displayMessage("Uploading " + content.length + " bytes to " + this.url);\n var xml = this.xmlhttprequest();\n xml._uploader = this;\n xml.onreadystatechange = function() {\n //displayMessage("Upload-State " + xml.readyState);\n if (xml.readyState == 4) {\n if (xml.status == 201 || xml.status == 204) {\n displayMessage("Uploaded", this.url);\n store.setDirty(false);\n } else {\n displayMessage("Upload failed " + xml.status, xml._uploader.url);\n }\n xml._uploader.reset();\n }\n }\n if (!isHttp()) {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n }\n xml.open('PUT', this.url, true);\n xml.send(content);\n },\n reviseStore: function(original) {\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 alert(config.messages.invalidFileError.format([localPath]));\n return;\n }\n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n convertUnicodeToUTF8(allTiddlersAsHtml()) + "\sn\st\st" +\n original.substr(posClosingDiv);\n var newSiteTitle = store.getTiddlerText("SiteTitle","TiddlyWiki").htmlEncode();\n revised = revised.replace(new RegExp("<title>[^<]*</title>", "im"),"<title>"+ newSiteTitle +"</title>");\n return revised;\n },\n onClick: function() {\n clearMessage();\n this.upload();\n },\n}\nvar davSaver = new DAVSaver();\n\nversion.extensions.saveChangesToDAV = {major: 0, minor: 2, revision: 1, date: new Date(2005,9,9)};\n\nif (isHttp() && (txtDAVURL == null || txtDAVURL == "")) {\n txtDAVURL = document.location.href;\n}\n\nconfig.macros.saveChangesToDAV = {\n label: "save to dav",\n prompt: "Save all tiddlers to create a new TiddlyWiki to DAV"\n}\n\nconfig.macros.saveChangesToDAV.handler = function(place) {\n if(!readOnly)\n createTiddlyButton(place,this.label,this.prompt, function() { davSaver.onClick() });\n}\n\n/** Override */\n\nconfig.messages.unsavedChangesWarningDAV = "Would you like to save changes to DAV ?";\n\nconfig.macros.option.handler = function(place,macroName,params)\n{\n var opt = params[0];\n if(config.options[opt] == undefined)\n return;\n var size = params[1] || 15; // configure size\n var c;\n switch(opt.substr(0,3))\n {\n case "txt":\n c = document.createElement("input");\n c.onkeyup = this.onChangeOption;\n c.setAttribute("option",opt);\n c.size = size; // configure size\n c.value = config.options[opt];\n place.appendChild(c);\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 c.checked = config.options[opt];\n place.appendChild(c);\n break;\n }\n}\n\nfunction convertUnicodeToUTF8(s)\n{\n if(saveUsingSafari)\n return s;\n/* This does not work remotely!\n else if(window.Components)\n return mozConvertUnicodeToUTF8(s);\n*/\n else\n return manualConvertUnicodeToUTF8(s);\n}\n\n/*\n}}}\n*/
/***\n''SearchOptionsPlugin for TiddlyWiki version 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#SearchOptionsPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nThe TiddlyWiki search function normally looks in both tiddler titles and tiddler body content ('text'). However, narrowing the search so that it examines only titles or only text, or expanding the search to include text contained in tiddler tags can be very helpful, especially when searching on common words or phrases. In addition, it is often useful for the search results to show tiddlers with matching titles before tiddlers that contain matching text or tags.\n\n!!!!!Usage\n<<<\nThis plugin adds checkboxes (see below and in AdvancedOptions) to let you selectively configure the TiddlyWiki search function to just examine any combination of tiddler titles, text, or tags. It also provides an option to switch the search results order between 'titles mixed in' (default) and 'titles shown first', as well as an option display the search results as a list of links (in an auto-generated "SearchResults" tiddler), rather than actually displaying all matching tiddlers. You can also enable/disable the "incremental search" (key-by-key searching), so that a search is only initiated when you press the ENTER key or click on the "search:" prompt text.\n<<<\n!!!!!Configuration\n<<<\nIn additional to the checkboxes in AdvancedOptions, a self-contained control panel is included here for your convenience:\n<<option chkSearchTitles>> Search tiddler titles\n<<option chkSearchText>> Search tiddler text\n<<option chkSearchTags>> Search in tiddler tags\n<<option chkSearchTitlesFirst>> Show title matches first\n<<option chkSearchList>> Show list of matching tiddlers\n<<option chkSearchIncremental>> Incremental searching\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''SearchOptionsPlugin'' (tagged with <<tag systemConfig>>)\n^^documentation and javascript for SearchOptionsPlugin handling^^\n\nWhen installed, this plugin automatically adds checkboxes in the AdvancedOptions shadow tiddler so you can enable/disable the extended search behavior. However, if you have customized your AdvancedOptions, you will need to manually add {{{<<option chkSearchTitles>>}}}, {{{<<option chkSearchText>>}}} and {{{<<option chkSearchTitlesFirst>>}}} (with suitable prompt text) to your customized tiddler.\n<<<\n!!!!!Revision History\n<<<\n''2006.02.03 [2.2.1]''\nrewrite timeout clearing code and blank search text handling to match 2.0.4 core release changes. note that core no longer permits "blank=all" searches, so neither does this plugin. To search for all, use "." with text patterns enabled.\n''2006.02.02 [2.2.0]''\nin search.handler(), KeyHandler() function clears 'left over' timeout when search input is < 3 chars. Prevents searching on shorter text when shortened by rapid backspaces (<500msec)\n''2006.02.01 [2.1.9]''\nin Story.prototype.search(), correct inverted logic for using/not using regular expressions when searching\nalso, blank search text now presents "No search text. Continue anyway?" confirm() message box, so search on blank can still be processed if desired by user.\n''2006.02.01 [2.1.8]''\nin doSearch(), added alert/return if search text is blank\n''2006.01.20 [2.1.7]''\nfixed setting of config.macros.search.reportTitle so that Tweaks can override it.\n''2006.01.19 [2.1.6]''\nimproved SearchResults formatting, added a "search again" form to the report (based on a suggestion from MorrisGray)\ndefine results report title using config.macros.search.reportTitle instead of hard-coding the tiddler title\n''2006.01.18 [2.1.5]''\nCreated separate functions for reportSearchResults(text,matches) and discardSearchResults(), so that other developers can create alternative report generators.\n''2006.01.17 [2.1.4]''\nUse regExp.search() instead of regExp.test() to scan for matches. Correctd the problem where only half the matching tiddlers (the odd-numbered ones) were being reported.\n''2006.01.15 [2.1.3]''\nAdded information (date/time, username, search options used) to SearchResults output\n''2006.01.10 [2.1.2]''\nuse displayTiddlers() to render matched tiddlers. This lets you display multiple matching tiddlers, even if SinglePageModePlugin is enabled.\n''2006.01.08 [2.1.1]''\ncorrected invalid variable reference, "txt.value" to "text" in story.search()\n''2006.01.08 [2.1.0]''\nre-write to match new store.search(), store.search.handler() and story.search() functions.\n''2005.12.30 [2.0.0]''\nUpgraded to TW2.0\nwhen rendering SearchResults tiddler, closeTiddler() first to ensure display is refreshed.\n''2005.12.26 [1.4.0]''\nadded option to search for matching text in tiddler tags\n''2005.12.21 [1.3.7]''\nuse \s\s to 'escape' single quotes in tiddler titles when generating "Open all matching tiddlers" link. Also, added access key: "O", to trigger "open all" link.\nBased on a suggestion by UdoBorkowski.\n''2005.12.18 [1.3.6]''\ncall displayMessage() AFTER showing matching tiddlers so message is not cleared too soon\n''2005.12.17 [1.3.5]''\nif no matches found, just display message and delete any existing SearchResults tiddler.\n''2005.12.17 [1.3.4]''\nuse """{{{""" and """}}}""" to 'escape' display text in SearchResults tiddler to ensure that formatting contained in search string is not rendered \nBased on a suggestion by UdoBorkowski.\n''2005.12.14 [1.3.3]''\ntag SearchResults tiddler with 'excludeSearch' so it won't list itself in subsequent searches\nBased on a suggestion by UdoBorkowski.\n''2005.12.14 [1.3.2]''\nadded "open all matching tiddlers..." link to search results output.\nBased on a suggestion by UdoBorkowski.\n''2005.12.10 [1.3.1]''\nadded "discard search results" link to end of search list tiddler output for quick self-removal of 'SearchResults' tiddler.\n''2005.12.01 [1.3.0]''\nadded chkSearchIncremental to enable/disable 'incremental' searching (i.e., search after each keystroke) (default is ENABLED).\nadded handling for Enter key so it can be used to start a search.\nBased on a suggestion by LyallPearce\n''2005.11.25 [1.2.1]''\nrenamed from SearchTitleOrTextPlugin to SearchOptionsPlugin\n''2005.11.25 [1.2.0]''\nadded chkSearchList option\nBased on a suggestion by RodneyGomes\n''2005.10.19 [1.1.0]''\nadded chkSearchTitlesFirst option.\nBased on a suggestion by ChristianHauck\n''2005.10.18 [1.0.0]''\nInitial Release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].\nBased on a suggestion by LyallPearce.\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.SearchTitleOrText = {major: 2, minor: 2, revision: 1, date: new Date(2006,2,3)};\n//}}}\n\n//{{{\nif (config.options.chkSearchTitles==undefined) config.options.chkSearchTitles=true;\nif (config.options.chkSearchText==undefined) config.options.chkSearchText=true;\nif (config.options.chkSearchTags==undefined) config.options.chkSearchTags=true;\nif (config.options.chkSearchTitlesFirst==undefined) config.options.chkSearchTitlesFirst=false;\nif (config.options.chkSearchList==undefined) config.options.chkSearchList=false;\nif (config.options.chkSearchIncremental==undefined) config.options.chkSearchIncremental=true;\n\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkSearchTitles>> Search in tiddler titles";\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkSearchText>> Search in tiddler text";\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkSearchTags>> Search in tiddler tags";\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkSearchTitlesFirst>> Search results show title matches first";\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkSearchList>> Search results show list of matching tiddlers";\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkSearchIncremental>> Incremental searching";\n//}}}\n\n//{{{\nif (config.macros.search.reportTitle==undefined)\n config.macros.search.reportTitle="SearchResults";\n//}}}\n\n//{{{\nconfig.macros.search.handler = function(place,macroName,params)\n{\n var lastSearchText = "";\n var searchTimeout = null;\n var doSearch = function(txt)\n {\n if (txt.value.length>0)\n {\n story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);\n lastSearchText = txt.value;\n }\n };\n var clickHandler = function(e)\n {\n doSearch(this.nextSibling);\n return false;\n };\n var keyHandler = function(e)\n {\n if (!e) var e = window.event;\n switch(e.keyCode)\n {\n case 13: // ELS: handle enter key\n doSearch(this);\n break;\n case 27:\n this.value = "";\n clearMessage();\n break;\n }\n if (config.options.chkSearchIncremental)\n {\n if(this.value.length > 2)\n {\n if(this.value != lastSearchText)\n {\n if(searchTimeout) clearTimeout(searchTimeout);\n var txt = this;\n searchTimeout = setTimeout(function() {doSearch(txt);},500);\n }\n }\n else\n if(searchTimeout) clearTimeout(searchTimeout);\n }\n };\n var focusHandler = function(e)\n {\n this.select();\n };\n var btn = createTiddlyButton(place,this.label,this.prompt,clickHandler);\n var txt = createTiddlyElement(place,"input",null,null,null);\n if(params[0])\n txt.value = params[0];\n txt.onkeyup = keyHandler;\n txt.onfocus = focusHandler;\n txt.setAttribute("size",this.sizeTextbox);\n txt.setAttribute("accessKey",this.accessKey);\n txt.setAttribute("autocomplete","off");\n if(config.browser.isSafari)\n {\n txt.setAttribute("type","search");\n txt.setAttribute("results","5");\n }\n else\n txt.setAttribute("type","text");\n}\n//}}}\n\n//{{{\nStory.prototype.search = function(text,useCaseSensitive,useRegExp)\n{\n highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");\n var matches = store.search(highlightHack,"title","excludeSearch");\n var q = useRegExp ? "/" : "'";\n clearMessage();\n if (!matches.length) {\n if (config.options.chkSearchList) discardSearchResults();\n displayMessage(config.macros.search.failureMsg.format([q+text+q]));\n } else {\n if (config.options.chkSearchList) \n reportSearchResults(text,matches);\n else {\n var titles = []; for(var t=0; t<matches.length; t++) titles.push(matches[t].title);\n this.closeAllTiddlers(); story.displayTiddlers(null,titles);\n displayMessage(config.macros.search.successMsg.format([matches.length, q+text+q]));\n }\n }\n highlightHack = null;\n}\n//}}}\n\n//{{{\nTiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag)\n{\n var candidates = this.reverseLookup("tags",excludeTag,false,sortField);\n\n // scan for matching titles\n var title_results = [];\n if (config.options.chkSearchTitles)\n for(var t=0; t<candidates.length; t++)\n if(candidates[t].title.search(searchRegExp)!=-1)\n title_results.push(candidates[t]);\n\n // scan for matching text\n var text_results = [];\n if (config.options.chkSearchText)\n for(var t=0; t<candidates.length; t++)\n if(candidates[t].text.search(searchRegExp)!=-1)\n text_results.push(candidates[t]);\n\n // scan for matching tags\n var tag_results = [];\n if (config.options.chkSearchTags)\n for(var t=0; t<candidates.length; t++)\n if(candidates[t].tags.join(" ").search(searchRegExp)!=-1)\n tag_results.push(candidates[t]);\n\n // merge the results, eliminating redundant matches\n var results = [];\n for(var t=0; t<title_results.length; t++) results.pushUnique(title_results[t]);\n for(var t=0; t<text_results.length; t++) results.pushUnique(text_results[t]);\n for(var t=0; t<tag_results.length; t++) results.pushUnique(tag_results[t]);\n\n // if not 'titles first', re-sort results to so titles, text and tag matches are mixed together\n if(!sortField) sortField = "title";\n var bySortField=function (a,b) {if(a[sortField] == b[sortField]) return(0); else return (a[sortField] < b[sortField]) ? -1 : +1; }\n if (!config.options.chkSearchTitlesFirst) results.sort(bySortField);\n return results;\n}\n//}}}\n\n// // ''REPORT GENERATOR''\n//{{{\nif (!window.reportSearchResults) window.reportSearchResults=function(text,matches)\n{\n var title=config.macros.search.reportTitle\n var q = config.options.chkRegExpSearch ? "/" : "'";\n var body="";\n\n // summary: nn tiddlers found matching '...', options used\n body+="''"+config.macros.search.successMsg.format([matches.length,q+"{{{"+text+"}}}"+q])+"''\sn";\n body+="^^//searched in:// ";\n body+=(config.options.chkSearchTitles?"''titles'' ":"");\n body+=(config.options.chkSearchText?"''text'' ":"");\n body+=(config.options.chkSearchTags?"''tags'' ":"");\n if (config.options.chkCaseSensitiveSearch||config.options.chkRegExpSearch) {\n body+=" //with options:// ";\n body+=(config.options.chkCaseSensitiveSearch?"''case sensitive'' ":"");\n body+=(config.options.chkRegExpSearch?"''text patterns'' ":"");\n }\n body+="^^";\n\n // numbered list of links to matching tiddlers\n body+="\sn<<<";\n for(var t=0;t<matches.length;t++) body+="\sn# [["+matches[t].title+"]]";\n body+="\sn<<<\sn";\n\n // open all matches button\n body+="<html><input type=\s"button\s" href=\s"javascript:;\s" ";\n body+="onclick=\s"story.displayTiddlers(null,["\n for(var t=0;t<matches.length;t++)\n body+="'"+matches[t].title.replace(/\s'/mg,"\s\s'")+"'"+((t<matches.length-1)?", ":"");\n body+="],1);\s" ";\n body+="accesskey=\s"O\s" ";\n body+="value=\s"open all matching tiddlers\s"></html> ";\n\n // discard search results button\n body+="<html><input type=\s"button\s" href=\s"javascript:;\s" ";\n body+="onclick=\s"story.closeTiddler('"+title+"'); store.deleteTiddler('"+title+"');\s" ";\n body+="value=\s"discard "+title+"\s"></html>";\n\n // search again\n body+="\sn\sn----\sn";\n body+="<<search \s""+text+"\s">> ";\n body+="<<option chkSearchTitles>>titles ";\n body+="<<option chkSearchText>>text ";\n body+="<<option chkSearchTags>>tags";\n body+="<<option chkCaseSensitiveSearch>>case-sensitive ";\n body+="<<option chkRegExpSearch>>text patterns";\n\n // create/update the tiddler\n var tiddler=store.getTiddler(title); if (!tiddler) tiddler=new Tiddler();\n tiddler.set(title,body,config.options.txtUserName,(new Date()),"excludeLists excludeSearch");\n store.addTiddler(tiddler); story.closeTiddler(title);\n\n // use alternate "search again" label in <<search>> macro\n var oldprompt=config.macros.search.label;\n config.macros.search.label="search again";\n\n // render tiddler\n story.displayTiddler(null,title,1); // force refresh\n\n // restore standard search label\n config.macros.search.label=oldprompt;\n\n}\n\nif (!window.discardSearchResults) window.discardSearchResults=function()\n{\n // remove the tiddler\n story.closeTiddler(config.macros.search.reportTitle);\n store.deleteTiddler(config.macros.search.reportTitle);\n}\n//}}}\n\n\n
/***\n''Select Stylesheet Plugin for TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#SelectStylesheetPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nSelect alternative TiddlyWiki CSS stylesheet 'themes' from a list of tiddlers tagged with "stylesheets".\n\n!!!!!Usage\n<<<\nThis plugin defines a macro that creates a stylesheet selection listbox/droplist that can be added to the content of any tiddler (such as the OptionsPanel or MainMenu tiddlers).\n\nFirst, create (or import) a custom style sheet tiddler (i.e, a tiddler containing CSS definitions) and tag it with <<tag stylesheets>> so it will appear in the selection list. Then, add the {{{<<selectStylesheet>>}}} macro to the desired tiddler to display the stylesheet list. Select your desired stylesheet from the droplist:\n** ''[none]'' bypasses all stylesheet tiddlers\n** ''[system]'' uses the built-in CSS definitions\n** ''[default]'' uses "StyleSheet" tiddler (if present)\n** //tiddlername// uses any named stylesheet\nThe currently selected stylesheet is indicated by a '>' symbol.\n\n//Note: If a previously selected stylesheet tiddler no longer exists (i.e, the tiddler was deleted or renamed after it had been selected for use), the [default] CSS tiddler ("StyleSheet") will be used as a fallback. If this tiddler does not exist either, then the built-in CSS definitions are used.//\n<<<\n!!!!!Parameters\n<<<\nThe selectStylesheet macro accepts parameters to control various features and functions. //Note: while each parameter is optional and may be omitted from the macro, the parameters (when present) must appear in the order shown below.//\n* ''size:nnn''\nDetermines the number of lines to display in the stylesheet list. If this parameter is omitted or "size:1" is specified, a single-line droplist is created. When a size > 1 is provided, a standard, fixed-size scrollable listbox is created. You can use "size:0" or "size:auto" to display a varible-height listbox that automatically adjusts to fit the current list contents without scrolling.\n* ''width:nnn[cm|px|em|%]''\nControls the width of the stylesheet list. Overrides the built-in CSS width declaration (=100%). Use standard CSS width units (cm=centimeters, px=pixels, em=M-space, %=proportional to containing area). You can also use a ".selectStylesheet" custom CSS class definition to override the built-in CSS declarations for the stylesheet list.\n<<<\n!!!!!Nested Stylesheets\n<<<\nThe CSS definitions for TiddlyWiki are fairly substantial, and stylesheet tiddlers can include hundreds of lines of CSS statements. Often, these stylesheets will use the exact same CSS for the bulk of their definitions plus several changes or additions to create a difference in appearance. This results in lots of duplicated CSS definitions that can become difficult to keep 'in sync' with each other.\n\nTo make this problem much easier to manage, you can move the common CSS definitions into separate stylesheet tiddlers. Then, embed {{{[[tiddlertitle]]}}} references in the original stylesheet tiddlers to re-combine the CSS definitions into a single stylesheet 'theme' to be applied.\n\nWith some clever division of CSS into separate tiddlers, you can quite easily construct dozens of stylesheet combinations. You can also mark the common CSS tiddlers with tags and use them as overlay stylesheets so you can mix-and-match their styles to create even more 'on-the-fly' stylesheet combinations.\n\nNote: Normally, when rendering tiddler content for display, the {{{[[tiddlertitle]]}}} syntax means "insert a link to this tiddler". However, when applying stylesheets, this syntax means "insert the content of this tiddler"\n<<<\n!!!!!Changing templates or invoking custom javascript from a stylesheet\n<<<\nIn addition to CSS definitions, some TiddlyWiki look-and-feel designs also make adjustments to the TiddlyWiki document structure so that certain document features can be moved, hidden, or otherwise redefined. The default set of templates that control the document structure are called PageTemplate, ViewTemplate, and EditTemplate. To select an alternative set of templates, you can include the special psuedo-macro ''{{{<<template prefix>>}}}'' in your stylesheet. This adds the indicated prefix to the standard template names, and automatically switches to using those templates whenever the stylesheet is selected and applied.\n\nWhenever a document is being viewed in read-only mode (i.e., via http: protocol), an implied template prefix of "Web" is also used, and is inserted between any custom template prefix and the standard template name. For example, ''{{{<<template Custom>>}}}'' will use {{{CustomWebViewTemplate}}} when the document is in read-only mode. You can specify an alternative for this implied prefix by including a second prefix parameter in the pseudo-macro. For example, ''{{{<<template Custom ReadOnly>>}}}'' will use {{{CustomReadOnlyViewTemplate}}}. Note: if a template tiddler with the indicated combination of custom and read-only prefixes is not available, a suitable fallback template is chosen, first by omitting the custom prefix, then by omitting the read-only prefix, and finally by omitting both, and reverting to the appropriate default template.\n\nIn addition to selecting alternative templates, a stylesheet can also include the psuedo-macro ''{{{<<init tiddlertitle>>}}}'' to execute custom javascript that can access TiddlyWiki internal data and 'core' functions or perform direct manipulation of the currently-rendered DOM elements of the document. First, place the desired javascript code into one or more tiddlers (note: //although these tiddlers will contain javascript, ''do NOT tag them as 'systemConfig', since this will cause the javascript to be executed every time TW starts'', rather than only when a specific stylesheet has been selected//). Then, add the ''{{{<<init tiddlertitle>>}}}'' pseudo-macro to your stylesheet so the javascript will be executed when that specific stylesheet is selected and applied.\n\nOf course, when another stylesheet is subsequently selected, other custom javascript functions may be needed to reset whatever TW internal data changes or DOM manipulations were performed by any {{{<<init>>}}} scripts. You can define tiddlers containing these ''reset'' scripts by embedding ''{{{<<reset tiddlertitle>>}}}'' in your stylesheet definition. Unlike {{{<<init>>}}} scripts, any tiddlers declared in this way will NOT be executed when the stylesheet is applied, but will be remembered and automatically executed before applying another stylesheet.\n\nNote: These special-purpose psuedo-macros are only executed when the stylesheet containing them is actually in use. When these macros are rendered as part of the tiddler content (such as when //viewing// a stylesheet definition), the macros simply report their values without performing any actions.\n<<<\n!!!!!Examples\n<<<\n^^single auto-sized listbox^^\n<<selectStylesheet size:auto width:60%>>\n^^droplist for stylesheets^^\n<<selectStylesheet size:1 width:30%>>\n^^stylesheet definitions (tagged with "stylesheets"):^^\n<<tag stylesheets>>\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''SelectStylesheetPlugin'' (tagged with <<tag systemConfig>>)\n^^documentation and javascript for SelectStylesheethandling^^\n\ncreate/edit ''OptionsPanel'':\nAdd "{{{<<selectStylesheet [size:nnn|auto] [width:nnn[cm|px|em|%]>>}}}" macro.\n<<<\n!!!!!Revision History\n<<<\n''2006.02.25 [4.1.3]''\nProblem: the ">" indicator was not always being refreshed, due to event "timing" issues. refreshSelectStylesheet() deferred for 10msec so it will execute *after* onChangeSelectStylesheet event processing has completed.\n''2006.02.24 [4.1.2]''\nProblem: """<<template>>""" macro was not being processed in IE.\nCause: regexp processing creates browser-internal "private globals" used to keep track of the regexp parser's state, including the current 'scan' position within the source string. This lets you use search() and exec() inside loops to scan for successive pattern matches. In applyStyleSheet(), "theCSS.search(templateRegExp)" was called before "theCSS.exec(templateRegExp)". As a result, the regexp parser had already matched the """<<template>>""" macro embedded in the CSS and thus did not actually process the macro and switch the templates.\nFix: use """indexOf("<<template")""" instead of search(templateRegExp) to check for presence of template switching macro in CSS.\n''2006.02.23 [4.1.1]''\nperformance fixes: in switchTemplates(), added default init of 'altTemplate' value to prevent unneeded triggering of refreshPageTemplate() during TW load-time when using standard templates. Saves LOTS of startup time and avoids the dreaded "script is running slowly" FireFox warnings.\nAlso, the forEachTiddler() call to force a "refresh all tiddlers" (needed when view/edit templates are changed) was moved from applyPageTemplate() and is now called directly from switchTemplates(). This eliminates redundant re-rendering of tiddlers while the page template is being refreshed.\n''2006.02.21 [4.1.0]''\nadded """<<template>>""" pseudo-macro with new switchTemplate() function. Allows stylsheets to switch page/view/edit templates by adding a prefix to standard template names. Detects readOnly mode and automatically adds "Web" to template name (e.g. "MyWebViewTemplate"). Defines "Web" shadow templates and "viewSource" toolbar command.\n''2006.02.21 [4.0.3]''\nadded real macro handlers for psuedo-macros "init", "reset" so they will display in the stylesheet tiddler without appearing as an error.\n''2006.01.20 [4.0.2]''\nadd 'var' to unintended global variable declarations and wrapped notification hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals\n''2006.01.20 [4.0.1]''\nAdded optional "init" keyword for {{{<<init tiddlertitle>>}}} psuedo-macro syntax (note: previous {{{<<tiddlertitle>>}}} syntax still permitted)\nRevised documentation to better describe use of init/reset for custom code invokation.\n''2005.11.05 [4.0.0]''\nEntire plugin simplified in response to new "shadow stylesheet" architecture introduced in TW1.2.37. Concept of separate overlays has been removed. Stylesheet themes are assembled using [[tiddler]] 'nesting' syntax, and tagged as 'stylesheet'. A single listbox/droplist is provided to select themes.\n''2005.10.25 [3.1.0]''\nadded support for embedding {{{<<reset tiddlertitle>>}}} companion code (to declare 'DOM cleanup' routines invoked when a stylesheet is UNloaded)\n//Based on a request from ClintChecketts//\n''2005.10.09 [3.0.1]''\ncombined documentation and code in a single tiddler\n''2005.08.15 [3.0.0]''\nAnother major re-write. Replaced separate "selectOverlays" macro definition with 'overlays' parameter on 'selectStylesheet' macro. Added support for embedding {{{<<tiddlertitle>>}}} companion code. applyStylesheets() completely re-designed to address quirks with loading and combining multiple stylesheets using browser-specific native handling, as well as add support for executing companion code. Stylesheets+overlays+code are now handled in a platform-neutral manner that avoids differences between browser implementations and uses much less overhead in the DOM.\n''2005.08.07 [2.0.0]''\nMajor re-write to not use static ID values for listbox controls, so that multiple macro instances can exist without corrupting each other or the DOM. Moved HTML and CSS definitions into plugin code instead of using separate tiddlers. Added new features: support for multiple groups of overlay stylesheets with collapsible tree display. Added size and width params for listbox display.\n''2005.07.27 [1.0.3]''\ncore update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet()\n''2005.07.25 [1.0.2]''\ncorrect 'fallback' handling in selectStyleSheet()\n''2005.07.23 [1.0.1]''\nadded parameter checks and corrected addNotification() usage\n''2005.07.20 [1.0.0]''\nInitial Release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]. Thanks to David Jaquith for testing and bug reports and SteveRumsby for feature suggestions.\n<<<\n!!!!!Code\n***/\n// // 1.2.x compatibility\n//{{{\nif (!window.story) window.story=window;\nif (!store.getTiddler) store.getTiddler=function(title){return store.tiddlers[title]}\nif (!store.addTiddler) store.addTiddler=function(tiddler){store.tiddlers[tiddler.title]=tiddler}\nif (!store.deleteTiddler) store.deleteTiddler=function(title){delete store.tiddlers[title]}\n//}}}\n\n//{{{\nversion.extensions.selectStylesheet = {major: 4, minor: 1, revision: 3, date: new Date(2006,2,25)};\n\n// IE needs explicit global scoping for functions/vars called from browser events\nwindow.onChangeSelectStylesheet=onChangeSelectStylesheet;\nwindow.refreshSelectStylesheet=refreshSelectStylesheet;\nwindow.applyStylesheets=applyStylesheets;\n\nif (!config.options.txtStyleSheet) config.options.txtStyleSheet="StyleSheet";\n//}}}\n\n//{{{\n// define macro rendering handler\nconfig.macros.selectStylesheet = { };\nconfig.macros.selectStylesheet.reset = [];\nconfig.macros.selectStylesheet.handler = function(place,macroName,params) {\n setStylesheet(".selectStylesheet {width:100%;font-size:8pt;margin:0em}","selectStylesheetPlugin");\n var theList=createTiddlyElement(place,"select",null,"selectStylesheet",null);\n theList.onchange=onChangeSelectStylesheet;\n theList.size=1;\n theList.autosize=1;\n if (params[0] && (params[0]=="size:auto")) { theList.autosize=0; params.shift(); }\n if (params[0] && (params[0].substr(0,5)=="size:")) theList.autosize=(params.shift()).substr(5);\n if (params[0] && (params[0].substr(0,6)=="width:")) theList.style.width=(params.shift()).substr(6);\n theList.extraStyles=params;\n store.addNotification(null,refreshSelectStylesheet);\n refreshSelectStylesheet();\n}\n// set to TRUE to enable debugging status messages when stylesheets are applied\nconfig.macros.selectStylesheet.verbose = false;\n\n// hijack existing notifications for refreshStyles() handler\ninitSelectStylesheetNotification();\nfunction initSelectStylesheetNotification() {\n for (var i=0; i<store.namedNotifications.length; i++)\n if (store.namedNotifications[i].notify==window.refreshStyles)\n store.namedNotifications[i].notify=applyStylesheets;\n}\n\n// hijack refreshStyles() handler\nwindow.refreshStyles=applyStylesheets;\n\nfunction onChangeSelectStylesheet()\n{\n if (this.value=="") return;\n config.options.txtStyleSheet=this.value;\n saveOptionCookie("txtStyleSheet");\n applyStylesheets();\n setTimeout("refreshSelectStylesheet()",10); // delay until after event handler returns\n return;\n}\n\nfunction getElementsByClass(classname)\n{\n var arr=new Array();\n var count=0;\n var all=document.all? document.all : document.getElementsByTagName("*");\n for (var i=0; i<all.length; i++)\n if (all[i].className==classname)\n arr[count++]=all[i];\n return arr;\n}\n\nfunction refreshSelectStylesheet()\n{\n var indent = String.fromCharCode(160)+String.fromCharCode(160)+String.fromCharCode(160);\n // for all instances of the selectStylesheet control\n var allStyleLists=getElementsByClass("selectStylesheet");\n for (var k=0; k<allStyleLists.length; k++) {\n var theList=allStyleLists[k];\n // clear current list contents\n while (theList.length > 0) { theList.options[0] = null; }\n theList.selectedIndex=-1;\n // fill the stylesheet list\n var count=0;\n // prompt text\n theList.options[count++] = new Option("select a stylesheet:","",false,false);\n // option: none (built-in hard-coded CSS only)\n theList.options[count++] = new Option(indent+"[none]","[none]",false,false);\n // option: default (built-in plus shadow stylesheets)\n theList.options[count++] = new Option(indent+"[system]","[system]",false,false);\n // option: StyleSheet tiddler, if present\n if (store.getTiddler("StyleSheet")!=undefined)\n theList.options[count++] = new Option(indent+"[default]","StyleSheet",false,false);\n // options: CSS tiddlers tagged with "stylesheets"\n var theSheets=store.getTaggedTiddlers("stylesheets");\n for (var i=0; i<theSheets.length; i++) {\n var theTitle=theSheets[i].title;\n if (theTitle=="StyleSheet") continue;\n theList.options[count++] = new Option(indent+theTitle,theTitle,false,false);\n }\n // set the listbox selection to current stylesheet\n theList.selectedIndex=0; // default to first item\n for (var t=0; t<theList.options.length; t++) \n if (theList.options[t].value==config.options.txtStyleSheet)\n { theList.selectedIndex=t; break; }\n theList.options[t].text=">"+theList.options[t].text.substr(2);\n // autosize as appropriate\n theList.size=(theList.autosize<1)?theList.options.length:theList.autosize;\n } // end of "for all instances"\n}\n//}}}\n\n//{{{\nconfig.macros.selectStylesheet.templates = { };\nfunction switchTemplates(which,readOnlyPrefix)\n{\n // remember original templates (init only)\n if (!config.macros.selectStylesheet.templates.originalpage)\n config.macros.selectStylesheet.templates.originalpage = "PageTemplate";\n if (!config.macros.selectStylesheet.templates.originalview)\n config.macros.selectStylesheet.templates.originalview = config.tiddlerTemplates[1];\n if (!config.macros.selectStylesheet.templates.originaledit)\n config.macros.selectStylesheet.templates.originaledit = config.tiddlerTemplates[2];\n if (!config.macros.selectStylesheet.altTemplate)\n config.macros.selectStylesheet.altTemplate="";\n\n // define shorthand variables just for code readability \n var page=config.macros.selectStylesheet.templates.originalpage;\n var view=config.macros.selectStylesheet.templates.originalview;\n var edit=config.macros.selectStylesheet.templates.originaledit;\n\n // get 'readOnly' mode... set by TW core, but not until after the plugin is loaded, so we need to do this here as well...\n var loc = document.location.toString();\n if (readOnly==undefined)\n var readOnly = (loc.substr(0,4) == "http" || loc.substr(0,3) == "ftp") ? config.options.chkHttpReadOnly : false;\n\n // get prefix defaults\n if (!which) var which="";\n if (!readOnlyPrefix) var readOnlyPrefix = "Web";\n if (!readOnly) readOnlyPrefix="";\n var alt = which+readOnlyPrefix;\n\n var msg="current template prefix: '%0', requested template prefix '%1'";\n if (config.macros.selectStylesheet.verbose) alert(msg.format([config.macros.selectStylesheet.altTemplate,alt]));\n\n // only switch if really changing templates\n if (alt == config.macros.selectStylesheet.altTemplate) return;\n\n // remember which templates are being used\n config.macros.selectStylesheet.altTemplate = alt;\n\n // set page template, with fallbacks for missing combinations\n var pageTemplate=alt+page;\n if (!store.getTiddlerText(pageTemplate)) pageTemplate=which+page;\n if (!store.getTiddlerText(pageTemplate)) pageTemplate=readOnlyPrefix+page;\n if (!store.getTiddlerText(pageTemplate)) pageTemplate=page;\n config.macros.selectStylesheet.templates.currentpage = pageTemplate;\n\n // set view template, with fallbacks for missing combinations\n var viewTemplate=alt+view;\n if (!store.getTiddlerText(viewTemplate)) viewTemplate=which+view;\n if (!store.getTiddlerText(viewTemplate)) viewTemplate=readOnlyPrefix+view;\n if (!store.getTiddlerText(viewTemplate)) viewTemplate=view;\n config.tiddlerTemplates[1] = config.macros.selectStylesheet.templates.currentview = viewTemplate;\n\n // set edit template, with fallbacks for missing combinations\n var editTemplate=alt+edit;\n if (!store.getTiddlerText(editTemplate)) editTemplate=which+edit;\n if (!store.getTiddlerText(editTemplate)) editTemplate=readOnlyPrefix+edit;\n if (!store.getTiddlerText(editTemplate)) editTemplate=edit;\n config.tiddlerTemplates[2] = config.macros.selectStylesheet.templates.currentedit = editTemplate;\n\n var msg="switching to templates: %0, %1, %2";\n if (config.macros.selectStylesheet.verbose) alert(msg.format([pageTemplate,viewTemplate,editTemplate]));\n\n // apply page template\n window.applyPageTemplate();\n // apply view/edit templates\n story.forEachTiddler(function(title,element) { this.refreshTiddler(title,null,true);});\n\n}\n\n// Hijack the applyPageTemplate so the alternate page template (if any) will refresh correctly\nconfig.macros.selectStylesheet.coreApplyPageTemplate = window.applyPageTemplate;\nwindow.applyPageTemplate = function(template)\n{\n var cw=document.getElementById("contentWrapper");\n cw.style.display="none";\n config.macros.selectStylesheet.coreApplyPageTemplate(config.macros.selectStylesheet.templates.currentpage);\n cw.style.display="block";\n}\n\n// define "viewSource" toolbar command for use in read-only templates\nconfig.commands.viewSource = {text: "source", tooltip: "View this tiddler's wiki markup"},\nconfig.commands.viewSource.handler = function(event,src,title){\n story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);\n var theTiddler = document.getElementById("tiddler"+title);\n var tiddlerElements = theTiddler.getElementsByTagName("textarea")\n for (var i=0; i<tiddlerElements.length; i++) tiddlerElements[i].setAttribute("readonly","readonly");\n if (tiddlerElements.length) { tiddlerElements[0].focus(); tiddlerElements[0].select(); }\n return false;\n}\n\n/* DISABLED - DON'T CREATE SHADOWS - USE DEFAULT TEMPLATES\n// create shadow tiddlers to ensure that read-only views are available...\nconfig.shadowTiddlers['WebPageTemplate'] = store.getTiddlerText("PageTemplate");\nconfig.shadowTiddlers['Web'+config.tiddlerTemplates[1]] = store.getTiddlerText(config.tiddlerTemplates[1]).replace(/\s+editTiddler/,"+viewSource");\nconfig.shadowTiddlers['Web'+config.tiddlerTemplates[2]] = "<!--{{{-->\sn<div class='toolbar' macro='toolbar -cancelTiddler'></div>\sn<div class='title'><span macro='view title'></span> (source code)</div>\sn<div class='editor' macro='edit text'></div>\sn<!--}}}-->\sn";\n*/\n\n//}}}\n\n//{{{\nfunction applyStylesheets()\n{\n // define pattern to match executable <<tiddlername>> references embedded in CSS text\n var setTiddlerRegExp = new RegExp("(?:<<(?:init )([^>]+)>>)","mg");\n var resetTiddlerRegExp = new RegExp("(?:<<reset ([^>]+)>>)","mg");\n var templateRegExp = new RegExp("(?:<<template ([^\ss>]+)( [^>]+)?>>)","mg");\n\n // make sure the requested stylesheet exists, fallback if not...\n var theSheet=config.options.txtStyleSheet;\n switch (theSheet) {\n case "[none]":\n case "[system]":\n break;\n default:\n if (!store.getTiddler(theSheet)) theSheet="StyleSheet";\n if (!store.getTiddler(theSheet)) theSheet="[system]";\n break;\n }\n\n // When store.NotifyAll() is invoked, it can trigger multiple calls to applyStylesheets(),\n // even though only one is needed to set the styles and render things properly. The extra calls\n // add unnecessary processing overhead by performing multiple re-rendering of entire TW display,\n // often resulting in "slow script" warnings. To avoid this, we can track the last stylesheet that\n // was applied and only apply the current requested sheet if it is really a different sheet, OR\n // if the TW contents have actually changed (which might include changes to the current stylesheet)\n if (theSheet==config.macros.selectStylesheet.current && !store.dirty) return;\n config.macros.selectStylesheet.current=theSheet;\n\n // get the primary stylesheet CSS\n var msg="stylesheet: '%0'";\n if (config.macros.selectStylesheet.verbose) alert(msg.format([theSheet]));\n var theCSS = (theSheet.substr(0,1)=='[')?"":store.getRecursiveTiddlerText(theSheet,"");\n if (theSheet.substr(0,1)!='[') store.addNotification(theSheet,refreshStyles);\n\n // if <<template>> reference is not specified, reset to standard template\n if (theCSS.indexOf("<<template")==-1) switchTemplates();\n\n // execute any embedded <<template>> references\n do {\n var match = templateRegExp.exec(theCSS);\n if(match && match[1]) switchTemplates(match[1],match[2]);\n } while(match);\n // filter out embedded <<template>> references\n theCSS = theCSS.replace(templateRegExp,"");\n\n // execute any saved stylesheet 'reset' code tiddlers\n while (config.macros.selectStylesheet.reset.length) {\n var tiddler=config.macros.selectStylesheet.reset.shift();\n var msg="stylesheet reset macro: '%0'";\n if (config.macros.selectStylesheet.verbose) alert(msg.format([tiddler]));\n var msg="error in '%0': %1";\n try { window.eval(store.getTiddlerText(tiddler)); }\n catch(e) { displayMessage(msg.format([tiddler,e.toString()])); }\n }\n\n // save embedded <<reset tiddlername>> references\n do {\n var match = resetTiddlerRegExp.exec(theCSS);\n if(match && match[1])\n config.macros.selectStylesheet.reset.push(match[1]);\n } while(match);\n // filter out embedded <<reset tiddlername>> references\n theCSS = theCSS.replace(resetTiddlerRegExp,"");\n\n // execute any embedded <<init tiddlername>> references\n do {\n var match = setTiddlerRegExp.exec(theCSS);\n if(match && match[1]) {\n var msg="stylesheet macro: '%0'";\n if (config.macros.selectStylesheet.verbose) alert(msg.format([match[1]]));\n var msg="error in '%0': %1";\n try { window.eval(store.getTiddlerText(match[1])); }\n catch(e) { displayMessage(msg.format([match[1],e.toString()])); }\n }\n } while(match);\n // filter out embedded <<set tiddlername>> references\n theCSS = theCSS.replace(setTiddlerRegExp,"");\n\n // finally, apply the styles\n switch (theSheet) {\n case "[none]":\n setStylesheet("","StyleSheetColors");\n setStylesheet("","StyleSheetLayout");\n setStylesheet("","StyleSheet");\n break;\n case "[system]":\n setStylesheet(store.getTiddlerText("StyleSheetColors"),"StyleSheetColors");\n setStylesheet(store.getTiddlerText("StyleSheetLayout"),"StyleSheetLayout");\n setStylesheet("","StyleSheet");\n break;\n default:\n setStylesheet("/* overridden by [["+theSheet+"]] */","StyleSheetColors");\n setStylesheet("/* overridden by [["+theSheet+"]] */","StyleSheetLayout");\n setStylesheet(theCSS,"StyleSheet");\n break;\n }\n}\n\nconfig.macros.init = { };\nconfig.macros.init.handler = function(place,macroName,params)\n { var out="init: [[%0]]"; wikify(out.format(params),place); }\nconfig.macros.reset = { };\nconfig.macros.reset.handler = function(place,macroName,params)\n { var out="reset: [[%0]]"; wikify(out.format(params),place); }\nconfig.macros.template = { };\nconfig.macros.template.handler = function(place,macroName,params)\n { var out="use template prefix: ''%0 %1''"; wikify(out.format(params),place); }\n\n//}}}
+++[search]\n <<tiddler SliderHeadline>>__Search__<script>place.style.top="3em";</script>\n <script>config.macros.search.label="find text:"</script><<search>>\n <<option chkSearchTitles>> search titles\n <<option chkSearchText>> search text\n <<option chkSearchTitlesFirst>> show titles first\n <<option chkSearchList>> show list of matches\n <<option chkRegExpSearch>> regular expressions\n <<option chkCaseSensitiveSearch>> case sensitive\n===\n+++[contents]\n <<tiddler SliderHeadline>>__Table of Contents__<script>place.style.top="6em";</script>\n <<tableOfContents "label: " date:YYYY.0MM.0DD width:14em>>\n===\n+++[calendar]\n <<tiddler SliderHeadline>>__Calendar__<script>place.style.top="9em";</script>\n <<calendar thismonth>>[[view entire year...|DocumentCalendarYear]]\n===\n+++[options]\n <<tiddler SliderHeadline>>__Options__<script>place.style.top="15em";</script>\n username:\n <<option txtUserName>><script>var s=place.lastChild.style;s.width="100%";s.fontSize="8pt";\n </script>stylesheets:\n <<selectStylesheet size:1 width:100%>>\n ++++[display]\n <script> var s=place.style; s.backgroundImage="none";\n s.position="static";s.width="15em";s.padding="0.5em";s.backgroundColor="#fff";\n </script><<option chkSinglePageMode>> one tiddler at a time\n <<option chkAnimate>> enable animations\n ===\n ++++[saving]\n <script> var s=place.style; s.backgroundImage="none";\n s.position="static";s.width="15em";s.padding="0.5em";s.backgroundColor="#fff";\n </script><<option chkAutoSave>> auto save changes\n <<option chkSaveBackups>> create backup file\n <<option chkGenerateAnRssFeed>> create RSS feed\n ===\n +++[advanced options...]\n <<tiddler SliderHeadline>>__[[AdvancedOptions]]__\n <script>var s=place.style;s.zIndex=50;s.top="3em";s.right="-2px";s.width="16em";</script>\n <<tiddler AdvancedOptions>>\n ===\n===\n+++[more...]\n <<tiddler SliderHeadline>>__More Functions__<script>place.style.top="18em";</script>\n<<newTiddler>>\n<<attach>>\n<<importTiddlers>>\n<<exportTiddlers>>\n<<saveChanges>>\n<<upload http://perso.enst.fr/~polti/realisations/shix20/doc/store.php index.html back>>\n<<permaview>>\n<<closeAll>>\n===\n+++[lists]\n <<tiddler SliderHeadline>>__Lists__<script>place.style.top="12em";</script>\n <<tiddler SideBarTabs>>\n===
/***\n''Single Page Mode Plugin for TiddlyWiki version 2.0 or above''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#SinglePageModePlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nNormally, as you click on the links in TiddlyWiki, more and more tiddlers are displayed on the page. The order of this tiddler display depends upon when and where you have clicked. Some people like this non-linear method of reading the document, while others have reported that when many tiddlers have been opened, it can get somewhat confusing.\n\n!!!!!Usage\n<<<\nSinglePageMode allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one item displayed at a time. You can select a checkbox in the AdvancedOptions tiddler to enable this behavior or revert to the standard TiddlyWiki multiple tiddler display behavior.\n\nWhen SinglePageMode is enabled, the title of the current tiddler is automatically displayed in the browser window's titlebar and the browser's location URL is updated with a 'permalink' for the current tiddler so that it is easier to create a browser 'bookmark' for the current tiddler.\n\n//Note: This feature currently effects ALL tiddler display behavior, including features that normally result in multiple tiddlers being displayed, such as the results of searches or the initial DefaultTiddlers shown when the document is loaded. //\n<<<\n!!!!!Configuration\n<<<\nWhen installed, this plugin automatically adds a checkbox in the AdvancedOptions tiddler so you can enable/disable the plugin behavior. You can also use the following ''control panel'' checkbox to change the current plugin handling:\n\n<<option chkSinglePageMode>> Display one tiddler at a time\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''SinglePageModePlugin'' (tagged with <<tag systemConfig>>)\n^^documentation and javascript for SinglePageMode handling^^\n\nWhen installed, this plugin automatically adds a checkbox in the AdvancedOptions tiddler so you can enable/disable this behavior. However, if you have customized your AdvancedOptions, you will need to manually add ''"<< {{{option chkSinglePageMode}}} >> display one tiddler at a time"'' to your customized tiddler.\n<<<\n!!!!!Revision History\n<<<\n''2006.02.04 [2.1.1]''\nmoved global variable declarations to config.* to avoid FireFox 1.5.0.1 crash bug when assigning to globals\n''2005.12.27 [2.1.0]''\nhijack displayTiddlers() so that SPM can be suspended during startup while displaying the DefaultTiddlers (or #hash list) \nalso, corrected initialization for undefined SPM flag to "false", so default behavior is to display multiple tiddlers\n''2005.12.27 [2.0.0]''\nUpdate for TW2.0\n''2005.11.24 [1.1.2]''\nWhen the back and forward buttons are used, the page now changes to match the URL. Based on code added by Clint Checketts\n''2005.10.14 [1.1.1]''\npermalink creation now calls encodeTiddlyLink() to handle tiddler titles with spaces in them\n''2005.10.14 [1.1.0]''\nadded automatic setting of window title and location bar ('auto-permalink').\nfeature suggestion by David Dickens.\n''2005.10.09 [1.0.1]''\ncombined documentation and code in a single tiddler\n''2005.08.15 [1.0.0]''\nInitial Release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].\nSupport for BACK/FORWARD buttons adapted from code developed by Clint Checketts\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.SinglePageMode= {major: 2, minor: 1, revision: 1, date: new Date(2006,2,4)};\n\nif (config.options.chkSinglePageMode==undefined)\n config.options.chkSinglePageMode=false;\n\nconfig.shadowTiddlers.AdvancedOptions\n += "\sn<<option chkSinglePageMode>> Display one tiddler at a time";\n\nconfig.SPMTimer = 0;\nconfig.lastURL = window.location.hash;\nfunction checkLastURL()\n{\n if (!config.options.chkSinglePageMode)\n { window.clearInterval(config.SPMTimer); config.SPMTimer=0; return; }\n if (config.lastURL == window.location.hash)\n return;\n var tiddlerName = convertUTF8ToUnicode(decodeURI(window.location.hash.substr(1)));\n tiddlerName=tiddlerName.replace(/\s[\s[/,"").replace(/\s]\s]/,""); // strip any [[ ]] bracketing\n if (tiddlerName.length) story.displayTiddler(null,tiddlerName,1,null,null);\n}\n\nStory.prototype.coreDisplayTiddler=Story.prototype.displayTiddler;\nStory.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)\n{\n if (config.options.chkSinglePageMode) {\n window.location.hash = encodeURIComponent(String.encodeTiddlyLink(title));\n config.lastURL = window.location.hash;\n document.title = wikifyPlain("SiteTitle") + " - " + title;\n story.closeAllTiddlers();\n if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);\n }\n this.coreDisplayTiddler(srcElement,title,template,animate,slowly)\n}\n\nStory.prototype.coreDisplayTiddlers=Story.prototype.displayTiddlers;\nStory.prototype.displayTiddlers = function(srcElement,titles,template,unused1,unused2,animate,slowly)\n{\n // suspend single-page mode when displaying multiple tiddlers\n var save=config.options.chkSinglePageMode;\n config.options.chkSinglePageMode=false;\n this.coreDisplayTiddlers(srcElement,titles,template,unused1,unused2,animate,slowly);\n config.options.chkSinglePageMode=save;\n}\n//}}}
v2.0
Documentation carte SHiX
http://www.comelec.enst.fr/~polti/wiki/shix/index.html
/***\nmargins, padding, borders, position, z-index, etc... \n***/\n/*{{{*/\n[[StyleSheetLayout]] /* TW shadow */\n[[StyleSheetColors]] /* TW shadow */\n[[StyleSheetPrint]] /* TW shadow */\n/*}}}*/\n\n/***\nTaggly tagging styles \n***/\n/*{{{*/\n[[TagglyTaggingStyles]]\n/*}}}*/\n\n/***\nMes styles\n***/\n/*{{{*/\n\n#mainMenu h1 .tiddlyLinkExisting, \n#mainMenu h1 .tiddlyLinkNonExisting {\n font-weight: bold;\n font-style: bold;\n}\n\n\n#mainMenu h1 {\n color: #841;\n background-color : transparent;\n text-align : left;\n font-size : 0.9em;\n}\n\na{\n color: #841;\n}\n\na:hover{\n background: #841;\n color: #fe8;\n}\n\n.headerShadow {\n color: #444;\n background: #300;\n}\n\n.header .siteSubtitle{\n color: #cf6;;\n background: #300;\n}\n\n.viewer h1,.viewer h2 {\nbackground: #cc9;\n}\n\n.viewer h2 {\n margin-left : 10px;\n}\n\n.viewer h3 {\n font-family: verdana,helvetica,arial,sans-serif;\n color: rgb(255, 255, 255);\n opacity: 1;\n background-color: rgb(189, 153, 111);\n margin-left : 15px;\n}\n\n.viewer h4 {\n font-family: verdana,helvetica,arial,sans-serif;\n color: rgb(255, 255, 255);\n opacity: 1;\n background-color: rgb(212, 177, 140);\n margin-left : 20px;\n}\n\n.viewer h5 {\n font-family: verdana,helvetica,arial,sans-serif;\n color: rgb(128, 128, 128);\n opacity: 1;\n background-color: rgb(232, 207, 170);\n margin-left : 25px;\n}\n/*}}}*/\n/*{{{*/\n\n.popup {\n background: rgb(189, 153, 111);\n border: 1px solid #04b;\n}\n\n.popup hr {\n color: #014;\n background: #db4;\n border-bottom: 1px;\n}\n\n.popup li.disabled {\n color: #04b;\n}\n\n.popup li a, .popup li a:visited {\n color: #eee;\n border: none;\n}\n\n.popup li a:hover {\n background: #db4;\n color: #fff;\n border: none;\n}\n\n\n#sidebar {\n color: #000;\n}\n\n#sidebarOptions {\n background: #c90;\n}\n\n#sidebarOptions input {\n border: 1px solid #000;\n}\n\n#sidebarOptions .sliderPanel {\n background: #eea;\n font-size: 0.95em;\n padding: 0.5em;\n margin-left: 0em;\n}\n\n#sidebarOptions .sliderPanel a {\n color: #930;\n font-weight: bold;\n display: inline;\n padding: 0;\n}\n\n#sidebarOptions .sliderPanel a:hover {\n color: #cf6;\n background: #930;\n}\n\n#sidebarOptions .sliderPanel a:active {\n color: #930;\n background: #cf6;\n}\n\n#sidebarOptions .button {\n color: #930;\n border:0;\n}\n\n\n#sidebarOptions .button:hover {\n color: #cf6;\n background: #930;\n}\n\n\n#sidebarOptions .button:active {\n color: #930;\n background: #cf6;\n}\n\n.editor input {\n border: 1px solid #000;\n}\n\n.editor textarea {\n border: 1px solid #000;\n width: 100%;\n}\n\n.viewer {\n border : 1px solid #ddd;\n padding : 1em;\n}\n\n#messageArea {\n border: 1px solid #841;\n background: #db4;\n color: #000;\n}\n\n#messageArea .button {\n padding: 0.2em 0.2em 0.2em 0.2em;\n color: #F22;\n background: #db4;\n font-weight : bold;\n border : none;\n}\n\n#messageArea a {\n padding: 0.2em 0.2em 0.2em 0.2em;\n color: #014;\n background: #db4;\n text-decoration : none;\n}\n\n.tabUnselected {\n color: #fff;\n background: #bbb;\n}\n\n\n/*}}}*/
/***\n!Colors Used\n*@@bgcolor(#8cf): #8cf - Background blue@@\n*@@bgcolor(#18f): #18f - Top blue@@\n*@@bgcolor(#04b): #04b - Mid blue@@\n*@@bgcolor(#014):color(#fff): #014 - Bottom blue@@\n*@@bgcolor(#ffc): #ffc - Bright yellow@@\n*@@bgcolor(#fe8): #fe8 - Highlight yellow@@\n*@@bgcolor(#db4): #db4 - Background yellow@@\n*@@bgcolor(#841): #841 - Border yellow@@\n*@@bgcolor(#703):color(#fff): #703 - Title red@@\n*@@bgcolor(#866): #866 - Subtitle grey@@\n!Generic Rules /%==============================================%/\n***/\n/*{{{*/\nbody {\n background: #fff;\n color: #000;\n}\n\na{\n color: #04b;\n}\n\na:hover{\n background: #04b;\n color: #fff;\n}\n\na img{\n border: 0;\n}\n\nh1,h2,h3,h4,h5 {\n color: #703;\n background: #8cf;\n}\n\n.button {\n color: #014;\n border: 1px solid #fff;\n}\n\n.button:hover {\n color: #014;\n background: #fe8;\n border: 1px solid #db4;\n}\n\n.button:active {\n color: #fff;\n background: #db4;\n border: 1px solid #841;\n}\n\n/*}}}*/\n/***\n!Header /%==================================================%/\n***/\n/*{{{*/\n.header {\n background: #04b;\n}\n\n.headerShadow {\n color: #000;\n background: #300;\n}\n\n.headerShadow a {\n font-weight: normal;\n color: #000;\n}\n\n.headerForeground {\n color: #fff;\n}\n\n.headerForeground a {\n font-weight: normal;\n color: #cf6;\n}\n\n/*}}}*/\n/***\n!General tabs /%=================================================%/\n***/\n/*{{{*/\n\n.tabSelected{\n color: #014;\n background: #eee;\n border-left: 1px solid #ccc;\n border-top: 1px solid #ccc;\n border-right: 1px solid #ccc;\n}\n\n.tabUnselected {\n color: #fff;\n background: #999;\n}\n\n.tabContents {\n color: #014;\n background: #eee;\n border: 1px solid #ccc;\n}\n\n.tabContents .button {\n border: 0;}\n\n/*}}}*/\n/***\n!Sidebar options /%=================================================%/\n~TiddlyLinks and buttons are treated identically in the sidebar and slider panel\n***/\n/*{{{*/\n#sidebar {\n}\n\n#sidebarOptions input {\n border: 1px solid #04b;\n}\n\n#sidebarOptions .sliderPanel {\n background: #8cf;\n}\n\n#sidebarOptions .sliderPanel a {\n border: none;\n color: #04b;\n}\n\n#sidebarOptions .sliderPanel a:hover {\n color: #fff;\n background: #04b;\n}\n\n#sidebarOptions .sliderPanel a:active {\n color: #04b;\n background: #fff;\n}\n/*}}}*/\n/***\n!Message Area /%=================================================%/\n***/\n/*{{{*/\n#messageArea {\n border: 1px solid #841;\n background: #db4;\n color: #014;\n}\n\n#messageArea .button {\n padding: 0.2em 0.2em 0.2em 0.2em;\n color: #014;\n background: #fff;\n}\n\n/*}}}*/\n/***\n!Popup /%=================================================%/\n***/\n/*{{{*/\n.popup {\n background: #18f;\n border: 1px solid #04b;\n}\n\n.popup hr {\n color: #014;\n background: #014;\n border-bottom: 1px;\n}\n\n.popup li.disabled {\n color: #04b;\n}\n\n.popup li a, .popup li a:visited {\n color: #eee;\n border: none;\n}\n\n.popup li a:hover {\n background: #014;\n color: #fff;\n border: none;\n}\n/*}}}*/\n/***\n!Tiddler Display /%=================================================%/\n***/\n/*{{{*/\n.tiddler .defaultCommand {\n font-weight: bold;\n}\n\n.shadow .title {\n color: #866;\n}\n\n.title {\n color: #703;\n}\n\n.subtitle {\n color: #866;\n}\n\n.toolbar {\n color: #04b;\n}\n\n.tagging, .tagged {\n border: 1px solid #eee;\n background-color: #eee;\n}\n\n.selected .tagging, .selected .tagged {\n background-color: #ddd;\n border: 1px solid #bbb;\n}\n\n.tagging .listTitle, .tagged .listTitle {\n color: #014;\n}\n\n.tagging .button, .tagged .button {\n border: none;\n}\n\n.footer {\n color: #ddd;\n}\n\n.selected .footer {\n color: #888;\n}\n\n.sparkline {\n background: #8cf;\n border: 0;\n}\n\n.sparktick {\n background: #014;\n}\n\n.errorButton {\n color: #ff0;\n background: #f00;\n}\n\n.cascade {\n background: #eef;\n color: #aac;\n border: 1px solid #aac;\n}\n\n.imageLink, #displayArea .imageLink {\n background: transparent;\n}\n\n/*}}}*/\n/***\n''The viewer is where the tiddler content is displayed'' /%------------------------------------------------%/\n***/\n/*{{{*/\n\n.viewer .listTitle {list-style-type: none; margin-left: -2em;}\n\n.viewer .button {\n border: 1px solid #db4;\n}\n\n.viewer blockquote {\n border-left: 3px solid #666;\n}\n\n.viewer table {\n border: 2px solid #333;\n}\n\n.viewer th, thead td {\n background: #996;\n border: 1px solid #666;\n color: #fff;\n}\n\n.viewer td, .viewer tr {\n border: 1px solid #666;\n}\n\n.viewer pre {\n border: 1px solid #fe8;\n background: #ffc;\n}\n\n.viewer code {\n color: #703;\n}\n\n.viewer hr {\n border: 0;\n border-top: dashed 1px #666;\n color: #666;\n}\n\n.highlight, .marked {\n background: #fe8;\n}\n/*}}}*/\n/***\n''The editor replaces the viewer in the tiddler'' /%------------------------------------------------%/\n***/\n/*{{{*/\n.editor input {\n border: 1px solid #04b;\n}\n\n.editor textarea {\n border: 1px solid #04b;\n width: 100%;\n}\n\n.editorFooter {\n color: #aaa;\n}\n\n/*}}}*/
!!!!Typographie\n\n| !Pour obtenir | !Taper ceci |h\n| ''Gras'' | {{{''Gras''}}} |\n| ==Rayé== | {{{==Rayé==}}} |\n| __Souligné__ | {{{__Souligné__}}} |\n| //Italique// | {{{//Italique//}}} |\n| Exposant: 2^^3^^=8 | {{{2^^3^^=8}}} |\n| Indice: a~~ij~~ = -a~~ji~~ | {{{a~~ij~~ = -a~~ji~~}}} |\n| @@surligné@@ | {{{@@surligné@@}}} |\n\n!!!!Listes\n\n// Numérotées : //\n<<<\n* Truc \n** chose\n** machin\n{{{\n* Truc \n** chose\n** machin\n}}}\n<<<\n\n// Alphabétiques : //\n<<<\n# Item1 \n## Item2\n## Item2\n{{{\n# Item1 \n## Item2\n## Item2\n}}}\n<<<\n\n!!!!Titres\n\n{{{\n!Titre1\n!!Titre2\n!!!Titre3\n!!!!Titre4\n!!!!!Titre5\n}}}\n\n!!!! Images\n\n{{{\n[img[http://img110.echo.cx/img110/139/gorilla8nw.jpg]]\n}}}\n\n[img[http://img110.echo.cx/img110/139/gorilla8nw.jpg]]\n\n\n!!!! Citations\n<<<\nVoici un exemple de citation longue, avec retour à la ligne automatique (il n'y a pas besoin de marquer chaque début de ligne).\n<<<\n\n>niveau 1\n>niveau 1\n>>niveau 2\n>>niveau 2\n>>>niveau 3\n>>>niveau 3\n>>niveau 2\n>niveau 1\n\n{{{\n<<<\nVoici un exemple de citation longue, avec retour à la ligne automatique (il n'y a pas besoin de marquer chaque début de ligne).\n<<<\n\n>niveau 1\n>niveau 1\n>>niveau 2\n>>niveau 2\n>>>niveau 3\n>>>niveau 3\n>>niveau 2\n>niveau 1\n}}}\n\n\n!!!!CSS\n\nToutes les syntaxes CSS sont supportées :\n* {{{@@color:green;couleur verte@@}}} : @@color:green;couleur verte@@\n* {{{ @@background-color:#ff0000;color:#ffffff;blanc sur fond rouge@@}}} : @@background-color:#ff0000;color:#ffffff;blanc sur fond rouge@@\n* {{{@@text-shadow:black 3px 3px 8px;font-size:11pt;display:block;margin:1em 1em 1em 1em;border:1px solid black;Insertion de n'importe quel formatage CSS@@}}} : @@text-shadow:black 3px 3px 8px;font-size:11pt;display:block;margin:1em 1em 1em 1em;border:1px solid black;Insertion de n'importe quel formatage CSS@@\n\n//La syntaxe des versions antérieures de TiddlyWiki fonctionne toujours ://\n<<<\n{{{\n@@bgcolor(#ff0000):color(#ffffff):rouge@@\n}}}\n@@bgcolor(#ff0000):color(#ffffff):blanc sur fond rouge@@ ;)\n<<
\n\n''Attention : ce wiki-documentation étant en cours d'écriture, cette table des matières n'est pas forcément à jour !''\n\n! Architecture matérielle\n\nOn commencera par la rubrique [[Matériel]], qui présente globalement la carte SHiX v2.0 d'un point de vue matériel. \nLes alimentations, les horloges et la génération des reset sont couverts dans les rubriques [[Alimentations]] et [[Processeur|ProcesseurHorlogesResets]].\nUn point clef du processeur est l'organisation de son espace mémoire, et le fonctionnement (électrique et logique) de son bus processeur. La [[rubrique sur le bus|Bus]] présente sont fonctionnement électrique et logique, tandis que l'organisation de la mémoire sera vue dans la partie Logiciel (rubrique [[Organisation Mémoire]]).\nLe processeur dispose aussi de deux UART (interface ~RS232), dont un avec contrôle de flux. Leur câblage, et notament le point délicat de l'interprétation des lignes {{{CTS}}}, {{{RTS}}}, etc., sont décrits dans la rubrique [[UART]].\nEnfin, la rubrique [[SSRAM]] décrit le fonctionnement des RAM statique synchrones dédiées au FPGA, et de leur arbitre.\n\n! Architecture logicielle\n!! Bios et bootloader\nIl n'y a pas que le noyau Linux qui tourne sur cette carte : son exécution est possible grâce à deux bootloaders, appelés, pour les différencier, ''bios'' et ''bootloader''. Pour comprendre leurs rôles, \n* on commencera par lire la rubrique sur le [[fonctionnement de la flash NAND|FonctionnementFlashNAND]]\n* puis on continuera par une [[introduction au bios et au bootloader|Boot]]\n* enfin, on étudiera le fonctionnement du [[bios|Bios]]\n* puis celui du [[bootloader|BootLoader]].\n\n!!Organisation mémoire et interruptions\nDeux rubriques expliquent l'[[organisation mémoire du SH4|Organisation Mémoire]], ainsi que la façon dont sont gérées les [[interruptions externes|Interruptions]].\n\n!Utilisation\nOn commencera avant tout par se créer sa chaîne de compilation croisée pour SH4 : [[Compilation Toolchain SH4]].\nPuis la rubrique [[Arbres Patch Kernel]] explique de quel ensemble de sources est composé le noyau. De là, on a deux possibilités pour recompiler un noyau :\n* [[créer sa propre arborescence from scratch|Creation Arborescence From Scratch]]\n* ou [[importer une arborescence déjà existante|Import Arborescence]].\nPuis, on compilera un premier noyau en lisant la rubrique [[Compilation noyau Linux pour SH4]].\n\n\n
/***\n''Table of Contents Plugin for TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#TableOfContentsPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nWhen there are many tiddlers in a document, the standard 'tabbed list of tiddlers' in the right-hand sidebar can become very long, occupying a lot of page space and requiring a lot scrolling in order to locate and select a tiddler.\n\nThe TableOfContentsPlugin addresses this problem by replacing the standard tabbed list display with a single listbox/droplist control that uses a very small amount of page space, regardless of the number of tiddlers in the document.\n\n!!!!!Usage\n<<<\nTo view a tiddler, simply select (or double-click) its title from the listbox and it will automatically be displayed on the page. The listbox also includes special 'command' items that determine the order and type of tiddlers that are shown in the list:\n\n''[by title]'' displays all tiddlers in the document.\n''[by date/author/tags]'' displays indented sections, sorted accordingly, with headings (indicated by a '+') that can be expanded, one at a time, to view the list of tiddlers in that section.\n''[missing]'' displays tiddlers that have been referenced within the document but do not yet exist.\n''[orphans]'' displays tiddlers that do exist in the document but have not been referenced by a link from anywhere else within the document.\n''[system]'' displays special tiddlers that are used by TiddlyWiki to configure built-in features and add-on macros/extensions. The list includes all tiddlers tagged with <<tag systemTiddlers>> ("templates") or <<tag systemConfig>> (plug-in extensions), plus any 'shadow tiddlers' (built-in default systemTiddlers) that have not been over-ridden by custom tiddler definitions.\n\nThe current list ''display setting is indicated by an arrow (">")'' symbol to the left of command item. Selecting a command item causes the listbox to be reloaded with the appropriate contents and sort order.\n\nWhen you are viewing a list of tiddlers by date/author/tags, ''shift-clicking'' on a section heading or command item causes the listbox display to ''toggle between "show-one-section-at-a-time" and "expand-all-sections"'' display options, allowing you to quickly see all tiddler titles at once without having to view individual indented sections one at a time.\n\nThe ''size of the listbox can be adjusted'' so you can view more (or less) tiddler titles at one time. Select ''[-]'' to reduce the size by one line, ''[+]'' to increase the size by one line, or ''[=]'' to autosize the list to fit the current contents (toggles on/off). //Note: If the listbox is reduced to a single line, it displayed as a droplist instead of a fixed-sized listbox.// You can ''show/hide the entire listbox'' by selecting the "contents" label that appears above the listbox.\n<<<\n!!!!!Control Panel\n<<<\nBy default, tiddlers tagged with <<tag excludeLists>>, are omitted from the TableOfContents so that 'system' tiddlers (e.g. MainMenu, SiteTitle, StyleSheet, etc.) can be hidden, reducing "information overload" and making it easier to select relevant tiddlers when reading your document. However, when //editing// your document, including these hidden tiddlers in the list can be more helpful, so that changes to the menus, titles, styles, etc. can be more quickly accomplished.\n----\n''To include hidden tiddlers in the TableOfContents display, select the following option:''\n<<option chkTOCIncludeHidden>> include hidden tiddlers in TableOfContents(ignores <<tag excludeLists>> tag)\n^^note: this setting is ignored when ''<<option chkHttpReadOnly>> HideEditingFeatures when viewed over HTTP'' is enabled^^\n<<<\n!!!!!Parameters\n<<<\nThe macro accepts optional parameters to control various features and functions:\n* ''label:text''\nReplace the default text ("contents") that appears above the TableOfContents listbox. //Note: to include spaces in the label text, you must enclose the entire parameter in quotes// (e.g., {{{"label:my list of tiddlers"}}})\n* ''sort:fieldtype''\nSets the initial display order for items in the listbox. 'fieldtype' is one of the following pre-defined keywords: ''title'', ''modified'' //(date)//, ''modifier'' //(author)//, ''tags'', ''missing'', ''orphans'', or ''system''\n* ''date:format''\nControls the formatting of dates in TableOfContents display. 'format' is a text-substitution template containing one or more of the following special notations.\n** DDD - day of week in full (eg, "Monday")\n** DD - day of month, 0DD - adds leading zero\n** MMM - month in full (eg, "July")\n** MM - month number, 0MM - adds leading zero\n** YYYY - full year, YY - two digit year\n** hh - hours\n** mm - minutes\n** ss - seconds\n//Note: to include spaces in the formatting template, you must enclose the entire parameter in quotes// (e.g., {{{"date:DDD, DD/MM/YY"}}})\n* ''size:nnn''\nSets the initial number of lines to display in the listbox. If this parameter is omitted or "size:1" is specified, a single-line droplist is created. When a size > 1 is provided, a standard, fixed-size scrollable listbox is created. You can use "size:0" or "size:auto" to display a varible-height listbox that automatically adjusts to fit the current list contents without scrolling.\n* ''width:nnn[cm|px|em|%]''\nSets the width of the listbox control. Overrides the built-in CSS width declaration (=100%). Use standard CSS width units (cm=centimeters, px=pixels, em=M-space, %=proportional to containing area). You can also use a ".TOCList" custom CSS class definition to override the built-in CSS declarations for the listbox.\n* ''hidelist''\nHides the listbox when the TableOfContents is first displayed. Initially, only the listbox label and size controls will appear. Clicking on the listbox label text will alternately show/hide the listbox display. //Note: this setting does not affect the content of the listbox, only whether or not it is initially visible.//\n* ''prompt''\nSets the non-selectable prompt text that is displayed as the first line of the listbox //(note: this feature is not supported by the listbox control on all browsers)//. Let's you include a short text message (such as "select a tiddler"), even when displaying a compact single-line droplist.\n* ''padding:nnn[cm|px|em|%]''\nOverrides default listbox control padding. Sets the CSS padding style.\n* ''margin:nnn[cm|px|em|%]''\nOverrides default listbox control spacing. Sets the CSS margin style.\n* ''inline''\nNormally, the TableOfContents plugin is contained inside a {{{<div>}}} element. This setting causes the plugin to use a {{{<span>}}} instead, allowing for more flexible 'inline' placement when embedded within other content.\n<<<\n!!!!!Examples\n<<<\n<<tableOfContents "label:all tiddlers" sort:title width:40% size:1>>\n<<tableOfContents "label:by date" sort:modified size:1 width:40%>>\n<<tableOfContents "label:tagged tiddlers" sort:tags size:1 width:40%>>\n<<tableOfContents "label:system tiddlers" sort:system size:1 width:40%>>\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''TableOfContentsPlugin'' (tagged with <<tag systemConfig>>)\n^^documentation and javascript for TableOfContents handling^^\n\ncreate/edit ''SideBarOptions'': (sidebar menu items) \n^^Add {{{<<tableOfContents>>}}} macro^^\n\n<<<\n!!!!!Revision History\n<<<\n''2006.02.14 [2.2.6]''\nFF1501 fix: add 'var r' and 'var k' to unintended global variable declarations in refreshTOCList() and getTOCListFromButton(). Thanks for report from AndreasHoefler.\n''2006.02.04 [2.2.5]''\nadd 'var' to unintended global variable declarations to avoid FireFox 1.5.0.1 crash bug when assigning to globals\n''2005.12.21 [2.2.2]''\nin onClickTOCList() and onDblClickTOCList(), prevent mouse events from 'bubbling' up to other handlers\n''2005.10.30 [2.2.1]''\nin refreshTOCList(), fixed calculation of "showHidden" to check for 'readOnly' (i.e., "via HTTP") flag\nbased on a report from LyallPearce\n''2005.10.30 [2.2.0]''\nhide tiddlers tagged with 'excludeLists' (with option to override, i.e., "include hidden tiddlers")\n''2005.10.09 [2.1.0]''\ncombined documentation and code in a single tiddler\nadded click toggle for expand-all vs. show-one-branch\n''2005.08.07 [2.0.0]''\nmajor re-write to not use static ID values for listbox controls, so that multiple macro instances can exist without corrupting each other or the DOM. Moved HTML and CSS definitions into plugin code instead of using separate tiddlers. Added macro parameters for label, sort, date, size, width, hidelist and showtabs\n''2005.08.03 [1.0.3]''\nadded "showtabs" optional parameter\n''2005.07.27 [1.0.2]''\ncore update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet(). Added show/hide toggle (click on 'contents' link)\n''2005.07.23 [1.0.1]''\nadded parameter checks and corrected addNotification() usage\n''2005.07.20 [1.0.0]''\nInitial Release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.tableOfContents = {major: 2, minor: 2, revision: 6, date: new Date(2006,2,14)};\n//}}}\n\n// // 1.2.x compatibility\n//{{{\nif (!window.story) window.story=window;\nif (!store.getTiddler) store.getTiddler=function(title){return store.tiddlers[title]}\nif (!store.addTiddler) store.addTiddler=function(tiddler){store.tiddlers[tiddler.title]=tiddler}\nif (!store.deleteTiddler) store.deleteTiddler=function(title){delete store.tiddlers[title]}\n//}}}\n\n//{{{\n// define defaults for cookie-based option values\nif (config.options.txtTOCSortBy==undefined) config.options.txtTOCSortBy="modified";\nif (config.options.txtTOCListSize==undefined) config.options.txtTOCListSize=12;\nif (config.options.chkTOCShow==undefined) config.options.chkTOCShow=true;\nif (config.options.chkTOCIncludeHidden==undefined) config.options.chkTOCIncludeHidden=false;\n\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkTOCIncludeHidden>> include hidden tiddlers in TableOfContents";\n\n// define macro "tableOfContents" to render controls\nconfig.macros.tableOfContents = { label: "contents" };\nconfig.macros.tableOfContents.cmdMax=7;\n\nconfig.macros.tableOfContents.css = '\s\n.TOC { padding:0.5em 1em 0.5em 1em; }\s\n.TOC a { padding:0em 0.25em 0em 0.25em; color:inherit; }\s\n.TOCList { width: 100%; font-size:8pt; margin:0em; }\s\n';\n\nconfig.macros.tableOfContents.html = '\s\n<div style="text-align:right">\s\n <span style="float:left">\s\n <a href="JavaScript:;" id="TOCMenu" style="padding: 0em;"\s\n onclick="onClickTOCMenu(this)" title="show/hide table of contents">%label%</a>\s\n </span>\s\n <a href="JavaScript:;" id="TOCSmaller" style="display:inline"\s\n onclick="resizeTOC(this)" title="reduce list size">–</a>\s\n <a href="JavaScript:;" id="TOCLarger"style="display:inline"\s\n onclick="resizeTOC(this)" title="increase list size">+</a>\s\n <a href="JavaScript:;" id="TOCMaximize"style="display:inline"\s\n onclick="resizeTOC(this)" title="maximize/restore list size">=</a>\s\n</div>\s\n';\n\nconfig.macros.tableOfContents.handler = function(place,macroName,params) { \n var parsedParams = new Array();\n parsedParams['label']=this.label;\n parsedParams['inline']=false;\n while (params.length>0) {\n if (params[0]=="label:none")\n parsedParams['label']="";\n else if (params[0].substr(0,6)=="label:")\n parsedParams['label']=params[0].substr(6);\n if (params[0].substr(0,7)=="prompt:")\n parsedParams['prompt']=params[0].substr(7);\n if (params[0].substr(0,8)=="padding:")\n parsedParams['padding']=params[0].substr(8);\n if (params[0].substr(0,7)=="margin:")\n parsedParams['margin']=params[0].substr(7);\n if (params[0].substr(0,5)=="sort:")\n parsedParams['sortby']=params[0].substr(5);\n if (params[0].substr(0,5)=="date:")\n parsedParams['date']=params[0].substr(5);\n if ((params[0]=="size:auto")||(params[0]=="size:0"))\n parsedParams['autosize']=true;\n else if (params[0] && (params[0].substr(0,5)=="size:"))\n parsedParams['requestedSize']=params[0].substr(5);\n if (params[0].substr(0,6)=="width:")\n parsedParams['width']=params[0].substr(6);\n if (params[0]=="hidelist")\n parsedParams['hidelist']=true;\n if (params[0]=="inline")\n parsedParams['inline']=true;\n params.shift(); \n }\n setStylesheet(config.macros.tableOfContents.css,"tableOfContents");\n var newTOC=createTiddlyElement(place,parsedParams['inline']?"span":"div",null,"TOC",null)\n if (parsedParams['margin']) { newTOC.style.margin=parsedParams['margin']; }\n if (parsedParams['padding']) { newTOC.style.padding=parsedParams['padding']; }\n if (parsedParams['label']!="") newTOC.innerHTML=config.macros.tableOfContents.html.replace(/%label%/,parsedParams['label']);\n var newTOCList=createTOCList(newTOC,parsedParams)\n refreshTOCList(newTOCList);\n store.addNotification(null,reloadTOCLists); // reload listbox after every tiddler change\n}\n\n// IE needs explicit global scoping for functions/vars called from browser events\nwindow.onChangeTOCList=onChangeTOCList;\nwindow.onClickTOCList=onClickTOCList;\nwindow.onDblClickTOCList=onDblClickTOCList;\nwindow.reloadTOCLists=reloadTOCLists;\nwindow.refreshTOCList=refreshTOCList;\nwindow.onClickTOCMenu=onClickTOCMenu;\nwindow.resizeTOC=resizeTOC;\n \nfunction createTOCList(place,params)\n{\n var theList = createTiddlyElement(place,"select",null,"TOCList",params['prompt'])\n theList.onchange=onChangeTOCList;\n theList.onclick=onClickTOCList;\n theList.ondblclick=onDblClickTOCList;\n theList.style.display=config.options.chkTOCShow ? "block" : "none" ;\n theList.sortBy=config.options.txtTOCSortBy;\n theList.dateFormat="DD MMM YYYY";\n theList.requestedSize=config.options.txtTOCListSize;\n theList.expandall=false;\n if (params['sortby'])\n { theList.sortBy=params['sortby']; theList.noSortCookie=true; }\n if (params['date'])\n { theList.dateFormat=params['date']; }\n if (params['autosize'])\n { theList.autosize=true; theList.noSizeCookie=true; }\n if (params['requestedSize'])\n { theList.requestedSize=params['requestedSize']; theList.noSizeCookie=true; }\n if (params['width'])\n { theList.style.width=params['width']; }\n if (params['hidelist'])\n { theList.style.display ="none" ; theList.noShowCookie=true; }\n if (params['expandall'])\n { theList.expandall=true; }\n return theList;\n}\n\nfunction onChangeTOCList()\n{\n var thisTiddler=this.options[this.selectedIndex].value;\n if ((this.size==1)&&(thisTiddler!='')) story.displayTiddler(null,thisTiddler,1);\n refreshTOCList(this);\n return false;\n}\n\nfunction onClickTOCList(e)\n{\n\n if (!e) var e = window.event;\n if (this.size==1)\n return; // don't toggle display for droplist\n if (e.shiftKey)\n { this.expandall=!this.expandall; refreshTOCList(this);}\n e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation();\n return true;\n}\n\nfunction onDblClickTOCList(e)\n{\n if (!e) var e = window.event;\n var thisTiddler=this.options[this.selectedIndex].value;\n if (thisTiddler!='') story.displayTiddler(null,thisTiddler,1);\n e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation();\n return false;\n}\n\nfunction reloadTOCLists()\n{\n var all=document.all? document.all : document.getElementsByTagName("*");\n for (var i=0; i<all.length; i++)\n if (all[i].className=="TOCList")\n { all[i].selectedIndex=-1; refreshTOCList(all[i]); }\n}\n\nfunction refreshTOCList(theList)\n{\n // DEBUG var starttime=new Date();\n var selectedIndex = theList.selectedIndex;\n if (selectedIndex==-1) selectedIndex=0;\n var sortBy = theList.sortBy;\n var showHidden = config.options.chkTOCIncludeHidden\n && !(config.options.chkHttpReadOnly && readOnly);\n\n if (selectedIndex==0) sortBy=theList.sortBy; // "nnn tiddlers" heading\n if (selectedIndex==1) sortBy='title';\n if (selectedIndex==2) sortBy='modified';\n if (selectedIndex==3) sortBy='modifier';\n if (selectedIndex==4) sortBy='tags';\n if (selectedIndex==5) sortBy='missing';\n if (selectedIndex==6) sortBy='orphans';\n if (selectedIndex==7) sortBy='system';\n if (selectedIndex>config.macros.tableOfContents.cmdMax)\n {\n if (theList.options[theList.selectedIndex].value=='')\n expandTOC(theList);\n return;\n }\n theList.sortBy = sortBy;\n if (!theList.noSortCookie)\n { config.options.txtTOCSortBy=sortBy; saveOptionCookie("txtTOCSortBy"); }\n\n // get the list of tiddlers and filter out 'hidden' tiddlers (i.e., tagged with "excludeLists")\n var tiddlers = [];\n switch (sortBy) {\n case "missing":\n tiddlers = store.getMissingLinks();\n break;\n case "tags":\n tiddlers = store.getTags();\n break;\n case "orphans":\n var titles = store.getOrphans();\n for (var t = 0; t < titles.length; t++)\n if (showHidden || store.getTiddler(titles[t]).tags.find("excludeLists")==null)\n tiddlers.push(titles[t]);\n break;\n case "system":\n var temp = store.getTaggedTiddlers("systemTiddlers");\n for (var t = 0; t < temp.length; t++)\n if (showHidden || temp[t].tags.find("excludeLists")==null)\n tiddlers.pushUnique(temp[t].title,true);\n var temp = store.getTaggedTiddlers("systemConfig");\n for (var t = 0; t < temp.length; t++)\n if (showHidden || temp[t].tags.find("excludeLists")==null)\n tiddlers.pushUnique(temp[t].title,true);\n for (var t in config.shadowTiddlers) tiddlers.pushUnique(t,true);\n tiddlers.sort();\n break;\n default:\n var temp = store.getTiddlers(sortBy);\n for (var t = 0; t < temp.length; t++)\n if (showHidden || temp[t].tags.find("excludeLists")==null)\n tiddlers.push(temp[t]);\n }\n\n // clear current list contents\n while (theList.length > 0) { theList.options[0] = null; }\n theList.saved=null;\n\n // add heading and control items to list\n var i=0;\n var theHeading=tiddlers.length+' tiddlers:';\n if (sortBy=='missing') theHeading=tiddlers.length+' missing tiddlers:';\n if (sortBy=='orphans') theHeading=tiddlers.length+' orphaned tiddlers:';\n if (sortBy=='tags') theHeading=tiddlers.length+' tags:';\n if (sortBy=='system') theHeading=tiddlers.length+' system tiddlers:';\n var indent=String.fromCharCode(160)+String.fromCharCode(160);\n var sel=">";\n theList.options[i++]=new Option(theHeading,'',false,false);\n theList.options[i++]=new Option(((sortBy=="title")?sel:indent)+' [by title]','',false,false);\n theList.options[i++]=new Option(((sortBy=="modified")?sel:indent)+' [by date]','',false,false);\n theList.options[i++]=new Option(((sortBy=="modifier")?sel:indent)+' [by author]','',false,false);\n theList.options[i++]=new Option(((sortBy=="tags")?sel:indent)+' [by tags]','',false,false);\n theList.options[i++]=new Option(((sortBy=="missing")?sel:indent)+' [missing]','',false,false);\n theList.options[i++]=new Option(((sortBy=="orphans")?sel:indent)+' [orphans]','',false,false);\n theList.options[i++]=new Option(((sortBy=="system")?sel:indent)+' [system]','',false,false);\n // output the tiddler list\n switch(sortBy)\n {\n case "title":\n for (var t = 0; t < tiddlers.length; t++)\n theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);\n break;\n case "modified":\n // sort descending for newest date first\n tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });\n // continue with same logic as for 'modifier'...\n case "modifier":\n var lastSection = "";\n for (var t = 0; t < tiddlers.length; t++)\n {\n var tiddler = tiddlers[t];\n var theSection = "";\n if (sortBy=="modified") theSection = tiddler.modified.formatString(theList.dateFormat);\n if (sortBy=="modifier") theSection = tiddler.modifier;\n if (theSection != lastSection)\n {\n theList.options[i++] = new Option('+ '+theSection,"",false,false);\n lastSection = theSection;\n }\n theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);\n }\n expandTOC(theList);\n break;\n case "tags":\n // tagged tiddlers, by tag\n var tagcount=0;\n var lastTag = null;\n for (var t = 0; t < tiddlers.length; t++) // actually a list of tags, not tiddlers...\n {\n var theTag = tiddlers[t][0];\n var tagged = new Array();\n var temp = store.getTaggedTiddlers(theTag);\n for(var r=0; r<temp.length; r++)\n if (showHidden || temp[r].tags.find("excludeLists")==null)\n tagged.push(temp[r]);\n if (tagged.length)\n {\n tagcount++;\n theList.options[i++]= new\n Option('+ '+theTag+" ("+tagged.length+")","",false,false);\n for(var r=0; r<tagged.length; r++)\n theList.options[i++] = new\n Option(indent+indent+tagged[r].title,tagged[r].title,false,false);\n }\n }\n // count untagged tiddlers\n var temp = store.getTiddlers("title");\n var c=0; for (var r=0; r<temp.length;r++) if (!temp[r].tags.length) c++;\n // create 'pseudo-tag' listing untagged tiddlers (if any)\n if (c>0)\n {\n theList.options[i++] = new Option("+ untagged ("+c+")","",false,false);\n for (var r=0; r<temp.length;r++) if (!temp[r].tags.length)\n theList.options[i++] = new\n Option(indent+indent+temp[r].title,temp[r].title,false,false);\n }\n theList.options[0].text=tagcount+' tags:';\n expandTOC(theList);\n break;\n case "missing":\n case "orphans":\n case "system":\n for (var t = 0; t < tiddlers.length; t++)\n theList.options[i++] = new Option(tiddlers[t],tiddlers[t],false,false);\n break;\n }\n theList.selectedIndex=selectedIndex; // select current control item\n theList.size = (theList.autosize)?theList.options.length:theList.requestedSize;\n // DEBUG var endtime=new Date();\n // DEBUG alert("refreshTOC() elapsed time: "+(endtime-starttime)+" msec");\n}\n\n// show/hide branch of TOCList based on current selection\nfunction expandTOC(theList)\n{\n var selectedIndex = theList.selectedIndex;\n if (selectedIndex==-1) selectedIndex=0;\n var sortBy = theList.sortBy;\n\n // don't collapse/expand list for alpha-sorted "flatlist" TOC contents\n if ((sortBy=="title")||(sortBy=="missing")||(sortBy=="orphans")||(sortBy=="system"))\n return;\n // or list control items\n if ((selectedIndex>0)&&(selectedIndex<=config.macros.tableOfContents.cmdMax))\n return;\n\n var theText = theList.options[selectedIndex].text;\n var theValue = theList.options[selectedIndex].value;\n // save fully expanded list contents (if not already saved)\n if (!theList.saved)\n {\n theList.saved = new Array();\n for (var i=0; i < theList.length; i++)\n {\n opt = theList.options[i];\n theList.saved[i] = new Option(opt.text, opt.value, opt.defaultSelected, opt.selected);\n }\n }\n // clear current list contents\n while (theList.length > 0) { theList.options[0] = null; }\n\n // put back all items \n if (theList.expandall)\n {\n var i=0;\n for (var t=0; t<theList.saved.length; t++)\n {\n var opt=theList.saved[t];\n theList.options[i++] = new Option(opt.text,opt.value,opt.defaultSelected,opt.selected);\n if (opt.text==theText) selectedIndex=i-1;\n }\n theList.selectedIndex = selectedIndex;\n theList.size = (theList.autosize)?theList.options.length:theList.requestedSize;\n return;\n }\n\n // put back heading items until item text matches current selected heading\n var i=0;\n for (var t=0; t<theList.saved.length; t++)\n {\n var opt=theList.saved[t];\n if (opt.value=='')\n theList.options[i++] = new Option(opt.text,opt.value,opt.defaultSelected,opt.selected);\n if (opt.text==theText)\n break;\n }\n selectedIndex=i-1; // this is the NEW index of the current selected heading\n // put back items with value!='' until value==''\n for ( t++; t<theList.saved.length; t++)\n {\n var opt=theList.saved[t];\n if (opt.value!='')\n theList.options[i++] = new Option(opt.text,opt.value,opt.defaultSelected,opt.selected);\n if (opt.value=='')\n break;\n }\n // put back remaining items with value==''\n for ( ; t<theList.saved.length; t++)\n {\n var opt=theList.saved[t];\n if (opt.value=='')\n theList.options[i++] = new Option(opt.text,opt.value,opt.defaultSelected,opt.selected);\n }\n theList.selectedIndex = selectedIndex;\n theList.size = (theList.autosize)?theList.options.length:theList.requestedSize;\n}\n\n// these functions process clicks on the 'control links' that are displayed above the listbox\nfunction getTOCListFromButton(which)\n{\n var theList = null;\n switch (which.id)\n {\n case 'TOCMenu':\n var theSiblings = which.parentNode.parentNode.parentNode.childNodes;\n var thePlace=which.parentNode.parentNode.parentNode.parentNode.parentNode.id;\n break;\n case 'TOCSmaller':\n case 'TOCLarger':\n case 'TOCMaximize':\n var theSiblings = which.parentNode.parentNode.childNodes;\n var thePlace=which.parentNode.parentNode.parentNode.parentNode.id;\n break;\n }\n for (var k=0; k<theSiblings.length; k++)\n if (theSiblings[k].className=="TOCList") { theList=theSiblings[k]; break; }\n // DEBUG if (theList) alert('found '+theList.className+' for '+which.id+' button in '+thePlace);\n return theList;\n}\n\nfunction onClickTOCMenu(which)\n{\n var theList=getTOCListFromButton(which);\n if (!theList) return;\n var opening = theList.style.display=="none";\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(theList,opening,false,"none"));\n else\n theList.style.display = opening ? "block" : "none" ;\n if (!theList.noShowCookie)\n { config.options.chkTOCShow = opening; saveOptionCookie("chkTOCShow"); }\n return(false);\n}\n\nfunction resizeTOC(which)\n{\n var theList=getTOCListFromButton(which);\n if (!theList) return;\n\n var size = theList.size;\n if (theList.style.display=="none") // make sure list is visible\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(theList,true,false,"none"));\n else\n theList.style.display = "block" ;\n switch (which.id)\n {\n case 'TOCSmaller': // decrease current listbox size\n if (theList.autosize) { theList.autosize=false; size=config.options.txtTOCListSize; }\n if (size==1) break;\n size -= 1; // shrink by one line\n theList.requestedSize = theList.size = size;\n break;\n case 'TOCLarger': // increase current listbox size\n if (theList.autosize) { theList.autosize=false; size=config.options.txtTOCListSize; }\n if (size>=theList.options.length) break;\n size += 1; // grow by one line\n theList.requestedSize = theList.size = size;\n break;\n case 'TOCMaximize': // toggle autosize\n theList.autosize = (theList.size!=theList.options.length);\n theList.size = (theList.autosize)?theList.options.length:theList.requestedSize;\n break;\n }\n if (!theList.noSizeCookie && !theList.autosize)\n { config.options.txtTOCListSize=size; saveOptionCookie("txtTOCListSize"); }\n}\n//}}}\n
/***\n|Name|TagglyListPlugin|\n|Created by|SimonBaird|\n|Location|http://simonbaird.com/mptw/#TagglyListPlugin|\n|Version|1.1 20-jan-06|\n|Requires|See TagglyTagging|\n***/\n\n/***\n!Setup and config\n***/\n//{{{\n\nconfig.macros.tagglyList = {};\nconfig.macros.tagglyListByTag = {};\nconfig.macros.tagglyListControl = {};\nconfig.macros.tagglyListWithSort = {};\nconfig.macros.hideSomeTags = {};\n\n// change this to your preference\nconfig.macros.tagglyListWithSort.maxCols = 6;\n\nconfig.macros.tagglyList.label = "Tagged as %0:";\n\n// the default sort options. set these to your preference\nconfig.macros.tagglyListWithSort.defaults = {\n sortBy:"title", // title|created|modified\n sortOrder: "asc", // asc|desc\n hideState: "show", // show|hide\n groupState: "nogroup", // nogroup|group\n numCols: 1\n};\n\n// these tags will be ignored by the grouped view\nconfig.macros.tagglyListByTag.excludeTheseTags = [\n "systemConfig"\n];\n\nconfig.macros.tagglyListControl.tags = {\n title:"sortByTitle", \n modified: "sortByModified", \n created: "sortByCreated",\n asc:"sortAsc", \n desc:"sortDesc",\n hide:"hideTagged", \n show:"showTagged",\n nogroup:"noGroupByTag",\n group:"groupByTag",\n cols1:"list1Cols",\n cols2:"list2Cols",\n cols3:"list3Cols",\n cols4:"list4Cols",\n cols5:"list5Cols",\n cols6:"list6Cols",\n cols7:"list7Cols",\n cols8:"list8Cols",\n cols9:"list9Cols" \n}\n\n// note: should match config.macros.tagglyListControl.tags\nconfig.macros.hideSomeTags.tagsToHide = [\n "sortByTitle",\n "sortByCreated",\n "sortByModified",\n "sortDesc",\n "sortAsc",\n "hideTagged",\n "showTagged",\n "noGroupByTag",\n "groupByTag",\n "list1Cols",\n "list2Cols",\n "list3Cols",\n "list4Cols",\n "list5Cols",\n "list6Cols",\n "list7Cols",\n "list8Cols",\n "list9Cols"\n];\n\n\n//}}}\n/***\n\n!Utils\n***/\n//{{{\n// from Eric\nfunction isTagged(title,tag) {\n var t=store.getTiddler(title); if (!t) return false;\n return (t.tags.find(tag)!=null);\n}\n\n// from Eric\nfunction toggleTag(title,tag) {\n var t=store.getTiddler(title); if (!t || !t.tags) return;\n if (t.tags.find(tag)==null) t.tags.push(tag);\n else t.tags.splice(t.tags.find(tag),1);\n}\n\nfunction addTag(title,tag) {\n var t=store.getTiddler(title); if (!t || !t.tags) return;\n t.tags.push(tag);\n}\n\nfunction removeTag(title,tag) {\n var t=store.getTiddler(title); if (!t || !t.tags) return;\n if (t.tags.find(tag)!=null) t.tags.splice(t.tags.find(tag),1);\n}\n\n// from Udo\nArray.prototype.indexOf = function(item) {\n for (var i = 0; i < this.length; i++) {\n if (this[i] == item) {\n return i;\n }\n }\n return -1;\n};\nArray.prototype.contains = function(item) {\n return (this.indexOf(item) >= 0);\n}\n//}}}\n/***\n\n!tagglyList\ndisplays a list of tagged tiddlers. \nparameters are sortField and sortOrder\n***/\n//{{{\n\n// not used at the moment...\nfunction sortedListOfOtherTags(tiddler,thisTag) {\n var list = tiddler.tags.concat(); // so we are working on a clone..\n for (var i=0;i<config.macros.hideSomeTags.tagsToHide.length;i++) {\n if (list.find(config.macros.hideSomeTags.tagsToHide[i]) != null)\n list.splice(list.find(config.macros.hideSomeTags.tagsToHide[i]),1); // remove hidden ones\n }\n for (var i=0;i<config.macros.tagglyListByTag.excludeTheseTags.length;i++) {\n if (list.find(config.macros.tagglyListByTag.excludeTheseTags[i]) != null)\n list.splice(list.find(config.macros.tagglyListByTag.excludeTheseTags[i]),1); // remove excluded ones\n }\n list.splice(list.find(thisTag),1); // remove thisTag\n return '[[' + list.sort().join("]] [[") + ']]';\n}\n\nfunction sortHelper(a,b) {\n if (a == b) return 0;\n else if (a < b) return -1;\n else return +1;\n}\n\nconfig.macros.tagglyListByTag.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n\n var sortBy = params[0] ? params[0] : "title"; \n var sortOrder = params[1] ? params[1] : "asc";\n\n var result = store.getTaggedTiddlers(tiddler.title,sortBy);\n\n if (sortOrder == "desc")\n result = result.reverse();\n\n var leftOvers = []\n for (var i=0;i<result.length;i++) {\n leftOvers.push(result[i].title);\n }\n\n var allTagsHolder = {};\n for (var i=0;i<result.length;i++) {\n for (var j=0;j<result[i].tags.length;j++) {\n\n if ( \n result[i].tags[j] != tiddler.title // not this tiddler\n && config.macros.hideSomeTags.tagsToHide.find(result[i].tags[j]) == null // not a hidden one\n && config.macros.tagglyListByTag.excludeTheseTags.find(result[i].tags[j]) == null // not excluded\n ) {\n if (!allTagsHolder[result[i].tags[j]])\n allTagsHolder[result[i].tags[j]] = "";\n allTagsHolder[result[i].tags[j]] += "**[["+result[i].title+"]]\sn";\n\n if (leftOvers.find(result[i].title) != null)\n leftOvers.splice(leftOvers.find(result[i].title),1); // remove from leftovers. at the end it will contain the leftovers...\n }\n }\n }\n\n\n var allTags = [];\n for (var t in allTagsHolder)\n allTags.push(t);\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 if (sortOrder == "desc")\n allTags.reverse();\n\n var markup = "";\n for (var i=0;i<allTags.length;i++)\n markup += "*[["+allTags[i]+"]]\sn" + allTagsHolder[allTags[i]];\n\n for (var i=0;i<leftOvers.length;i++)\n markup += "*[["+leftOvers[i]+"]]\sn";\n\n wikify(markup,place);\n}\n\nconfig.macros.tagglyList.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n var sortBy = params[0] ? params[0] : "title"; \n var sortOrder = params[1] ? params[1] : "asc";\n var numCols = params[2] ? params[2] : 1;\n\n var result = store.getTaggedTiddlers(tiddler.title,sortBy);\n if (sortOrder == "desc")\n result = result.reverse();\n\n var listSize = result.length;\n var colSize = listSize/numCols;\n var remainder = listSize % numCols;\n\n var upperColsize;\n var lowerColsize;\n if (colSize != Math.floor(colSize)) {\n // it's not an exact fit so..\n lowerColsize = Math.floor(colSize);\n upperColsize = Math.floor(colSize) + 1;\n }\n else {\n lowerColsize = colSize;\n upperColsize = colSize;\n }\n\n var markup = "";\n var c=0;\n\n var newTaggedTable = createTiddlyElement(place,"table");\n var newTaggedBody = createTiddlyElement(newTaggedTable,"tbody");\n var newTaggedTr = createTiddlyElement(newTaggedBody,"tr");\n\n for (var j=0;j<numCols;j++) {\n var foo = "";\n var thisSize;\n\n if (j<remainder)\n thisSize = upperColsize;\n else\n thisSize = lowerColsize;\n\n for (var i=0;i<thisSize;i++) \n foo += ( "*[[" + result[c++].title + "]]\sn"); // was using splitList.shift() but didn't work in IE;\n\n var newTd = createTiddlyElement(newTaggedTr,"td",null,"tagglyTagging");\n wikify(foo,newTd);\n\n }\n\n};\n\n/* snip for later.....\n //var groupBy = params[3] ? params[3] : "t.title.substr(0,1)";\n //var groupBy = params[3] ? params[3] : "sortedListOfOtherTags(t,tiddler.title)";\n //var groupBy = params[3] ? params[3] : "t.modified";\n var groupBy = null; // for now. groupBy here is working but disabled for now.\n\n var prevGroup = "";\n var thisGroup = "";\n\n if (groupBy) {\n result.sort(function(a,b) {\n var t = a; var aSortVal = eval(groupBy); var aSortVal2 = eval("t".sortBy);\n var t = b; var bSortVal = eval(groupBy); var bSortVal2 = eval("t".sortBy);\n var t = b; var bSortVal2 = eval(groupBy);\n return (aSortVal == bSortVal ?\n (aSortVal2 == bSortVal2 ? 0 : (aSortVal2 < bSortVal2 ? -1 : +1)) // yuck\n : (aSortVal < bSortVal ? -1 : +1));\n });\n }\n\n if (groupBy) {\n thisGroup = eval(groupBy);\n if (thisGroup != prevGroup)\n markup += "*[["+thisGroup+']]\sn';\n markup += "**[["+t.title+']]\sn';\n prevGroup = thisGroup;\n }\n\n\n\n*/\n\n\n//}}}\n\n/***\n\n!tagglyListControl\nUse to make the sort control buttons\n***/\n//{{{\n\nfunction getSortBy(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.sortBy;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["title"])) return "title";\n else if (tiddler.tags.contains(usetags["modified"])) return "modified";\n else if (tiddler.tags.contains(usetags["created"])) return "created";\n else return defaultVal;\n}\n\nfunction getSortOrder(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.sortOrder;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["asc"])) return "asc";\n else if (tiddler.tags.contains(usetags["desc"])) return "desc";\n else return defaultVal;\n}\n\nfunction getHideState(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.hideState;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["hide"])) return "hide";\n else if (tiddler.tags.contains(usetags["show"])) return "show";\n else return defaultVal;\n}\n\nfunction getGroupState(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.groupState;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["group"])) return "group";\n else if (tiddler.tags.contains(usetags["nogroup"])) return "nogroup";\n else return defaultVal;\n}\n\nfunction getNumCols(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.numCols; // an int\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n for (var i=1;i<=config.macros.tagglyListWithSort.maxCols;i++)\n if (tiddler.tags.contains(usetags["cols"+i])) return i;\n return defaultVal;\n}\n\n\nfunction getSortLabel(title,which) {\n // TODO. the strings here should be definable in config\n var by = getSortBy(title);\n var order = getSortOrder(title);\n var hide = getHideState(title);\n var group = getGroupState(title);\n if (which == "hide") return (hide == "show" ? "−" : "+"); // 0x25b8;\n else if (which == "group") return (group == "group" ? "normal" : "grouped");\n else if (which == "cols") return "cols±"; // ±\n else if (by == which) return which + (order == "asc" ? "↓" : "↑"); // ↑ ↓\n else return which;\n}\n\nfunction handleSortClick(title,which) {\n var currentSortBy = getSortBy(title);\n var currentSortOrder = getSortOrder(title);\n var currentHideState = getHideState(title);\n var currentGroupState = getGroupState(title);\n var currentNumCols = getNumCols(title);\n\n var tags = config.macros.tagglyListControl.tags;\n\n // if it doesn't exist, lets create it..\n if (!store.getTiddler(title))\n store.saveTiddler(title,title,"",config.options.txtUserName,new Date(),null);\n\n if (which == "hide") {\n // toggle hide state\n var newHideState = (currentHideState == "hide" ? "show" : "hide");\n removeTag(title,tags[currentHideState]);\n if (newHideState != config.macros.tagglyListWithSort.defaults.hideState)\n toggleTag(title,tags[newHideState]);\n }\n else if (which == "group") {\n // toggle hide state\n var newGroupState = (currentGroupState == "group" ? "nogroup" : "group");\n removeTag(title,tags[currentGroupState]);\n if (newGroupState != config.macros.tagglyListWithSort.defaults.groupState)\n toggleTag(title,tags[newGroupState]);\n }\n else if (which == "cols") {\n // toggle num cols\n var newNumCols = currentNumCols + 1; // confusing. currentNumCols is an int\n if (newNumCols > config.macros.tagglyListWithSort.maxCols || newNumCols > store.getTaggedTiddlers(title).length)\n newNumCols = 1;\n removeTag(title,tags["cols"+currentNumCols]);\n if (("cols"+newNumCols) != config.macros.tagglyListWithSort.defaults.groupState)\n toggleTag(title,tags["cols"+newNumCols]);\n }\n else if (currentSortBy == which) {\n // toggle sort order\n var newSortOrder = (currentSortOrder == "asc" ? "desc" : "asc");\n removeTag(title,tags[currentSortOrder]);\n if (newSortOrder != config.macros.tagglyListWithSort.defaults.sortOrder)\n toggleTag(title,tags[newSortOrder]);\n }\n else {\n // change sortBy only\n removeTag(title,tags["title"]);\n removeTag(title,tags["created"]);\n removeTag(title,tags["modified"]);\n\n if (which != config.macros.tagglyListWithSort.defaults.sortBy)\n toggleTag(title,tags[which]);\n }\n\n store.setDirty(true); // save is required now.\n story.refreshTiddler(title,false,true); // force=true\n}\n\nconfig.macros.tagglyListControl.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n var onclick = function(e) {\n if (!e) var e = window.event;\n handleSortClick(tiddler.title,params[0]);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return false;\n };\n createTiddlyButton(place,getSortLabel(tiddler.title,params[0]),"Click to change sort options",onclick,params[0]=="hide"?"hidebutton":"button");\n}\n//}}}\n/***\n\n!tagglyListWithSort\nput it all together..\n***/\n//{{{\nconfig.macros.tagglyListWithSort.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n if (tiddler && store.getTaggedTiddlers(tiddler.title).length > 0)\n wikify(\n "<<tagglyListControl hide>>"+\n (getHideState(tiddler.title) != "hide" ? \n '<html><span class="tagglyLabel">'+config.macros.tagglyList.label.format([tiddler.title])+' </span></html>'+\n "<<tagglyListControl title>><<tagglyListControl modified>><<tagglyListControl created>><<tagglyListControl cols>><<tagglyListControl group>>\sn" + \n "<<tagglyList" + (getGroupState(tiddler.title)=="group"?"ByTag ":" ") + getSortBy(tiddler.title)+" "+getSortOrder(tiddler.title)+" "+getNumCols(tiddler.title)+">>" // hacky\n // + \sn----\sn" +\n //"<<tagglyList "+getSortBy(tiddler.title)+" "+getSortOrder(tiddler.title)+">>"\n : ""),\n place,null,tiddler);\n}\n\n//}}}\n/***\n\n!hideSomeTags\nSo we don't see the sort tags.\n(note, they are still there when you edit. Will that be too annoying?\n***/\n//{{{\n\n// based on tags.handler\nconfig.macros.hideSomeTags.handler = function(place,macroName,params,wikifier,paramString,tiddler) {\n var theList = createTiddlyElement(place,"ul");\n if(params[0] && store.tiddlerExists[params[0]])\n tiddler = store.getTiddler(params[0]);\n var lingo = config.views.wikified.tag;\n var prompt = tiddler.tags.length == 0 ? lingo.labelNoTags : lingo.labelTags;\n createTiddlyElement(theList,"li",null,"listTitle",prompt.format([tiddler.title]));\n for(var t=0; t<tiddler.tags.length; t++)\n if (!this.tagsToHide.contains(tiddler.tags[t])) // this is the only difference from tags.handler...\n createTagButton(createTiddlyElement(theList,"li"),tiddler.tags[t],tiddler.title);\n\n}\n\n//}}}\n/***\n\n!Refresh everything when we save a tiddler. So the tagged lists never get stale. Is this too slow???\n***/\n//{{{\n\nfunction refreshAllVisible() {\n story.forEachTiddler(function(title,element) {\n story.refreshTiddler(title,false,true);\n });\n}\n\nstory.saveTiddler_orig_mptw = story.saveTiddler;\nstory.saveTiddler = function(title,minorUpdate) {\n var result = this.saveTiddler_orig_mptw(title,minorUpdate);\n refreshAllVisible();\n return result;\n}\n\nstore.removeTiddler_orig_mptw = store.removeTiddler;\nstore.removeTiddler = function(title) {\n this.removeTiddler_orig_mptw(title);\n refreshAllVisible();\n}\n\n//}}}\n\n// // <html>▸▾−±</html>
/***\nCosmetic fixes that probably should be included in a future TW...\n***/\n/*{{{*/\n.viewer .listTitle { list-style-type:none; margin-left:-2em; }\n.editorFooter .button { padding-top: 0px; padding-bottom:0px; }\n/*}}}*/\n/***\nImportant stuff. See TagglyTaggingStyles\n***/\n/*{{{*/\n[[TagglyTaggingStyles]]\n/*}}}*/\n/***\nClint's fix for weird IE behaviours\n***/\n/*{{{*/\nbody {position:static;}\n.tagClear{margin-top:1em;clear:both;}\n/*}}}*/\n/***\nJust colours, fonts, tweaks etc. See SideBarWhiteAndGrey\n***/\n/*{{{*/\nbody {background:#eee; }\na{ color: #069; }\na:hover{ background: #069; color: #fff; }\n.popup { background: #178; border: 1px solid #069; }\n.headerForeground a { color: #6fc;}\n.headerShadow { left: 2px; top: 2px; }\n.title { padding:0px; margin:0px; }\n.siteSubtitle { padding:0px; margin:0px; padding-left:1.5em; }\n.subtitle { font-size:90%; color:#ccc; padding-left:0.25em; }\nh1,h2,h3,h4,h5 { color: #000; background: transparent; }\n.title {color:black; font-size:2em;}\n.shadow .title {color:#999; }\n.viewer pre { background-color:#f8f8ff; border-color:#ddf}\n.viewer { padding-top:0px; }\n#sidebarOptions { border:1px #ccc solid; }\n.tiddler {\n border-bottom:1px solid #ccc; border-right:1px solid #ccc; padding-bottom:1em; margin-bottom:1em; \n background:#fff; padding-right:1.5em; }\n#messageArea { background-color:#bde; border-color:#8ab; border-width:4px; border-style:dotted; font-size:90%; }\n#messageArea .button { text-decoration:none; font-weight:bold; background:transparent; border:0px; }\n#messageArea .button:hover {background: #acd; }\n[[SideBarWhiteAndGrey]]\n#adsense { margin: 1em 15.7em 0em 1em; border:1px solid #ddd; background:#f8f8f8; text-align:center;margin-bottom:1em;overflow:hidden;padding:0.5em;} \n/*}}}*/\n
\n.tagglyTagged li.listTitle { display:none;}\n.tagglyTagged li { display: inline; font-size:90%; }\n.tagglyTagged ul { margin:0px; padding:0px; }\n.tagglyTagging { padding-top:0.5em; }\n.tagglyTagging li.listTitle { display:none;}\n.tagglyTagging ul { margin-top:0px; padding-top:0.5em; padding-left:2em; margin-bottom:0px; padding-bottom:0px; }\n\n\n/* .tagglyTagging .tghide { display:inline; } */\n\n.tagglyTagging { vertical-align: top; margin:0px; padding:0px; }\n.tagglyTagging table { margin:0px; padding:0px; }\n\n\n.tagglyTagging .button { display:none; margin-left:3px; margin-right:3px; }\n.tagglyTagging .button, .hidebutton { color:#aaa; font-size:90%; border:0px; padding-left:0.3em;padding-right:0.3em;}\n.tagglyTagging .button:hover, .hidebutton:hover { background:#eee; color:#888; }\n.selected .tagglyTagging .button { display:inline; }\n\n.tagglyLabel { color:#aaa; font-size:90%; }\n\n.tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }\n.tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}\n.tagglyTagging ul ul li {margin-left:0.5em; }\n\n.editLabel { font-size:90%; padding-top:0.5em; }\n
/***\n''TextAreaPlugin for TiddlyWiki version 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#TextAreaPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nThis plugin 'hijacks' the TW core function, ''Story.prototype.focusTiddler()'', so it can add special 'keyDown' handlers to adjust several behaviors associated with the textarea control used in the tiddler editor. Specifically, it:\n* Adds text search INSIDE of edit fields.^^\nUse ~CTRL-F for "Find" (prompts for search text), and ~CTRL-G for "Find Next" (uses previous search text)^^\n* Enables TAB characters to be entered into field content^^\n(instead of moving to next field)^^\n* Option to set cursor at top of edit field instead of auto-selecting contents^^\n(see configuration section for checkbox)^^\n!!!!!Configuration\n<<<\n<<option chkDisableAutoSelect>> place cursor at start of textarea instead of pre-selecting content\n<<option chkTextAreaExtensions>> add control-f (find), control-g (find again) and allow TABs as input in textarea\n<<<\n!!!!!Installation\n<<<\nImport (or copy/paste) the following tiddlers into your document:\n''TextAreaPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2006.01.22 [1.0.1]''\nonly add extra key processing for TEXTAREA elements (not other edit fields).\nadded option to enable/disable textarea keydown extensions (default is "standard keys" only)\n''2006.01.22 [1.0.0]''\nMoved from temporary "System Tweaks" tiddler into 'real' TextAreaPlugin tiddler.\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.textAreaPlugin= {major: 1, minor: 0, revision: 1, date: new Date(2006,1,23)};\n//}}}\n\n//{{{\nif (!config.options.chkDisableAutoSelect) config.options.chkDisableAutoSelect=false; // default to standard action\nif (!config.options.chkTextAreaExtensions) config.options.chkTextAreaExtensions=false; // default to standard action\n\n// Focus a specified tiddler. Attempts to focus the specified field, otherwise the first edit field it finds\nStory.prototype.focusTiddler = function(title,field)\n{\n var tiddler = document.getElementById(this.idPrefix + title);\n if(tiddler != null)\n {\n var children = tiddler.getElementsByTagName("*")\n var e = null;\n for (var t=0; t<children.length; t++)\n {\n var c = children[t];\n if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea")\n {\n if(!e)\n e = c;\n if(c.getAttribute("edit") == field)\n e = c;\n }\n }\n if(e)\n {\n e.focus();\n e.select(); // select entire contents\n\n // TWEAK: add TAB and "find" key handlers\n if (config.options.chkTextAreaExtensions) // add extra key handlers\n addKeyDownHandlers(e);\n\n // TWEAK: option to NOT autoselect contents\n if (config.options.chkDisableAutoSelect) // set cursor to start of field content\n if (e.setSelectionRange) e.setSelectionRange(0,0); // for FF\n else if (e.createTextRange) { var r=e.createTextRange(); r.collapse(true); r.select(); } // for IE\n\n }\n }\n}\n//}}}\n\n//{{{\nfunction addKeyDownHandlers(e)\n{\n // exit if not textarea or element doesn't allow selections\n if (e.tagName.toLowerCase()!="textarea" || !e.setSelectionRange) return;\n\n // utility function: exits keydown handler and prevents browser from processing the keystroke\n var processed=function(ev) { ev.cancelBubble=true; if (ev.stopPropagation) ev.stopPropagation(); return false; }\n\n // capture keypress in edit field\n e.onkeydown = function(ev) { if (!ev) var ev=window.event;\n\n // process TAB\n if (!ev.shiftKey && ev.keyCode==9) { \n // replace current selection with a TAB character\n var start=e.selectionStart; var end=e.selectionEnd;\n e.value=e.value.substr(0,start)+String.fromCharCode(9)+e.value.substr(end);\n // update insertion point, scroll it into view\n e.setSelectionRange(start+1,start+1);\n var linecount=e.value.split('\sn').length;\n var thisline=e.value.substr(0,e.selectionStart).split('\sn').length-1;\n e.scrollTop=Math.floor((thisline-e.rows/2)*e.scrollHeight/linecount);\n return processed(ev);\n }\n\n // process CTRL-F (find matching text) or CTRL-G (find next match)\n if (ev.ctrlKey && (ev.keyCode==70||ev.keyCode==71)) {\n // if ctrl-f or no previous search, prompt for search text (default to previous text or current selection)... if no search text, exit\n if (ev.keyCode==70||!e.find||!e.find.length)\n { var f=prompt("find:",e.find?e.find:e.value.substring(e.selectionStart,e.selectionEnd)); e.focus(); e.find=f?f:e.find; }\n if (!e.find||!e.find.length) return processed(ev);\n // do case-insensitive match with 'wraparound'... if not found, alert and exit \n var newstart=e.value.toLowerCase().indexOf(e.find.toLowerCase(),e.selectionStart+1);\n if (newstart==-1) newstart=e.value.toLowerCase().indexOf(e.find.toLowerCase());\n if (newstart==-1) { alert("'"+e.find+"' not found"); e.focus(); return processed(ev); }\n // set new selection, scroll it into view, and report line position in status bar\n e.setSelectionRange(newstart,newstart+e.find.length);\n var linecount=e.value.split('\sn').length;\n var thisline=e.value.substr(0,e.selectionStart).split('\sn').length;\n e.scrollTop=Math.floor((thisline-1-e.rows/2)*e.scrollHeight/linecount);\n window.status="line: "+thisline+"/"+linecount;\n return processed(ev);\n }\n }\n}\n//}}}
! UART (interface RS232)\n\nLe processeur ~SH4 dispose de deux UART (appelés //SCI// et //SICF//), dont un (//SCIF//) avec fifo et lignes de contrôle de flux. Les deux UART disposent sur la carte de transceivers électriques RS232. Les signaux de contrôle du SCIF ({{{RTS}}} et {{{CTS}}}) sont câblés.\n\nAttention :\n* {{{CTS}}} : ce signal est une entrée du ~SH4, qui est bien un Clear To Send : si elle est à l'état bas, le ~SH4 peut envoyer des données, sinon la transmission est bloquée.\n* {{{RTS}}} : ce signal est une sortie du ~SH4. Il est asserté (état bas) quand le ~SH4 peut recevoir des données (le seuil de déclenchement, en fonction du remplissement de la FIFO est réglable en soft).\n\n!! SCIF : UART avec contrôle de flux\nLe problème avec les signaux de contrôle de flux est qu'ils n'ont pas de signification fixe. Au fur et à mesure de l'évolution des technologies, leur signification a évoluée, parfois de façon incompatible. Pour plus de renseignements, on consultera le [[Linux Serial HOWTO|http://www.tldp.org/HOWTO/Serial-HOWTO-20.html#ss20.4]] ou [[cette page-ci|http://www.lammertbies.nl/comm/info/RS-232_null_modem.html]]. Pour compliquer le problème, les logiciels utilisés pour communiquer sur ligne série (minicom, ...) ne gèrent pas tous tous les protocoles de contrôle de flux hardware.\n\nLe développement de la carte s'étant effectué au début sous Windows, pour lequel tous les protocoles de contrôle {{{RTS/CTS}}} et {{{DSR/DTR}}} ne sont pas implémentés, il a fallu réaliser un câblage des pins de contrôle en adéquation avec le procole utilisé par le logiciel de terminal sur le PC. En utilisant TeraTerm 3.1 pour le logiciel de contrôle du port série, avec flow-control hardware, le câble est réalisé comme indiqué dans le tableau ci-dessous. En d'autres termes, les broches {{{CTS/RTS}}} côté SH4 sont mappées sur {{{DSR/DTR}}} côté PC, et on utilise alors le protocole {{{DSR/DTR}}} sur le logiciel de terminal (TeraTerm, mais Hyperterminal fonctionne correctement aussi avec ce mapping-ci).\n\n| Pin ~SH4 | Broche micromatch | Broche prise ~RS232 femelle | Pin PC | Direction |h\n| RX | 3 | 3 | TX | PC vers ~SH4 |\n| TX | 5 | 2 | RX | ~SH4 vers PC |\n| CTS | 6 | 4 | DTR | PC vers ~SH4 |\n| RTS | 4 | 1, 8, 6 | CD, DSR, RI | ~SH4 vers PC |\n| GND | 1, 9 | 5 | GND | |\n\n''Note'' : la broche 1 du micromatch est la broche côté du détrompeur\n\n!! SCI : UART sans contrôle de flux\n\nIci, pas de subtilités, il suffit de brancher RX, TX et GND. Le brochage du câble est le suivant :\n\n| Pin ~SH4 | Broche micromatch | Broche prise ~RS232 femelle | Pin PC | Direction |h\n| RX | 2 | 3 | TX | PC vers ~SH4 |\n| TX | 1 | 2 | RX | ~SH4 vers PC |\n| GND | 3, 4 | 5 | GND | |\n\n''Note'' : la broche 1 du micromatch est la broche côté du détrompeur\n\n
/***\n''UnformattedTextPlugin for TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#UnformattedTextPlugin \nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nAdd //extended quotes// around specific tiddler content to prevent any embedded formatting syntax from being processed by TiddlyWiki's rendering engine, so the content will appear exactly as entered into the tiddler (i.e., "raw text"), even when it contains character sequences that would normally be treated as TiddlyWiki formatting instructions.\n!!!!!Usage\n<<<\nWhen installed, this plugin adds new wiki syntax for surrounding tiddler content so that it can be excluded from the TiddlyWiki formatting rules when it is rendered.\n//{{{\n"""content goes here"""\n//}}}\nwhere:\n* {{{"""}}} //(three double-quote characters)//^^\nmarks the start and end of the unformatted content^^\n<<<\n!!!!!Examples\n<<<\nContent containing TiddlyWiki formatting syntax can be shown with the syntax unchanged:\n{{{\n"""this text is //not italic// and <<not a macro>> and [[not a link]]"""\n}}}\n"""this text is //not italic// and <<not a macro>> and [[not a link]]"""\n\nNote that, although formatting syntax contained ''within'' the quoted content does not affect the style of the output, any formatting syntax ''surrounding'' the quoted content will still be applied. For example, the following unformatted output will be underlined:\n{{{\n__"""this text is //not italic// and <<not a macro>> and [[not a link]], but it IS underlined"""__\n}}}\n__"""this text is //not italic// and <<not a macro>> and [[not a link]], but it IS underlined"""__\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''UnformattedTextPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2005.11.07 [1.0.0]''\ninitial release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.unformattedText = {major: 0, minor: 5, revision: 0, date: new Date(2005,11,07)};\n\nconfig.formatters.push( {\n name: "rawText",\n match: "\s\s\s"{3}",\n lookahead: "\s\s\s"{3}((?:.|\s\sn)*?)\s\s\s"{3}",\n handler: function(w)\n {\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 {\n var e = createTiddlyElement(w.output,"span",null,null,lookaheadMatch[1]);\n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n }\n }\n }\n)\n//}}}\n
|!Date|!url|!toFilename|!backupDir|!user|!status|\n| 23/2/2006 19:5:17 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 23/2/2006 19:44:49 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 23/2/2006 20:19:44 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 23/2/2006 20:22:14 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 24/2/2006 2:6:24 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 24/2/2006 2:12:59 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 24/2/2006 2:29:43 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 24/2/2006 2:31:51 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 24/2/2006 2:37:38 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 24/2/2006 2:59:4 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 24/2/2006 3:6:52 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 24/2/2006 3:8:41 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 24/2/2006 3:13:55 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 24/2/2006 3:15:0 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 24/2/2006 3:16:27 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 24/2/2006 3:24:20 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 24/2/2006 3:30:23 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 24/2/2006 19:25:13 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 26/2/2006 17:48:58 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 26/2/2006 18:31:16 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 26/2/2006 18:32:14 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 26/2/2006 19:3:59 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 26/2/2006 19:7:1 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 26/2/2006 19:12:45 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 26/2/2006 22:11:40 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 26/2/2006 22:40:17 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 26/2/2006 22:47:40 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 26/2/2006 23:17:0 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 26/2/2006 23:19:30 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 27/2/2006 19:50:23 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 27/2/2006 19:54:45 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 27/2/2006 19:59:37 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 27/2/2006 20:7:17 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 27/2/2006 20:10:42 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 27/2/2006 20:51:29 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 28/2/2006 16:4:44 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 16:12:26 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 16:13:44 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 16:14:26 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 16:14:48 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 16:39:18 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 17:13:37 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 19:4:22 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 19:4:56 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 19:27:53 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 19:30:43 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 28/2/2006 19:31:13 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 1/3/2006 0:41:57 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 1/3/2006 0:43:43 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 1/3/2006 13:52:50 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 8/3/2006 1:15:56 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 8/3/2006 1:16:39 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |\n| 9/3/2006 13:49:32 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti | ok |\n| 10/3/2006 2:20:34 | [[store.php|http://perso.enst.fr/~polti/realisations/shix20/doc/store.php]] | [[index.html|http://perso.enst.fr/~polti/realisations/shix20/doc/index.html]] | back | AlexisPolti |
!Options used by UploadPlugin\nUsername : <<option txtUploadUserName>>\nPassword : <<option pasUploadPassword>>\n\nUrl of the [[store.php]] script^^(1)^^ : <<option txtUploadStoreUrl>>\nFilename of the uploaded file^^(2)^^ : <<option txtUploadFilename>>\nDirectory to backup file on webserver^^(3)^^ : <<option txtUploadBackupDir>>\n\n^^(1)^^Mandatory either in UploadOptions or in MacroParameter\n^^(2)^^If omitted take the actual filename\n^^(3)^^If omitted existing file with same name on webserver will be overwriten\n\n!Macro\n{{{<<upload [[UploadStoreUrl]}}}^^(1)^^{{{ [UploadFilename] [UploadBackupDir]]>>}}}\n\n<<upload>>
/***\n\n\n----\nUploadPlugin, with [[store.php]], provides @@upload@@ and @@save to web@@ functions. See [[HowToUpload|http://TiddlyWiki.bidix.info/#HowToUpload]].\nUploadPlugin uses Username and Password from UploadOptions stored in cookies to authenticate itself to [[store.php]].\nThe french translation available as a separate tiddler UploadPluginMsgFR\n----\n\n\n***/\n\n/***\n|''Name:''|UploadPlugin|\n|''Type:''|Plugin|\n|''Version:''|3.2.1 (16/02/2006)|\n|''Source:''|[[TiddlyWiki.BidiX.info/#UploadPlugin|http://tiddlywiki.BidiX.info/#UploadPlugin]]|\n|''Author:''|BidiX[at]BidiX.info|\n|''Compatibility:''|TW1.2 & TW2 & FF1.5.0.1|\n!Usage : \n{{{\n<<upload>>\n uses UploadOptions.\n<<upload [storeUrl [toFilename [backupDir]]]>>\n overwrite UploadOptions\n storeUrl : the url of the store.php to upload the TiddlyWiki\n toFilename : the filename in the storeUrl directory\n backupDir : if present backup the previous toFilename file\n to the backupDir directory\n}}}\n\nInstall the {{{<<upload ... >>}}} macro in SideBarOptions just below {{{<<saveChanges>>}}} macro.\n\n!Description\n!!UploadPlugin\n*If the TiddlyWiki is viewed from @@local disk@@ :\n**{{{<<saveChanges>>}}} \n***display as ''save to disk''\n***work as usual\n**{{{<<upload>>}}}\n***display as ''upload''\n***after saving to disk, upload in the storeUrl directory.\n*If the TiddlyWiki is viewed from @@website@@ :\n**{{{<<saveChanges>>}}} \n***print nothing\n***has been disabled\n**{{{<<upload>>}}}\n***display as '''save to web''\n***save in the storeUrl directory.\n*If GenerateAnRssFeed in AdvancedOptions is set :\n**generate the content of the RSSFeed \n**upload the RssFile in the same directory\n**Caution : use the SiteUrl tiddler to specify the right url of the TiddlyWiki in the generated RssFile\n*DisplayMessage\n*Log upload action in UploadLog\nhint : if UploadLog is the first tiddler in the Timeline Tab, no tiddler has been updated since last upload.\n\n!![[store.php]]\n*UserVariables to set :\n//{{{\n$AUTHENTICATE_USER = true; // true | false\n$USER = 'UsernameToCheck'; // set a Username\n$PASSWORD = 'PasswordToCheck'; // set a strong password\n$DEBUG = false; // true | false\n//}}}\n*method GET\n**display an information page\n*method POST\n**if $~AUTHENTICATE_USER is ''true''\n***presence and value of user and password are checked with $USER and $PASSWORD \n**if toFilename already exists and backDir parameter specified\n***rename toFilename to backupDir/toFilename.AAAAMMDD.HHSS.html\n**copy temporaryUploadedFile to toFilename\n** return status\n\n!User manual\nSee HowToUpload\n\n!Installation :\n*Install the UploadPlugin as usual\n*Upload the [[store.php]] file on your php aware webserver in your TiddlyWiki directory\n*Protect against malicious upload. Two approaches :\n**set $~AUTHENTICATE_USER to true in the [[store.php]] script\n***configure $USER and $PASSWORD in the [[store.php]] script on your webserver\n***set UploadOptions in conformity with [[store.php]]\n**Use server protection :\n***for Apache web server ([[for detail see Apache documentation|http://httpd.apache.org/docs/1.3/howto/htaccess.html]]) : \n****configure and upload the [[.htaccess]] [[.passwd]]\n***for other web servers see the appropriate documentation\n*Configure an upload button, for example in the SideBarOptions\n!Suppported Browser\n*Firefox : tested Ok\n*Internet Explorer : tested Ok\n*Safari : reported ok on OS X\n*Others : Not tested, please report status.\n\n!Revision history\n*V3.2.1 (13/02/2006)\n**name and password added to open.request (Thanks to TedPavlic)\n*V3.2.0 (14/02/2006)\n**Use PassworDTweak (http://tiddlyWiki.bidix.info/#PasswordTweak) for password\n*V3.1.0 (12/02/2006)\n**UploadOptions in Cookies\n**Username and password from UploadOptions pass to store.php script for authentification check\n*V3.0.3 (03/02/2006)\n**Firefox 1.5.0.1 crashes due to global var fixed\n*V3.0.2 (25-Jan-2006)\n**HTTPS compatible\n*V3.0.1 (18-Jan-2006)\n**UTF8toUnicode conversion problem in Firefox\n*V3.0.0 (15-Jan-2006)\n**Asynchronous upload\n**Synchronous upload before unload of the page\n**All strings extracted in macro config\n**Compatibility checked with TW 2.0.2 & TW 1.2.39 for both FF 1.5 and IE 6\n*V2.0.2 (8-Jan-2006)\n**conversion of SiteTitle and SiteSubtitle in web page Title\n*V2.0.1 (8-Jan-2006)\n**Compatibilty with TiddlyWiki 2.0.1\n*V2.0.0 (3-Jan-2006)\n**Save to web\n**Compatibilty with TiddlyWiki 1.2.39 and TiddlyWiki 2.0.0 Beta 6\n*v1.1.0 (27-Dec-2005)\n**Upload RSS File\n*v1.0.3 (26-Dec-2005)\n**UploadLog tiddler\n*v1.0.2 (24-Dec-2005)\n**Optional parameter toFilename\n**Optional parameter backupDir\n*v1.0.1 (23-Dec-2005)\n**reformatting code\n* v1.0.0 (17-Dec-2005)\n** first public working version\n\n\n!Code\n***/\n//{{{\nversion.extensions.UploadPlugin = {major: 3, minor: 2, revision: 1, date: new Date(2006,2,16)};\n//}}}\n/***\n!! Macro definition\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 var storeUrl;\n if (params[0]) {\n storeUrl = params[0];\n this.defaultStoreScript = basename(storeUrl);\n }\n var toFilename=params[1];\n var backupDir=params[2];\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([dirname(storeUrl)]);\n }\n else {\n prompt = this.label.promptOption;\n }\n createTiddlyButton(place, label, prompt, \n function () {upload(storeUrl, toFilename, backupDir, true); return false;}, \n null, null, this.accessKey);\n};\n//}}}\n/***\n!! UploadOPtions stored in cookies\n***/\n//{{{\nconfig.options.txtUploadStoreUrl = 'UploadStoreUrl';\nconfig.options.txtUploadFilename = 'UploadFilename ';\nconfig.options.txtUploadBackupDir = 'UploadBackupDir ';\nconfig.options.txtUploadUserName = config.options.txtUserName;\nconfig.options.pasUploadPassword = 'UploadPassword ';\n//We have to reload Cookies because options are loaded before systemConfigs\nloadOptionsCookie();\n//}}}\n/***\n!!Core tweaks\n***/\n//{{{\n// overwrite the saveChanges handler \n// configure no Macro instead of saveChanges Macro in case of http: access\nconfig.macros.saveChanges.label = config.macros.upload.label.saveToDisk;\nconfig.macros.saveChanges.handler = function(place,macroName,params)\n{\n if(!readOnly) {\n if (document.location.toString().substr(0,4) != "http") \n createTiddlyButton(place,this.label,this.prompt,function () {saveChanges(); return false;},null,null,this.accessKey);\n // else no TiddlyButton\n }\n};\n\n// Check if there is any unsaved changes before exiting\n// if unsaved changes : saveOrUpload\n//function checkUnsavedChanges()\ncheckUnsavedChanges = function ()\n{\n if(store && store.dirty) {\n if(confirm(config.messages.unsavedChangesWarning))\n saveOrUpload(false); // Because called by <body onunload=... Upload must be synchronous\n }\n};\n\n// saveOrUpload\nfunction saveOrUpload(asynchronous) {\n if (document.location.toString().substr(0,4) == "http") {\n // try a default synchronous upload\n var url = dirname(document.location.toString())+"/"+ config.macros.upload.defaultStoreScript;\n upload(url, null, null, asynchronous);\n }\n else \n saveChanges();\n}\n\n//}}}\n/***\n!!Utility functions \n***/\n//{{{\nfunction dirname(filePath)\n{\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(0, lastpos);\n }\n else\n return filePath.substring(0, filePath.lastIndexOf("\s\s"));\n}\n\nfunction basename(filePath)\n{\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 }\n else\n return filePath.substring(filePath.lastIndexOf("\s\s")+1);\n}\n\n// TiddlyWiki utilities\n\nfunction getLocalPath() {\n //extract from the Jeremy's SaveFile \n var originalPath = document.location.toString();\n // Check we were loaded from a file URL\n if(originalPath.substr(0,5) != "file:")\n {\n alert(config.messages.notFileUrlError);\n displayTiddler(null,"SaveChanges",0,null,null,false,false);\n return;\n }\n // Remove any location part of the URL\n var hashPos = originalPath.indexOf("#");\n if(hashPos != -1)\n originalPath = originalPath.substr(0,hashPos);\n // Convert to a native file format assuming\n // "file:///x:/path/path/path..." - pc local file --> "x:\spath\spath\spath..."\n // "file://///server/share/path/path/path..." - FireFox pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n // "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."\n // "file://server/share/path/path/path..." - pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n var localPath;\n if(originalPath.charAt(9) == ":") // pc local file\n localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file:///") === 0) // mac/unix local file\n localPath = unescape(originalPath.substr(7));\n else if(originalPath.indexOf("file:/") === 0) // mac/unix local file\n localPath = unescape(originalPath.substr(5));\n else // pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\s\s");\n return localPath;\n}\n\n//}}}\n/***\n!! UploadLog \n***/\n//{{{\n\nfunction getUploadLogTiddler() {\n var tiddler;\n if (version.major < 2)\n tiddler = store.tiddlers['UploadLog'];\n else\n tiddler = store.getTiddler("UploadLog");\n if (!tiddler) \n {\n tiddler = new Tiddler();\n tiddler.title = 'UploadLog';\n tiddler.text = "|!Date|!url|!toFilename|!backupDir|!user|!status|";\n if (version.major < 2)\n store.tiddlers['UploadLog'] = tiddler;\n else\n store.addTiddler(tiddler);\n }\n return tiddler;\n}\n\nfunction uploadLog(url, toFilename, backupDir) \n{\n var tiddler = getUploadLogTiddler();\n var now = new Date();\n var newText = "| ";\n //newText += now.toLocaleString() + " | ";\n \n newText += now.getDate()+"/"+(now.getMonth()+1)+"/"+now.getFullYear() + " ";\n newText += now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+" | ";\n newText += "[["+basename(url)+"|"+url + "]] | ";\n newText += "[["+basename(toFilename) + "|" + dirname(url)+"/"+basename(toFilename) + "]] | ";\n newText += backupDir + " | ";\n newText += config.options.txtUserName + " |";\n\n tiddler.text = tiddler.text + "\sn" + newText;\n tiddler.modifier = config.options.txtUserName;\n tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers['UploadLog'] = tiddler;\n else\n store.addTiddler(tiddler);\n //displayTiddler(document.getElementById('sidebar'),"UploadLog",1,null,null,false);\n if (version.major < 2)\n store.notifyAll();\n}\n\nfunction uploadLogStatusOk() \n{\n var tiddler = getUploadLogTiddler();\n var newText = " ok |";\n tiddler.text = tiddler.text + newText;\n tiddler.modifier = config.options.txtUserName;\n tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers['UploadLog'] = tiddler;\n else\n store.addTiddler(tiddler);\n //displayTiddler(document.getElementById('sidebar'),"UploadLog",1,null,null,false);\n if (version.major < 2)\n store.notifyAll();\n store.notify('UploadLog',true);\n}\n\n//}}}\n\n/***\n!! download file before uploading it\n***/\n//{{{\n\nfunction download(uploadUrl, uploadToFilename, uploadBackupDir, asynchronous) {\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 netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n }\n else {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n }\n } catch (e) { }\n\n request.open("GET",document.location.toString(), asynchronous, config.options.txtUploadUserName,\nconfig.options.pasUploadPassword);\n if (asynchronous) {\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if(request.status == 200) {\n uploadChangesFrom(uploadUrl, uploadToFilename, uploadBackupDir, request.responseText, asynchronous);\n }\n else\n alert(config.macros.upload.messages.errorDownloading.format([document.location.toString()]));\n }\n };\n }\n request.send(null);\n if (! asynchronous) {\n if(request.status == 200) {\n uploadChangesFrom(uploadUrl, uploadToFilename, uploadBackupDir, request.responseText, asynchronous);\n }\n else\n alert(config.macros.upload.messages.errorDownloading.format([document.location.toString()]));\n }\n\n}\n\n//}}}\n\n/***\n!! Upload functions\n***/\n//{{{\n\nfunction upload(url, toFilename, backupDir, asynchronous)\n{\n clearMessage();\n // only for forcing the message to display\n if (version.major < 2)\n store.notifyAll();\n // determine good url\n if (!url) {\n url = config.options.txtUploadStoreUrl;\n }\n if ((!url) && (document.location.toString().substr(0,4) == "http")) {\n url = basename(document.location.toString())+"/"+config.macros.upload.defaultStoreScript;\n }\n if (!url) {\n alert(config.macros.upload.messages.urlParamMissing);\n return;\n }\n // backupdir\n if (!backupDir) {\n backupDir = config.options.txtUploadBackupDir;\n }\n if (!backupDir) {\n backupDir = '';\n }\n \n // UploadFilename\n var toPath;\n if (toFilename)\n toPath = toFilename;\n else {\n if (config.options.txtUploadFilename) {\n toPath = config.options.txtUploadFilename;\n }\n else {\n toPath = basename(document.location.toString());\n }\n }\n \n uploadLog(url, toPath, backupDir);\n if (document.location.toString().substr(0,5) == "file:") {\n saveChanges();\n }\n displayMessage(config.macros.upload.messages.aboutToUpload.format([dirname(url)]), dirname(url));\n uploadChanges(url, toPath, backupDir, asynchronous);\n if(config.options.chkGenerateAnRssFeed) {\n //var rssContent = convertUnicodeToUTF8(generateRss());\n var rssContent = generateRss();\n var rssPath = toPath.substr(0,toPath.lastIndexOf(".")) + ".xml";\n uploadContent(url, rssContent, rssPath, '', asynchronous, function (responseText) {\n if (responseText.substring(0,1) != 0) {\n alert(responseText);\n displayMessage(config.macros.upload.messages.rssFileNotUploaded.format([rssPath]));\n }\n else {\n displayMessage(config.macros.upload.messages.rssFileUploaded.format([dirname(url)+"/"+basename(rssPath)]), dirname(url)+"/"+basename(rssPath));\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n }\n );\n }\n return;\n}\n\nfunction uploadChanges(url, toFilename, backupDir, asynchronous)\n{\n var original;\n if (document.location.toString().substr(0,4) == "http") {\n original = download(url, toFilename, backupDir, asynchronous);\n return;\n }\n else {\n // standard way : Local file\n original = loadFile(getLocalPath());\n if(window.Components)\n // it's a mozilla browser\n try {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]\n .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);\n converter.charset = /* The character encoding you want, using UTF-8 here */ "UTF-8";\n original = converter.ConvertToUnicode(original);\n }\n catch(e) {\n }\n }\n //DEBUG alert(original);\n uploadChangesFrom(url, toFilename, backupDir, original, asynchronous);\n}\n\nfunction uploadChangesFrom(url, toFilename, backupDir, original, asynchronous)\n{\n\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 // I think conversion is automatically done\n //var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n // convertUnicodeToUTF8(allTiddlersAsHtml()) + "\sn\st\st" +\n // original.substr(posClosingDiv);\n \n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n allTiddlersAsHtml() + "\sn\st\st" +\n original.substr(posClosingDiv);\n\n // I think conversion is automatically done\n // var newSiteTitle = convertUnicodeToUTF8((getElementText("siteTitle") + " - " + getElementText("siteSubtitle")).htmlEncode());\n var newSiteTitle;\n if(version.major < 2){ //version is set in core TW code\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 = uploadContent(url, revised, toFilename, backupDir, asynchronous, function (responseText) {\n if (responseText.substring(0,1) != 0) {\n alert(responseText);\n displayMessage(config.macros.upload.messages.fileNotUploaded.format([getLocalPath()]));\n }\n else {\n displayMessage(config.macros.upload.messages.mainFileUploaded.format([dirname(url)+"/"+basename(toFilename)]), dirname(url)+"/"+basename(toFilename));\n uploadLogStatusOk();\n store.setDirty(false);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n }\n );\n}\n\nfunction uploadContent(url, content, toPath, backupDir, asynchronous, callbackFn) {\n var boundary = "---------------------------"+"AaB03x";\n //Create XMLHttpRequest Object\n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n try {\n // Needed for Mozilla if local file tries to access an http URL\n if (document.location.toString().substr(0,4) == "http") {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n }\n else {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n }\n } catch (e) { }\n \n //DEBUG alert("user["+config.options.txtUploadUserName+"] password[" + config.options.pasUploadPassword + "]");\n // compose headers data\n var sheader = "\sr\sn";\n sheader += "--" + boundary + "\sr\snContent-disposition: form-data;name=\s"" + config.macros.upload.formName +"\s"\sr\sn\sr\sn";\n sheader += "backupDir="+backupDir+";user=" + config.options.txtUploadUserName +";password="+config.options.pasUploadPassword + ";\sr\sn"; \n sheader += "\sr\sn" + "--" + boundary + "\sr\sn";\n sheader += "Content-disposition: form-data;name=\s"userfile\s";filename=\s""+toPath+"\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 request.open("POST",url,asynchronous, config.options.txtUploadUserName, config.options.pasUploadPassword);\n if (asynchronous) {\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 }\n request.setRequestHeader("Content-Length",data.length);\n request.setRequestHeader("Content-Type","multipart/form-data; boundary="+boundary);\n request.send(data); \n if (! asynchronous) {\n if(request.status == 200)\n callbackFn(request.responseText);\n else\n alert(config.macros.upload.messages.errorUploadingContent);\n }\n\n}\n\n//}}}\n\n/***\n\n\n----\nPasswordTweak implements the PasswordOption\n----\n\n\n***/\n\n/***\n|''Name:''|PasswordTweak|\n|''Type:''|tweak|\n|''Version:''|1.0.0 (14/02/2006)|\n|''Source:''|[[TiddlyWiki.BidiX.info/#PasswordTweak|http://tiddlywiki.BidiX.info/#PasswordTweak]]|\n|''Author:''|BidiX[at]BidiX.info|\n|''Compatibility:''|TW1.2 & TW2 & FF1.5.0.1|\n!Description : \n*a password option has {{{pas}}} as prefix\n*in a tiddler the {{{<<option pasXXXX>>}}} provide a password input field a checkbox and a text ("Save this password on this computer")\n*when the password field changes ''or'' the checkbox changes the password is saved in a cookie, but only when the associated checkbox is checked\n*config.options.pasPassword is defined for general use. Put it in OptionsPanel\n''Password : '' <<option pasPassword>>\n\n***/\n/***\n!Configs\n***/\n//{{{\nconfig.messages.savePasswordCheckboxLabel = "Save this password on this computer";\nconfig.macros.option.passwordType = "password"; // password | text\n//}}}\n/***\n!option macro\n***/\n//{{{\nversion.extensions.PasswordTweak = {major: 1, minor: 0, revision: 0, date: new Date(2006,2,14)};\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 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 = 15;\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 = 15;\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.messages.savePasswordCheckboxLabel));\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! Options cookie stuff\n***/\n//{{{\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 = 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! config.options.pasPassword \n***/\n//{{{\nconfig.options.pasPassword = 'password';\nwindow.loadOptionsCookie();\n//}}}\n
<!---\n| Name:|~TagglyTaggingViewTemplate |\n| Version:|1.2 (16-Jan-2006)|\n| Source:|http://simonbaird.com/mptw/#TagglyTaggingViewTemplate|\n| Purpose:|See TagglyTagging for more info|\n| Requires:|You need the CSS in TagglyTaggingStyles to make it look right|\n!History\n* 16-Jan-06, version 1.2, added tagglyListWithSort\n* 12-Jan-06, version 1.1, first version\n!Notes\nRemove the miniTag if you don't like it or you don't use QuickOpenTagPlugin\n--->\n<!--{{{-->\n<div class="toolbar" macro="toolbar -closeTiddler closeOthers +editTiddler permalink references jump newHere"></div>\n<div class="tagglyTagged" macro="hideSomeTags"></div>\n<div><span class="title" macro="view title"></span><span class="miniTag" macro="miniTag"></span></div>\n<div class='subtitle'>Updated <span macro='view modified date [[DD MMM, YYYY]]'></span></div>\n<div class="viewer" macro="view text wikified"></div>\n<div class="tagglyTagging" macro="tagglyListWithSort"></div>\n<!--}}}-->\n
!ECC\n\nIl existe deux façons de calculer les ECC : celle de Steve Hill (utilisée dans la couche MTD) et celle de ~SmartMedia. Yaffs prend comme parti que la façon de ~SmartMedia est la bonne, et celle de la couche MTD est inversée (~WRONG_ORDER). On prendra comme convention que l'ordre ECC par défaut de la couche MTD est la bonne, autrement dit {{{CONFIG_YAFFS_ECC_WRONG_ORDER}}} sera défini à chaque fois qu'on touchera à un ECC...\n\n!Cohabitation YAFFS et MTD\n\nLe problème d'interfaçage de YAFFS et de la couche MTD est un problème épineux. Il a été discuté à maintes reprises dans les mailing-list des deux couches en question, sans qu'une réponse correcte soit apportée. Deux patchs temporaires existent : l'un porte sur YAFFS, par Sergei Kubushyn, et l'autre sur la couche MTD, par Vitaly Wool. Cependant, ces deux patchs ne portent que sur YAFFS pour les flashs à pages de 2k, et non sur celles qui nous intéressent...\n\nObjectifs :\n* pouvoir utiliser indifférement YAFFS, ~JFFS2 ou tout autre système de fichier sur les flash NAND, en minimisant les pertes de performance (ie, en laissant YAFFS gérer l'ECC sur ses partitions)\n* patcher les deux couches au minimum\n\nProblèmes :\n* il n'est pas possible de spécifier partition par partition le mode d'ECC et le layout OOB utilisé (seules les structures de données sont prévues pour, aucun code ne l'implémente).\n* si YAFFS se charge de l'ECC ({{{YAFFS_DOES_ECC}}} est défini), alors {{{useNANDECC}}} est faux (cf. {{{yaffs_fs.c}}} et {{{yaffs_mtdif.c}}}), et les OOB ne sont pas lus par la couche MTD.\n* si YAFFS ne se charge pas de l'ECC, alors on doit utiliser le calcul d'ECC par la couche MTD, qui est plus lent que celui de YAFFS\n\nLe problème a été résolu de la façon suivante :\n* la flash est mise en mode {{{ NAND_ECC_SOFT}}} qui assure que la couche MTD se charge des ECC, sauf sur les partitions de type YAFFS. C'est le layout de YAFFS ({{{ {8, 9, 10, 13, 14, 15} }}}) qui est utilisé par défaut.\n* YAFFS est configuré pour gérer l'ECC sur ses partitions : {{{YAFFS_DOES_ECC}}} est défini, ce qui potentiellement empêche la couche MTD de lire les infos d'OOB\n* mais la couche MTD est alors patchée ({{{nand_base.c}}}) de façon à ce que les OOB soient quand même lus...\n* pour garder des systèmes d'écriture en flash simples, l'ordre d'ECC est le même sur toutes les partitions ({{{CONFIG_YAFFS_ECC_WRONG_ORDER}}} est défini dans YAFFS)\n
<?php\n/***\n! User settings\nEdit these lines according to your need\n***/\n//{{{\n$AUTHENTICATE_USER = true; // true | false\n$USERS = array(\n 'UserName1'=>'Password1', \n 'UserName2'=>'Password2', \n 'UserName3'=>'Password3'); // set usernames and strong passwords\n$DEBUG = false; // true | false\n//}}}\n/***\n!Code\nNo change needed under\n***/\n//{{{\n\n/***\n * store.php - upload a file in this directory\n * version :1.3 - 17/02/2006 - BidiX@BidiX.info\n * \n * see : \n * http://tiddlywiki.bidi.info/#UploadPlugin for usage\n * http://www.php.net/manual/en/features.file-upload.php \n * for détails on uploading files\n * usage : \n * POST \n * UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;]\n * userfile <file>\n * GET\n *\n * Revision history\n * v 1.3 - 17/02/2006 :\n * presence and value of user are checked with $USERS Array (thanks to PauloSoares)\n * v 1.2 - 12/02/2006 : \n * POST \n * UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;]\n * userfile <file>\n* if $AUTHENTICATE_USER\n * presence and value of user and password are checked with \n * $USER and $PASSWORD\n * v 1.1 - 23/12/2005 : \n * POST UploadPlugin[backupDir=<backupdir>] userfile <file>\n * v 1.0 - 12/12/2005 : \n * POST userfile <file>\n *\n * Copyright (c) BidiX@BidiX.info 2005-2006\n ***/\n//}}}\n\n//{{{\n\nif ($_SERVER['REQUEST_METHOD'] == 'GET') {\n?>\n<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n<html>\n <head>\n <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >\n <title>BidiX.info - TiddlyWiki UploadPlugin - Store script</title>\n </head>\n <body>\n <p>\n <p>store.php V 1.2\n <p>BidiX@BidiX.info\n <p> </p>\n <p> </p>\n <p> </p>\n <p align="center">This page is designed to upload a <a href="http://www.tiddlywiki.com/">TiddlyWiki<a>.</p>\n <p align="center">for details see : <a href="http://www.bidix.info/TiddlyWiki/BidiXTW.html#HowToUpload">www.bidix.info/TiddlyWiki/BidiXTW.html#HowToUpload<a>.</p> \n </body>\n</html>\n<?php\n}\nelse {\n $uploaddir = './';\n $backuperror = false;\n $optionStr = $_POST['UploadPlugin'];\n $optionArr=explode(';',$optionStr);\n $options = array();\n $backupFilename = '';\n foreach($optionArr as $o) {\n list($key, $value) = split('=', $o);\n $options[$key] = $value;\n }\n if ((!$AUTHENTICATE_USER) \n || (($options['user']) && ($options['password']) && ($USERS[$options['user']] == $options['password']))) {\n if (file_exists($uploaddir . $_FILES['userfile']['name']) && ($options['backupDir'] != '')) {\n if (! file_exists($options['backupDir'])) {\n mkdir($options['backupDir']) or ($backuperror = "mkdir error");\n }\n $filename = $_FILES['userfile']['name'];\n $backupFilename = $options['backupDir'].'/'.substr($filename, 0, strpos($filename, '.'))\n .date('.Ymd.His').substr($filename,strpos($filename,'.'));\n rename($filename, $backupFilename) or ($backuperror = "rename error");\n }\n if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir . $_FILES['userfile']['name'])) {\n if (!$backuperror) {\n if($DEBUG) {\n echo "debug mode \sn\sn";\n }\n echo "0 - File successfully loaded in " .$uploaddir . $_FILES['userfile']['name']. "\sn";\n if ($backupFilename)\n echo "backupFile=$backupFilename;\sn";\n } else {\n echo "BackupError : $backuperror - File successfully loaded in " .$uploaddir . $_FILES['userfile']['name']. "\sn";\n }\n } \n else {\n echo "Error : " . $_FILES['error']." - File NOT uploaded !\sn";\n }\n }\n else {\n echo "Error : UserName or Password do not match \sn";\n echo "UserName : [".$options['user']. "] Password : [". $options['password'] . "]\sn";\n }\n if ($DEBUG) {\n echo '\snHere is some more debugging info : \sn';\n print ("\s$_FILES : \sn");\n print_r($_FILES);\n print ("\s$options : \sn");\n print_r($options);\n }\n}\n//}}}\n?>