Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
[img[argazki erakusketa 2009|http://farm4.static.flickr.com/3600/3559581999_028a97d392.jpg]]
[img[argazki erakusketa 2010|http://farm5.static.flickr.com/4015/4680090740_c75031142a.jpg]]
!usage
{{{[img[25.urteurrena.jpg]]}}}
[img[25.urteurrena.jpg]]
!notes
//none//
!type
image/jpeg
!file
./25.urteurrena.jpg
!url
!data
data:image/jpeg;base64,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
|Antonio Villanueva (Zaldibar)|[img[http://farm1.static.flickr.com/40/86488248_06d719aab8_m.jpg]]|
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625285527605%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625285527605%2F&set_id=72157625285527605&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625285527605%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625285527605%2F&set_id=72157625285527605&jump_to=" width="500" height="375"></embed></object></center></html>
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625285611447%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625285611447%2F&set_id=72157625285611447&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625285611447%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625285611447%2F&set_id=72157625285611447&jump_to=" width="500" height="375"></embed></object></center></html>
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625287614221%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625287614221%2F&set_id=72157625287614221&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625287614221%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625287614221%2F&set_id=72157625287614221&jump_to=" width="500" height="375"></embed></object></center></html>
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625293012505%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625293012505%2F&set_id=72157625293012505&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625293012505%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625293012505%2F&set_id=72157625293012505&jump_to=" width="500" height="375"></embed></object></center></html>
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625293211869%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625293211869%2F&set_id=72157625293211869&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625293211869%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625293211869%2F&set_id=72157625293211869&jump_to=" width="500" height="375"></embed></object></center></html>
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625293379375%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625293379375%2F&set_id=72157625293379375&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625293379375%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625293379375%2F&set_id=72157625293379375&jump_to=" width="500" height="375"></embed></object></center></html>
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625293467773%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625293467773%2F&set_id=72157625293467773&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625293467773%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625293467773%2F&set_id=72157625293467773&jump_to=" width="500" height="375"></embed></object></center></html>
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625293559359%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625293559359%2F&set_id=72157625293559359&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625293559359%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625293559359%2F&set_id=72157625293559359&jump_to=" width="500" height="375"></embed></object></center></html>
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157613716945146%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157613716945146%2F&set_id=72157613716945146&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157613716945146%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157613716945146%2F&set_id=72157613716945146&jump_to=" width="500" height="375"></embed></object></center></html>
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157613638303813%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157613638303813%2F&set_id=72157613638303813&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157613638303813%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157613638303813%2F&set_id=72157613638303813&jump_to=" width="500" height="375"></embed></object></center></html>
<html><center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157613637716075%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157613637716075%2F&set_id=72157613637716075&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157613637716075%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157613637716075%2F&set_id=72157613637716075&jump_to=" width="500" height="375"></embed></object></center</html>
<html><div align="center"><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157611729465310%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157611729465310%2F&set_id=72157611729465310&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157611729465310%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157611729465310%2F&set_id=72157611729465310&jump_to=" width="500" height="375"></embed></object></div></html>
<html><div align=center><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157613638488931%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157613638488931%2F&set_id=72157613638488931&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157613638488931%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157613638488931%2F&set_id=72157613638488931&jump_to=" width="500" height="375"></embed></object></div></html>
<html><div align="center"><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F1647250%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F1647250%2F&set_id=1647250&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F1647250%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F1647250%2F&set_id=1647250&jump_to=" width="500" height="375"></embed></object></div></html>
<html><div align="center"><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157611730759652%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157611730759652%2F&set_id=72157611730759652&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157611730759652%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157611730759652%2F&set_id=72157611730759652&jump_to=" width="500" height="375"></embed></object></div></html>
<html><div align="center""><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157611748841781%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157611748841781%2F&set_id=72157611748841781&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157611748841781%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157611748841781%2F&set_id=72157611748841781&jump_to=" width="500" height="375"></embed></object></div></object>
</html>
<html><div align="center"><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157603419331082%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157603419331082%2F&set_id=72157603419331082&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157603419331082%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157603419331082%2F&set_id=72157603419331082&jump_to=" width="500" height="375"></embed></object></div></html>
<html><div align="center"><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157610695727907%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157610695727907%2F&set_id=72157610695727907&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157610695727907%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157610695727907%2F&set_id=72157610695727907&jump_to=" width="500" height="375"></embed></object></div></html>
<html><div align="center"><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157622953130828%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157622953130828%2F&set_id=72157622953130828&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157622953130828%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157622953130828%2F&set_id=72157622953130828&jump_to=" width="500" height="375"></embed></object></div></html>
<html><div align="center"><object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625351969835%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625351969835%2F&set_id=72157625351969835&jump_to="></param> <param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Filargi%2Fsets%2F72157625351969835%2Fshow%2F&page_show_back_url=%2Fphotos%2Filargi%2Fsets%2F72157625351969835%2F&set_id=72157625351969835&jump_to=" width="500" height="375"></embed></object></object></div></html>
<html><div align="center"><object width="500" height="580" align="middle"><param name="FlashVars" VALUE="ids=72157594211823208&names=Rally06&userName=ilargi-zaldibar&userId=14153873@N00&titles=on&source=sets"></param><param name="PictoBrowser" value="http://www.db798.com/pictobrowser.swf"></param><param name="scale" value="noscale"></param><param name="bgcolor" value="#ffffff"></param><param name="wmode" value="transparent"></param><embed src="http://www.db798.com/pictobrowser.swf" FlashVars="ids=72157594211823208&names=Rally06&userName=ilargi-zaldibar&userId=14153873@N00&titles=on&source=sets" loop="false" scale="noscale" bgcolor="#ffffff" width="500" height="580" name="PictoBrowser" align="middle" wmode="transparent"></embed></object></div></html>
[img[argazki rallya 2007 erakusketa|http://farm2.static.flickr.com/1047/730401806_9186162414.jpg]]
<html><div align="center"><object width="500" height="580" align="middle"><param name="FlashVars" VALUE="ids=72157608712126476&names=rally2008&userName=ilargi-zaldibar&userId=14153873@N00&titles=on&source=sets"></param><param name="PictoBrowser" value="http://www.db798.com/pictobrowser.swf"></param><param name="scale" value="noscale"></param><param name="bgcolor" value="#ffffff"></param><param name="wmode" value="transparent"></param><embed src="http://www.db798.com/pictobrowser.swf" FlashVars="ids=72157608712126476&names=rally2008&userName=ilargi-zaldibar&userId=14153873@N00&titles=on&source=sets" loop="false" scale="noscale" bgcolor="#ffffff" width="500" height="580" name="PictoBrowser" align="middle" wmode="transparent"></embed></object></div></html>
<html><div align="center"><object width="500" height="580" align="middle"><param name="FlashVars" VALUE="ids=72157621146342433&names=Rally09&userName=ilargi-zaldibar&userId=14153873@N00&titles=on&source=sets"></param><param name="PictoBrowser" value="http://www.db798.com/pictobrowser.swf"></param><param name="scale" value="noscale"></param><param name="bgcolor" value="#ffffff"></param><param name="wmode" value="transparent"></param><embed src="http://www.db798.com/pictobrowser.swf" FlashVars="ids=72157621146342433&names=Rally09&userName=ilargi-zaldibar&userId=14153873@N00&titles=on&source=sets" loop="false" scale="noscale" bgcolor="#ffffff" width="500" height="580" name="PictoBrowser" align="middle" wmode="transparent"></embed></object></div></html>
<html><div align="center"><object width="500" height="580" align="middle"><param name="FlashVars" VALUE="ids=72157624546425260&names=Rally010&userName=ilargi-zaldibar&userId=14153873@N00&titles=on&source=sets"></param><param name="PictoBrowser" value="http://www.db798.com/pictobrowser.swf"></param><param name="scale" value="noscale"></param><param name="bgcolor" value="#ffffff"></param><param name="wmode" value="transparent"></param><embed src="http://www.db798.com/pictobrowser.swf" FlashVars="ids=72157624546425260&names=Rally010&userName=ilargi-zaldibar&userId=14153873@N00&titles=on&source=sets" loop="false" scale="noscale" bgcolor="#ffffff" width="500" height="580" name="PictoBrowser" align="middle" wmode="transparent"></embed></object></div></html>
text/plain
.txt .text .js .vbs .asp .cgi .pl
----
text/html
.htm .html .hta .htx .mht
----
text/comma-separated-values
.csv
----
text/javascript
.js
----
text/css
.css
----
text/xml
.xml .xsl .xslt
----
image/gif
.gif
----
image/jpeg
.jpg .jpe .jpeg
----
image/png
.png
----
image/bmp
.bmp
----
image/tiff
.tif .tiff
----
audio/basic
.au .snd
----
audio/wav
.wav
----
audio/x-pn-realaudio
.ra .rm .ram
----
audio/x-midi
.mid .midi
----
audio/mp3
.mp3
----
audio/m3u
.m3u
----
video/x-ms-asf
.asf
----
video/avi
.avi
----
video/mpeg
.mpg .mpeg
----
video/quicktime
.qt .mov .qtvr
----
application/pdf
.pdf
----
application/rtf
.rtf
----
application/postscript
.ai .eps .ps
----
application/wordperfect
.wpd
----
application/mswrite
.wri
----
application/msexcel
.xls .xls3 .xls4 .xls5 .xlw
----
application/msword
.doc
----
application/mspowerpoint
.ppt .pps
----
application/x-director
.swa
----
application/x-shockwave-flash
.swf
----
application/x-zip-compressed
.zip
----
application/x-gzip
.gz
----
application/x-rar-compressed
.rar
----
application/octet-stream
.com .exe .dll .ocx
----
application/java-archive
.jar
[[AttachFilePlugin]] reads binary data from locally-stored files (e.g., images, PDFs, mp3's, etc.) and converts it to base64-encoded text that is stored in tiddlers tagged with<<tag attachment>>. [[AttachFilePluginFormatters]] allows you to use those tiddlers in place of the external path/file references that are normally part of the image and external links wiki syntax.
[[FileDropPlugin]] and [[FileDropPluginConfig]] allow you to quickly create attachment tiddlers simply by dragging files directly from your system's desktop folder display and dropping it onto an open TiddlyWiki document. Text files are automatically created as simple tiddlers, while binary files are automatically encoded and attached.
/***
|Name|AttachFilePlugin|
|Source|http://www.TiddlyTools.com/#AttachFilePlugin|
|Documentation|http://www.TiddlyTools.com/#AttachFilePluginInfo|
|Version|4.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|AttachFilePluginFormatters, AttachFileMIMETypes|
|Description|Store binary files as base64-encoded tiddlers with fallback links for separate local and/or remote file storage|
Store or link binary files (such as jpg, gif, pdf or even mp3) within your TiddlyWiki document and then use them as images or links from within your tiddler content.
> Important note: As of version 3.6.0, in order to //render// images and other binary attachments created with this plugin, you must also install [[AttachFilePluginFormatters]], which extends the behavior of the TiddlyWiki core formatters for embedded images ({{{[img[tooltip|image]]}}}), linked embedded images ({{{[img[tooltip|image][link]]}}}), and external/"pretty" links ({{{[[label|link]]}}}), so that these formatter will process references to attachment tiddlers as if a normal file reference had been provided. |
!!!!!Documentation
>see [[AttachFilePluginInfo]]
!!!!!Inline interface (live)
>see [[AttachFile]] (shadow tiddler)
><<tiddler AttachFile>>
!!!!!Revisions
<<<
2009.06.04 [4.0.0] changed attachment storage format to use //sections// instead of embedded substring markers.
|please see [[AttachFilePluginInfo]] for additional revision details|
2005.07.20 [1.0.0] Initial Release
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.AttachFilePlugin= {major: 4, minor: 0, revision: 0, date: new Date(2009,6,4)};
// shadow tiddler
config.shadowTiddlers.AttachFile="<<attach inline>>";
// add 'attach' backstage task (insert before built-in 'importTask')
if (config.tasks) { // for TW2.2b or above
config.tasks.attachTask = {
text: "attach",
tooltip: "Attach a binary file as a tiddler",
content: "<<attach inline>>"
}
config.backstageTasks.splice(config.backstageTasks.indexOf("importTask"),0,"attachTask");
}
config.macros.attach = {
// // lingo
//{{{
label: "attach file",
tooltip: "Attach a file to this document",
linkTooltip: "Attachment: ",
typeList: "AttachFileMIMETypes",
titlePrompt: " enter tiddler title...",
MIMEPrompt: "<option value=''>select MIME type...</option><option value='editlist'>[edit list...]</option>",
localPrompt: " enter local path/filename...",
URLPrompt: " enter remote URL...",
tiddlerErr: "Please enter a tiddler title",
sourceErr: "Please enter a source path/filename",
storageErr: "Please select a storage method: embedded, local or remote",
MIMEErr: "Unrecognized file format. Please select a MIME type",
localErr: "Please enter a local path/filename",
URLErr: "Please enter a remote URL",
fileErr: "Invalid path/file or file not found",
tiddlerFormat: '!usage\n{{{%0}}}\n%0\n!notes\n%1\n!type\n%2\n!file\n%3\n!url\n%4\n!data\n%5\n',
//}}}
// // macro definition
//{{{
handler:
function(place,macroName,params) {
if (params && !params[0])
{ createTiddlyButton(place,this.label,this.tooltip,this.toggleAttachPanel); return; }
var id=params.shift();
this.createAttachPanel(place,id+"_attachPanel",params);
document.getElementById(id+"_attachPanel").style.position="static";
document.getElementById(id+"_attachPanel").style.display="block";
},
//}}}
//{{{
createAttachPanel:
function(place,panel_id,params) {
if (!panel_id || !panel_id.length) var panel_id="_attachPanel";
// remove existing panel (if any)
var panel=document.getElementById(panel_id); if (panel) panel.parentNode.removeChild(panel);
// set styles for this panel
setStylesheet(this.css,"attachPanel");
// create new panel
var title=""; if (params && params[0]) title=params.shift();
var types=this.MIMEPrompt+this.formatListOptions(store.getTiddlerText(this.typeList)); // get MIME types
panel=createTiddlyElement(place,"span",panel_id,"attachPanel",null);
var html=this.html.replace(/%id%/g,panel_id);
html=html.replace(/%title%/g,title);
html=html.replace(/%disabled%/g,title.length?"disabled":"");
html=html.replace(/%IEdisabled%/g,config.browser.isIE?"disabled":"");
html=html.replace(/%types%/g,types);
panel.innerHTML=html;
if (config.browser.isGecko) { // FF3 FIXUP
document.getElementById("attachSource").style.display="none";
document.getElementById("attachFixPanel").style.display="block";
}
return panel;
},
//}}}
//{{{
toggleAttachPanel:
function (e) {
if (!e) var e = window.event;
var parent=resolveTarget(e).parentNode;
var panel = document.getElementById("_attachPanel");
if (panel==undefined || panel.parentNode!=parent)
panel=config.macros.attach.createAttachPanel(parent,"_attachPanel");
var isOpen = panel.style.display=="block";
if(config.options.chkAnimate)
anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
else
panel.style.display = isOpen ? "none" : "block" ;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return(false);
},
//}}}
//{{{
formatListOptions:
function(text) {
if (!text || !text.trim().length) return "";
// get MIME list content from text
var parts=text.split("\n----\n");
var out="";
for (var p=0; p<parts.length; p++) {
var lines=parts[p].split("\n");
var label=lines.shift(); // 1st line=display text
var value=lines.shift(); // 2nd line=item value
out +='<option value="%1">%0</option>'.format([label,value]);
}
return out;
},
//}}}
// // interface definition
//{{{
css:
".attachPanel { display: none; position:absolute; z-index:10; width:35em; right:105%; top:0em;\
background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
padding: 0.5em; margin:0em; -moz-border-radius:1em;-webkit-border-radius:1em; text-align:left }\
.attachPanel form { display:inline;border:0;padding:0;margin:0; }\
.attachPanel select { width:99%;margin:0px;font-size:8pt;line-height:110%;}\
.attachPanel input { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\
.attachPanel textarea { width:98%;margin:0px;height:2em;font-size:8pt;line-height:110%}\
.attachPanel table { width:100%;border:0;margin:0;padding:0;color:inherit; }\
.attachPanel tbody, .attachPanel tr, .attachPanel td { border:0;margin:0;padding:0;color:#000; }\
.attachPanel .box { border:1px solid black; padding:.3em; margin:.3em 0px; background:#f8f8f8; \
-moz-border-radius:5px;-webkit-border-radius:5px; }\
.attachPanel .chk { width:auto;border:0; }\
.attachPanel .btn { width:auto; }\
.attachPanel .btn2 { width:49%; }\
",
//}}}
//{{{
html:
'<form>\
attach from source file\
<input type="file" id="attachSource" name="source" size="56"\
onChange="config.macros.attach.onChangeSource(this)">\
<div id="attachFixPanel" style="display:none"><!-- FF3 FIXUP -->\
<input type="text" id="attachFixSource" style="width:90%"\
title="Enter a path/file to attach"\
onChange="config.macros.attach.onChangeSource(this);">\
<input type="button" style="width:7%" value="..."\
title="Enter a path/file to attach"\
onClick="config.macros.attach.askForFilename(document.getElementById(\'attachFixSource\'));">\
</div><!--end FF3 FIXUP-->\
<div class="box">\
<table style="border:0"><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
embed data <input type=checkbox class=chk name="useData" %IEdisabled% \
onclick="if (!this.form.MIMEType.value.length)\
this.form.MIMEType.selectedIndex=this.checked?1:0; "> \
</td><td style="border:0">\
<select size=1 name="MIMEType" \
onchange="this.title=this.value; if (this.value==\'editlist\')\
{ this.selectedIndex=this.form.useData.checked?1:0; story.displayTiddler(null,config.macros.attach.typeList,2); return; }">\
<option value=""></option>\
%types%\
</select>\
</td></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
local link <input type=checkbox class=chk name="useLocal"\
onclick="this.form.local.value=this.form.local.defaultValue=this.checked?config.macros.attach.localPrompt:\'\';"> \
</td><td style="border:0">\
<input type=text name="local" size=15 autocomplete=off value=""\
onchange="this.form.useLocal.checked=this.value.length" \
onkeyup="this.form.useLocal.checked=this.value.length" \
onfocus="if (!this.value.length) this.value=config.macros.attach.localPrompt; this.select()">\
</td></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
remote link <input type=checkbox class=chk name="useURL"\
onclick="this.form.URL.value=this.form.URL.defaultValue=this.checked?config.macros.attach.URLPrompt:\'\';\"> \
</td><td style="border:0">\
<input type=text name="URL" size=15 autocomplete=off value=""\
onfocus="if (!this.value.length) this.value=config.macros.attach.URLPrompt; this.select()"\
onchange="this.form.useURL.checked=this.value.length;"\
onkeyup="this.form.useURL.checked=this.value.length;">\
</td></tr></table>\
</div>\
<table style="border:0"><tr style="border:0"><td style="border:0;text-align:right;vertical-align:top;width:1%;white-space:nowrap">\
notes \
</td><td style="border:0" colspan=2>\
<textarea name="notes" style="width:98%;height:3.5em;margin-bottom:2px"></textarea>\
</td><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
attach as \
</td><td style="border:0" colspan=2>\
<input type=text name="tiddlertitle" size=15 autocomplete=off value="%title%"\
onkeyup="if (!this.value.length) { this.value=config.macros.attach.titlePrompt; this.select(); }"\
onfocus="if (!this.value.length) this.value=config.macros.attach.titlePrompt; this.select()" %disabled%>\
</td></tr></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
add tags \
</td><td style="border:0">\
<input type=text name="tags" size=15 autocomplete=off value="" onfocus="this.select()">\
</td><td style="width:40%;text-align:right;border:0">\
<input type=button class=btn2 value="attach"\
onclick="config.macros.attach.onClickAttach(this)"><!--\
--><input type=button class=btn2 value="close"\
onclick="var panel=document.getElementById(\'%id%\'); if (panel) panel.parentNode.removeChild(panel);">\
</td></tr></table>\
</form>',
//}}}
// // control processing
//{{{
onChangeSource:
function(here) {
var form=here.form;
var list=form.MIMEType;
var theFilename = here.value;
var theExtension = theFilename.substr(theFilename.lastIndexOf('.')).toLowerCase();
// if theFilename is in current document folder, remove path prefix and use relative reference
var h=document.location.href; folder=getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf("/")+1)));
if (theFilename.substr(0,folder.length)==folder) theFilename='./'+theFilename.substr(folder.length);
else theFilename='file:///'+theFilename; // otherwise, use absolute reference
theFilename=theFilename.replace(/\\/g,"/"); // fixup: change \ to /
form.useLocal.checked = true;
form.local.value = theFilename;
form.useData.checked = !form.useData.disabled;
list.selectedIndex=1;
for (var i=0; i<list.options.length; i++) // find matching MIME type
if (list.options[i].value.indexOf(theExtension)!=-1) { list.selectedIndex = i; break; }
if (!form.tiddlertitle.disabled)
form.tiddlertitle.value=theFilename.substr(theFilename.lastIndexOf('/')+1); // get tiddlername from filename
},
//}}}
//{{{
onClickAttach:
function (here) {
clearMessage();
// get input values
var form=here.form;
var src=form.source; if (config.browser.isGecko) src=document.getElementById("attachFixSource");
src=src.value!=src.defaultValue?src.value:"";
var when=(new Date()).formatString(config.macros.timeline.dateFormat);
var title=form.tiddlertitle.value;
var local = form.local.value!=form.local.defaultValue?form.local.value:"";
var url = form.URL.value!=form.URL.defaultValue?form.URL.value:"";
var notes = form.notes.value;
var tags = "attachment excludeMissing "+form.tags.value;
var useData=form.useData.checked;
var useLocal=form.useLocal.checked;
var useURL=form.useURL.checked;
var mimetype = form.MIMEType.value.length?form.MIMEType.options[form.MIMEType.selectedIndex].text:"";
// validate checkboxes and get filename
if (useData) {
if (src.length) { if (!theLocation) var theLocation=src; }
else { alert(this.sourceErr); src.focus(); return false; }
}
if (useLocal) {
if (local.length) { if (!theLocation) var theLocation = local; }
else { alert(this.localErr); form.local.focus(); return false; }
}
if (useURL) {
if (url.length) { if (!theLocation) var theLocation = url; }
else { alert(this.URLErr); form.URL.focus(); return false; }
}
if (!(useData||useLocal||useURL))
{ form.useData.focus(); alert(this.storageErr); return false; }
if (!theLocation)
{ src.focus(); alert(this.sourceErr); return false; }
if (!title || !title.trim().length || title==this.titlePrompt)
{ form.tiddlertitle.focus(); alert(this.tiddlerErr); return false; }
// if not already selected, determine MIME type based on filename extension (if any)
if (useData && !mimetype.length && theLocation.lastIndexOf('.')!=-1) {
var theExt = theLocation.substr(theLocation.lastIndexOf('.')).toLowerCase();
var theList=form.MIMEType;
for (var i=0; i<theList.options.length; i++)
if (theList.options[i].value.indexOf(theExt)!=-1)
{ var mimetype=theList.options[i].text; theList.selectedIndex=i; break; }
}
// attach the file
return this.createAttachmentTiddler(src, when, notes, tags, title,
useData, useLocal, useURL, local, url, mimetype);
},
getMIMEType:
function(src,def) {
var ext = src.substr(src.lastIndexOf('.')).toLowerCase();
var list=store.getTiddlerText(this.typeList);
if (!list || !list.trim().length) return def;
// get MIME list content from tiddler
var parts=list.split("\n----\n");
for (var p=0; p<parts.length; p++) {
var lines=parts[p].split("\n");
var mime=lines.shift(); // 1st line=MIME type
var match=lines.shift(); // 2nd line=matching extensions
if (match.indexOf(ext)!=-1) return mime;
}
return def;
},
createAttachmentTiddler:
function (src, when, notes, tags, title, useData, useLocal, useURL, local, url, mimetype, noshow) {
if (useData) { // encode the data
if (!mimetype.length) {
alert(this.MIMEErr);
form.MIMEType.selectedIndex=1; form.MIMEType.focus();
return false;
}
var d = this.readFile(src); if (!d) { return false; }
displayMessage('encoding '+src);
var encoded = this.encodeBase64(d);
displayMessage('file size='+d.length+' bytes, encoded size='+encoded.length+' bytes');
}
var usage=(mimetype.substr(0,5)=="image"?'[img[%0]]':'[[%0|%0]]').format([title]);
var theText=this.tiddlerFormat.format([
usage, notes.length?notes:'//none//', mimetype,
useLocal?local.replace(/\\/g,'/'):'', useURL?url:'',
useData?('data:'+mimetype+';base64,'+encoded):'' ]);
store.saveTiddler(title,title,theText,config.options.txtUserName,new Date(),tags);
var panel=document.getElementById("attachPanel"); if (panel) panel.style.display="none";
if (!noshow) { story.displayTiddler(null,title); story.refreshTiddler(title,null,true); }
displayMessage('attached "'+title+'"');
return true;
},
//}}}
// // base64 conversion
//{{{
encodeBase64:
function (d) {
if (!d) return null;
// encode as base64
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var out="";
var chr1,chr2,chr3="";
var enc1,enc2,enc3,enc4="";
for (var count=0,i=0; i<d.length; ) {
chr1=d.charCodeAt(i++);
chr2=d.charCodeAt(i++);
chr3=d.charCodeAt(i++);
enc1=chr1 >> 2;
enc2=((chr1 & 3) << 4) | (chr2 >> 4);
enc3=((chr2 & 15) << 2) | (chr3 >> 6);
enc4=chr3 & 63;
if (isNaN(chr2)) enc3=enc4=64;
else if (isNaN(chr3)) enc4=64;
out+=keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4);
chr1=chr2=chr3=enc1=enc2=enc3=enc4="";
}
return out;
},
decodeBase64: function(input) {
var out="";
var chr1,chr2,chr3;
var enc1,enc2,enc3,enc4;
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input=input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1=keyStr.indexOf(input.charAt(i++));
enc2=keyStr.indexOf(input.charAt(i++));
enc3=keyStr.indexOf(input.charAt(i++));
enc4=keyStr.indexOf(input.charAt(i++));
chr1=(enc1 << 2) | (enc2 >> 4);
chr2=((enc2 & 15) << 4) | (enc3 >> 2);
chr3=((enc3 & 3) << 6) | enc4;
out=out+String.fromCharCode(chr1);
if (enc3!=64) out=out+String.fromCharCode(chr2);
if (enc4!=64) out=out+String.fromCharCode(chr3);
} while (i<input.length);
return out;
},
//}}}
// // I/O functions
//{{{
readFile: // read local BINARY file data
function(filePath) {
if(!window.Components) { return null; }
try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
catch(e) { alert("access denied: "+filePath); return null; }
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
try { file.initWithPath(filePath); } catch(e) { alert("cannot read file - invalid path: "+filePath); return null; }
if (!file.exists()) { alert("cannot read file - not found: "+filePath); return null; }
var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
inputStream.init(file, 0x01, 00004, null);
var bInputStream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
bInputStream.setInputStream(inputStream);
return(bInputStream.readBytes(inputStream.available()));
},
//}}}
//{{{
writeFile:
function(filepath,data) {
// TBD: decode base64 and write BINARY data to specified local path/filename
return(false);
},
//}}}
//{{{
askForFilename: // for FF3 fixup
function(target) {
var msg=config.messages.selectFile;
if (target && target.title) msg=target.title; // use target field tooltip (if any) as dialog prompt text
// get local path for current document
var path=getLocalPath(document.location.href);
var p=path.lastIndexOf("/"); if (p==-1) p=path.lastIndexOf("\\"); // Unix or Windows
if (p!=-1) path=path.substr(0,p+1); // remove filename, leave trailing slash
var file=""
var result=window.mozAskForFilename(msg,path,file,true); // FF3 FIXUP ONLY
if (target && result.length) // set target field and trigger handling
{ target.value=result; target.onchange(); }
return result;
}
};
//}}}
//{{{
if (window.mozAskForFilename===undefined) { // also defined by CoreTweaks (for ticket #604)
window.mozAskForFilename=function(msg,path,file,mustExist) {
if(!window.Components) return false;
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, mustExist?nsIFilePicker.modeOpen:nsIFilePicker.modeSave);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension='';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
if (picker.show()!=nsIFilePicker.returnCancel)
var result=picker.file.persistentDescriptor;
}
catch(ex) { displayMessage(ex.toString()); }
return result;
}
}
//}}}
/***
|Name|AttachFilePluginFormatters|
|Source|http://www.TiddlyTools.com/#AttachFilePluginFormatters|
|Version|4.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1.3|
|Type|plugin|
|Description|run-time library for displaying attachment tiddlers|
Runtime processing for //rendering// attachment tiddlers created by [[AttachFilePlugin]]. Attachment tiddlers are tagged with<<tag attachment>>and contain binary file content (e.g., jpg, gif, pdf, mp3, etc.) that has been stored directly as base64 text-encoded data or can be loaded from external files stored on a local filesystem or remote web server. Note: after creating new attachment tiddlers, you can remove [[AttachFilePlugin]], as long as you retain //this// tiddler (so that images can be rendered later on).
!!!!!Formatters
<<<
This plugin extends the behavior of the following TiddlyWiki core "wikify()" formatters:
* embedded images: {{{[img[tooltip|image]]}}}
* linked embedded images: {{{[img[tooltip|image][link]]}}}
* external/"pretty" links: {{{[[label|link]]}}}
''Please refer to AttachFilePlugin (source: http://www.TiddlyTools.com/#AttachFilePlugin) for additional information.''
<<<
!!!!!Revisions
<<<
2009.10.10 [4.0.1] in fileExists(), check for IE to avoid hanging Chrome during startup
2009.06.04 [4.0.0] changed attachment storage format to use //sections// instead of embedded substring markers.
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.10.29 [3.7.0] more code reduction: removed upload handling from AttachFilePlugin (saves ~7K!)
2007.10.28 [3.6.0] removed duplicate formatter code from AttachFilePlugin (saves ~10K!) and updated documentation accordingly. This plugin ([[AttachFilePluginFormatters]]) is now //''required''// in order to display attached images/binary files within tiddler content.
2006.05.20 [3.4.0] through 2007.03.01 [3.5.3] sync with AttachFilePlugin
2006.05.13 [3.2.0] created from AttachFilePlugin v3.2.0
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.AttachFilePluginFormatters= {major: 4, minor: 0, revision: 1, date: new Date(2009,10,10)};
//}}}
//{{{
if (config.macros.attach==undefined) config.macros.attach= { };
//}}}
//{{{
if (config.macros.attach.isAttachment==undefined) config.macros.attach.isAttachment=function (title) {
var tiddler = store.getTiddler(title);
if (tiddler==undefined || tiddler.tags==undefined) return false;
return (tiddler.tags.indexOf("attachment")!=-1);
}
//}}}
//{{{
// test for local file existence - returns true/false without visible error display
if (config.macros.attach.fileExists==undefined) config.macros.attach.fileExists=function(f) {
if(window.Components) { // MOZ
try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
catch(e) { return false; } // security access denied
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
try { file.initWithPath(f); }
catch(e) { return false; } // invalid directory
return file.exists();
}
else if (config.browser.isIE) { // IE
var fso = new ActiveXObject("Scripting.FileSystemObject");
return fso.FileExists(f);
}
else return true; // other browsers: assume file exists
}
//}}}
//{{{
if (config.macros.attach.getAttachment==undefined) config.macros.attach.getAttachment=function(title) {
// extract embedded data, local and remote links (if any)
var text=store.getTiddlerText(title,'');
var embedded=store.getTiddlerText(title+'##data','').trim();
var locallink=store.getTiddlerText(title+'##file','').trim();
var remotelink=store.getTiddlerText(title+'##url','').trim();
// backward-compatibility for older attachments (pre 4.0.0)
var startmarker="---BEGIN_DATA---\n";
var endmarker="\n---END_DATA---";
var pos=0; var endpos=0;
if ((pos=text.indexOf(startmarker))!=-1 && (endpos=text.indexOf(endmarker))!=-1)
embedded="data:"+(text.substring(pos+startmarker.length,endpos)).replace(/\n/g,'');
if ((pos=text.indexOf("/%LOCAL_LINK%/"))!=-1)
locallink=text.substring(text.indexOf("|",pos)+1,text.indexOf("]]",pos));
if ((pos=text.indexOf("/%REMOTE_LINK%/"))!=-1)
remotelink=text.substring(text.indexOf("|",pos)+1,text.indexOf("]]",pos));
// if there is a data: URI defined (not supported by IE)
if (embedded.length && !config.browser.isIE) return embedded;
// document is being served remotely... use remote URL (if any) (avoids security alert)
if (remotelink.length && document.location.protocol!="file:")
return remotelink;
// local link only... return link without checking file existence (avoids security alert)
if (locallink.length && !remotelink.length)
return locallink;
// local link, check for file exist... use local link if found
if (locallink.length) {
locallink=locallink.replace(/^\.[\/\\]/,''); // strip leading './' or '.\' (if any)
if (this.fileExists(getLocalPath(locallink))) return locallink;
// maybe local link is relative... add path from current document and try again
var pathPrefix=document.location.href; // get current document path and trim off filename
var slashpos=pathPrefix.lastIndexOf("/"); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf("\\");
if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
if (this.fileExists(getLocalPath(pathPrefix+locallink))) return locallink;
}
// no embedded data, no local (or not found), fallback to remote URL (if any)
if (remotelink.length) return remotelink;
// attachment URL doesn't resolve, just return input as is
return title;
}
//}}}
//{{{
if (config.macros.attach.init_formatters==undefined) config.macros.attach.init_formatters=function() {
if (this.initialized) return;
// find the formatter for "image" and replace the handler
for (var i=0; i<config.formatters.length && config.formatters[i].name!="image"; i++);
if (i<config.formatters.length) config.formatters[i].handler=function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) // Simple bracketted link
{
var e = w.output;
if(lookaheadMatch[5])
{
var link = lookaheadMatch[5];
// ELS -------------
var external=config.formatterHelpers.isExternalLink(link);
if (external)
{
if (config.macros.attach.isAttachment(link))
{
e = createExternalLink(w.output,link);
e.href=config.macros.attach.getAttachment(link);
e.title = config.macros.attach.linkTooltip + link;
}
else
e = createExternalLink(w.output,link);
}
else
e = createTiddlyLink(w.output,link,false,null,w.isStatic);
// ELS -------------
addClass(e,"imageLink");
}
var img = createTiddlyElement(e,"img");
if(lookaheadMatch[1])
img.align = "left";
else if(lookaheadMatch[2])
img.align = "right";
if(lookaheadMatch[3])
img.title = lookaheadMatch[3];
img.src = lookaheadMatch[4];
// ELS -------------
if (config.macros.attach.isAttachment(lookaheadMatch[4]))
img.src=config.macros.attach.getAttachment(lookaheadMatch[4]);
// ELS -------------
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
//}}}
//{{{
// find the formatter for "prettyLink" and replace the handler
for (var i=0; i<config.formatters.length && config.formatters[i].name!="prettyLink"; i++);
if (i<config.formatters.length) {
config.formatters[i].handler=function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var e;
var text = lookaheadMatch[1];
if(lookaheadMatch[3]) {
// Pretty bracketted link
var link = lookaheadMatch[3];
if (config.macros.attach.isAttachment(link)) {
e = createExternalLink(w.output,link);
e.href=config.macros.attach.getAttachment(link);
e.title=config.macros.attach.linkTooltip+link;
}
else e = (!lookaheadMatch[2] && config.formatterHelpers.isExternalLink(link))
? createExternalLink(w.output,link)
: createTiddlyLink(w.output,link,false,null,w.isStatic);
} else {
e = createTiddlyLink(w.output,text,false,null,w.isStatic);
}
createTiddlyText(e,text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
} // if "prettyLink" formatter found
this.initialized=true;
}
//}}}
//{{{
config.macros.attach.init_formatters(); // load time init
//}}}
//{{{
if (TiddlyWiki.prototype.coreGetRecursiveTiddlerText==undefined) {
TiddlyWiki.prototype.coreGetRecursiveTiddlerText = TiddlyWiki.prototype.getRecursiveTiddlerText;
TiddlyWiki.prototype.getRecursiveTiddlerText = function(title,defaultText,depth) {
return config.macros.attach.isAttachment(title)?
config.macros.attach.getAttachment(title):this.coreGetRecursiveTiddlerText.apply(this,arguments);
}
}
//}}}
/***
|Name|AttachFilePluginInfo|
|Source|http://www.TiddlyTools.com/#AttachFilePlugin|
|Documentation|http://www.TiddlyTools.com/#AttachFilePluginInfo|
|Version|4.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Documentation for AttachFilePlugin|
Store or link binary files (such as jpg, gif, pdf or even mp3) within your TiddlyWiki document and then use them as images or links from within your tiddler content.
!!!!!Inline interface (live)
>see [[AttachFile]] (shadow tiddler)
><<tiddler AttachFile>>
!!!!!Syntax
<<<
''To display the attach file control panel, simply view the [[AttachFile]] shadow tiddler that is automatically created by the plugin, and contains an instance of the inline control panel.''. Or, you can write:
{{{
<<attach inline>>
}}}
in any tiddler to display the control panel embedded within that tiddler. Note: you can actually use any unique identifier in place of the "inline" keyword. Each unique id creates a separate instance of the controls. If the same ID is used in more than one tiddler, then the control panel is automatically moved to the most recently rendered location. Or, you can write:
{{{
<<attach>>
}}}
(with no ID parameter) in SidebarOptions. This adds a command link that opens the controls as a floating panel, positioned directly to the left of the sidebar.
<<<
!!!!!Usage
<<<
Binary file content can be stored in three different locations:
#embedded in the attachment tiddler (encoded as base64)
#on your filesystem (a 'local link' path/filename)
#on a web server (a 'remote link' URL)
The plugin creates an "attachment tiddler" for each file you attach. Regardless of where you store the binary content, your document can refer to the attachment tiddler rather than using a direct file or URL reference in your embedded image or external links, so that changing document locations will not require updating numerous tiddlers or copying files from one system to another.
> Important note: As of version 3.6.0, in order to //render// images and other binary attachments created with this plugin, you must also install [[AttachFilePluginFormatters]], which extends the behavior of the TiddlyWiki core formatters for embedded images ({{{[img[tooltip|image]]}}}), linked embedded images ({{{[img[tooltip|image][link]]}}}), and external/"pretty" links ({{{[[label|link]]}}}), so that these formatter will process references to attachment tiddlers as if a normal file reference had been provided. |
When you attach a file, a tiddler (tagged with<<tag attachment>>) is generated (using the source filename as the tiddler's title). The tiddler contains //''base64 text-encoded binary data''//, surrounded by {{{/%...%/}}} comment markers (so they are not visible when viewing the tiddler). The tiddler also includes summary details about the file: when it was attached, by whom, etc. and, if the attachment is an image file (jpg, gif, or png), the image is automatically displayed below the summary information.
>Note: although 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 the attachment unusable. //If needed, you ''can'' edit the header information or even the MIME type declaration in the attachment data, but be very careful not to change any of the base64-encoded binary data.//
Unfortunately, embedding just a few moderately-sized binary files using base64 text-encoding can dramatically increase the size of your document. To avoid this problem, you can create attachment tiddlers that define external local filesystem (file://) and/or remote web server (http://) 'reference' links, without embedding the binary data directly in the tiddler (i.e., uncheck "embed data" in the 'control panel').
These links provide an alternative source for the binary data: if embedded data is not found (or you are running on Internet Explorer, which does not currently support using embedded data), then the plugin tries the local filesystem reference. If a local file is not found, then the remote reference (if any) is used. This "fallback" approach also lets you 'virtualize' the external links in your document, so that you can access very large binary content such as PDFs, MP3's, and even *video* files, by using just a 'remote reference link' without embedding any data or downloading huge files to your hard disk.
Of course, when you //do// download an attached file, the local copy will be used instead of accessing a remote server each time, thereby saving bandwidth and allowing you to 'go mobile' without having to edit any tiddlers to alter the link locations...
<<<
!!!!!Syntax / Examples
<<<
To embed attached files as images or link to them from other tiddlers, use the standard ~TiddlyWiki image syntax ({{{[img[tooltip|filename]]}}}), linked image syntax ({{{[img[tooltip|filename][tiddlername]]}}}) , or "external link" syntax ({{{[[text|URL]]}}}), replacing the filename or URL that is normally entered with the title of an attachment tiddler.
embedded image data:
>{{{[img[Meow|AttachFileSample]]}}}
>[img[Meow|AttachFileSample]]
embedded image data with link to larger remote image:
>{{{[img[click for larger view|AttachFileSample][AttachFileSample2]]}}}
>[img[click for larger view|AttachFileSample][AttachFileSample2]]
'external' link to embedded image data:
>{{{[[click to view attachment|AttachFileSample]]}}}
>[[click to view attachment|AttachFileSample]]
'external' link to remote image:
>{{{[[click to view attachment|AttachFileSample2]]}}}
>[[click to view attachment|AttachFileSample2]]
regular ~TiddlyWiki links to attachment tiddlers:
>{{{[[AttachFileSample]]}}} [[AttachFileSample]]
>{{{[[AttachFileSample2]]}}} [[AttachFileSample2]]
<<<
!!!!!Defining MIME types
<<<
When you select a source file, a ''[[MIME|http://en.wikipedia.org/wiki/MIME]]'' file type is automatically suggested, based on filename extension. The AttachFileMIMETypes tiddler defines the list of MIME types that will be recognized by the plugin. Each MIME type definition consists of exactly two lines of text: the official MIME type designator (e.g., "text/plain", "image/gif", etc.), and a space-separated list of file extensions associated with that type. List entries are separated by "----" (horizontal rules).
<<<
!!!!!Known Limitations
<<<
Internet Explorer does not support the data: URI scheme, and cannot use the //embedded// data to render images or links. However, you can still use the local/remote link definitions to create file attachments that are stored externally. In addition, while it is relatively easy to read local //text// files, reading binary files is not directly 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. As a result, you cannot //create// new attachment tiddlers using IE.
<<<
!!!!!Installation
<<<
Import (or copy/paste) the following tiddlers into your document:
* [[AttachFilePlugin]] (tagged with <<tag systemConfig>>)
* [[AttachFilePluginFormatters]] ("runtime distribution library") (tagged with <<tag systemConfig>>)
* [[AttachFileSample]] and [[AttachFileSample2]] //(tagged with <<tag attachment>>)//
* [[AttachFileMIMETypes]] //(defines binary file types)//
> Important note: As of version 3.6.0, in order to //render// images and other binary attachments created with this plugin, you must also install [[AttachFilePluginFormatters]], which extends the behavior of the TiddlyWiki core formatters for embedded images ({{{[img[tooltip|image]]}}}), linked embedded images ({{{[img[tooltip|image][link]]}}}), and external/"pretty" links ({{{[[label|link]]}}}), so that these formatter will process references to attachment tiddlers as if a normal file reference had been provided. |
<<<
!!!!!Revisions
<<<
2009.06.04 4.0.0 changed attachment storage format to use //sections// instead of embedded substring markers.
2008.07.21 3.9.0 Fixup for FireFox 3: use HTML with separate text+button control instead of type='file' control
2008.05.12 3.8.1 automatically add 'attach' task to backstage (moved from BackstageTweaks)
2008.04.09 3.8.0 in onChangeSource(), if source matches current document folder, use relative reference for local link. Also, disable 'embed' when using IE (which //still// doesn't support data: URI)
2008.04.07 3.7.3 fixed typo in HTML for 'local file link' so that clicking in input field doesn't erase current path/file (if any)
2008.04.07 3.7.2 auto-create AttachFile shadow tiddler for inline interface
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.12.03 3.7.1 in createAttachmentTiddler(), added optional "noshow" flag to suppress display of newly created tiddlers.
2007.10.29 3.7.0 code reduction: removed support for built-in upload to server... on-line hosting of binary attachments is left to the document author, who can upload/host files using 3rd-party web-based services (e.g. www.flickr.com, ) or stand-alone applications (e.g., FTP).
2007.10.28 3.6.0 code reduction: removed duplicate definition of image and prettyLink formatters. Rendering of attachment tiddlers now //requires// installation of AttachFilePluginFormatters
2007.03.01 3.5.3 use apply() to invoke hijacked function
2007.02.25 3.5.2 in hijack of "prettyLink", fix version check for TW2.2 compatibility (prevent incorrect use of fallback handler)
2007.01.09 3.5.1 onClickAttach() refactored to create separate createAttachmentTiddler() API for use with FileDropPluginHandlers
2006.11.30 3.5.0 in getAttachment(), for local references, add check for file existence and fallback to remote URL if local file not found. Added fileExists() to encapsulate FF vs. IE local file test function (IE FSO object code is TBD).
2006.11.29 3.4.8 in hijack for PrettyLink, 'simple bracketed link' opens tiddler instead of external link to attachment
2006.11.29 3.4.7 in readFile(), added try..catch around initWithPath() to handle invalid/non-existent paths better.
2006.11.09 3.4.6 REAL FIX for TWv2.1.3: incorporate new TW2.1.3 core "prettyLink" formatter regexp handling logic and check for version < 2.1.3 with fallback to old plugin code. Also, cleanup table layout in HTML (added "border:0" directly to table elements to override stylesheet)
2006.11.08 3.4.5 TEMPORARY FIX for TWv2.1.3: disable hijack of wikiLink formatter due to changes in core wikiLink regexp definition. //Links to attachments are broken, but you can still use {{{[img[TiddlerName]]}}} to render attachments as images, as well as {{{background:url('[[TiddlerName]]')}}} in CSS declarations for background images.//
2006.09.10 3.4.4 update formatters for 2.1 compatibility (use this.lookaheadRegExp instead of temp variable)
2006.07.24 3.4.3 in prettyLink formatter, added check for isShadowTiddler() to fix problem where shadow links became external links.
2006.07.13 3.4.2 in getAttachment(), fixed stripping of newlines so data: used in CSS will work
2006.05.21 3.4.1 in getAttachment(), fixed substring() to extract data: URI (was losing last character, which broken rendering of SOME images)
2006.05.20 3.4.0 hijack core getRecursiveTiddlerText() to support rendering attachments in stylesheets (e.g. {{{url([[AttachFileSample]])}}})
2006.05.20 3.3.6 add "description" feature to easily include notes in attachment tiddler (you can always edit to add them later... but...)
2006.05.19 3.3.5 add "attach as" feature to change default name for attachment tiddlers. Also, new optional param to specify tiddler name (disables editing)
2006.05.16 3.3.0 completed XMLHttpRequest handling for GET or POST to configurable server scripts
2006.05.13 3.2.0 added interface for upload feature. Major rewrite of code for clean object definitions. Major improvements in UI interaction and validation.
2006.05.09 3.1.1 add wikifer support for using attachments in links from "linked image" syntax: {{{[img[tip|attachment1][attachment2]]}}}
2006.05.09 3.1.0 lots of code changes: new options for attachments that use embedded data and/or links to external files (local or remote)
2006.05.03 3.0.2 added {{{/%...%/}}} comments around attachment data to hide it when viewing attachment tiddler.
2006.02.05 3.0.1 wrapped wikifier hijacks in initAttachmentFormatters() function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.27 3.0.0 Update for TW2.0. Automatically add 'excludeMissing' tag to attachments
2005.12.16 2.2.0 Dynamically create/remove attachPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding.
2005.11.20 2.1.0 added wikifier handler extensions for "image" and "prettyLink" to render tiddler attachments
2005.11.09 2.0.0 begin port from old ELS Design adaptation based on ~TW1.2.33
2005.07.20 1.0.0 Initial release (as adaptation)
<<<
"La vida en sí no es la realidad. Somos nosotros quienes ponemos vida en piedras y guijarros". Frederick Sommer.
----
"Fotografiar es conferir importancia". Susan Sontag.
----
"The only way for me to be human is for you to reflect my humanity back on me ". Chris Abani."Ubuntu"
[[TagHodeiaNubedeTags]] [[Sarrera]][[Introducción]]
/***
| Name:|''dropTagging''|
| Created by:|SaqImtiaz|
| Location:|http://tw.lewcid.org/|
| Version:|0.1 (06-Apr-2006)|
| Requires:|~TW2.07|
!About
*provides a drop down list of tiddlers tagged with the specified tag, a replacement for the core tagging macro.
!Demonstration
*<<dropTagging Saq>>
''I recommend using either TaggerPlugin or monkeyTagger, with dropTags and dropTagging in the toolbar:''
!Usage
{{{<<dropTagging>>}}} for tiddlers tagged by current tiddler/tag
{{{<<dropTagging 'Saq'>>}}} for tiddlers tagged by the tag 'Saq' <<dropTagging 'Saq'>>
{{{<<dropTagging 'Saq' 'custom label'>>}}} for tiddlers tagged by the tag 'Saq' with a custom label. <<dropTagging 'Saq' 'custom label'>>
!Installation:
*Copy this tiddler to your TW with the systemConfig tag
* copy the following to your ViewTemplate:
#either {{{<div class='tagging' macro='dropTagging'></div>}}} to add next to or replace tagging macro, or
#{{{<div class='toolbar' >
<span style="padding-right:1.75em;" macro='dropTagging''></span>
<span macro='toolbar -closeTiddler closeOthers +editTiddler permalink references jump'></span>
</div>}}}(adjust padding to taste)
!To Do
*tweak popup css to optimize placement and colors.
*''optimize code to use core onClickTag function, can cut code size by half!''
!Code
***/
//{{{
config.macros.dropTagging={};
config.macros.dropTagging.dropdownchar = (document.all?"▼":"▾"); // the fat one is the only one that works in IE
config.macros.dropTagging.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
var arrow=': '+ config.macros.dropTagging.dropdownchar;
if(params[0] && store.tiddlerExists(params[0]))
tiddler = store.getTiddler(params[0]);
var droptagginglabel= (params[1] && params[1] !='.')? params[1]: 'tagging'+arrow;
var droptaggingtooltip="tiddlers tagged with '"+tiddler.title+"'";
if(params[0] && store.tiddlerExists(params[0]))
tiddler = store.getTiddler(params[0]);
var tagged = store.getTaggedTiddlers(tiddler.title);
if(tagged.length==0)
return false;
var droptagging = function(e)
{ if (!e) var e = window.event;
var popup = Popup.create(this);
for(var t=0; t<tagged.length; t++)
createTiddlyLink(createTiddlyElement(popup,"li"),tagged[t].title,true);
Popup.show(popup,false);
e.cancelBubble = true;
if (e.stopPropagation)
e.stopPropagation();
return(false);
};
var createdropperButton = function(place){
var sp = createTiddlyElement(place,"span",null,"taggingdropbutton");
var theDropDownBtn = createTiddlyButton(sp,droptagginglabel,droptaggingtooltip,droptagging);
};
createdropperButton(place);
};
setStylesheet(
".toolbar .taggingdropbutton {margin-right:0em; border:0px solid #eee; padding:0px; padding-right:0px; padding-left:0px; }\n"+
".taggingdropbutton a.button {padding:2px; padding-left:2px; padding-right:2px;}\n"+
// ".taggingdropbutton {font-size:150%;}\n"+
".popup .highlight{background: #fe8; color:#000;}\n"+
"",
"DropTaggingStyles");
//}}}
<html><div align="center"<object width="500" height="580" align="middle"><param name="FlashVars" VALUE="ids=72157611668984543&names=antzinekoak&userName=ilargi-zaldibar&userId=14153873@N00&titles=on&source=sets"></param><param name="PictoBrowser" value="http://www.db798.com/pictobrowser.swf"></param><param name="scale" value="noscale"></param><param name="bgcolor" value="#ffffff"></param><param name="wmode" value="transparent"></param><embed src="http://www.db798.com/pictobrowser.swf" FlashVars="ids=72157611668984543&names=antzinekoak&userName=ilargi-zaldibar&userId=14153873@N00&titles=on&source=sets" loop="false" scale="noscale" bgcolor="#ffffff" width="500" height="580" name="PictoBrowser" align="middle" wmode="transparent"></embed></object></div></html>
|Elena Millan. (Zaldibar)|[img[http://farm4.static.flickr.com/3261/3145442246_2253c84472_m.jpg]]|[img[http://farm3.static.flickr.com/2242/2100726160_64f08e1d91_m.jpg]]|
/***
|Name|FontSizePlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#FontSizePlugin|
|Version|1.0|
|Requires|~TW2.x|
!Description:
Resize tiddler text on the fly. The text size is remembered between sessions by use of a cookie.
You can customize the maximum and minimum allowed sizes.
(only affects tiddler content text, not any other text)
Also, you can load a TW file with a font-size specified in the url.
Eg: http://tw.lewcid.org/#font:110
!Demo:
Try using the font-size buttons in the sidebar, or in the MainMenu above.
!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
Then put {{{<<fontSize "font-size:">>}}} in your SideBarOptions tiddler, or anywhere else that you might like.
!Usage
{{{<<fontSize>>}}} results in <<fontSize>>
{{{<<fontSize font-size: >>}}} results in <<fontSize font-size:>>
!Customizing:
The buttons and prefix text are wrapped in a span with class fontResizer, for easy css styling.
To change the default font-size, and the maximum and minimum font-size allowed, edit the config.fontSize.settings section of the code below.
!Notes:
This plugin assumes that the initial font-size is 100% and then increases or decreases the size by 10%. This stepsize of 10% can also be customized.
!History:
*27-07-06, version 1.0 : prevented double clicks from triggering editing of containing tiddler.
*25-07-06, version 0.9
!Code
***/
//{{{
config.fontSize={};
//configuration settings
config.fontSize.settings =
{
defaultSize : 100, // all sizes in %
maxSize : 200,
minSize : 40,
stepSize : 10
};
//startup code
var fontSettings = config.fontSize.settings;
if (!config.options.txtFontSize)
{config.options.txtFontSize = fontSettings.defaultSize;
saveOptionCookie("txtFontSize");}
setStylesheet(".tiddler .viewer {font-size:"+config.options.txtFontSize+"%;}\n","fontResizerStyles");
setStylesheet("#contentWrapper .fontResizer .button {display:inline;font-size:105%; font-weight:bold; margin:0 1px; padding: 0 3px; text-align:center !important;}\n .fontResizer {margin:0 0.5em;}","fontResizerButtonStyles");
//macro
config.macros.fontSize={};
config.macros.fontSize.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
var sp = createTiddlyElement(place,"span",null,"fontResizer");
sp.ondblclick=this.onDblClick;
if (params[0])
createTiddlyText(sp,params[0]);
createTiddlyButton(sp,"+","increase font-size",this.incFont);
createTiddlyButton(sp,"=","reset font-size",this.resetFont);
createTiddlyButton(sp,"–","decrease font-size",this.decFont);
}
config.macros.fontSize.onDblClick = function (e)
{
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return false;
}
config.macros.fontSize.setFont = function ()
{
saveOptionCookie("txtFontSize");
setStylesheet(".tiddler .viewer {font-size:"+config.options.txtFontSize+"%;}\n","fontResizerStyles");
}
config.macros.fontSize.incFont=function()
{
if (config.options.txtFontSize < fontSettings.maxSize)
config.options.txtFontSize = (config.options.txtFontSize*1)+fontSettings.stepSize;
config.macros.fontSize.setFont();
}
config.macros.fontSize.decFont=function()
{
if (config.options.txtFontSize > fontSettings.minSize)
config.options.txtFontSize = (config.options.txtFontSize*1) - fontSettings.stepSize;
config.macros.fontSize.setFont();
}
config.macros.fontSize.resetFont=function()
{
config.options.txtFontSize=fontSettings.defaultSize;
config.macros.fontSize.setFont();
}
config.paramifiers.font =
{
onstart: function(v)
{
config.options.txtFontSize = v;
config.macros.fontSize.setFont();
}
};
//}}}
/***
|''Name:''|ForEachTiddlerPlugin|
|''Version:''|1.0.8 (2007-04-12)|
|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|© 2005-2007 [[abego Software|http://www.abego-software.de]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
!Description
Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.
''Syntax:''
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]] is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
See details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].
!Revision history
* v1.0.8 (2007-04-12)
** Adapted to latest TiddlyWiki 2.2 Beta importTiddlyWiki API (introduced with changeset 2004). TiddlyWiki 2.2 Beta builds prior to changeset 2004 are no longer supported (but TiddlyWiki 2.1 and earlier, of cause)
* v1.0.7 (2007-03-28)
** Also support "pre" formatted TiddlyWikis (introduced with TW 2.2) (when using "in" clause to work on external tiddlers)
* v1.0.6 (2006-09-16)
** Context provides "viewerTiddler", i.e. the tiddler used to view the macro. Most times this is equal to the "inTiddler", but when using the "tiddler" macro both may be different.
** Support "begin", "end" and "none" expressions in "write" action
* v1.0.5 (2006-02-05)
** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.
** Support Firefox 1.5.0.1
** Internal
*** Make "JSLint" conform
*** "Only install once"
* v1.0.4 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.3 (2005-12-22)
** Features:
*** Write output to a file supports multi-byte environments (Thanks to Bram Chen)
*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)
** Enhancements:
*** Improved error messages on InternetExplorer.
* v1.0.2 (2005-12-10)
** Features:
*** context object also holds reference to store (TiddlyWiki)
** Fixed Bugs:
*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)
* v1.0.1 (2005-12-08)
** Features:
*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".
*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.
*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).
*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .
*** Improved script evaluation (for where/sort clause and write scripts).
* v1.0.0 (2005-11-20)
** initial version
!Code
***/
//{{{
//============================================================================
//============================================================================
// ForEachTiddlerPlugin
//============================================================================
//============================================================================
// Only install once
if (!version.extensions.ForEachTiddlerPlugin) {
if (!window.abego) window.abego = {};
version.extensions.ForEachTiddlerPlugin = {
major: 1, minor: 0, revision: 8,
date: new Date(2007,3,12),
source: "http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin",
licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
copyright: "Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"
};
// For backward compatibility with TW 1.2.x
//
if (!TiddlyWiki.prototype.forEachTiddler) {
TiddlyWiki.prototype.forEachTiddler = function(callback) {
for(var t in this.tiddlers) {
callback.call(this,t,this.tiddlers[t]);
}
};
}
//============================================================================
// forEachTiddler Macro
//============================================================================
version.extensions.forEachTiddler = {
major: 1, minor: 0, revision: 8, date: new Date(2007,3,12), provider: "http://tiddlywiki.abego-software.de"};
// ---------------------------------------------------------------------------
// Configurations and constants
// ---------------------------------------------------------------------------
config.macros.forEachTiddler = {
// Standard Properties
label: "forEachTiddler",
prompt: "Perform actions on a (sorted) selection of tiddlers",
// actions
actions: {
addToList: {},
write: {}
}
};
// ---------------------------------------------------------------------------
// The forEachTiddler Macro Handler
// ---------------------------------------------------------------------------
config.macros.forEachTiddler.getContainingTiddler = function(e) {
while(e && !hasClass(e,"tiddler"))
e = e.parentNode;
var title = e ? e.getAttribute("tiddler") : null;
return title ? store.getTiddler(title) : null;
};
config.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
// config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);
if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);
// --- Parsing ------------------------------------------
var i = 0; // index running over the params
// Parse the "in" clause
var tiddlyWikiPath = undefined;
if ((i < params.length) && params[i] == "in") {
i++;
if (i >= params.length) {
this.handleError(place, "TiddlyWiki path expected behind 'in'.");
return;
}
tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");
i++;
}
// Parse the where clause
var whereClause ="true";
if ((i < params.length) && params[i] == "where") {
i++;
whereClause = this.paramEncode((i < params.length) ? params[i] : "");
i++;
}
// Parse the sort stuff
var sortClause = null;
var sortAscending = true;
if ((i < params.length) && params[i] == "sortBy") {
i++;
if (i >= params.length) {
this.handleError(place, "sortClause missing behind 'sortBy'.");
return;
}
sortClause = this.paramEncode(params[i]);
i++;
if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {
sortAscending = params[i] == "ascending";
i++;
}
}
// Parse the script
var scriptText = null;
if ((i < params.length) && params[i] == "script") {
i++;
scriptText = this.paramEncode((i < params.length) ? params[i] : "");
i++;
}
// Parse the action.
// When we are already at the end use the default action
var actionName = "addToList";
if (i < params.length) {
if (!config.macros.forEachTiddler.actions[params[i]]) {
this.handleError(place, "Unknown action '"+params[i]+"'.");
return;
} else {
actionName = params[i];
i++;
}
}
// Get the action parameter
// (the parsing is done inside the individual action implementation.)
var actionParameter = params.slice(i);
// --- Processing ------------------------------------------
try {
this.performMacro({
place: place,
inTiddler: tiddler,
whereClause: whereClause,
sortClause: sortClause,
sortAscending: sortAscending,
actionName: actionName,
actionParameter: actionParameter,
scriptText: scriptText,
tiddlyWikiPath: tiddlyWikiPath});
} catch (e) {
this.handleError(place, e);
}
};
// Returns an object with properties "tiddlers" and "context".
// tiddlers holds the (sorted) tiddlers selected by the parameter,
// context the context of the execution of the macro.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {
var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);
var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;
context["tiddlyWiki"] = tiddlyWiki;
// Get the tiddlers, as defined by the whereClause
var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);
context["tiddlers"] = tiddlers;
// Sort the tiddlers, when sorting is required.
if (parameter.sortClause) {
this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);
}
return {tiddlers: tiddlers, context: context};
};
// Returns the (sorted) tiddlers selected by the parameter.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlers = function(parameter) {
return this.getTiddlersAndContext(parameter).tiddlers;
};
// Performs the macros with the given parameter.
//
// @param parameter holds the parameter of the macro as separate properties.
// The following properties are supported:
//
// place
// whereClause
// sortClause
// sortAscending
// actionName
// actionParameter
// scriptText
// tiddlyWikiPath
//
// All properties are optional.
// For most actions the place property must be defined.
//
config.macros.forEachTiddler.performMacro = function(parameter) {
var tiddlersAndContext = this.getTiddlersAndContext(parameter);
// Perform the action
var actionName = parameter.actionName ? parameter.actionName : "addToList";
var action = config.macros.forEachTiddler.actions[actionName];
if (!action) {
this.handleError(parameter.place, "Unknown action '"+actionName+"'.");
return;
}
var actionHandler = action.handler;
actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);
};
// ---------------------------------------------------------------------------
// The actions
// ---------------------------------------------------------------------------
// Internal.
//
// --- The addToList Action -----------------------------------------------
//
config.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {
// Parse the parameter
var p = 0;
// Check for extra parameters
if (parameter.length > p) {
config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);
return;
}
// Perform the action.
var list = document.createElement("ul");
place.appendChild(list);
for (var i = 0; i < tiddlers.length; i++) {
var tiddler = tiddlers[i];
var listItem = document.createElement("li");
list.appendChild(listItem);
createTiddlyLink(listItem, tiddler.title, true);
}
};
abego.parseNamedParameter = function(name, parameter, i) {
var beginExpression = null;
if ((i < parameter.length) && parameter[i] == name) {
i++;
if (i >= parameter.length) {
throw "Missing text behind '%0'".format([name]);
}
return config.macros.forEachTiddler.paramEncode(parameter[i]);
}
return null;
}
// Internal.
//
// --- The write Action ---------------------------------------------------
//
config.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {
// Parse the parameter
var p = 0;
if (p >= parameter.length) {
this.handleError(place, "Missing expression behind 'write'.");
return;
}
var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);
p++;
// Parse the "begin" option
var beginExpression = abego.parseNamedParameter("begin", parameter, p);
if (beginExpression !== null)
p += 2;
var endExpression = abego.parseNamedParameter("end", parameter, p);
if (endExpression !== null)
p += 2;
var noneExpression = abego.parseNamedParameter("none", parameter, p);
if (noneExpression !== null)
p += 2;
// Parse the "toFile" option
var filename = null;
var lineSeparator = undefined;
if ((p < parameter.length) && parameter[p] == "toFile") {
p++;
if (p >= parameter.length) {
this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");
return;
}
filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));
p++;
if ((p < parameter.length) && parameter[p] == "withLineSeparator") {
p++;
if (p >= parameter.length) {
this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");
return;
}
lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);
p++;
}
}
// Check for extra parameters
if (parameter.length > p) {
config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);
return;
}
// Perform the action.
var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);
var count = tiddlers.length;
var text = "";
if (count > 0 && beginExpression)
text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);
for (var i = 0; i < count; i++) {
var tiddler = tiddlers[i];
text += func(tiddler, context, count, i);
}
if (count > 0 && endExpression)
text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);
if (count == 0 && noneExpression)
text += config.macros.forEachTiddler.getEvalTiddlerFunction(noneExpression, context)(undefined, context, count, undefined);
if (filename) {
if (lineSeparator !== undefined) {
lineSeparator = lineSeparator.replace(/\\n/mg, "\n").replace(/\\r/mg, "\r");
text = text.replace(/\n/mg,lineSeparator);
}
saveFile(filename, convertUnicodeToUTF8(text));
} else {
var wrapper = createTiddlyElement(place, "span");
wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);
}
};
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
// Internal.
//
config.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {
return {
place : placeParam,
whereClause : whereClauseParam,
sortClause : sortClauseParam,
sortAscending : sortAscendingParam,
script : scriptText,
actionName : actionNameParam,
actionParameter : actionParameterParam,
tiddlyWikiPath : tiddlyWikiPathParam,
inTiddler : inTiddlerParam, // the tiddler containing the <<forEachTiddler ...>> macro call.
viewerTiddler : config.macros.forEachTiddler.getContainingTiddler(placeParam) // the tiddler showing the forEachTiddler result
};
};
// Internal.
//
// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of
// the given path.
//
config.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {
if (!idPrefix) {
idPrefix = "store";
}
var lenPrefix = idPrefix.length;
// Read the content of the given file
var content = loadFile(this.getLocalPath(path));
if(content === null) {
throw "TiddlyWiki '"+path+"' not found.";
}
var tiddlyWiki = new TiddlyWiki();
// Starting with TW 2.2 there is a helper function to import the tiddlers
if (tiddlyWiki.importTiddlyWiki) {
if (!tiddlyWiki.importTiddlyWiki(content))
throw "File '"+path+"' is not a TiddlyWiki.";
tiddlyWiki.dirty = false;
return tiddlyWiki;
}
// The legacy code, for TW < 2.2
// Locate the storeArea div's
var posOpeningDiv = content.indexOf(startSaveArea);
var posClosingDiv = content.lastIndexOf(endSaveArea);
if((posOpeningDiv == -1) || (posClosingDiv == -1)) {
throw "File '"+path+"' is not a TiddlyWiki.";
}
var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);
// Create a "div" element that contains the storage text
var myStorageDiv = document.createElement("div");
myStorageDiv.innerHTML = storageText;
myStorageDiv.normalize();
// Create all tiddlers in a new TiddlyWiki
// (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)
var store = myStorageDiv.childNodes;
for(var t = 0; t < store.length; t++) {
var e = store[t];
var title = null;
if(e.getAttribute)
title = e.getAttribute("tiddler");
if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
title = e.id.substr(lenPrefix);
if(title && title !== "") {
var tiddler = tiddlyWiki.createTiddler(title);
tiddler.loadFromDiv(e,title);
}
}
tiddlyWiki.dirty = false;
return tiddlyWiki;
};
// Internal.
//
// Returns a function that has a function body returning the given javaScriptExpression.
// The function has the parameters:
//
// (tiddler, context, count, index)
//
config.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {
var script = context["script"];
var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";
var fullText = (script ? script+";" : "")+functionText+";theFunction;";
return eval(fullText);
};
// Internal.
//
config.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {
var result = [];
var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);
tiddlyWiki.forEachTiddler(function(title,tiddler) {
if (func(tiddler, context, undefined, undefined)) {
result.push(tiddler);
}
});
return result;
};
// Internal.
//
config.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {
var message = "Extra parameter behind '"+actionName+"':";
for (var i = firstUnusedIndex; i < parameter.length; i++) {
message += " "+parameter[i];
}
this.handleError(place, message);
};
// Internal.
//
config.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {
var result =
(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue)
? 0
: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
? -1
: +1;
return result;
};
// Internal.
//
config.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {
var result =
(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue)
? 0
: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
? +1
: -1;
return result;
};
// Internal.
//
config.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {
// To avoid evaluating the sortClause whenever two items are compared
// we pre-calculate the sortValue for every item in the array and store it in a
// temporary property ("forEachTiddlerSortValue") of the tiddlers.
var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);
var count = tiddlers.length;
var i;
for (i = 0; i < count; i++) {
var tiddler = tiddlers[i];
tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);
}
// Do the sorting
tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);
// Delete the temporary property that holds the sortValue.
for (i = 0; i < tiddlers.length; i++) {
delete tiddlers[i].forEachTiddlerSortValue;
}
};
// Internal.
//
config.macros.forEachTiddler.trace = function(message) {
displayMessage(message);
};
// Internal.
//
config.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {
var message ="<<"+macroName;
for (var i = 0; i < params.length; i++) {
message += " "+params[i];
}
message += ">>";
displayMessage(message);
};
// Internal.
//
// Creates an element that holds an error message
//
config.macros.forEachTiddler.createErrorElement = function(place, exception) {
var message = (exception.description) ? exception.description : exception.toString();
return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);
};
// Internal.
//
// @param place [may be null]
//
config.macros.forEachTiddler.handleError = function(place, exception) {
if (place) {
this.createErrorElement(place, exception);
} else {
throw exception;
}
};
// Internal.
//
// Encodes the given string.
//
// Replaces
// "$))" to ">>"
// "$)" to ">"
//
config.macros.forEachTiddler.paramEncode = function(s) {
var reGTGT = new RegExp("\\$\\)\\)","mg");
var reGT = new RegExp("\\$\\)","mg");
return s.replace(reGTGT, ">>").replace(reGT, ">");
};
// Internal.
//
// Returns the given original path (that is a file path, starting with "file:")
// as a path to a local file, in the systems native file format.
//
// Location information in the originalPath (i.e. the "#" and stuff following)
// is stripped.
//
config.macros.forEachTiddler.getLocalPath = function(originalPath) {
// Remove any location part of the URL
var hashPos = originalPath.indexOf("#");
if(hashPos != -1)
originalPath = originalPath.substr(0,hashPos);
// Convert to a native file format assuming
// "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
// "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
// "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
// "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
var localPath;
if(originalPath.charAt(9) == ":") // pc local file
localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file
localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
else if(originalPath.indexOf("file:///") === 0) // mac/unix local file
localPath = unescape(originalPath.substr(7));
else if(originalPath.indexOf("file:/") === 0) // mac/unix local file
localPath = unescape(originalPath.substr(5));
else // pc network file
localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");
return localPath;
};
// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
".forEachTiddlerError{color: #ffffff;background-color: #880000;}",
"forEachTiddler");
//============================================================================
// End of forEachTiddler Macro
//============================================================================
//============================================================================
// String.startsWith Function
//============================================================================
//
// Returns true if the string starts with the given prefix, false otherwise.
//
version.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.startsWith = function(prefix) {
var n = prefix.length;
return (this.length >= n) && (this.slice(0, n) == prefix);
};
//============================================================================
// String.endsWith Function
//============================================================================
//
// Returns true if the string ends with the given suffix, false otherwise.
//
version.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.endsWith = function(suffix) {
var n = suffix.length;
return (this.length >= n) && (this.right(n) == suffix);
};
//============================================================================
// String.contains Function
//============================================================================
//
// Returns true when the string contains the given substring, false otherwise.
//
version.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.contains = function(substring) {
return this.indexOf(substring) >= 0;
};
//============================================================================
// Array.indexOf Function
//============================================================================
//
// Returns the index of the first occurance of the given item in the array or
// -1 when no such item exists.
//
// @param item [may be null]
//
version.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.indexOf = function(item) {
for (var i = 0; i < this.length; i++) {
if (this[i] == item) {
return i;
}
}
return -1;
};
//============================================================================
// Array.contains Function
//============================================================================
//
// Returns true when the array contains the given item, otherwise false.
//
// @param item [may be null]
//
version.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.contains = function(item) {
return (this.indexOf(item) >= 0);
};
//============================================================================
// Array.containsAny Function
//============================================================================
//
// Returns true when the array contains at least one of the elements
// of the item. Otherwise (or when items contains no elements) false is returned.
//
version.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAny = function(items) {
for(var i = 0; i < items.length; i++) {
if (this.contains(items[i])) {
return true;
}
}
return false;
};
//============================================================================
// Array.containsAll Function
//============================================================================
//
// Returns true when the array contains all the items, otherwise false.
//
// When items is null false is returned (even if the array contains a null).
//
// @param items [may be null]
//
version.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAll = function(items) {
for(var i = 0; i < items.length; i++) {
if (!this.contains(items[i])) {
return false;
}
}
return true;
};
} // of "install only once"
// Used Globals (for JSLint) ==============
// ... DOM
/*global document */
// ... TiddlyWiki Core
/*global convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink,
displayMessage, endSaveArea, hasClass, loadFile, saveFile,
startSaveArea, store, wikify */
//}}}
/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/
/***
|Name|HoverMenuPlugin|
|Created by|SaqImtiaz|
|Location|http://lewcid.googlepages.com/lewcid.html#HoverMenuPlugin|
|Version|1.11|
|Requires|~TW2.x|
!Description:
Provides a hovering menu on the edge of the screen for commonly used commands, that scrolls with the page.
!Demo:
Observe the hovering menu on the right edge of the screen.
!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
To customize your HoverMenu, edit the HoverMenu shadow tiddler.
To customize whether the menu sticks to the right or left edge of the screen, and its start position, edit the HoverMenu configuration settings part of the code below. It's well documented, so don't be scared!
The menu has an id of hoverMenu, in case you want to style the buttons in it using css.
!Notes:
Since the default HoverMenu contains buttons for toggling the side bar and jumping to the top of the screen and to open tiddlers, the ToggleSideBarMacro, JumpMacro and the JumpToTopMacro are included in this tiddler, so you dont need to install them separately. Having them installed separately as well could lead to complications.
If you dont intend to use these three macros at all, feel free to remove those sections of code in this tiddler.
!To Do:
* rework code to allow multiple hovering menus in different positions, horizontal etc.
* incorporate code for keyboard shortcuts that correspond to the buttons in the hovermenu
!History:
*03-08-06, ver 1.11: fixed error with button tooltips
*27-07-06, ver 1.1 : added JumpMacro to hoverMenu
*23-07-06
!Code
***/
/***
start HoverMenu plugin code
***/
//{{{
config.hoverMenu={};
//}}}
/***
HoverMenu configuration settings
***/
//{{{
config.hoverMenu.settings={
align: 'right', //align menu to right or left side of screen, possible values are 'right' and 'left'
x: 1, // horizontal distance of menu from side of screen, increase to your liking.
y: 158 //vertical distance of menu from top of screen at start, increase or decrease to your liking
};
//}}}
//{{{
//continue HoverMenu plugin code
config.hoverMenu.handler=function()
{
var theMenu = createTiddlyElement(document.getElementById("contentWrapper"), "div","hoverMenu");
theMenu.setAttribute("refresh","content");
theMenu.setAttribute("tiddler","HoverMenu");
var menuContent = store.getTiddlerText("HoverMenu");
wikify(menuContent,theMenu);
var Xloc = this.settings.x;
Yloc =this.settings.y;
var ns = (navigator.appName.indexOf("Netscape") != -1);
function SetMenu(id)
{
var GetElements=document.getElementById?document.getElementById(id):document.all?document.all[id]:document.layers[id];
if(document.layers)GetElements.style=GetElements;
GetElements.sP=function(x,y){this.style[config.hoverMenu.settings.align]=x +"px";this.style.top=y +"px";};
GetElements.x = Xloc;
GetElements.y = findScrollY();
GetElements.y += Yloc;
return GetElements;
}
window.LoCate_XY=function()
{
var pY = findScrollY();
ftlObj.y += (pY + Yloc - ftlObj.y)/15;
ftlObj.sP(ftlObj.x, ftlObj.y);
setTimeout("LoCate_XY()", 10);
}
ftlObj = SetMenu("hoverMenu");
LoCate_XY();
};
window.old_lewcid_hovermenu_restart = restart;
restart = function()
{
window.old_lewcid_hovermenu_restart();
config.hoverMenu.handler();
};
setStylesheet(
"#hoverMenu .button, #hoverMenu .tiddlyLink {border:none; font-weight:bold; background:#18f; color:#FFF; padding:0 5px; float:right; margin-bottom:4px;}\n"+
"#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {font-weight:bold; border:none; color:#fff; background:#000; padding:0 5px; float:right; margin-bottom:4px;}\n"+
"#hoverMenu .button {width:100%; text-align:center}"+
"#hoverMenu { position:absolute; width:7px;}\n"+
"\n","hoverMenuStyles");
config.macros.renameButton={};
config.macros.renameButton.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
if (place.lastChild.tagName!="BR")
{
place.lastChild.firstChild.data = params[0];
if (params[1]) {place.lastChild.title = params[1];}
}
};
config.shadowTiddlers["HoverMenu"]="<<top>>\n<<toggleSideBar>><<renameButton '>' >>\n<<jump j '' top>>\n<<saveChanges>><<renameButton s 'Save TiddlyWiki'>>\n<<newTiddler>><<renameButton n>>\n";
//}}}
//end HoverMenu plugin code
//Start ToggleSideBarMacro code
//{{{
config.macros.toggleSideBar={};
config.macros.toggleSideBar.settings={
styleHide : "#sidebar { display: none;}\n"+"#contentWrapper #displayArea { margin-right: 1em;}\n"+"",
styleShow : " ",
arrow1: "«",
arrow2: "»"
};
config.macros.toggleSideBar.handler=function (place,macroName,params,wikifier,paramString,tiddler)
{
var tooltip= params[1]||'toggle sidebar';
var mode = (params[2] && params[2]=="hide")? "hide":"show";
var arrow = (mode == "hide")? this.settings.arrow1:this.settings.arrow2;
var label= (params[0]&¶ms[0]!='.')?params[0]+" "+arrow:arrow;
var theBtn = createTiddlyButton(place,label,tooltip,this.onToggleSideBar,"button HideSideBarButton");
if (mode == "hide")
{
(document.getElementById("sidebar")).setAttribute("toggle","hide");
setStylesheet(this.settings.styleHide,"ToggleSideBarStyles");
}
};
config.macros.toggleSideBar.onToggleSideBar = function(){
var sidebar = document.getElementById("sidebar");
var settings = config.macros.toggleSideBar.settings;
if (sidebar.getAttribute("toggle")=='hide')
{
setStylesheet(settings.styleShow,"ToggleSideBarStyles");
sidebar.setAttribute("toggle","show");
this.firstChild.data= (this.firstChild.data).replace(settings.arrow1,settings.arrow2);
}
else
{
setStylesheet(settings.styleHide,"ToggleSideBarStyles");
sidebar.setAttribute("toggle","hide");
this.firstChild.data= (this.firstChild.data).replace(settings.arrow2,settings.arrow1);
}
return false;
}
setStylesheet(".HideSideBarButton .button {font-weight:bold; padding: 0 5px;}\n","ToggleSideBarButtonStyles");
//}}}
//end ToggleSideBarMacro code
//start JumpToTopMacro code
//{{{
config.macros.top={};
config.macros.top.handler=function(place,macroName)
{
createTiddlyButton(place,"^","jump to top",this.onclick);
}
config.macros.top.onclick=function()
{
window.scrollTo(0,0);
};
config.commands.top =
{
text:" ^ ",
tooltip:"jump to top"
};
config.commands.top.handler = function(event,src,title)
{
window.scrollTo(0,0);
}
//}}}
//end JumpToStartMacro code
//start JumpMacro code
//{{{
config.macros.jump= {};
config.macros.jump.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
var label = (params[0] && params[0]!=".")? params[0]: 'jump';
var tooltip = (params[1] && params[1]!=".")? params[1]: 'jump to an open tiddler';
var top = (params[2] && params[2]=='top') ? true: false;
var btn =createTiddlyButton(place,label,tooltip,this.onclick);
if (top==true)
btn.setAttribute("top","true")
}
config.macros.jump.onclick = function(e)
{
if (!e) var e = window.event;
var theTarget = resolveTarget(e);
var top = theTarget.getAttribute("top");
var popup = Popup.create(this);
if(popup)
{
if(top=="true")
{createTiddlyButton(createTiddlyElement(popup,"li"),'Top ↑','Top of TW',config.macros.jump.top);
createTiddlyElement(popup,"hr");}
story.forEachTiddler(function(title,element) {
createTiddlyLink(createTiddlyElement(popup,"li"),title,true);
});
}
Popup.show(popup,false);
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return false;
}
config.macros.jump.top = function()
{
window.scrollTo(0,0);
}
//}}}
//end JumpMacro code
//utility functions
//{{{
Popup.show = function(unused,slowly)
{
var curr = Popup.stack[Popup.stack.length-1];
var rootLeft = findPosX(curr.root);
var rootTop = findPosY(curr.root);
var rootHeight = curr.root.offsetHeight;
var popupLeft = rootLeft;
var popupTop = rootTop + rootHeight;
var popupWidth = curr.popup.offsetWidth;
var winWidth = findWindowWidth();
if (isChild(curr.root,'hoverMenu'))
var x = config.hoverMenu.settings.x;
else
var x = 0;
if(popupLeft + popupWidth+x > winWidth)
popupLeft = winWidth - popupWidth -x;
if (isChild(curr.root,'hoverMenu'))
{curr.popup.style.right = x + "px";}
else
curr.popup.style.left = popupLeft + "px";
curr.popup.style.top = popupTop + "px";
curr.popup.style.display = "block";
addClass(curr.root,"highlight");
if(config.options.chkAnimate)
anim.startAnimating(new Scroller(curr.popup,slowly));
else
window.scrollTo(0,ensureVisible(curr.popup));
}
window.isChild = function(e,parentId) {
while (e != null) {
var parent = document.getElementById(parentId);
if (parent == e) return true;
e = e.parentNode;
}
return false;
};
//}}}
<html><div align="center"><iframe src ="http://ilargi.blogsome.com/ilargiAN" width="100%" align="center" height="800"></iframe></div></html>
!Estimados socios y seguidores del Colectivo Fotográfico ILARGI:
{{twocolumns justify {
{{firstletter{
@@color:#3300CC;C@@
}}}
on motivo de la celebración del 25 aniversario de la constitución del Colectivo Fotográfico ILARGI, queremos rescatar y ordenar los hitos más importantes de nuestra historia. Y lo queremos hacer mediante los instrumentos de nuestro tiempo. Nos debemos a las herramientas digitales. Utilizamos TiddlyWiki. Nos apoyamos en Flickr. Puede constituir este nuevo enlace una guinda a un año de celebraciones.
[>img[25. urteurrena|http://farm5.static.flickr.com/4133/5211733662_2b81b88753_o.jpg ]] Sin ningún genero de dudas, lo que aquí se recoge no es más que la parte de un iceberg de trabajo y dedicación desigual e intermitente... pero constante en el tiempo. Incontables serán sin duda las horas dedicadas por Rafa al Colectivo, escaneando fotografías antiguas, organizando los eventos. Impagable la tarea de Jose Luis documentando las fotografias o acudiendo al ayuntamiento que tan regularmente nos ha proporcionado la financiación necesaria.
[<img[25. urteurrena|http://farm1.static.flickr.com/28/95800989_f0cd8ddf89_m.jpg ]]Las imágenes que incluimos no presentan novedades, son conocidas por todos. Es cierto que se precipitaban al olvido de nuestra memoria. Este wiki pretende facilitar su búsqueda mediante un pretendido etiquetado correcto. En la columna de la izquierda aparecen todas la etiquetas //tags// que nos permiten navegar con soltura por los //tiddler//s
[>img[http://farm5.static.flickr.com/4132/5210898535_2fb83b9def_t.jpg]]
De igual manera que nuestra historia presenta lagunas, esta representación de la misma no está exenta de vacíos y errores en algunos datos.Tampoco faltan promesas incumplidas. Predicamos "Cien fotos antiguas", y solo aparecen cuatro... El tiempo nos irá dando la razón... aparecerán.
}}}
<html><center><a href="http://www.flickr.com/photos/ilargi/4679469241/" title="iñigo bernedo by ilargi-zaldibar, on Flickr"><img src="http://farm5.static.flickr.com/4045/4679469241_25c7382cec_z.jpg" width="500" alt="iñigo bernedo" /></a></center></html>
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
major: 1, minor: 1, revision: 0,
date: new Date("mar 17, 2007"),
source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};
if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};
bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){
url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
}
return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
^^<<tagCloud>>^^
----
^^[[WelcomeToTiddlyspot]] ^^
----
^^TiddlyWiki versión <<version>>
© 2007 [[UnaMesa|http://www.unamesa.org/]]^^
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>Ilargi. Zaldibarko argazki taldea.</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>
/***
|Name|NestedSlidersPlugin|
|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|Version|2.2.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Slider.prototype.stop|
|Description|show content in nest-able 'slider' or 'floating' panels, without needing to create separate tiddlers for each panel|
!!!!!Configuration
<<<
Enable animation for slider panels
<<option chkFloatingSlidersAnimate>> allow sliders to animate when opening/closing
>(note: This setting is in //addition// to the general option for enabling/disabling animation effects:
><<option chkAnimate>> enable animations (entire document)
>For slider animation to occur, you must also allow animation in general.
Debugging messages for 'lazy sliders' deferred rendering:
<<option chkDebugLazySliderDefer>> show debugging alert when deferring slider rendering
<<option chkDebugLazySliderRender>> show debugging alert when deferred slider is actually rendered
<<<
!!!!!Usage
<<<
When installed, this plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content. Use {{{+++}}} and {{{===}}} to delimit the slider content. You 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.
Additional optional syntax elements let you specify
*default to open
*cookiename
*heading level
*floater (with optional CSS width value)
*transient display (clicking elsewhere closes panel)
*custom class/label/tooltip/accesskey
*alternate label/tooltip (displayed when panel is open)
*panelID (for later use with {{{<<DOM>>}}} macro. See [[DOMTweaksPlugin]])
*automatic blockquote style on panel
*deferred rendering of panel content
The complete syntax, using all options, is:
//{{{
++++(cookiename)!!!!!^width^*{{class{[label=key|tooltip][altlabel|alttooltip]}}}#panelID:>...
content goes here
===
//}}}
where:
* {{{+++}}} (or {{{++++}}}) and {{{===}}}<br>marks the start and end of the slider definition, respectively. When the extra {{{+}}} is used, the slider will be open when initially displayed.
* {{{(cookiename)}}}<br>saves the slider opened/closed state, and restores this state whenever the slider is re-rendered.
* {{{!}}} through {{{!!!!!}}}<br>displays the slider label using a formatted headline (Hn) style instead of a button/link style
* {{{^width^}}} (or just {{{^}}})<br>makes the slider 'float' on top of other content rather than shifting that content downward. 'width' must be a valid CSS value (e.g., "30em", "180px", "50%", etc.). If omitted, the default width is "auto" (i.e., fit to content)
* {{{"*"}}} //(without the quotes)//<br>denotes "transient display": when a click occurs elsewhere in the document, the slider/floating panel will be automatically closed. This is useful for creating 'pulldown menus' that automatically go away after they are used.
* {{{{{class{[label=key|tooltip][altlabel|alttooltip]}}}}}}<br>uses label/tooltip/accesskey. {{{{{class{...}}}}}}, {{{=key}}}, {{{|tooltip}}} and {{{[altlabel|alttooltip]}} are optional. 'class' is any valid CSS class name, used to style the slider label text. 'key' must be a ''single letter only''. altlabel/alttooltip specifiy alternative label/tooltip for use when slider/floating panel is displayed.
* {{{#panelID:}}}<br>defines a unique DOM element ID that is assigned to the panel element used to display the slider content. This ID can then be used later to reposition the panel using the {{{<<DOM move id>>}}} macro (see [[DOMTweaksPlugin]]), or to access/modify the panel element through use of {{{document.getElementById(...)}}}) javascript code in a plugin or inline script.
* {{{">"}}} //(without the quotes)//<br>automatically adds blockquote formatting to slider content
* {{{"..."}}} //(without the quotes)//<br>defers rendering of closed sliders until the first time they are opened. //Note: deferred rendering may produce unexpected results in some cases. Use with care.//
//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.//
<<<
!!!!!Examples
<<<
simple in-line slider:
{{{
+++
content
===
}}}
+++
content
===
----
use a custom label and tooltip:
{{{
+++[label|tooltip]
content
===
}}}
+++[label|tooltip]
content
===
----
content automatically blockquoted:
{{{
+++>
content
===
}}}
+++>
content
===
----
all options combined //(default open, cookie, heading, sized floater, transient, class, label/tooltip/key, blockquoted, deferred)//
{{{
++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...
content
===
}}}
++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...
content
===
----
complex nesting example:
{{{
+++[get info...=I|click for information or press Alt-I]
put some general information here,
plus a floating panel with more specific info:
+++^10em^[view details...|click for details]
put some detail here, which could in turn contain a transient panel,
perhaps with a +++^25em^*[glossary definition]explaining technical terms===
===
===
}}}
+++[get info...=I|click for information or press Alt-I]
put some general information here,
plus a floating panel with more specific info:
+++^10em^[view details...|click for details]
put some detail here, which could in turn contain a transient panel,
perhaps with a +++^25em^*[glossary definition]explaining technical terms===
===
===
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''NestedSlidersPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2007.07.20 - 2.3.0'' added syntax for setting panel ID (#panelID:). This allows individual slider panels to be repositioned within tiddler content simply by giving them a unique ID and then moving them to the desired location using the {{{<<DOM move id>>}}} macro.
''2007.07.19 - 2.2.0'' added syntax for alttext and alttip (button label and tooltip to be displayed when panel is open)
''2007.07.14 - 2.1.2'' corrected use of 'transient' attribute in IE to prevent (non-recursive) infinite loop
''2007.07.12 - 2.1.0'' replaced use of "*" for 'open/close on rollover' (which didn't work too well). "*" now indicates 'transient' panels that are automatically closed if a click occurs somewhere else in the document. This permits use of nested sliders to create nested "pulldown menus" that automatically disappear after interaction with them has been completed. Also, in onClickNestedSlider(), use "theTarget.sliderCookie", instead of "this.sliderCookie" to correct cookie state tracking when automatically dismissing transient panels.
''2007.06.10 - 2.0.5'' add check to ensure that window.adjustSliderPanel() is defined before calling it (prevents error on shutdown when mouse event handlers are still defined)
''2007.05.31 - 2.0.4'' add handling to invoke adjustSliderPanel() for onmouseover events on slider button and panel. This allows the panel position to be re-synced when the button position shifts due to changes in unrelated content above it on the page. (thanks to Harsha for bug report)
''2007.03.30 - 2.0.3'' added chkFloatingSlidersAnimate (default to FALSE), so that slider animation can be disabled independent of the overall document animation setting (avoids strange rendering and focus problems in floating panels)
''2007.03.01 - 2.0.2'' for TW2.2+, hijack Morpher.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends
''2007.03.01 - 2.0.1'' in hijack for Slider.prototype.stop, use apply() to pass params to core function
|please see [[NestedSlidersPluginHistory]] for additional revision details|
''2005.11.03 - 1.0.0'' initial public release
<<<
!!!!!Credits
<<<
This feature was implemented by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]] with initial research and suggestions from RodneyGomes, GeoffSlocock, and PaulPetterson.
<<<
!!!!!Code
***/
//{{{
version.extensions.nestedSliders = {major: 2, minor: 3, revision: 0, date: new Date(2007,7,20)};
//}}}
//{{{
// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkDebugLazySliderDefer==undefined) config.options.chkDebugLazySliderDefer=false;
if (config.options.chkDebugLazySliderRender==undefined) config.options.chkDebugLazySliderRender=false;
if (config.options.chkFloatingSlidersAnimate==undefined) config.options.chkFloatingSlidersAnimate=false;
// default styles for 'floating' class
setStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \
background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");
//}}}
//{{{
config.formatters.push( {
name: "nestedSliders",
match: "\\n?\\+{3}",
terminator: "\\s*\\={3}\\n?",
lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\[\\>]*\\^)?)?(\\*)?(?:\\{\\{([\\w]+[\\s\\w]*)\\{)?(\\[[^\\]]*\\])?(\\[[^\\]]*\\])?(?:\\}{3})?(\\#[^:]*\\:)?(\\>)?(\\.\\.\\.)?\\s*",
handler: function(w)
{
lookaheadRegExp = new RegExp(this.lookahead,"mg");
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
{
// var defopen=lookaheadMatch[1]
// var cookiename=lookaheadMatch[2]
// var header=lookaheadMatch[3]
// var panelwidth=lookaheadMatch[4]
// var transient=lookaheadMatch[5]
// var class=lookaheadMatch[6]
// var label=lookaheadMatch[7]
// var openlabel=lookaheadMatch[8]
// var panelID=lookaheadMatch[9]
// var blockquote=lookaheadMatch[10]
// var deferred=lookaheadMatch[11]
// location for rendering button and panel
var place=w.output;
// default to closed, no cookie, no accesskey, no alternate text/tip
var show="none"; var cookie=""; var key="";
var closedtext=">"; var closedtip="";
var openedtext="<"; var openedtip="";
// extra "+", default to open
if (lookaheadMatch[1]) show="block";
// cookie, use saved open/closed state
if (lookaheadMatch[2]) {
cookie=lookaheadMatch[2].trim().slice(1,-1);
cookie="chkSlider"+cookie;
if (config.options[cookie]==undefined)
{ config.options[cookie] = (show=="block") }
show=config.options[cookie]?"block":"none";
}
// parse label/tooltip/accesskey: [label=X|tooltip]
if (lookaheadMatch[7]) {
var parts=lookaheadMatch[7].trim().slice(1,-1).split("|");
closedtext=parts.shift();
if (closedtext.substr(closedtext.length-2,1)=="=")
{ key=closedtext.substr(closedtext.length-1,1); closedtext=closedtext.slice(0,-2); }
openedtext=closedtext;
if (parts.length) closedtip=openedtip=parts.join("|");
else { closedtip="show "+closedtext; openedtip="hide "+closedtext; }
}
// parse alternate label/tooltip: [label|tooltip]
if (lookaheadMatch[8]) {
var parts=lookaheadMatch[8].trim().slice(1,-1).split("|");
openedtext=parts.shift();
if (parts.length) openedtip=parts.join("|");
else openedtip="hide "+openedtext;
}
var title=show=='block'?openedtext:closedtext;
var tooltip=show=='block'?openedtip:closedtip;
// create the button
if (lookaheadMatch[3]) { // use "Hn" header format instead of button/link
var lvl=(lookaheadMatch[3].length>6)?6:lookaheadMatch[3].length;
var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,lookaheadMatch[6],title);
btn.onclick=onClickNestedSlider;
btn.setAttribute("href","javascript:;");
btn.setAttribute("title",tooltip);
}
else
var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,lookaheadMatch[6]);
btn.innerHTML=title; // enables use of HTML entities in label
// set extra button attributes
btn.setAttribute("closedtext",closedtext);
btn.setAttribute("closedtip",closedtip);
btn.setAttribute("openedtext",openedtext);
btn.setAttribute("openedtip",openedtip);
btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
btn.defOpen=lookaheadMatch[1]!=null; // save default open/closed state (boolean)
btn.keyparam=key; // save the access key letter ("" if none)
if (key.length) {
btn.setAttribute("accessKey",key); // init access key
btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus
}
btn.onmouseover=function(event) // mouseover on button aligns floater position with button
{ if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this,this.sliderPanel,this.sliderPanel.className); }
// create slider panel
var panelClass=lookaheadMatch[4]?"floatingPanel":"sliderPanel";
var panelID=lookaheadMatch[9]; if (panelID) panelID=panelID.slice(1,-1); // trim off delimiters
var panel=createTiddlyElement(place,"div",panelID,panelClass,null);
panel.button = btn; // so the slider panel know which button it belongs to
btn.sliderPanel=panel; // so the button knows which slider panel it belongs to
panel.defaultPanelWidth=(lookaheadMatch[4] && lookaheadMatch[4].length>2)?lookaheadMatch[4].slice(1,-1):"";
panel.setAttribute("transient",lookaheadMatch[5]=="*"?"true":"false");
panel.style.display = show;
panel.style.width=panel.defaultPanelWidth;
panel.onmouseover=function(event) // mouseover on panel aligns floater position with button
{ if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this.button,this,this.className); }
// render slider (or defer until shown)
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
if ((show=="block")||!lookaheadMatch[11]) {
// render now if panel is supposed to be shown or NOT deferred rendering
w.subWikify(lookaheadMatch[10]?createTiddlyElement(panel,"blockquote"):panel,this.terminator);
// align floater position with button
if (window.adjustSliderPos) window.adjustSliderPos(place,btn,panel,panelClass);
}
else {
var src = w.source.substr(w.nextMatch);
var endpos=findMatchingDelimiter(src,"+++","===");
panel.setAttribute("raw",src.substr(0,endpos));
panel.setAttribute("blockquote",lookaheadMatch[10]?"true":"false");
panel.setAttribute("rendered","false");
w.nextMatch += endpos+3;
if (w.source.substr(w.nextMatch,1)=="\n") w.nextMatch++;
if (config.options.chkDebugLazySliderDefer) alert("deferred '"+title+"':\n\n"+panel.getAttribute("raw"));
}
}
}
}
)
// TBD: ignore 'quoted' delimiters (e.g., "{{{+++foo===}}}" isn't really a slider)
function findMatchingDelimiter(src,starttext,endtext) {
var startpos = 0;
var endpos = src.indexOf(endtext);
// check for nested delimiters
while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {
// count number of nested 'starts'
var startcount=0;
var temp = src.substring(startpos,endpos-1);
var pos=temp.indexOf(starttext);
while (pos!=-1) { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }
// set up to check for additional 'starts' after adjusting endpos
startpos=endpos+endtext.length;
// find endpos for corresponding number of matching 'ends'
while (startcount && endpos!=-1) {
endpos = src.indexOf(endtext,endpos+endtext.length);
startcount--;
}
}
return (endpos==-1)?src.length:endpos;
}
//}}}
//{{{
window.onClickNestedSlider=function(e)
{
if (!e) var e = window.event;
var theTarget = resolveTarget(e);
var theLabel = theTarget.firstChild.data;
var theSlider = theTarget.sliderPanel
var isOpen = theSlider.style.display!="none";
// toggle label
theTarget.innerHTML=isOpen?theTarget.getAttribute("closedText"):theTarget.getAttribute("openedText");
// toggle tooltip
theTarget.setAttribute("title",isOpen?theTarget.getAttribute("closedTip"):theTarget.getAttribute("openedTip"));
// deferred rendering (if needed)
if (theSlider.getAttribute("rendered")=="false") {
if (config.options.chkDebugLazySliderRender)
alert("rendering '"+theLabel+"':\n\n"+theSlider.getAttribute("raw"));
var place=theSlider;
if (theSlider.getAttribute("blockquote")=="true")
place=createTiddlyElement(place,"blockquote");
wikify(theSlider.getAttribute("raw"),place);
theSlider.setAttribute("rendered","true");
}
// show/hide the slider
if(config.options.chkAnimate && (theSlider.className!='floatingPanel' || config.options.chkFloatingSlidersAnimate))
anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
else
theSlider.style.display = isOpen ? "none" : "block";
// reset to default width (might have been changed via plugin code)
theSlider.style.width=theSlider.defaultPanelWidth;
// align floater panel position with target button
if (!isOpen && window.adjustSliderPos) window.adjustSliderPos(theSlider.parentNode,theTarget,theSlider,theSlider.className);
// if showing panel, set focus to first 'focus-able' element in panel
if (theSlider.style.display!="none") {
var ctrls=theSlider.getElementsByTagName("*");
for (var c=0; c<ctrls.length; c++) {
var t=ctrls[c].tagName.toLowerCase();
if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")
{ ctrls[c].focus(); break; }
}
}
var cookie=theTarget.sliderCookie;
if (cookie && cookie.length) {
config.options[cookie]=!isOpen;
if (config.options[cookie]!=theTarget.defOpen)
saveOptionCookie(cookie);
else { // remove cookie if slider is in default display state
var ex=new Date(); ex.setTime(ex.getTime()-1000);
document.cookie = cookie+"=novalue; path=/; expires="+ex.toGMTString();
}
}
return false;
}
//}}}
//{{{
// click in document background closes transient panels
document.nestedSliders_savedOnClick=document.onclick;
document.onclick=function(ev) { if (!ev) var ev=window.event; var target=resolveTarget(ev);
// call original click handler
if (document.nestedSliders_savedOnClick) document.nestedSliders_savedOnClick.apply(this,arguments);
// if click was inside transient panel (or something contained by a transient panel)... leave it alone
var p=target;
while (p)
if ((p.className=="floatingPanel"||p.className=="sliderPanel")&&p.getAttribute("transient")=="true") break;
else p=p.parentNode;
if (p) return true; // let click bubble up
// otherwise, find and close all transient panels...
var all=document.all?document.all:document.getElementsByTagName("DIV");
for (var i=0; i<all.length; i++) {
// if it is not a transient panel, or the click was on the button that opened this panel, don't close it.
if (all[i].getAttribute("transient")!="true" || all[i].button==target) continue;
// otherwise, if the panel is currently visible, close it by clicking it's button
if (all[i].style.display!="none") window.onClickNestedSlider({target:all[i].button})
}
return true; // let click bubble up
};
//}}}
//{{{
// adjust floating panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel,panelClass) {
if (panelClass=="floatingPanel") {
var left=0;
var top=btn.offsetHeight;
if (place.style.position!="relative") {
var left=findPosX(btn);
var top=findPosY(btn)+btn.offsetHeight;
var p=place; while (p && p.className!='floatingPanel') p=p.parentNode;
if (p) { left-=findPosX(p); top-=findPosY(p); }
}
if (findPosX(btn)+panel.offsetWidth > getWindowWidth()) // adjust position to stay inside right window edge
left-=findPosX(btn)+panel.offsetWidth-getWindowWidth()+15; // add extra 15px 'fudge factor'
panel.style.left=left+"px"; panel.style.top=top+"px";
}
}
function getWindowWidth() {
if(document.width!=undefined)
return document.width; // moz (FF)
if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
return document.documentElement.clientWidth; // IE6
if(document.body && ( document.body.clientWidth || document.body.clientHeight ) )
return document.body.clientWidth; // IE4
if(window.innerWidth!=undefined)
return window.innerWidth; // IE - general
return 0; // unknown
}
//}}}
//{{{
// TW2.1 and earlier:
// hijack Slider animation handler 'stop' handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function()
{ this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }
// TW2.2+
// hijack Morpher animation handler 'stop' handler so overflow is visible after animation has completed
if (version.major+.1*version.minor+.01*version.revision>=2.2) {
Morpher.prototype.coreStop = Morpher.prototype.stop;
Morpher.prototype.stop = function()
{ this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }
}
//}}}
/***
|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
|''Version:''|1.0.7 (2007-03-07)|
|''Source:''|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Table of Content<html><a name="TOC"/></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Description',null, event)">Description, Syntax</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Applications',null, event)">Applications</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('LongTiddler',null, event)">Refering to Paragraphs of a Longer Tiddler</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Citation',null, event)">Citation Index</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('TableCells',null, event)">Creating "multi-line" Table Cells</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Tabs',null, event)">Creating Tabs</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Sliders',null, event)">Using Sliders</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Revisions',null, event)">Revision History</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Code',null, event)">Code</a></html>
!Description<html><a name="Description"/></html>
With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate (named) parts.
Each part can be referenced as a "normal" tiddler, using the "//tiddlerName//''/''//partName//" syntax (e.g. "About/Features"). E.g. you may create links to the parts, use it in {{{<<tiddler...>>}}} or {{{<<tabs...>>}}} macros etc.
''Syntax:''
|>|''<part'' //partName// [''hidden''] ''>'' //any tiddler content// ''</part>''|
|//partName//|The name of the part. You may reference a part tiddler with the combined tiddler name "//nameOfContainerTidder//''/''//partName//.|
|''hidden''|When defined the content of the part is not displayed in the container tiddler. But when the part is explicitly referenced (e.g. in a {{{<<tiddler...>>}}} macro or in a link) the part's content is displayed.|
|<html><i>any tiddler content</i></html>|<html>The content of the part.<br>A part can have any content that a "normal" tiddler may have, e.g. you may use all the formattings and macros defined.</html>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Applications<html><a name="Applications"/></html>
!!Refering to Paragraphs of a Longer Tiddler<html><a name="LongTiddler"/></html>
Assume you have written a long description in a tiddler and now you want to refer to the content of a certain paragraph in that tiddler (e.g. some definition.) Just wrap the text with a ''part'' block, give it a nice name, create a "pretty link" (like {{{[[Discussion Groups|Introduction/DiscussionGroups]]}}}) and you are done.
Notice this complements the approach to first writing a lot of small tiddlers and combine these tiddlers to one larger tiddler in a second step (e.g. using the {{{<<tiddler...>>}}} macro). Using the ''part'' feature you can first write a "classic" (longer) text that can be read "from top to bottom" and later "reuse" parts of this text for some more "non-linear" reading.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Citation Index<html><a name="Citation"/></html>
Create a tiddler "Citations" that contains your "citations".
Wrap every citation with a part and a proper name.
''Example''
{{{
<part BAX98>Baxter, Ira D. et al: //Clone Detection Using Abstract Syntax Trees.//
in //Proc. ICSM//, 1998.</part>
<part BEL02>Bellon, Stefan: //Vergleich von Techniken zur Erkennung duplizierten Quellcodes.//
Thesis, Uni Stuttgart, 2002.</part>
<part DUC99>Ducasse, Stéfane et al: //A Language Independent Approach for Detecting Duplicated Code.//
in //Proc. ICSM//, 1999.</part>
}}}
You may now "cite" them just by using a pretty link like {{{[[Citations/BAX98]]}}} or even more pretty, like this {{{[[BAX98|Citations/BAX98]]}}}.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Creating "multi-line" Table Cells<html><a name="TableCells"/></html>
You may have noticed that it is hard to create table cells with "multi-line" content. E.g. if you want to create a bullet list inside a table cell you cannot just write the bullet list
{{{
* Item 1
* Item 2
* Item 3
}}}
into a table cell (i.e. between the | ... | bars) because every bullet item must start in a new line but all cells of a table row must be in one line.
Using the ''part'' feature this problem can be solved. Just create a hidden part that contains the cells content and use a {{{<<tiddler >>}}} macro to include its content in the table's cell.
''Example''
{{{
|!Subject|!Items|
|subject1|<<tiddler ./Cell1>>|
|subject2|<<tiddler ./Cell2>>|
<part Cell1 hidden>
* Item 1
* Item 2
* Item 3
</part>
...
}}}
Notice that inside the {{{<<tiddler ...>>}}} macro you may refer to the "current tiddler" using the ".".
BTW: The same approach can be used to create bullet lists with items that contain more than one line.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Creating Tabs<html><a name="Tabs"/></html>
The build-in {{{<<tabs ...>>}}} macro requires that you defined an additional tiddler for every tab it displays. When you want to have "nested" tabs you need to define a tiddler for the "main tab" and one for every tab it contains. I.e. the definition of a set of tabs that is visually displayed at one place is distributed across multiple tiddlers.
With the ''part'' feature you can put the complete definition in one tiddler, making it easier to keep an overview and maintain the tab sets.
''Example''
The standard tabs at the sidebar are defined by the following eight tiddlers:
* SideBarTabs
* TabAll
* TabMore
* TabMoreMissing
* TabMoreOrphans
* TabMoreShadowed
* TabTags
* TabTimeline
Instead of these eight tiddlers one could define the following SideBarTabs tiddler that uses the ''part'' feature:
{{{
<<tabs txtMainTab
Timeline Timeline SideBarTabs/Timeline
All 'All tiddlers' SideBarTabs/All
Tags 'All tags' SideBarTabs/Tags
More 'More lists' SideBarTabs/More>>
<part Timeline hidden><<timeline>></part>
<part All hidden><<list all>></part>
<part Tags hidden><<allTags>></part>
<part More hidden><<tabs txtMoreTab
Missing 'Missing tiddlers' SideBarTabs/Missing
Orphans 'Orphaned tiddlers' SideBarTabs/Orphans
Shadowed 'Shadowed tiddlers' SideBarTabs/Shadowed>></part>
<part Missing hidden><<list missing>></part>
<part Orphans hidden><<list orphans>></part>
<part Shadowed hidden><<list shadowed>></part>
}}}
Notice that you can easily "overwrite" individual parts in separate tiddlers that have the full name of the part.
E.g. if you don't like the classic timeline tab but only want to see the 100 most recent tiddlers you could create a tiddler "~SideBarTabs/Timeline" with the following content:
{{{
<<forEachTiddler
sortBy 'tiddler.modified' descending
write '(index < 100) ? "* [["+tiddler.title+"]]\n":""'>>
}}}
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Using Sliders<html><a name="Sliders"/></html>
Very similar to the build-in {{{<<tabs ...>>}}} macro (see above) the {{{<<slider ...>>}}} macro requires that you defined an additional tiddler that holds the content "to be slid". You can avoid creating this extra tiddler by using the ''part'' feature
''Example''
In a tiddler "About" we may use the slider to show some details that are documented in the tiddler's "Details" part.
{{{
...
<<slider chkAboutDetails About/Details details "Click here to see more details">>
<part Details hidden>
To give you a better overview ...
</part>
...
}}}
Notice that putting the content of the slider into the slider's tiddler also has an extra benefit: When you decide you need to edit the content of the slider you can just doubleclick the content, the tiddler opens for editing and you can directly start editing the content (in the part section). In the "old" approach you would doubleclick the tiddler, see that the slider is using tiddler X, have to look for the tiddler X and can finally open it for editing. So using the ''part'' approach results in a much short workflow.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Revision history<html><a name="Revisions"/></html>
* v1.0.7 (2007-03-07)
** Bugfix: <<tiddler "./partName">> does not always render correctly after a refresh (e.g. like it happens when using the "Include" plugin). Thanks to Morris Gray for reporting the bug.
* v1.0.6 (2006-11-07)
** Bugfix: cannot edit tiddler when UploadPlugin by Bidix is installed. Thanks to José Luis González Castro for reporting the bug.
* v1.0.5 (2006-03-02)
** Bugfix: Example with multi-line table cells does not work in IE6. Thanks to Paulo Soares for reporting the bug.
* v1.0.4 (2006-02-28)
** Bugfix: Shadow tiddlers cannot be edited (in TW 2.0.6). Thanks to Torsten Vanek for reporting the bug.
* v1.0.3 (2006-02-26)
** Adapt code to newly introduced Tiddler.prototype.isReadOnly() function (in TW 2.0.6). Thanks to Paulo Soares for reporting the problem.
* v1.0.2 (2006-02-05)
** Also allow other macros than the "tiddler" macro use the "." in the part reference (to refer to "this" tiddler)
* v1.0.1 (2006-01-27)
** Added Table of Content for plugin documentation. Thanks to RichCarrillo for suggesting.
** Bugfix: newReminder plugin does not work when PartTiddler is installed. Thanks to PauloSoares for reporting.
* v1.0.0 (2006-01-25)
** initial version
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Code<html><a name="Code"/></html>
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
//{{{
//============================================================================
// PartTiddlerPlugin
// Ensure that the PartTiddler Plugin is only installed once.
//
if (!version.extensions.PartTiddlerPlugin) {
version.extensions.PartTiddlerPlugin = {
major: 1, minor: 0, revision: 7,
date: new Date(2007, 2, 7),
type: 'plugin',
source: "http://tiddlywiki.abego-software.de/#PartTiddlerPlugin"
};
if (!window.abego) window.abego = {};
if (version.major < 2) alertAndThrow("PartTiddlerPlugin requires TiddlyWiki 2.0 or newer.");
//============================================================================
// Common Helpers
// Looks for the next newline, starting at the index-th char of text.
//
// If there are only whitespaces between index and the newline
// the index behind the newline is returned,
// otherwise (or when no newline is found) index is returned.
//
var skipEmptyEndOfLine = function(text, index) {
var re = /(\n|[^\s])/g;
re.lastIndex = index;
var result = re.exec(text);
return (result && text.charAt(result.index) == '\n')
? result.index+1
: index;
}
//============================================================================
// Constants
var partEndOrStartTagRE = /(<\/part>)|(<part(?:\s+)((?:[^>])+)>)/mg;
var partEndTagREString = "<\\/part>";
var partEndTagString = "</part>";
//============================================================================
// Plugin Specific Helpers
// Parse the parameters inside a <part ...> tag and return the result.
//
// @return [may be null] {partName: ..., isHidden: ...}
//
var parseStartTagParams = function(paramText) {
var params = paramText.readMacroParams();
if (params.length == 0 || params[0].length == 0) return null;
var name = params[0];
var paramsIndex = 1;
var hidden = false;
if (paramsIndex < params.length) {
hidden = params[paramsIndex] == "hidden";
paramsIndex++;
}
return {
partName: name,
isHidden: hidden
};
}
// Returns the match to the next (end or start) part tag in the text,
// starting the search at startIndex.
//
// When no such tag is found null is returned, otherwise a "Match" is returned:
// [0]: full match
// [1]: matched "end" tag (or null when no end tag match)
// [2]: matched "start" tag (or null when no start tag match)
// [3]: content of start tag (or null if no start tag match)
//
var findNextPartEndOrStartTagMatch = function(text, startIndex) {
var re = new RegExp(partEndOrStartTagRE);
re.lastIndex = startIndex;
var match = re.exec(text);
return match;
}
//============================================================================
// Formatter
// Process the <part ...> ... </part> starting at (w.source, w.matchStart) for formatting.
//
// @return true if a complete part section (including the end tag) could be processed, false otherwise.
//
var handlePartSection = function(w) {
var tagMatch = findNextPartEndOrStartTagMatch(w.source, w.matchStart);
if (!tagMatch) return false;
if (tagMatch.index != w.matchStart || !tagMatch[2]) return false;
// Parse the start tag parameters
var arguments = parseStartTagParams(tagMatch[3]);
if (!arguments) return false;
// Continue processing
var startTagEndIndex = skipEmptyEndOfLine(w.source, tagMatch.index + tagMatch[0].length);
var endMatch = findNextPartEndOrStartTagMatch(w.source, startTagEndIndex);
if (endMatch && endMatch[1]) {
if (!arguments.isHidden) {
w.nextMatch = startTagEndIndex;
w.subWikify(w.output,partEndTagREString);
}
w.nextMatch = skipEmptyEndOfLine(w.source, endMatch.index + endMatch[0].length);
return true;
}
return false;
}
config.formatters.push( {
name: "part",
match: "<part\\s+[^>]+>",
handler: function(w) {
if (!handlePartSection(w)) {
w.outputText(w.output,w.matchStart,w.matchStart+w.matchLength);
}
}
} )
//============================================================================
// Extend "fetchTiddler" functionality to also recognize "part"s of tiddlers
// as tiddlers.
var currentParent = null; // used for the "." parent (e.g. in the "tiddler" macro)
// Return the match to the first <part ...> tag of the text that has the
// requrest partName.
//
// @return [may be null]
//
var findPartStartTagByName = function(text, partName) {
var i = 0;
while (true) {
var tagMatch = findNextPartEndOrStartTagMatch(text, i);
if (!tagMatch) return null;
if (tagMatch[2]) {
// Is start tag
// Check the name
var arguments = parseStartTagParams(tagMatch[3]);
if (arguments && arguments.partName == partName) {
return tagMatch;
}
}
i += tagMatch[0].length;
}
}
// Return the part "partName" of the given parentTiddler as a "readOnly" Tiddler
// object, using fullName as the Tiddler's title.
//
// All remaining properties of the new Tiddler (tags etc.) are inherited from
// the parentTiddler.
//
// @return [may be null]
//
var getPart = function(parentTiddler, partName, fullName) {
var text = parentTiddler.text;
var startTag = findPartStartTagByName(text, partName);
if (!startTag) return null;
var endIndexOfStartTag = skipEmptyEndOfLine(text, startTag.index+startTag[0].length);
var indexOfEndTag = text.indexOf(partEndTagString, endIndexOfStartTag);
if (indexOfEndTag >= 0) {
var partTiddlerText = text.substring(endIndexOfStartTag,indexOfEndTag);
var partTiddler = new Tiddler();
partTiddler.set(
fullName,
partTiddlerText,
parentTiddler.modifier,
parentTiddler.modified,
parentTiddler.tags,
parentTiddler.created);
partTiddler.abegoIsPartTiddler = true;
return partTiddler;
}
return null;
}
// Hijack the store.fetchTiddler to recognize the "part" addresses.
//
var hijackFetchTiddler = function() {
var oldFetchTiddler = store.fetchTiddler ;
store.fetchTiddler = function(title) {
var result = oldFetchTiddler.apply(this, arguments);
if (!result && title) {
var i = title.lastIndexOf('/');
if (i > 0) {
var parentName = title.substring(0, i);
var partName = title.substring(i+1);
var parent = (parentName == ".")
? store.resolveTiddler(currentParent)
: oldFetchTiddler.apply(this, [parentName]);
if (parent) {
return getPart(parent, partName, parent.title+"/"+partName);
}
}
}
return result;
};
};
// for debugging the plugin is not loaded through the systemConfig mechanism but via a script tag.
// At that point in the "store" is not yet defined. In that case hijackFetchTiddler through the restart function.
// Otherwise hijack now.
if (!store) {
var oldRestartFunc = restart;
window.restart = function() {
hijackFetchTiddler();
oldRestartFunc.apply(this,arguments);
};
} else
hijackFetchTiddler();
// The user must not edit a readOnly/partTiddler
//
config.commands.editTiddler.oldIsReadOnlyFunction = Tiddler.prototype.isReadOnly;
Tiddler.prototype.isReadOnly = function() {
// Tiddler.isReadOnly was introduced with TW 2.0.6.
// For older version we explicitly check the global readOnly flag
if (config.commands.editTiddler.oldIsReadOnlyFunction) {
if (config.commands.editTiddler.oldIsReadOnlyFunction.apply(this, arguments)) return true;
} else {
if (readOnly) return true;
}
return this.abegoIsPartTiddler;
}
config.commands.editTiddler.handler = function(event,src,title)
{
var t = store.getTiddler(title);
// Edit the tiddler if it either is not a tiddler (but a shadowTiddler)
// or the tiddler is not readOnly
if(!t || !t.abegoIsPartTiddler)
{
clearMessage();
story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);
story.focusTiddler(title,"text");
return false;
}
}
// To allow the "./partName" syntax in macros we need to hijack
// the invokeMacro to define the "currentParent" while it is running.
//
var oldInvokeMacro = window.invokeMacro;
function myInvokeMacro(place,macro,params,wikifier,tiddler) {
var oldCurrentParent = currentParent;
if (tiddler) currentParent = tiddler;
try {
oldInvokeMacro.apply(this, arguments);
} finally {
currentParent = oldCurrentParent;
}
}
window.invokeMacro = myInvokeMacro;
// To correctly support the "./partName" syntax while refreshing we need to hijack
// the config.refreshers.tiddlers to define the "currentParent" while it is running.
//
(function() {
var oldTiddlerRefresher= config.refreshers.tiddler;
config.refreshers.tiddler = function(e,changeList) {
var oldCurrentParent = currentParent;
try {
currentParent = e.getAttribute("tiddler");
return oldTiddlerRefresher.apply(this,arguments);
} finally {
currentParent = oldCurrentParent;
}
};
})();
// Scroll the anchor anchorName in the viewer of the given tiddler visible.
// When no tiddler is defined use the tiddler of the target given event is used.
window.scrollAnchorVisible = function(anchorName, tiddler, evt) {
var tiddlerElem = null;
if (tiddler) {
tiddlerElem = document.getElementById(story.idPrefix + tiddler);
}
if (!tiddlerElem && evt) {
var target = resolveTarget(evt);
tiddlerElem = story.findContainingTiddler(target);
}
if (!tiddlerElem) return;
var children = tiddlerElem.getElementsByTagName("a");
for (var i = 0; i < children.length; i++) {
var child = children[i];
var name = child.getAttribute("name");
if (name == anchorName) {
var y = findPosY(child);
window.scrollTo(0,y);
return;
}
}
}
} // of "install only once"
//}}}
/***
<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2006 ([[www.abego-software.de|http://www.abego-software.de]])
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date("Apr 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
coreVersion: '2.2.0 (Beta 5)'
};
config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");
merge(config.macros.option.types, {
'pas': {
elementType: "input",
valueField: "value",
eventName: "onkeyup",
className: "pasOptionInput",
typeValue: config.macros.option.passwordInputType,
create: function(place,type,opt,className,desc) {
// password field
config.macros.option.genericCreate(place,'pas',opt,className,desc);
// checkbox linked with this password "save this password on this computer"
config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);
// text savePasswordCheckboxLabel
place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
},
onChange: config.macros.option.genericOnChange
}
});
merge(config.optionHandlers['chk'], {
get: function(name) {
// is there an option linked with this chk ?
var opt = name.substr(3);
if (config.options[opt])
saveOptionCookie(opt);
return config.options[name] ? "true" : "false";
}
});
merge(config.optionHandlers, {
'pas': {
get: function(name) {
if (config.options["chk"+name]) {
return encodeCookie(config.options[name].toString());
} else {
return "";
}
},
set: function(name,value) {config.options[name] = decodeCookie(value);}
}
});
// need to reload options to load passwordOptions
loadOptionsCookie();
/*
if (!config.options['pasPassword'])
config.options['pasPassword'] = '';
merge(config.optionsDesc,{
pasPassword: "Test password"
});
*/
//}}}
/***
|''Name:''|QuoteOfTheDayPlugin|
|''Source:''|http://www.TiddlyTools.com/#QuoteOfTheDayPlugin|
|''Author:''|Eric Shulman - ELS Design Studios|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.0.10|
Display a randomly selected "quote of the day"
!!!!!Usage
<<<
{{{<<QOTD //tiddlername//>>}}}
Put your quotations into a tiddler (called //tiddlername//). Separate each quote by a horizontal rule (use "----" on a line by itself). Each time the macro is rendered it will display a different quotation, selected at random from the specified tiddler.
<<<
!!!!!Example
<<<
{{{<<QOTD Quotations>>}}}
<<QOTD Quotations>>
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''QuoteOfTheDayPlugin'' (tagged with <<tag systemConfig>>)
^^documentation and javascript for QuoteOfTheDay handling^^
<<<
!!!!!Revision History
<<<
''2005.10.21 [1.0.0]''
Initial Release
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].
Based on a suggestion by M.Russula
<<<
!!!!!Code
***/
//{{{
version.extensions.QOTD = {major: 1, minor: 0, revision: 0, date: new Date(2005,10,21)};
config.macros.QOTD = {};
config.macros.QOTD.handler= function(place,macroName,params) {
var txt=store.getTiddlerText(params[0]); if (!txt) return;
var quotes=txt.split("\n----\n");
// then, get a random index number between 0 and N-1 and wikify that text
wikify(quotes[Math.floor(Math.random()*quotes.length)],place);
}
//}}}
|Santi Etxebarria (Zaldibar)|[img[http://farm1.static.flickr.com/37/76849040_d666ec57ba_m.jpg]]|[img[http://farm4.static.flickr.com/3302/3272948500_4c020e4ce5_m.jpg]]|
!Ilargiko bazkide eta jarraitzaile maiteok:
{{twocolumns justify {
{{firstletter{
@@color:#3300CC;G@@
}}}
ure 25. urteurrena ospatzen dogula eta, hona hemen gaur eguneko tresna digitala erabiliz, TiddlyWiki hain zuzen, gure historiaren mugarririk garrantzitsuenak.
[>img[25. urteurrena|http://farm5.static.flickr.com/4133/5211733662_2b81b88753_o.jpg ]]Dudarik ez dago hemen biltzen doguna, gure eginkizunaren zatirik txikiena baino ez dana.
Batek daki zenbat zigarro erreko zituen Rafak antzineko argazkiak eskaneatzen, edo ta zenbat ordu beteko zituen Jose Luisek informazio bilatzen edo Udalari diru eske.
Urterik urte begiratuta inork pentsa lezake, ez genduala ezer egiten, baina bilketa honetan nabarmentzen da gure zaletasuna indarrean dagoela.
[<img[25. urteurrena|http://farm1.static.flickr.com/28/95800989_f0cd8ddf89_m.jpg ]]Wiki honetan irudi ezagunak sartzen ditugu. Batzuk gure memorian bizi ziren gero eta galduagoak.
Baina "etiketen" bitartez irudiak topatzeko bidea erreztu egiten da erabat.
Ezkerreko zutabean aurki ditzakezu //tags// guztiak. Adibidez "2010" urtean zer egin dogun eta zeintzuk izan diren irudien irabazleak, klikatu behar dozun 2010 etiketaren gainean erabakitzeko ze //tiddler// nahi dozun zabaldu.
[>img[http://farm5.static.flickr.com/4132/5210898535_2fb83b9def_t.jpg]]
Gure historian hutsuneak dauden bezalaze, akatz eta bete gabeko promesak eskeintzen ditugu. Ehun argazki zahar esaten dogu eta 4 baino ez dira agertzen... etorriko dira.
}}}
<<search>><<fontSize "letra">><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY">><<saveChanges>><<tiddler TspotSidebar>><<slider chkSliderOptionsPanel OptionsPanel "opciones »" "Cambiar las opciones avanzadas de TiddlyWiki">>
Colectivo fotográfico de Zaldibar.
[img[25.urteurrena.jpg]] Ilargi. Zaldibarko argazki taldea.
/***
|''Name:''|SpanishTranslationPlugin|
|''Description:''|Translation of TiddlyWiki into Spanish|
|''Author:''|Dave Gifford giff (at) giffmex (dot) org|
|''Source:''|www.giffmex.org/twtutorialespanol.html |
|''CodeRepository:''||
|''Version:''||
|''Date:''|August 29, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]] |
|''~CoreVersion:''|2.2.5|
***/
//{{{
//--
//-- Translateable strings
//--
// Strings in "double quotes" should be translated; strings in 'single quotes' should be left alone
config.locale = "en"; // W3C language tag
if (config.options.txtUserName == 'YourName') // do not translate this line, but do translate the next line
merge(config.options,{txtUserName: "SuNombre"});
merge(config.tasks,{
save: {text: "guardar", tooltip: "Guardar sus cambios a este TiddlyWiki", action: saveChanges},
sync: {text: "sincronizar", tooltip: "Sincronizar cambios con otros archivos TiddlyWiki y servidores", content: '<<sync>>'},
importTask: {text: "importar", tooltip: "Importar tiddlers y plugins de otros archivos TiddlyWiki y servidores", content: '<<importTiddlers>>'},
tweak: {text: "modificar", tooltip: "Modificar la apariencia y comportamiento de TiddlyWiki", content: '<<options>>'},
plugins: {text: "plugins", tooltip: "Manejar plugins instalados", content: '<<plugins>>'}
});
// Options that can be set in the options panel and/or cookies
merge(config.optionsDesc,{
txtUserName: "Nombre usuario para firmar sus cambios",
chkRegExpSearch: "Habilitar expresiones normales para búsquedas",
chkCaseSensitiveSearch: "Búsquedas sensibles a mayúsculas",
chkAnimate: "Habilitar animaciones",
chkSaveBackups: "Guardar archivo de respaldo al guardar cambios",
chkAutoSave: "Guardar cambios automáticamente",
chkGenerateAnRssFeed: "Generar un archivo RSS al guardar cambios",
chkSaveEmptyTemplate: "Generar una plantilla vacía al guardar cambios",
chkOpenInNewWindow: "Abrir enlaces externos en una nueva ventana",
chkToggleLinks: "Un tiddler abierto se cierra cuando el usuario hace clic en un enlace al tiddler",
chkHttpReadOnly: "Ocultar elementos de edición cuando visto por medio de HTTP",
chkForceMinorUpdate: "No actualizar modificador, nombre usuario o fecha cuando un tiddler es editado",
chkConfirmDelete: "Requerir confirmación antes de borrar tiddlers",
chkInsertTabs: "Usar la tecla de tabulación para insertar carácteres de tabulación en vez de alternar entre campos",
txtBackupFolder: "Nombre de la carpeta que debe usarse para respaldos",
txtMaxEditRows: "Máximo número de renglones en cajas de edición",
txtFileSystemCharSet: "Juego de carácteres por defecto para guardar cambios (Firefox/Mozilla solamente)"});
merge(config.messages,{
customConfigError: "Hubo problemas en la instalación de plugins. Véase PluginManager para los detalles",
pluginError: "Error: %0",
pluginDisabled: "No ejecutado por ser deshabilitado via la etiqueta 'systemConfigDisable'",
pluginForced: "Ejecutado por ser forzado via la etiqueta 'systemConfigForce'",
pluginVersionError: "No ejecutado porque este plugin requiere una versión más reciente TiddlyWiki",
nothingSelected: "Nada ha sido seleccionado. Debe seleccionar uno o más elementos primero",
savedSnapshotError: "Parece que este TiddlyWiki no ha sido guardado correctamente. Favor de consultar http://www.tiddlywiki.com/#DownloadSoftware para más información",
subtitleUnknown: "(desconocido)",
undefinedTiddlerToolTip: "El tiddler '%0' no existe todavía",
shadowedTiddlerToolTip: "El tiddler '%0' no existe todavía, pero tiene un valor oculto predefinido",
tiddlerLinkTooltip: "%0 - %1, %2",
externalLinkTooltip: "Enlace externo a %0",
noTags: "No hay tiddlers con etiquetas",
notFileUrlError: "Se necesita guardar este TiddlyWiki a un archivo antes de poder guardar cambios",
cantSaveError: "No es posible guardar cambios. Posibles causas incluyen:\n- su navegador web no permite que guarde los cambios (Firefox, Internet Explorer, Safari y Opera funcionan si son configurados correctamente)\n- la dirección a su TiddlyWiki contiene carácteres ilegales \n- el archivo TiddlyWiki HTML file ha sido removido o renombrado",
invalidFileError: "El archivo original '%0' no parece ser un TiddlyWiki válido",
backupSaved: "Respaldo guardado",
backupFailed: "Respaldo no pudo ser guardado",
rssSaved: "Archivo RSS guardado",
rssFailed: "Archivo RSS no pudo ser guardado",
emptySaved: "Plantilla vacía guardada",
emptyFailed: "Plantilla vacía no pudo ser guardada",
mainSaved: "Archivo TiddlyWiki guardado",
mainFailed: "El archivo TiddlyWiki o pudo ser guardado. Sus cambios no han sido guardados",
macroError: "Error en macro <<\%0>>",
macroErrorDetails: "Error al ejecutar macro <<\%0>>:\n%1",
missingMacro: "Tal macro no existe",
overwriteWarning: "Un tiddler llamado '%0' ya existe. Presione OK para reemplazarlo",
unsavedChangesWarning: "CUIDADO! Hay cambios no guardados en TiddlyWiki\n\nPresione OK para guardar\nPresione CANCELAR para cancelar cambios",
confirmExit: "--------------------------------\n\nHay cambios no guardados en TiddlyWiki. Si continue, perderá los cambios\n\n--------------------------------",
saveInstructions: "GuardarRespaldos",
unsupportedTWFormat: "Formato '%0' no apoyado por TiddlyWiki",
tiddlerSaveError: "Error en guardar tiddler '%0'",
tiddlerLoadError: "Error en cargar tiddler '%0'",
wrongSaveFormat: "No se puede guardar con formato de almacenaje '%0'. Cambiando a un formato válido para guardar.",
invalidFieldName: "Nombre de campo '%0' inválido",
fieldCannotBeChanged: "El campo '%0' no puede ser cambiado",
loadingMissingTiddler: "Intentando acceder el tiddler '%0' del servidor '%1' en:\n\n'%2' en el área de trabajo '%3'"});
merge(config.messages.messageClose,{
text: "cerrar",
tooltip: "cerrar este área de mensaje"});
config.messages.backstage = {
open: {text: "bastidores", tooltip: "Abrir el área entre bastidores para ejecutar tareas especiales de composición y edición"},
close: {text: "cerrar", tooltip: "Cerrar el área entre bastidores"},
prompt: "bastidores: ",
decal: {
edit: {text: "editar", tooltip: "Editar el tiddler '%0'"}
}
};
config.messages.listView = {
tiddlerTooltip: "Hacer clic para ver el texto completo de este tiddler",
previewUnavailable: "(preeestreno no disponible)"
};
config.messages.dates.months = ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre","diciembre"];
config.messages.dates.days = ["domingo", "lunes", "martes", "miercoles", "jueves", "viernes", "sábado"];
config.messages.dates.shortMonths = ["ene", "feb", "mar", "abr", "mayo", "jun", "jul", "ag", "sep", "oct", "nov", "dic"];
config.messages.dates.shortDays = ["dom", "lun", "mar", "mier", "jue", "vie", "sáb"];
// suffixes for dates, eg "1st","2nd","3rd"..."30th","31st"
config.messages.dates.daySuffixes = ["","","","","","","","","","",
"","","","","","","","","","",
"","","","","","","","","","",
""];
config.messages.dates.am = "am";
config.messages.dates.pm = "pm";
merge(config.messages.tiddlerPopup,{
});
merge(config.views.wikified.tag,{
labelNoTags: "no hay etiquetas",
labelTags: "etiquetas: ",
openTag: "Abrir etiqueta '%0'",
tooltip: "Mostrar tiddlers con etiqueta '%0'",
openAllText: "Abrir todos",
openAllTooltip: "Abrir todos estos tiddlers",
popupNone: "No hay otros tiddlers con la etiqueta '%0'"});
merge(config.views.wikified,{
defaultText: "El tiddler '%0' aún no existe. Hacer doble-clic para crearlo",
defaultModifier: "(no encontrado)",
shadowModifier: "(tiddler integral oculto)",
dateFormat: "DD MMM YYYY", // use this to change the date format for your locale, eg "YYYY MMM DD", do not translate the Y, M or D
createdPrompt: "creado"});
merge(config.views.editor,{
tagPrompt: "Escribir etiquetas separados por espacios, [[usar doble corchetes]] si es necesario, or seleccionar existentes",
defaultText: "Escribir el texto para '%0'"});
merge(config.views.editor.tagChooser,{
text: "etiquetas",
tooltip: "Seleccionar etiquetas existentes para añadir a este tiddler",
popupNone: "No hay etiquetas definidas",
tagTooltip: "Añadir la etiqueta '%0'"});
merge(config.messages,{
sizeTemplates:
[
{unit: 1024*1024*1024, template: "%0\u00a0GB"},
{unit: 1024*1024, template: "%0\u00a0MB"},
{unit: 1024, template: "%0\u00a0KB"},
{unit: 1, template: "%0\u00a0B"}
]});
merge(config.macros.search,{
label: "búsqueda",
prompt: "Buscar en este TiddlyWiki",
accessKey: "F",
successMsg: "%0 tiddlers encontrados con %1",
failureMsg: "Ningunos tiddlers encontrados con %0"});
merge(config.macros.tagging,{
label: "etiquetas: ",
labelNotTag: "no etiquetas",
tooltip: "Lista de tiddlers con la etiqueta '%0'"});
merge(config.macros.timeline,{
dateFormat: "DD MMM YYYY"});// use this to change the date format for your locale, eg "YYYY MMM DD", do not translate the Y, M or D
merge(config.macros.allTags,{
tooltip: "Mostrar tiddlers con la etiqueta '%0'",
noTags: "No hay tiddlers con etiquetas"});
config.macros.list.all.prompt = "Todos los tiddlers en orden alfabético";
config.macros.list.missing.prompt = "Tiddlers enlazados por otros tiddlers pero que no son definidos";
config.macros.list.orphans.prompt = "Tiddlers que no han sido enlazados por nigin otro tiddler";
config.macros.list.shadowed.prompt = "Tiddlers ocultos con contenido por defecto";
config.macros.list.touched.prompt = "Tiddlers que han sido modificados localmente";
merge(config.macros.closeAll,{
label: "cerrar todos",
prompt: "Cerrar todos los tiddlers abiertos (excepto los que están en modo de edición)"});
merge(config.macros.permaview,{
label: "permavista",
prompt: "Enlace al URL de este archivo con todos los tiddlers actualmente abiertos"});
merge(config.macros.saveChanges,{
label: "guardar cambios",
prompt: "Guardar todos los cambios a este TiddlyWiki",
accessKey: "S"});
merge(config.macros.newTiddler,{
label: "nuevo tiddler",
prompt: "Crear un nuevo tiddler",
title: "Nuevo Tiddler",
accessKey: "N"});
merge(config.macros.newJournal,{
label: "nuevo diario",
prompt: "Crear un nuevo tiddler con el día y la hora como el título",
accessKey: "J"});
merge(config.macros.options,{
wizardTitle: "Modificar las opciones avanzadas",
step1Title: "Estas opciones son guardadas como cookies en su navegador web",
step1Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='false' name='chkUnknown'>Mostrar opciones desconocidas</input>",
unknownDescription: "//(desconocido)//",
listViewTemplate: {
columns: [
{name: 'Option', field: 'option', title: "Opción", type: 'String'},
{name: 'Description', field: 'description', title: "Descripción", type: 'WikiText'},
{name: 'Name', field: 'name', title: "Nombre", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
});
merge(config.macros.plugins,{
wizardTitle: "Manejar plugins",
step1Title: "Plugins actualmente instalados",
step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
skippedText: "(Este plugin no ha sido ejecutado porque fue añadido desde el último inicio del archivo)",
noPluginText: "No hay plugins instalados",
confirmDeleteText: "¿Está seguro que quiere eliminar estos plugins?:\n\n%0",
removeLabel: "remover ña etiqueta systemConfig",
removePrompt: "Remover la etiqueta systemConfig",
deleteLabel: "borrar",
deletePrompt: "Eliminar estos tiddlers para siempre",
listViewTemplate: {
columns: [
{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Tamaño", type: 'Size'},
{name: 'Forced', field: 'forced', title: "Forzado", tag: 'systemConfigForce', type: 'TagCheckbox'},
{name: 'Disabled', field: 'disabled', title: "Deshabilitado", tag: 'systemConfigDisable', type: 'TagCheckbox'},
{name: 'Executed', field: 'executed', title: "Cargado", type: 'Boolean', trueText: "Sí", falseText: "No"},
{name: 'Startup Time', field: 'startupTime', title: "Tiempo de inicio", type: 'String'},
{name: 'Error', field: 'error', title: "Estado", type: 'Boolean', trueText: "Error", falseText: "OK"},
{name: 'Log', field: 'log', title: "Log", type: 'StringList'}
],
rowClasses: [
{className: 'error', field: 'error'},
{className: 'warning', field: 'warning'}
]}
});
merge(config.macros.toolbar,{
moreLabel: "más",
morePrompt: "Mostar más órdenes"
});
merge(config.macros.refreshDisplay,{
label: "refrescar",
prompt: "Re-dibujar toda la visualización de TiddlyWiki"
});
merge(config.macros.importTiddlers,{
readOnlyWarning: "No se puede importar a un archivo TiddlyWiki de lectura. Intente abrirlo desde un archivo:// URL",
wizardTitle: "Importar tiddlers de otro archivo o servidor",
step1Title: "Primer paso: Localizar el servidor o archivo TiddlyWiki",
step1Html: "Especificar el tipo de servidor: <select name='selTypes'><option value=''>Escoger...</option></select><br>Ingresar el URL or dirección al archivo aquí: <input type='text' size=50 name='txtPath'><br>...o navegar para buscar un archivo: <input type='file' size=50 name='txtBrowse'><br><hr>...o seleccionar un FEED predefinido: <select name='selFeeds'><option value=''>Escoger...</option></select>",
openLabel: "abrir",
openPrompt: "Abrir la conexión a este archivo o servidor",
openError: "Hubo problemas en acceder el archivo Tiddlywiki",
statusOpenHost: "Abriendo el servidor",
statusGetWorkspaceList: "Adquiriendo la lista de áreas de trabajo disponibles",
step2Title: "Segundo paso: Escoger el área de trabajo",
step2Html: "Ingresar un nombre de un área de trabajo: <input type='text' size=50 name='txtWorkspace'><br>...o seleccionar un área de trabajo: <select name='selWorkspace'><option value=''>Escoger...</option></select>",
cancelLabel: "cancelar",
cancelPrompt: "Cancelar esta importación",
statusOpenWorkspace: "Abriendo el área de trabajo",
statusGetTiddlerList: "Adquiriendo la lista de tiddlers disponibles",
step3Title: "Tercer paso: Escoger los tiddlers para importar",
step3Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='true' name='chkSync'>Mantener estos tiddlers enlazados a este server para poder sincronizar cambios posteriores</input><br><input type='checkbox' name='chkSave'>Guardar los detalles de este servidor en un tiddler 'systemServer' tiddler llamado:</input> <input type='text' size=25 name='txtSaveTiddler'>",
importLabel: "importar",
importPrompt: "Importar estos tiddlers",
confirmOverwriteText: "¿Está seguro que quiere reemplazar estos tiddlers?:\n\n%0",
step4Title: "Cuarto paso: Importando %0 tiddler(s)",
step4Html: "<input type='hidden' name='markReport'></input>", // DO NOT TRANSLATE
doneLabel: "OK",
donePrompt: "Cerrar este wizard",
statusDoingImport: "Importando tiddlers",
statusDoneImport: "Todos los tiddlers importados",
systemServerNamePattern: "%2 en %1",
systemServerNamePatternNoWorkspace: "%1",
confirmOverwriteSaveTiddler: "El tiddler '%0' ya existe. Haga clic en 'OK' para reemplazarlo con los detalles de este servidor, o haga clic en 'Cancelar' para cancelar los cambios",
serverSaveTemplate: "|''Tipo:''|%0|\n|''URL:''|%1|\n|''Área de trabajo:''|%2|\n\nEste tiddler fue creado automáticamente para guardar un record de los detallles de este servidor",
serverSaveModifier: "(Sistema)",
listViewTemplate: {
columns: [
{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Tamaño", type: 'Size'},
{name: 'Tags', field: 'tags', title: "Etiquetas", type: 'Tags'}
],
rowClasses: [
]}
});
merge(config.macros.sync,{
listViewTemplate: {
columns: [
{name: 'Selected', field: 'selected', rowName: 'title', type: 'Selector'},
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
{name: 'Server Type', field: 'serverType', title: "Tipo de servidor", type: 'String'},
{name: 'Server Host', field: 'serverHost', title: "Servidor", type: 'String'},
{name: 'Server Workspace', field: 'serverWorkspace', title: "Área de trabajo del servidor", type: 'String'},
{name: 'Status', field: 'status', title: "Estado de sincronización", type: 'String'},
{name: 'Server URL', field: 'serverUrl', title: "Servidor URL", text: "View", type: 'Link'}
],
rowClasses: [
],
buttons: [
{caption: "Sincronizar estos tiddlers", name: 'sync'}
]},
wizardTitle: "Sincronizar con servidores y archivos externos",
step1Title: "Escoger los tiddlers para sincronizar",
step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
syncLabel: "sincronizar",
syncPrompt: "Sincronizar estos tiddlers",
hasChanged: "Cambiado mientras desconectado",
hasNotChanged: "No cambiado mientras desconectado",
syncStatusList: {
none: {text: "...", color: "ninguno"},
changedServer: {text: "Cambiado en el servidor", color: '#80ff80'},
changedLocally: {text: "Cambiado mientras desconectado", color: '#80ff80'},
changedBoth: {text: "Cambiado mientras desconectado y en el servidor", color: '#ff8080'},
notFound: {text: "No encontrado en el servidor", color: '#ffff80'},
putToServer: {text: "Se guardó una actualización en el servidor", color: '#ff80ff'},
gotFromServer: {text: "Adquirió una actualización del servidor", color: '#80ffff'}
}
});
merge(config.commands.closeTiddler,{
text: "cerrar",
tooltip: "Cerrar este tiddler"});
merge(config.commands.closeOthers,{
text: "cerrar los demás",
tooltip: "Cerrar todos los demás tiddlers"});
merge(config.commands.editTiddler,{
text: "editar",
tooltip: "Editar este tiddler",
readOnlyText: "ver",
readOnlyTooltip: "Ver la fuente de este tiddler"});
merge(config.commands.saveTiddler,{
text: "OK",
tooltip: "Guardar los cambios a este tiddler"});
merge(config.commands.cancelTiddler,{
text: "cancelar",
tooltip: "Cancelar los cambios a este tiddler",
warning: "¿Seguro que quiere abandonar sus cambios a '%0'?",
readOnlyText: "OK",
readOnlyTooltip: "Ver este tiddler normalmente"});
merge(config.commands.deleteTiddler,{
text: "borrar",
tooltip: "Borrar este tiddler",
warning: "¿Seguro que quiere borrar '%0'?"});
merge(config.commands.permalink,{
text: "permaenlace",
tooltip: "Permaenlace para este tiddler"});
merge(config.commands.references,{
text: "referencias",
tooltip: "Mostar tiddlers que hacen referencia a este tiddler",
popupNone: "No hay referencias"});
merge(config.commands.jump,{
text: "saltar",
tooltip: "Saltar a otro tiddler abierto"});
merge(config.commands.syncing,{
text: "sincronización",
tooltip: "Controlar la sincronización de este tiddler con un servidor o archivo externo",
currentlySyncing: "<div>En proceso de sincronizar via <span class='popupHighlight'>'%0'</span> a:</"+"div><div>servidor: <span class='popupHighlight'>%1</span></"+"div><div>área de trabajo: <span class='popupHighlight'>%2</span></"+"div>", // Note escaping of closing <div> tag
notCurrentlySyncing: "No hay sincronización en proceso",
captionUnSync: "Dejar de sincronizar este tiddler",
chooseServer: "Sincronizar este tiddler con otro servidor:",
currServerMarker: "\u25cf ",
notCurrServerMarker: " "});
merge(config.commands.fields,{
text: "campos",
tooltip: "Mostrar los campos extendidos de este tiddler",
emptyText: "No hay campos extendidos para este tiddler",
listViewTemplate: {
columns: [
{name: 'Field', field: 'field', title: "Campo", type: 'String'},
{name: 'Value', field: 'value', title: "Valor", type: 'String'}
],
rowClasses: [
],
buttons: [
]}});
merge(config.shadowTiddlers,{
DefaultTiddlers: "[[IniciarConTiddlyWiki]]",
MainMenu: "[[IniciarConTiddlyWiki]]\n\n\n^^~TiddlyWiki versión <<version>>\n© 2007 [[UnaMesa|http://www.unamesa.org/]]^^",
IniciarConTiddlyWiki: "Para empezar con este TiddlyWiki vacío, necesitará modificar los siguientes tiddlers:\n* SiteTitle & SiteSubtitle: El título y subtítulo del sitio, mostrados en el encabezado (después de guardar, también aparecerán en la barra del título de su navegador web)\n* MainMenu: El menú principal que funciona como tabla de contenido para el usuario (generalmente este menú se encuentra a la izquierda)\n* DefaultTiddlers: Contiene los nombres de los tiddlers que aparecerán cuando el archivo TiddlyWiki se abre\nAdemás, necesitará ingresar su nombre usuario para firmar sus cambios posteriores al archivo: <<option txtUserName>>",
SiteTitle: "Mi TiddlyWiki",
SiteSubtitle: "un cuaderno web personal, no lineal y reutilizable",
SiteUrl: "http://www.tiddlywiki.com/",
OptionsPanel: "Estas opciones para personalizar TiddlyWiki son guardados en su navegador\n\nSu nombre de usuario para firmar los cambios que realiza. Escríbalo como PalabraWiki (eg JuanDiego)\n<<option txtUserName>>\n\n<<option chkSaveBackups>> GuardarRespaldos\n<<option chkAutoSave>> AutoGuardar\n<<option chkRegExpSearch>> BuscaRegExp\n<<option chkCaseSensitiveSearch>> BúsquedaSensible\n<<option chkAnimate>> HabilitarAnimaciones\n\n----\Véase también [[OpcionesAvanzadas|AdvancedOptions]]",
SideBarOptions: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "opciones »" "Cambiar las opciones avanzadas de TiddlyWiki">>',
SideBarTabs: '<<tabs txtMainTab "Fecha" "tiddlers por fecha de creación" TabTimeline "Título" "Tiddlers por título" TabAll "Etiquetas" "Todas las etiquetas" TabTags "Más" "Más listas" TabMore>>',
TabMore: '<<tabs txtMoreTab "perdidos" "Tiddlers que no existen" TabMoreMissing "huérfanos" "Tiddlers que no han sido enlazados por ningun otro tiddler" TabMoreOrphans "ocultos" "Tiddlers ocultos" TabMoreShadowed>>'});
merge(config.annotations,{
AdvancedOptions: "Este tiddler oculto provee acceso a varias opciones avanzadas",
ColorPalette: "Los valores en este tiddler oculto determinan la esquema de colores de este ~TiddlyWiki",
DefaultTiddlers: "Los tiddlers alistados en este tiddler oculto se abren automáticamente cuando se abre este archivo ~TiddlyWiki",
EditTemplate: "La plantilla HTML en este tiddler oculto determina la apariencia de los tiddlers cuando están en modo de edición",
GettingStarted: "Este tiddler oculto provee instrucciones básicas acerca del uso de ~TiddlyWiki",
ImportTiddlers: "Este tiddler oculto permite la importación de tiddlers de otros archivos",
MainMenu: "Este tiddler oculto se usa como la tabla de contenido del menú principal en la columna a la izquiera de la pantalla",
MarkupPreHead: "Este tiddler es insertado en la parte superior de la sección <head> del HTML de ~TiddlyWiki",
MarkupPostHead: "Este tiddler es insertado en la parte inferior de la sección <head> del HTML de ~TiddlyWiki",
MarkupPreBody: "Este tiddler es insertado en la parte superior de la sección <body> del HTML de ~TiddlyWiki",
MarkupPostBody: "Este tiddler es insertado en la parte inferior de la sección <body> del HTML de ~TiddlyWiki immediatamente antes del 'script block'",
OptionsPanel: "Este tiddler oculto se usa como el contenido del panel de opciones en el menú a la derecha",
PageTemplate: "La plantilla HTML en este tiddler oculto determina la presentación general de este ~TiddlyWiki",
PluginManager: "Este tiddler oculto provee acceso al administrador de plugins",
SideBarOptions: "Este tiddler oculto se usa como el contenido de las opciones de la parte superior del menú a la derecha",
SideBarTabs: "Este tiddler oculto se usa como el contenido del panel de pestañas en el menú a la derecha",
SiteSubtitle: "Este tiddler oculto contiene el subtítulo del sitio o página",
SiteTitle: "Este tiddler oculto contiene el título del sitio o página",
SiteUrl: "Este tiddler debe ser configurado al URL completo cuando el archivo se publica",
StyleSheetColours: "Este tiddler oculto contiene definiciones de CSS relacionadas con los colores de los elementos de la página",
StyleSheet: "Este tiddler puede contener definiciones de CSS que el usuario asigna",
StyleSheetLayout: "Este tiddler oculto contiene definiciones de CSS relacionadas con la configuración visual de los elementos de la página",
StyleSheetLocale: "Este tiddler oculto contiene definiciones de CSS relacionadas con el local de la traducción",
StyleSheetPrint: "Este tiddler oculto contiene definiciones de CSS relacionadas con la impresión",
TabAll: "Este tiddler oculto contiene los contenidos de la pestaña 'Título' en el menú a la derecha",
TabMore: "Este tiddler oculto contiene los contenidos de la pestaña 'Más' en el menú a la derecha",
TabMoreMissing: "Este tiddler oculto contiene los contenidos de la pestaña 'perdidos' en el menú a la derecha",
TabMoreOrphans: "Este tiddler oculto contiene los contenidos de la pestaña 'huérfanos' en el menú a la derecha",
TabMoreShadowed: "Este tiddler oculto contiene los contenidos de la pestaña 'ocultos' en el menú a la derecha",
TabTags: "Este tiddler oculto contiene los contenidos de la pestaña 'Etiquetas' en el menú a la derecha",
TabTimeline: "Este tiddler oculto contiene los contenidos de la pestaña 'Fecha' en el menú a la derecha",
ViewTemplate: "la plantilla HTML en este tiddler oculto determina la apariencia de los tiddlers cuando están en modo de lectura"
});
//}}}
/***
''Inspired by [[TiddlyPom|http://www.warwick.ac.uk/~tuspam/tiddlypom.html]]''
|Name|SplashScreenPlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#SplashScreenPlugin|
|Version|0.21 |
|Requires|~TW2.08+|
!Description:
Provides a simple splash screen that is visible while the TW is loading.
!Installation
Copy the source text of this tiddler to your TW in a new tiddler, tag it with systemConfig and save and reload. The SplashScreen will now be installed and will be visible the next time you reload your TW.
!Customizing
Once the SplashScreen has been installed and you have reloaded your TW, the splash screen html will be present in the MarkupPreHead tiddler. You can edit it and customize to your needs.
!History
* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.
* 26-06-06 : version 0.2, first release
!Code
***/
//{{{
var old_lewcid_splash_restart=restart;
restart = function()
{ if (document.getElementById("SplashScreen"))
document.getElementById("SplashScreen").style.display = "none";
if (document.getElementById("contentWrapper"))
document.getElementById("contentWrapper").style.display = "block";
old_lewcid_splash_restart();
if (splashScreenInstall)
{if(config.options.chkAutoSave)
{saveChanges();}
displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");
}
}
var oldText = store.getTiddlerText("MarkupPreHead");
if (oldText.indexOf("SplashScreen")==-1)
{var siteTitle = store.getTiddlerText("SiteTitle");
var splasher='\n\n<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>'+siteTitle +'</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>';
if (! store.tiddlerExists("MarkupPreHead"))
{var myTiddler = store.createTiddler("MarkupPreHead");}
else
{var myTiddler = store.getTiddler("MarkupPreHead");}
myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);
store.setDirty(true);
var splashScreenInstall = true;
}
//}}}
/* text alignments */
.left
{ display:block;text-align:left; }
.center
{ display:block;text-align:center; }
.center table
{ margin:auto !important; }
.right
{ display:block;text-align:right; }
.justify
{ display:block;text-align:justify; }
.indent
{ display:block;margin:0;padding:0;border:0;margin-left:2em; }
.floatleft
{ float:left; }
.floatright
{ float:right; }
.valignTop, .valignTop table, .valignTop tbody, .valignTop th, .valignTop tr, .valignTop td
{ vertical-align:top; }
.valignBottom, .valignBottom table, .valignBottom tbody, .valignBottom th, .valignBottom tr, .valignBottom td
{ vertical-align:bottom; }
.clear
{ clear:both; }
.wrap
{ white-space:normal; }
.nowrap
{ white-space:nowrap; }
.hidden
{ display:none; }
.show
{ display:inline !important; }
.span
{ display:span; }
.block
{ display:block; }
.relative
{ position:relative; }
.absolute
{ position:absolute; }
/* multi-column tiddler content (not supported in Internet Explorer) */
.twocolumns { display:block;
-moz-column-count:2; -moz-column-gap:1em; -moz-column-width:50%; /* FireFox */
-webkit-column-count:2; -webkit-column-gap:1em; -webkit-column-width:50%; /* Safari */
column-count:2; column-gap:1em; column-width:50%; /* Opera */
}
.threecolumns { display:block;
-moz-column-count:3; -moz-column-gap:1em; -moz-column-width:33%; /* FireFox */
-webkit-column-count:3; -webkit-column-gap:1em; -webkit-column-width:33%; /* Safari */
column-count:3; column-gap:1em; column-width:33%; /* Opera */
}
.fourcolumns { display:block;
-moz-column-count:4; -moz-column-gap:1em; -moz-column-width:25%; /* FireFox */
-webkit-column-count:4; -webkit-column-gap:1em; -webkit-column-width:25%; /* Safari */
column-count:4; column-gap:1em; column-width:25%; /* Opera */
}
.firstletter{ float:left; width:0.75em; font-size:400%; font-family:times,arial; line-height:60%; }
/***
''Plugin:'' Tag Cloud Macro
''Author:'' Clint Checketts
''Source URL:''
!Usage
<<tagCloud>>
!Code
***/
//{{{
version.extensions.tagCloud = {major: 1, minor: 0 , revision: 0, date: new Date(2006,2,04)};
//Created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman
config.macros.tagCloud = {
noTags: "No tag cloud created because there are no tags.",
tooltip: "%1 tiddlers tagged with '%0'"
};
config.macros.tagCloud.handler = function(place,macroName,params) {
var tagCloudWrapper = createTiddlyElement(place,"div",null,"tagCloud",null);
var tags = store.getTags();
for (var t=0; t<tags.length; t++) {
for (var p=0;p<params.length; p++) if (tags[t][0] == params[p]) tags[t][0] = "";
}
if(tags.length == 0)
createTiddlyElement(tagCloudWrapper,"span",null,null,this.noTags);
//Findout the maximum number of tags
var mostTags = 0;
for (var t=0; t<tags.length; t++) if (tags[t][0].length > 0){
if (tags[t][1] > mostTags) mostTags = tags[t][1];
}
//divide the mostTags into 4 segments for the 4 different tagCloud sizes
var tagSegment = mostTags / 4;
for (var t=0; t<tags.length; t++) if (tags[t][0].length > 0){
var tagCloudElement = createTiddlyElement(tagCloudWrapper,"span",null,null,null);
tagCloudWrapper.appendChild(document.createTextNode(" "));
var theTag = createTiddlyButton(tagCloudElement,tags[t][0],this.tooltip.format(tags[t]),onClickTag,"tagCloudtag tagCloud" + (Math.round(tags[t][1]/tagSegment)+1));
theTag.setAttribute("tag",tags[t][0]);
}
};
setStylesheet(".tagCloud span{height: 1.8em;margin: 3px;}.tagCloud1{font-size: 1.2em;}.tagCloud2{font-size: 1.4em;}.tagCloud3{font-size: 1.6em;}.tagCloud4{font-size: 1.8em;}.tagCloud5{font-size: 1.8em;font-weight: bold;}","tagCloudsStyles");
//}}}
<<tagCloud>>
!<<QOTD Citas>>
----
<html>
<div style="overflow:auto;">
<img src="http://farm5.static.flickr.com/4107/5211481872_16b69a0717_b.jpg" width="1024" height="338" alt="2.saria 2010 Juan Antonio Unzurrunzaga">
</div>
</html>
^^J.A.Unzurrunzaga^^
/***
|''Name:''|TiddlersBarPlugin|
|''Description:''|A bar to switch between tiddlers through tabs (like browser tabs bar).|
|''Version:''|1.2.5|
|''Date:''|Jan 18,2008|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Demos
On [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], open several tiddlers to use the tabs bar.
!Installation
#import this tiddler from [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] (tagged as systemConfig)
#save and reload
#''if you're using a custom [[PageTemplate]]'', add {{{<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>}}} before {{{<div id='tiddlerDisplay'></div>}}}
#optionally, adjust StyleSheetTiddlersBar
!Tips
*Doubleclick on the tiddlers bar (where there is no tab) create a new tiddler.
*Tabs include a button to close {{{x}}} or save {{{!}}} their tiddler.
*By default, click on the current tab close all others tiddlers.
!Configuration options
<<option chkDisableTabsBar>> Disable the tabs bar (to print, by example).
<<option chkHideTabsBarWhenSingleTab >> Automatically hide the tabs bar when only one tiddler is displayed.
<<option txtSelectedTiddlerTabButton>> ''selected'' tab command button.
<<option txtPreviousTabKey>> previous tab access key.
<<option txtNextTabKey>> next tab access key.
!Code
***/
//{{{
config.options.chkDisableTabsBar = config.options.chkDisableTabsBar ? config.options.chkDisableTabsBar : false;
config.options.chkHideTabsBarWhenSingleTab = config.options.chkHideTabsBarWhenSingleTab ? config.options.chkHideTabsBarWhenSingleTab : false;
config.options.txtSelectedTiddlerTabButton = config.options.txtSelectedTiddlerTabButton ? config.options.txtSelectedTiddlerTabButton : "closeOthers";
config.options.txtPreviousTabKey = config.options.txtPreviousTabKey ? config.options.txtPreviousTabKey : "";
config.options.txtNextTabKey = config.options.txtNextTabKey ? config.options.txtNextTabKey : "";
config.macros.tiddlersBar = {
tooltip : "see ",
tooltipClose : "click here to close this tab",
tooltipSave : "click here to save this tab",
promptRename : "Enter tiddler new name",
currentTiddler : "",
previousState : false,
previousKey : config.options.txtPreviousTabKey,
nextKey : config.options.txtNextTabKey,
tabsAnimationSource : null, //use document.getElementById("tiddlerDisplay") if you need animation on tab switching.
handler: function(place,macroName,params) {
var previous = null;
if (config.macros.tiddlersBar.isShown())
story.forEachTiddler(function(title,e){
if (title==config.macros.tiddlersBar.currentTiddler){
var d = createTiddlyElement(null,"span",null,"tab tabSelected");
config.macros.tiddlersBar.createActiveTabButton(d,title);
if (previous && config.macros.tiddlersBar.previousKey) previous.setAttribute("accessKey",config.macros.tiddlersBar.nextKey);
previous = "active";
}
else {
var d = createTiddlyElement(place,"span",null,"tab tabUnselected");
var btn = createTiddlyButton(d,title,config.macros.tiddlersBar.tooltip + title,config.macros.tiddlersBar.onSelectTab);
btn.setAttribute("tiddler", title);
if (previous=="active" && config.macros.tiddlersBar.nextKey) btn.setAttribute("accessKey",config.macros.tiddlersBar.previousKey);
previous=btn;
}
var isDirty =story.isDirty(title);
var c = createTiddlyButton(d,isDirty ?"!":"x",isDirty?config.macros.tiddlersBar.tooltipSave:config.macros.tiddlersBar.tooltipClose, isDirty ? config.macros.tiddlersBar.onTabSave : config.macros.tiddlersBar.onTabClose,"tabButton");
c.setAttribute("tiddler", title);
if (place.childNodes) {
place.insertBefore(document.createTextNode(" "),place.firstChild); // to allow break line here when many tiddlers are open
place.insertBefore(d,place.firstChild);
}
else place.appendChild(d);
})
},
refresh: function(place,params){
removeChildren(place);
config.macros.tiddlersBar.handler(place,"tiddlersBar",params);
if (config.macros.tiddlersBar.previousState!=config.macros.tiddlersBar.isShown()) {
story.refreshAllTiddlers();
if (config.macros.tiddlersBar.previousState) story.forEachTiddler(function(t,e){e.style.display="";});
config.macros.tiddlersBar.previousState = !config.macros.tiddlersBar.previousState;
}
},
isShown : function(){
if (config.options.chkDisableTabsBar) return false;
if (!config.options.chkHideTabsBarWhenSingleTab) return true;
var cpt=0;
story.forEachTiddler(function(){cpt++});
return (cpt>1);
},
selectNextTab : function(){ //used when the current tab is closed (to select another tab)
var previous="";
story.forEachTiddler(function(title){
if (!config.macros.tiddlersBar.currentTiddler) {
story.displayTiddler(null,title);
return;
}
if (title==config.macros.tiddlersBar.currentTiddler) {
if (previous) {
story.displayTiddler(null,previous);
return;
}
else config.macros.tiddlersBar.currentTiddler=""; // so next tab will be selected
}
else previous=title;
});
},
onSelectTab : function(e){
var t = this.getAttribute("tiddler");
if (t) story.displayTiddler(null,t);
return false;
},
onTabClose : function(e){
var t = this.getAttribute("tiddler");
if (t) {
if(story.hasChanges(t) && !readOnly) {
if(!confirm(config.commands.cancelTiddler.warning.format([t])))
return false;
}
story.closeTiddler(t);
}
return false;
},
onTabSave : function(e) {
var t = this.getAttribute("tiddler");
if (!e) e=window.event;
if (t) config.commands.saveTiddler.handler(e,null,t);
return false;
},
onSelectedTabButtonClick : function(event,src,title) {
var t = this.getAttribute("tiddler");
if (!event) event=window.event;
if (t && config.options.txtSelectedTiddlerTabButton && config.commands[config.options.txtSelectedTiddlerTabButton])
config.commands[config.options.txtSelectedTiddlerTabButton].handler(event, src, t);
return false;
},
onTiddlersBarAction: function(event) {
var source = event.target ? event.target.id : event.srcElement.id; // FF uses target and IE uses srcElement;
if (source=="tiddlersBar") story.displayTiddler(null,'New Tiddler',DEFAULT_EDIT_TEMPLATE,false,null,null);
},
createActiveTabButton : function(place,title) {
if (config.options.txtSelectedTiddlerTabButton && config.commands[config.options.txtSelectedTiddlerTabButton]) {
var btn = createTiddlyButton(place, title, config.commands[config.options.txtSelectedTiddlerTabButton].tooltip ,config.macros.tiddlersBar.onSelectedTabButtonClick);
btn.setAttribute("tiddler", title);
}
else
createTiddlyText(place,title);
}
}
story.coreCloseTiddler = story.coreCloseTiddler? story.coreCloseTiddler : story.closeTiddler;
story.coreDisplayTiddler = story.coreDisplayTiddler ? story.coreDisplayTiddler : story.displayTiddler;
story.closeTiddler = function(title,animate,unused) {
if (title==config.macros.tiddlersBar.currentTiddler)
config.macros.tiddlersBar.selectNextTab();
story.coreCloseTiddler(title,false,unused); //disable animation to get it closed before calling tiddlersBar.refresh
var e=document.getElementById("tiddlersBar");
if (e) config.macros.tiddlersBar.refresh(e,null);
}
story.displayTiddler = function(srcElement,tiddler,template,animate,unused,customFields,toggle){
story.coreDisplayTiddler(config.macros.tiddlersBar.tabsAnimationSource,tiddler,template,animate,unused,customFields,toggle);
var title = (tiddler instanceof Tiddler)? tiddler.title : tiddler;
if (config.macros.tiddlersBar.isShown()) {
story.forEachTiddler(function(t,e){
if (t!=title) e.style.display="none";
else e.style.display="";
})
config.macros.tiddlersBar.currentTiddler=title;
}
var e=document.getElementById("tiddlersBar");
if (e) config.macros.tiddlersBar.refresh(e,null);
}
var coreRefreshPageTemplate = coreRefreshPageTemplate ? coreRefreshPageTemplate : refreshPageTemplate;
refreshPageTemplate = function(title) {
coreRefreshPageTemplate(title);
if (config.macros.tiddlersBar) config.macros.tiddlersBar.refresh(document.getElementById("tiddlersBar"));
}
ensureVisible=function (e) {return 0} //disable bottom scrolling (not useful now)
config.shadowTiddlers.StyleSheetTiddlersBar = "/*{{{*/\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar .button {border:0}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar .tab {white-space:nowrap}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar {padding : 1em 0.5em 2px 0.5em}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += ".tabUnselected .tabButton, .tabSelected .tabButton {padding : 0 2px 0 2px; margin: 0 0 0 4px;}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += ".tiddler, .tabContents {border:1px [[ColorPalette::TertiaryPale]] solid;}\n";
config.shadowTiddlers.StyleSheetTiddlersBar +="/*}}}*/";
store.addNotification("StyleSheetTiddlersBar", refreshStyles);
config.refreshers.none = function(){return true;}
config.shadowTiddlers.PageTemplate=config.shadowTiddlers.PageTemplate.replace(/<div id='tiddlerDisplay'><\/div>/m,"<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>\n<div id='tiddlerDisplay'></div>");
//}}}
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{
// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'zaldibarkoilargi';
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
// disable autosave in d3
if (window.location.protocol != "file:")
config.options.chkGTDLazyAutoSave = false;
// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}
// create some shadow tiddler content
merge(config.shadowTiddlers,{
'WelcomeToTiddlyspot':[
"This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
"<<tiddler TspotControls>>",
"See also GettingStarted.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),
'TspotControls':[
"| tiddlyspot password:|<<option pasUploadPassword>>|",
"| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
"| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),
'TspotSidebar':[
"<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),
'TspotOptions':[
"tiddlyspot password:",
"<<option pasUploadPassword>>",
""
].join("\n")
});
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 26/12/2010 13:41:23 | Ilargi | [[/|http://zaldibarkoilargi.tiddlyspot.com/]] | [[store.cgi|http://zaldibarkoilargi.tiddlyspot.com/store.cgi]] | . | [[index.html | http://zaldibarkoilargi.tiddlyspot.com/index.html]] | . | ok |
| 26/12/2010 13:53:33 | Ilargi | [[/|http://zaldibarkoilargi.tiddlyspot.com/]] | [[store.cgi|http://zaldibarkoilargi.tiddlyspot.com/store.cgi]] | . | [[index.html | http://zaldibarkoilargi.tiddlyspot.com/index.html]] | . | ok |
| 26/12/2010 13:54:26 | Ilargi | [[/|http://zaldibarkoilargi.tiddlyspot.com/]] | [[store.cgi|http://zaldibarkoilargi.tiddlyspot.com/store.cgi]] | . | [[index.html | http://zaldibarkoilargi.tiddlyspot.com/index.html]] | . | ok |
| 26/12/2010 13:55:12 | Ilargi | [[/|http://zaldibarkoilargi.tiddlyspot.com/]] | [[store.cgi|http://zaldibarkoilargi.tiddlyspot.com/store.cgi]] | . | [[index.html | http://zaldibarkoilargi.tiddlyspot.com/index.html]] | . |
| 26/12/2010 14:17:57 | Ilargi | [[/|http://zaldibarkoilargi.tiddlyspot.com/]] | [[store.cgi|http://zaldibarkoilargi.tiddlyspot.com/store.cgi]] | . | [[index.html | http://zaldibarkoilargi.tiddlyspot.com/index.html]] | . |
| 26/12/2010 14:18:00 | Ilargi | [[/|http://zaldibarkoilargi.tiddlyspot.com/]] | [[store.cgi|http://zaldibarkoilargi.tiddlyspot.com/store.cgi]] | . | [[index.html | http://zaldibarkoilargi.tiddlyspot.com/index.html]] | . |
| 26/12/2010 15:29:06 | Ilargi | [[/|http://zaldibarkoilargi.tiddlyspot.com/]] | [[store.cgi|http://zaldibarkoilargi.tiddlyspot.com/store.cgi]] | . | [[index.html | http://zaldibarkoilargi.tiddlyspot.com/index.html]] | . |
| 28/12/2010 16:31:00 | SuNombre | [[/|http://zaldibarkoilargi.tiddlyspot.com/]] | [[store.cgi|http://zaldibarkoilargi.tiddlyspot.com/store.cgi]] | . | [[index.html | http://zaldibarkoilargi.tiddlyspot.com/index.html]] | . |
| 02/01/2011 19:07:17 | Ilargi | [[/|http://zaldibarkoilargi.tiddlyspot.com/]] | [[store.cgi|http://zaldibarkoilargi.tiddlyspot.com/store.cgi]] | . | [[index.html | http://zaldibarkoilargi.tiddlyspot.com/index.html]] | . | ok |
| 02/01/2011 19:07:55 | Ilargi | [[/|http://zaldibarkoilargi.tiddlyspot.com/]] | [[store.cgi|http://zaldibarkoilargi.tiddlyspot.com/store.cgi]] | . | [[index.html | http://zaldibarkoilargi.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 3,
date: new Date("Feb 24, 2008"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
var wizard = new Wizard();
wizard.createWizard(place,this.wizardTitle);
wizard.addStep(this.step1Title,this.step1Html);
var markList = wizard.getElement("markList");
var listWrapper = document.createElement("div");
markList.parentNode.insertBefore(listWrapper,markList);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
for(n=0; n<opts.length; n++) {
var type = opts[n].name.substr(0,3);
var h = config.macros.option.types[type];
if (h && h.create) {
h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
[img[ zaldibarko lehioak|http://farm1.static.flickr.com/45/141514982_db2431d959.jpg]]