webby 0.9.3-x86-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (229) hide show
  1. data/History.txt +206 -0
  2. data/Manifest.txt +228 -0
  3. data/README.txt +92 -0
  4. data/Rakefile +49 -0
  5. data/bin/webby +41 -0
  6. data/bin/webby-gen +41 -0
  7. data/examples/blog/Sitefile +7 -0
  8. data/examples/blog/tasks/blog.rake +72 -0
  9. data/examples/blog/templates/atom_feed.erb +40 -0
  10. data/examples/blog/templates/blog/month.erb +22 -0
  11. data/examples/blog/templates/blog/post.erb +16 -0
  12. data/examples/blog/templates/blog/year.erb +22 -0
  13. data/examples/presentation/Sitefile +10 -0
  14. data/examples/presentation/content/css/uv/twilight.css +137 -0
  15. data/examples/presentation/content/presentation/_sample_code.txt +10 -0
  16. data/examples/presentation/content/presentation/index.txt +63 -0
  17. data/examples/presentation/content/presentation/s5/blank.gif +0 -0
  18. data/examples/presentation/content/presentation/s5/bodybg.gif +0 -0
  19. data/examples/presentation/content/presentation/s5/framing.css +23 -0
  20. data/examples/presentation/content/presentation/s5/iepngfix.htc +42 -0
  21. data/examples/presentation/content/presentation/s5/opera.css +7 -0
  22. data/examples/presentation/content/presentation/s5/outline.css +15 -0
  23. data/examples/presentation/content/presentation/s5/pretty.css +86 -0
  24. data/examples/presentation/content/presentation/s5/print.css +25 -0
  25. data/examples/presentation/content/presentation/s5/s5-core.css +9 -0
  26. data/examples/presentation/content/presentation/s5/slides.css +3 -0
  27. data/examples/presentation/content/presentation/s5/slides.js +553 -0
  28. data/examples/presentation/layouts/presentation.txt +43 -0
  29. data/examples/presentation/templates/_code_partial.erb +13 -0
  30. data/examples/presentation/templates/presentation.erb +40 -0
  31. data/examples/tumblog/Sitefile +9 -0
  32. data/examples/tumblog/content/css/tumblog.css +308 -0
  33. data/examples/tumblog/content/images/tumblog/permalink.gif +0 -0
  34. data/examples/tumblog/content/images/tumblog/rss.gif +0 -0
  35. data/examples/tumblog/content/tumblog/200806/the-noble-chicken/index.txt +12 -0
  36. data/examples/tumblog/content/tumblog/200807/historical-perspectives-on-the-classic-chicken-joke/index.txt +12 -0
  37. data/examples/tumblog/content/tumblog/200807/mad-city-chickens/index.txt +10 -0
  38. data/examples/tumblog/content/tumblog/200807/the-wisdom-of-the-dutch/index.txt +11 -0
  39. data/examples/tumblog/content/tumblog/200807/up-a-tree/index.txt +13 -0
  40. data/examples/tumblog/content/tumblog/index.txt +37 -0
  41. data/examples/tumblog/content/tumblog/rss.txt +37 -0
  42. data/examples/tumblog/layouts/tumblog/default.txt +44 -0
  43. data/examples/tumblog/layouts/tumblog/post.txt +15 -0
  44. data/examples/tumblog/lib/tumblog_helper.rb +32 -0
  45. data/examples/tumblog/tasks/tumblog.rake +30 -0
  46. data/examples/tumblog/templates/atom_feed.erb +40 -0
  47. data/examples/tumblog/templates/tumblog/conversation.erb +12 -0
  48. data/examples/tumblog/templates/tumblog/link.erb +10 -0
  49. data/examples/tumblog/templates/tumblog/photo.erb +13 -0
  50. data/examples/tumblog/templates/tumblog/post.erb +12 -0
  51. data/examples/tumblog/templates/tumblog/quote.erb +11 -0
  52. data/examples/webby/Sitefile +19 -0
  53. data/examples/webby/content/communicate/index.txt +28 -0
  54. data/examples/webby/content/css/background.gif +0 -0
  55. data/examples/webby/content/css/blueprint/print.css +76 -0
  56. data/examples/webby/content/css/blueprint/screen.css +696 -0
  57. data/examples/webby/content/css/coderay.css +96 -0
  58. data/examples/webby/content/css/site.css +196 -0
  59. data/examples/webby/content/css/uv/twilight.css +137 -0
  60. data/examples/webby/content/index.txt +37 -0
  61. data/examples/webby/content/learn/index.txt +28 -0
  62. data/examples/webby/content/reference/index.txt +204 -0
  63. data/examples/webby/content/release-notes/index.txt +21 -0
  64. data/examples/webby/content/release-notes/rel-0-9-0/index.txt +74 -0
  65. data/examples/webby/content/release-notes/rel-0-9-1/index.txt +93 -0
  66. data/examples/webby/content/release-notes/rel-0-9-2/index.txt +14 -0
  67. data/examples/webby/content/release-notes/rel-0-9-3/index.txt +49 -0
  68. data/examples/webby/content/robots.txt +6 -0
  69. data/examples/webby/content/script/jquery.corner.js +152 -0
  70. data/examples/webby/content/script/jquery.js +31 -0
  71. data/examples/webby/content/sitemap.txt +31 -0
  72. data/examples/webby/content/tips_and_tricks/index.txt +97 -0
  73. data/examples/webby/content/tutorial/index.txt +135 -0
  74. data/examples/webby/content/user-manual/index.txt +419 -0
  75. data/examples/webby/layouts/default.txt +49 -0
  76. data/examples/webby/templates/page.erb +10 -0
  77. data/examples/website/Sitefile +7 -0
  78. data/examples/website/content/css/blueprint/License.txt +21 -0
  79. data/examples/website/content/css/blueprint/Readme.txt +100 -0
  80. data/examples/website/content/css/blueprint/compressed/print.css +76 -0
  81. data/examples/website/content/css/blueprint/compressed/screen.css +696 -0
  82. data/examples/website/content/css/blueprint/lib/forms.css +45 -0
  83. data/examples/website/content/css/blueprint/lib/grid.css +193 -0
  84. data/examples/website/content/css/blueprint/lib/grid.png +0 -0
  85. data/examples/website/content/css/blueprint/lib/ie.css +30 -0
  86. data/examples/website/content/css/blueprint/lib/reset.css +39 -0
  87. data/examples/website/content/css/blueprint/lib/typography.css +116 -0
  88. data/examples/website/content/css/blueprint/plugins/buttons/Readme +31 -0
  89. data/examples/website/content/css/blueprint/plugins/buttons/buttons.css +97 -0
  90. data/examples/website/content/css/blueprint/plugins/buttons/icons/cross.png +0 -0
  91. data/examples/website/content/css/blueprint/plugins/buttons/icons/key.png +0 -0
  92. data/examples/website/content/css/blueprint/plugins/buttons/icons/tick.png +0 -0
  93. data/examples/website/content/css/blueprint/plugins/css-classes/Readme +14 -0
  94. data/examples/website/content/css/blueprint/plugins/css-classes/css-classes.css +24 -0
  95. data/examples/website/content/css/blueprint/plugins/fancy-type/Readme +22 -0
  96. data/examples/website/content/css/blueprint/plugins/fancy-type/fancy-type-compressed.css +5 -0
  97. data/examples/website/content/css/blueprint/plugins/fancy-type/fancy-type.css +74 -0
  98. data/examples/website/content/css/blueprint/print.css +68 -0
  99. data/examples/website/content/css/blueprint/screen.css +22 -0
  100. data/examples/website/content/css/coderay.css +111 -0
  101. data/examples/website/content/css/site.css +67 -0
  102. data/examples/website/content/index.txt +19 -0
  103. data/examples/website/layouts/default.txt +58 -0
  104. data/examples/website/lib/breadcrumbs.rb +28 -0
  105. data/examples/website/templates/_partial.erb +10 -0
  106. data/examples/website/templates/page.erb +18 -0
  107. data/lib/webby.rb +221 -0
  108. data/lib/webby/apps.rb +12 -0
  109. data/lib/webby/apps/generator.rb +276 -0
  110. data/lib/webby/apps/main.rb +255 -0
  111. data/lib/webby/auto_builder.rb +157 -0
  112. data/lib/webby/builder.rb +180 -0
  113. data/lib/webby/core_ext/enumerable.rb +11 -0
  114. data/lib/webby/core_ext/hash.rb +28 -0
  115. data/lib/webby/core_ext/kernel.rb +26 -0
  116. data/lib/webby/core_ext/string.rb +163 -0
  117. data/lib/webby/core_ext/time.rb +9 -0
  118. data/lib/webby/filters.rb +83 -0
  119. data/lib/webby/filters/basepath.rb +97 -0
  120. data/lib/webby/filters/erb.rb +9 -0
  121. data/lib/webby/filters/haml.rb +18 -0
  122. data/lib/webby/filters/markdown.rb +16 -0
  123. data/lib/webby/filters/outline.rb +309 -0
  124. data/lib/webby/filters/sass.rb +17 -0
  125. data/lib/webby/filters/slides.rb +56 -0
  126. data/lib/webby/filters/textile.rb +16 -0
  127. data/lib/webby/filters/tidy.rb +76 -0
  128. data/lib/webby/filters/wiki_words.rb +14 -0
  129. data/lib/webby/helpers.rb +30 -0
  130. data/lib/webby/helpers/capture_helper.rb +141 -0
  131. data/lib/webby/helpers/coderay_helper.rb +69 -0
  132. data/lib/webby/helpers/graphviz_helper.rb +136 -0
  133. data/lib/webby/helpers/tag_helper.rb +65 -0
  134. data/lib/webby/helpers/tex_img_helper.rb +133 -0
  135. data/lib/webby/helpers/ultraviolet_helper.rb +63 -0
  136. data/lib/webby/helpers/url_helper.rb +241 -0
  137. data/lib/webby/journal.rb +126 -0
  138. data/lib/webby/link_validator.rb +152 -0
  139. data/lib/webby/renderer.rb +386 -0
  140. data/lib/webby/resources.rb +136 -0
  141. data/lib/webby/resources/db.rb +251 -0
  142. data/lib/webby/resources/layout.rb +54 -0
  143. data/lib/webby/resources/meta_file.rb +211 -0
  144. data/lib/webby/resources/page.rb +81 -0
  145. data/lib/webby/resources/partial.rb +85 -0
  146. data/lib/webby/resources/resource.rb +201 -0
  147. data/lib/webby/resources/static.rb +36 -0
  148. data/lib/webby/stelan/mktemp.rb +135 -0
  149. data/lib/webby/stelan/paginator.rb +165 -0
  150. data/lib/webby/stelan/spawner.rb +339 -0
  151. data/lib/webby/tasks/build.rake +27 -0
  152. data/lib/webby/tasks/create.rake +22 -0
  153. data/lib/webby/tasks/deploy.rake +22 -0
  154. data/lib/webby/tasks/growl.rake +16 -0
  155. data/lib/webby/tasks/validate.rake +19 -0
  156. data/spec/core_ext/hash_spec.rb +47 -0
  157. data/spec/core_ext/string_spec.rb +110 -0
  158. data/spec/core_ext/time_spec.rb +19 -0
  159. data/spec/data/hooligans/bad_meta_data_1.txt +34 -0
  160. data/spec/data/hooligans/bad_meta_data_2.txt +34 -0
  161. data/spec/data/outline/basic.out +81 -0
  162. data/spec/data/outline/basic.txt +25 -0
  163. data/spec/data/outline/no_clobber.out +86 -0
  164. data/spec/data/outline/numbering.out +81 -0
  165. data/spec/data/outline/numbering_only.out +21 -0
  166. data/spec/data/outline/toc_range_1.out +66 -0
  167. data/spec/data/outline/toc_range_2.out +55 -0
  168. data/spec/data/outline/toc_style.out +81 -0
  169. data/spec/data/site/Sitefile +9 -0
  170. data/spec/data/site/content/_partial.txt +10 -0
  171. data/spec/data/site/content/css/coderay.css +111 -0
  172. data/spec/data/site/content/css/site.css +67 -0
  173. data/spec/data/site/content/css/tumblog.css +308 -0
  174. data/spec/data/site/content/images/tumblog/permalink.gif +0 -0
  175. data/spec/data/site/content/images/tumblog/rss.gif +0 -0
  176. data/spec/data/site/content/index.txt +19 -0
  177. data/spec/data/site/content/photos.txt +21 -0
  178. data/spec/data/site/content/tumblog/200806/the-noble-chicken/index.txt +12 -0
  179. data/spec/data/site/content/tumblog/200807/historical-perspectives-on-the-classic-chicken-joke/index.txt +12 -0
  180. data/spec/data/site/content/tumblog/200807/mad-city-chickens/index.txt +10 -0
  181. data/spec/data/site/content/tumblog/200807/the-wisdom-of-the-dutch/index.txt +11 -0
  182. data/spec/data/site/content/tumblog/200807/up-a-tree/index.txt +13 -0
  183. data/spec/data/site/content/tumblog/index.txt +37 -0
  184. data/spec/data/site/content/tumblog/rss.txt +37 -0
  185. data/spec/data/site/layouts/default.txt +58 -0
  186. data/spec/data/site/layouts/tumblog/default.txt +44 -0
  187. data/spec/data/site/layouts/tumblog/post.txt +15 -0
  188. data/spec/data/site/lib/breadcrumbs.rb +28 -0
  189. data/spec/data/site/lib/tumblog_helper.rb +32 -0
  190. data/spec/data/site/tasks/tumblog.rake +30 -0
  191. data/spec/data/site/templates/_partial.erb +10 -0
  192. data/spec/data/site/templates/atom_feed.erb +40 -0
  193. data/spec/data/site/templates/page.erb +18 -0
  194. data/spec/data/site/templates/presentation.erb +40 -0
  195. data/spec/data/site/templates/tumblog/conversation.erb +12 -0
  196. data/spec/data/site/templates/tumblog/link.erb +10 -0
  197. data/spec/data/site/templates/tumblog/photo.erb +13 -0
  198. data/spec/data/site/templates/tumblog/post.erb +12 -0
  199. data/spec/data/site/templates/tumblog/quote.erb +11 -0
  200. data/spec/spec.opts +1 -0
  201. data/spec/spec_helper.rb +51 -0
  202. data/spec/webby/apps/generator_spec.rb +116 -0
  203. data/spec/webby/apps/main_spec.rb +88 -0
  204. data/spec/webby/filters/basepath_spec.rb +167 -0
  205. data/spec/webby/filters/outline_spec.rb +92 -0
  206. data/spec/webby/filters/textile_spec.rb +20 -0
  207. data/spec/webby/helpers/capture_helper_spec.rb +56 -0
  208. data/spec/webby/renderer_spec.rb +139 -0
  209. data/spec/webby/resources/db_spec.rb +250 -0
  210. data/spec/webby/resources/layout_spec.rb +83 -0
  211. data/spec/webby/resources/meta_file_spec.rb +171 -0
  212. data/spec/webby/resources/page_spec.rb +111 -0
  213. data/spec/webby/resources/partial_spec.rb +58 -0
  214. data/spec/webby/resources/resource_spec.rb +219 -0
  215. data/spec/webby/resources/static_spec.rb +49 -0
  216. data/spec/webby/resources_spec.rb +69 -0
  217. data/tasks/ann.rake +81 -0
  218. data/tasks/bones.rake +21 -0
  219. data/tasks/gem.rake +187 -0
  220. data/tasks/git.rake +41 -0
  221. data/tasks/manifest.rake +48 -0
  222. data/tasks/notes.rake +28 -0
  223. data/tasks/post_load.rake +39 -0
  224. data/tasks/rdoc.rake +51 -0
  225. data/tasks/rubyforge.rake +55 -0
  226. data/tasks/setup.rb +268 -0
  227. data/tasks/spec.rake +55 -0
  228. data/tasks/website.rake +38 -0
  229. metadata +365 -0
@@ -0,0 +1,14 @@
1
+
2
+ Webby::Filters.register :wikiwords do |input, cursor|
3
+
4
+ renderer = cursor.renderer
5
+ input.gsub %r/\[\[([^\]]+)\]\]/ do
6
+ name = $1
7
+ renderer.link_to_page(name) {
8
+ %Q(<a class="missing internal">#{name}</a>)
9
+ }
10
+ end
11
+
12
+ end
13
+
14
+ # EOF
@@ -0,0 +1,30 @@
1
+ require Webby.libpath(*%w[webby renderer])
2
+
3
+ module Webby
4
+
5
+ # The Helpers module is used to register helper modules that provide extra
6
+ # functionality to the Webby renderer. The most notable example is the
7
+ # UrlHelpers module that provides methods to link to another page in a
8
+ # Webby webiste.
9
+ #
10
+ # Helpers are registered with the Webby framework by calling:
11
+ #
12
+ # Webby::Helpers.register( MyHelper )
13
+ #
14
+ module Helpers
15
+
16
+ # call-seq:
17
+ # Helpers.register( module )
18
+ #
19
+ # Register the given _module_ as a helper module for the Webby framework.
20
+ #
21
+ def self.register( helper )
22
+ ::Webby::Renderer.__send__( :include, helper )
23
+ end
24
+
25
+ end # module Helper
26
+ end # module Webby
27
+
28
+ Webby.require_all_libs_relative_to(__FILE__)
29
+
30
+ # EOF
@@ -0,0 +1,141 @@
1
+
2
+ module Webby::Helpers
3
+
4
+ # Based on code from Rails and Merb.
5
+ #
6
+ module CaptureHelper
7
+
8
+ # Called in pages and partials to store up content for later use. Takes a
9
+ # string and/or a block. First, the string is evaluated, and then the
10
+ # block is captured using the capture() helper provided by the template
11
+ # languages. The two are concatenated together.
12
+ #
13
+ # Content is retrieved by calling the method without a string or a block.
14
+ #
15
+ # ==== Parameters
16
+ # obj<Object>:: The key in the conetnt_for hash.
17
+ # string<String>:: Textual content. Defaults to nil.
18
+ # &block:: A block to be evaluated and concatenated to string.
19
+ #
20
+ # ==== Returns
21
+ # Any content associated with the key (or nil).
22
+ #
23
+ # ==== Example
24
+ # content_for(:foo, "Foo")
25
+ # content_for(:foo) #=> "Foo"
26
+ # content_for(:foo, "Bar")
27
+ # content_for(:foo) #=> "FooBar"
28
+ #
29
+ def content_for( obj, string = nil, &block )
30
+ return @_content_for[obj] unless string || block_given?
31
+
32
+ cur = @_content_for[obj].to_s
33
+ new = string.to_s + (block_given? ? capture_erb(&block) : "")
34
+ @_content_for[obj] = cur + new
35
+ end
36
+
37
+ # Returns true if there is content for the given key. Otherwise returns
38
+ # false.
39
+ #
40
+ # ==== Parameters
41
+ # obj<Object>:: The key in the conetnt_for hash.
42
+ #
43
+ # ==== Example
44
+ # content_for(:foo, "Foo")
45
+ # content_for?(:foo) #=> true
46
+ # content_for?(:bar) #=> false
47
+ #
48
+ def content_for?( obj )
49
+ @_content_for.key?(obj)
50
+ end
51
+
52
+ # Deletes any content associated with the given object in the content_for
53
+ # hash.
54
+ #
55
+ # ==== Parameters
56
+ # obj<Object>:: The key in the conetnt_for hash.
57
+ #
58
+ # ==== Returns
59
+ # Any content associated with the key (or nil).
60
+ #
61
+ # ==== Example
62
+ # content_for(:foo, "Foo")
63
+ # content_for?(:foo) #=> true
64
+ # delete_content_for(:foo)
65
+ # content_for?(:foo) #=> false
66
+ #
67
+ def delete_content_for( obj )
68
+ @_content_for.delete(obj)
69
+ end
70
+
71
+ # This method is used to capture content from an ERB filter evaluation. It
72
+ # is useful to helpers that need to process chunks of data during ERB filter
73
+ # processing.
74
+ #
75
+ # ==== Parameters
76
+ # *args:: Arguments to pass to the block.
77
+ # &block:: The ERB block to call.
78
+ #
79
+ # ==== Returns
80
+ # String:: The output of the block.
81
+ #
82
+ # ==== Examples
83
+ # Capture being used in an ERB page:
84
+ #
85
+ # <% @foo = capture_erb do %>
86
+ # <p>Some Foo content!</p>
87
+ # <% end %>
88
+ #
89
+ def capture_erb( *args, &block )
90
+ # get the buffer from the block's binding
91
+ buffer = _erb_buffer(block.binding) rescue nil
92
+
93
+ # If there is no buffer, just call the block and get the contents
94
+ if buffer.nil?
95
+ block.call(*args)
96
+ # If there is a buffer, execute the block, then extract its contents
97
+ else
98
+ pos = buffer.length
99
+ block.call(*args)
100
+
101
+ # extract the block
102
+ data = buffer[pos..-1]
103
+
104
+ # replace it in the original with empty string
105
+ buffer[pos..-1] = ""
106
+
107
+ data
108
+ end
109
+ end
110
+
111
+ # This method is used to concatenate content into the ERB output buffer.
112
+ # It is usefule to helpers that need to insert transformed text back into
113
+ # the ERB output buffer.
114
+ #
115
+ # ==== Parameters
116
+ # string<String>:: The string to insert into the ERB output.
117
+ # the_binding<Binding>:: The binding to pass to the buffer.
118
+ #
119
+ def concat_erb( string, the_binding )
120
+ _erb_buffer(the_binding) << string
121
+ end
122
+
123
+ # Provides direct acccess to the ERB buffer in the conext of the binding.
124
+ #
125
+ # ==== Parameters
126
+ # the_binding<Binding>:: The binding to pass to the buffer.
127
+ #
128
+ # ==== Returns
129
+ # The current ERB output buffer.
130
+ #
131
+ def _erb_buffer( the_binding )
132
+ eval("_erbout", the_binding, __FILE__, __LINE__)
133
+ end
134
+
135
+ end # module CaptureHelper
136
+
137
+ register(CaptureHelper)
138
+
139
+ end # module Webby::Helpers
140
+
141
+ # EOF
@@ -0,0 +1,69 @@
1
+ if try_require 'coderay'
2
+ require 'enumerator'
3
+
4
+ module Webby::Helpers
5
+ module CodeRayHelper
6
+
7
+ # The +coderay+ method applies syntax highlighting to source code embedded
8
+ # in a webpage. The CodeRay highlighting engine is used for the HTML
9
+ # markup of the source code. The page sections to be highlighted are given
10
+ # as blocks of text to the +coderay+ method.
11
+ #
12
+ # Options can be passed to the CodeRay engine via attributes in the
13
+ # +coderay+ method.
14
+ #
15
+ # <% coderay( :lang => "ruby", :line_numbers => "inline" ) do -%>
16
+ # # Initializer for the class.
17
+ # def initialize( string )
18
+ # @str = stirng
19
+ # end
20
+ # <% end -%>
21
+ #
22
+ # The supported CodeRay options are the following:
23
+ #
24
+ # :lang : the language to highlight (ruby, c, html, ...)
25
+ # :line_numbers : include line numbers in 'table', 'inline',
26
+ # or 'list'
27
+ # :line_number_start : where to start with line number counting
28
+ # :bold_every : make every n-th number appear bold
29
+ # :tab_width : convert tab characters to n spaces
30
+ #
31
+ def coderay( *args, &block )
32
+ opts = args.last.instance_of?(Hash) ? args.pop : {}
33
+
34
+ text = capture_erb(&block)
35
+ return if text.empty?
36
+
37
+ defaults = ::Webby.site.coderay
38
+ lang = opts.getopt(:lang, defaults[:lang]).to_sym
39
+
40
+ cr_opts = {}
41
+ %w(line_numbers to_sym
42
+ line_number_start to_i
43
+ bold_every to_i
44
+ tab_width to_i).each_slice(2) do |key,convert|
45
+ key = key.to_sym
46
+ val = opts.getopt(key, defaults[key])
47
+ next if val.nil?
48
+ cr_opts[key] = val.send(convert)
49
+ end
50
+
51
+ #cr.swap(CodeRay.scan(text, lang).html(opts).div)
52
+ out = '<div class="CodeRay"><pre>'
53
+ out << ::CodeRay.scan(text, lang).html(cr_opts)
54
+ out << '</pre></div>'
55
+
56
+ # put some guards around the output (specifically for textile)
57
+ out = _guard(out)
58
+
59
+ concat_erb(out, block.binding)
60
+ return
61
+ end
62
+ end # module CodeRayHelper
63
+
64
+ register(CodeRayHelper)
65
+
66
+ end # module Webby::Helpers
67
+ end # try_require
68
+
69
+ # EOF
@@ -0,0 +1,136 @@
1
+ require 'fileutils'
2
+ require 'tempfile'
3
+
4
+ module Webby::Helpers
5
+ module GraphvizHelper
6
+
7
+ # call-seq:
8
+ # GraphvizHelper.error_check( file )
9
+ #
10
+ # Check the temporary error file to see if it contains any error messages
11
+ # from the graphviz program. If it is not empty, then read the contents
12
+ # and log an error message and raise an exception.
13
+ #
14
+ def self.error_check( file )
15
+ if ::File.size(file.path) != 0
16
+ msg = "\n" << ::File.read(file.path).strip
17
+ raise ::Webby::Error, msg
18
+ end
19
+ end
20
+
21
+ # The +graphviz+ method processes DOT scripts in a webpage and replaces them
22
+ # with generated image files. The page sections to be processed are given
23
+ # as blocks of text to the +graphviz+ method.
24
+ #
25
+ # Options can be passed to the Graphviz program using attributes in the
26
+ # +graphviz+ method.
27
+ #
28
+ # <% graphviz( :path => "images", :type => "gif", cmd => "dot" ) do %>
29
+ # digraph graph_1 {
30
+ # graph [URL="default.html"]
31
+ # a [URL="a.html"]
32
+ # b [URL="b.html"]
33
+ # c [URL="c.html"]
34
+ # a -> b -> c
35
+ # a -> c
36
+ # }
37
+ # <% end %>
38
+ #
39
+ # If the DOT script contains *URL* or *href* attributes on any of the nodes
40
+ # or edges, then an image map will be generated and the image will be
41
+ # "clikcable" in the webpage. If *URL* or *href* attributes do not appear in
42
+ # the DOT script, then a regular image will be inserted into the webpage.
43
+ #
44
+ # The image is inserted into the page using an HTML <img /> tag. A
45
+ # corresponding <map>...</map> element will be inserted if needed.
46
+ #
47
+ # The supported Graphviz options are the following:
48
+ #
49
+ # :path : where generated images will be stored
50
+ # [default is "/"]
51
+ # :type : the type of image to generate (png, jpeg, gif)
52
+ # [default is png]
53
+ # :cmd : the Graphviz command to use when generating images
54
+ # (dot, neato, twopi, circo, fdp) [default is dot]
55
+ #
56
+ # the following options are passed as-is to the generated <img /> tag
57
+ # :style : CSS styles to apply to the <img />
58
+ # :class : CSS class to apply to the <img />
59
+ # :id : HTML identifier
60
+ # :alt : alternate text for the <img />
61
+ #
62
+ def graphviz( *args, &block )
63
+ opts = args.last.instance_of?(Hash) ? args.pop : {}
64
+
65
+ text = capture_erb(&block)
66
+ return if text.empty?
67
+
68
+ # create a temporary file for holding any error messages
69
+ # from the graphviz program
70
+ err = Tempfile.new('graphviz_err')
71
+ err.close
72
+
73
+ defaults = ::Webby.site.graphviz
74
+ path = opts.getopt(:path, defaults[:path])
75
+ cmd = opts.getopt(:cmd, defaults[:cmd])
76
+ type = opts.getopt(:type, defaults[:type])
77
+
78
+ # pull the name of the graph|digraph out of the DOT script
79
+ name = text.match(%r/\A\s*(?:strict\s+)?(?:di)?graph\s+([A-Za-z_][A-Za-z0-9_]*)\s+\{/o)[1]
80
+
81
+ # see if the user includes any URL or href attributes
82
+ # if so, then we need to create an imagemap
83
+ usemap = text.match(%r/(?:URL|href)\s*=/o) != nil
84
+
85
+ # generate the image filename based on the path, graph name, and type
86
+ # of image to generate
87
+ image_fn = path.nil? ? name.dup : ::File.join(path, name)
88
+ image_fn = ::File.join('', image_fn) << '.' << type
89
+
90
+ # create the HTML img tag
91
+ out = "<img src=\"#{image_fn}\""
92
+
93
+ %w[class style id alt].each do |atr|
94
+ val = opts.getopt(atr)
95
+ next if val.nil?
96
+ out << " %s=\"%s\"" % [atr, val]
97
+ end
98
+
99
+ out << " usemap=\"\##{name}\"" if usemap
100
+ out << " />\n"
101
+
102
+ # generate the image map if needed
103
+ if usemap
104
+ IO.popen("#{cmd} -Tcmapx 2> #{err.path}", 'r+') do |io|
105
+ io.write text
106
+ io.close_write
107
+ out << io.read
108
+ end
109
+ GraphvizHelper.error_check(err)
110
+ end
111
+
112
+ # generate the image using graphviz -- but first ensure that the
113
+ # path exists
114
+ out_dir = ::Webby.site.output_dir
115
+ out_file = ::File.join(out_dir, image_fn)
116
+ FileUtils.mkpath(::File.join(out_dir, path)) unless path.nil?
117
+ cmd = "#{cmd} -T#{type} -o #{out_file} 2> #{err.path}"
118
+
119
+ IO.popen(cmd, 'w') {|io| io.write text}
120
+ GraphvizHelper.error_check(err)
121
+
122
+ # put some guards around the output (specifically for textile)
123
+ out = _guard(out)
124
+
125
+ concat_erb(out, block.binding)
126
+ return
127
+ end
128
+ end # module GraphvizHelper
129
+
130
+ if cmd_available? %w[dot -V]
131
+ register(GraphvizHelper)
132
+ end
133
+
134
+ end # module Webby::Helpers
135
+
136
+ # EOF
@@ -0,0 +1,65 @@
1
+ require 'erb'
2
+ require 'set'
3
+
4
+ # :stopdoc:
5
+ class ERB
6
+ module Util
7
+ HTML_ESCAPE = { '&' => '&amp;', '"' => '&quot;', '>' => '&gt;', '<' => '&lt;' }
8
+
9
+ def html_escape(s)
10
+ s.to_s.gsub(/[&\"><]/) { |special| HTML_ESCAPE[special] }
11
+ end
12
+ end
13
+ end
14
+ # :startdoc:
15
+
16
+ module Webby::Helpers
17
+
18
+ # Provides methods to generate HTML tags programmatically.
19
+ # By default, they output XHTML compliant tags.
20
+ #
21
+ module TagHelper
22
+ include ERB::Util
23
+
24
+ BOOLEAN_ATTRIBUTES = Set.new(%w(disabled readonly multiple))
25
+
26
+ # Returns an escaped version of +html+ without affecting existing escaped
27
+ # entities.
28
+ #
29
+ # ==== Examples
30
+ # escape_once("1 > 2 &amp; 3")
31
+ # # => "1 &lt; 2 &amp; 3"
32
+ #
33
+ # escape_once("&lt;&lt; Accept & Checkout")
34
+ # # => "&lt;&lt; Accept &amp; Checkout"
35
+ #
36
+ def escape_once( html )
37
+ html.to_s.gsub(/[\"><]|&(?!([a-zA-Z]+|(#\d+));)/) { |special| ERB::Util::HTML_ESCAPE[special] }
38
+ end
39
+
40
+ private
41
+
42
+ def tag_options( options, escape = true )
43
+ unless options.empty?
44
+ attrs = []
45
+ if escape
46
+ options.each do |key, value|
47
+ next if value.nil?
48
+ key = key.to_s
49
+ value = BOOLEAN_ATTRIBUTES.include?(key) ? key : escape_once(value)
50
+ attrs << %Q(#{key}="#{value}")
51
+ end
52
+ else
53
+ attrs = options.map {|key, value| %Q(#{key}="#{value}")}
54
+ end
55
+ %Q( #{attrs.sort * ' '}) unless attrs.empty?
56
+ end
57
+ end
58
+
59
+ end # module TagHelper
60
+
61
+ register(TagHelper)
62
+
63
+ end # module Webby::Helpers
64
+
65
+ # EOF