bluemark-smallcage 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. data/History.txt +48 -0
  2. data/License.txt +20 -0
  3. data/README.txt +1 -0
  4. data/Rakefile +140 -0
  5. data/bin/smc +16 -0
  6. data/lib/smallcage.rb +18 -0
  7. data/lib/smallcage/application.rb +164 -0
  8. data/lib/smallcage/commands/auto.rb +158 -0
  9. data/lib/smallcage/commands/base.rb +19 -0
  10. data/lib/smallcage/commands/clean.rb +32 -0
  11. data/lib/smallcage/commands/export.rb +41 -0
  12. data/lib/smallcage/commands/import.rb +217 -0
  13. data/lib/smallcage/commands/manifest.rb +39 -0
  14. data/lib/smallcage/commands/server.rb +15 -0
  15. data/lib/smallcage/commands/update.rb +121 -0
  16. data/lib/smallcage/document_path.rb +46 -0
  17. data/lib/smallcage/erb_base.rb +16 -0
  18. data/lib/smallcage/http_server.rb +66 -0
  19. data/lib/smallcage/loader.rb +278 -0
  20. data/lib/smallcage/misc.rb +13 -0
  21. data/lib/smallcage/renderer.rb +19 -0
  22. data/lib/smallcage/resources/Manifest.erb +19 -0
  23. data/lib/smallcage/resources/auto.html +119 -0
  24. data/lib/smallcage/runner.rb +51 -0
  25. data/lib/smallcage/version.rb +9 -0
  26. data/project/base/_smc/helpers/base_helper.rb +41 -0
  27. data/project/base/_smc/helpers/site_helper.rb +5 -0
  28. data/project/base/_smc/templates/default.rhtml +5 -0
  29. data/project/base/_smc/templates/footer.rhtml +0 -0
  30. data/project/base/_smc/templates/header.rhtml +0 -0
  31. data/project/bluecloth/_smc/helpers/blue_cloth_helper.rb +10 -0
  32. data/project/bluecloth/_smc/templates/markdown.rhtml +5 -0
  33. data/project/lang/_smc/helpers/lang_helper.rb +19 -0
  34. data/project/lang/_smc/templates/other_lang.rhtml +6 -0
  35. data/project/news/_smc/helpers/news_helper.rb +36 -0
  36. data/project/nkf/_smc/filters/filters.yml +3 -0
  37. data/project/nkf/_smc/filters/nkf_filter.rb +15 -0
  38. data/project/rake/_smc/Rakefile +68 -0
  39. data/project/redcloth/_smc/helpers/red_cloth_helper.rb +10 -0
  40. data/project/redcloth/_smc/templates/textile.rhtml +5 -0
  41. data/project/relpath/_smc/filters/filters.yml +2 -0
  42. data/project/relpath/_smc/filters/relpath_filter.rb +13 -0
  43. data/project/standard/_dir.smc +2 -0
  44. data/project/standard/_smc/helpers/base_helper.rb +34 -0
  45. data/project/standard/_smc/helpers/menu_helper.rb +23 -0
  46. data/project/standard/_smc/templates/default.rhtml +5 -0
  47. data/project/standard/_smc/templates/footer.rhtml +13 -0
  48. data/project/standard/_smc/templates/header.rhtml +37 -0
  49. data/project/standard/_smc/templates/menu.rhtml +6 -0
  50. data/project/standard/_smc/templates/redirect.rhtml +13 -0
  51. data/project/standard/_smc/templates/sidebar.rhtml +7 -0
  52. data/project/standard/_smc/templates/topic_path.rhtml +6 -0
  53. data/project/standard/common/css/default.css +145 -0
  54. data/project/standard/common/css/print.css +0 -0
  55. data/project/standard/index.html.smc +3 -0
  56. data/project/standard/sample/_dir.smc +1 -0
  57. data/project/standard/sample/index.html.smc +7 -0
  58. data/project/standard/sample/redirect.html.smc +2 -0
  59. data/project/standard/sample/sub/_dir.smc +1 -0
  60. data/project/standard/sample/sub/contents.html.smc +3 -0
  61. data/project/standard/sample/sub/index.html.smc +7 -0
  62. data/spec/data/htdocs1/_dir.smc +0 -0
  63. data/spec/data/htdocs1/a/b/c/index.html.smc +6 -0
  64. data/spec/data/htdocs2/_smc/templates/dummy.rhtml +0 -0
  65. data/spec/data/htdocs2/a/b/c/test.html +1 -0
  66. data/spec/data/htdocs2/a/b/test.html +1 -0
  67. data/spec/data/htdocs2/a/test.html.smc +2 -0
  68. data/spec/document_path_spec.rb +42 -0
  69. data/spec/export_spec.rb +45 -0
  70. data/spec/import_spec.rb +20 -0
  71. data/spec/loader_spec.rb +55 -0
  72. data/spec/manifest_spec.rb +39 -0
  73. data/spec/misc_spec.rb +25 -0
  74. data/spec/smallcage_spec.rb +40 -0
  75. data/spec/spec.opts +1 -0
  76. data/spec/spec_helper.rb +9 -0
  77. data/test/test_helper.rb +2 -0
  78. data/test/test_smallcage.rb +11 -0
  79. metadata +193 -0
@@ -0,0 +1,46 @@
1
+ module SmallCage
2
+ class DocumentPath
3
+
4
+ attr_reader :root, :uri, :path
5
+
6
+ def initialize(root, path)
7
+ @root = Pathname.new(root).realpath;
8
+
9
+ @path = Pathname.new(path)
10
+ if @path.exist?
11
+ @path = @path.realpath
12
+ else
13
+ @path = @path.cleanpath
14
+ end
15
+
16
+ if @path.to_s[0...@root.to_s.length] != @root.to_s
17
+ raise "Illegal path: #{path.to_s}"
18
+ end
19
+
20
+ if @path == @root
21
+ @uri = "/"
22
+ else
23
+ @uri = @path.to_s[@root.to_s.length .. -1]
24
+ end
25
+ end
26
+
27
+ def smc?
28
+ return @path.extname == ".smc"
29
+ end
30
+
31
+ def outfile
32
+ return nil unless smc?
33
+ return self.class.new(@root, @path.to_s[0 .. -5])
34
+ end
35
+
36
+ def outuri
37
+ return nil unless smc?
38
+ return uri[0 .. -5]
39
+ end
40
+
41
+ def self.to_uri(root, path)
42
+ return self.new(root,path).uri
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+
2
+ class SmallCage::ErbBase
3
+ def initialize(loader, renderer, obj)
4
+ @loader, @renderer, @obj = loader, renderer, obj
5
+ end
6
+
7
+ def method_missing(name)
8
+ n = name.to_s
9
+
10
+ return @obj[n] unless @obj[n].nil?
11
+ return @obj["strings"][0] if n == "body" && ! @obj["strings"][0].nil?
12
+
13
+ # render if template file exists. or return nil.
14
+ return @renderer.render(name, @obj)
15
+ end
16
+ end
@@ -0,0 +1,66 @@
1
+ require 'webrick'
2
+
3
+ module SmallCage
4
+ class HTTPServer
5
+
6
+ def initialize(document_root, port)
7
+ # logger = WEBrick::Log.new(nil, 1)
8
+ @server = WEBrick::HTTPServer.new({
9
+ :DocumentRoot => document_root,
10
+ :Port => port,
11
+ :AccessLog => []
12
+ })
13
+
14
+ WEBrick::HTTPServlet::FileHandler.remove_handler("cgi")
15
+ WEBrick::HTTPServlet::FileHandler.remove_handler("rhtml")
16
+
17
+ @server.mount("/_smc/update_uri", UpdateUriServlet)
18
+ @server.mount("/_smc/auto", AutoServlet)
19
+ end
20
+
21
+ def start
22
+ @server.start
23
+ end
24
+
25
+ def shutdown
26
+ @server.shutdown
27
+ end
28
+
29
+ def updated_uri=(uri)
30
+ UpdateUriServlet.uri = uri
31
+ end
32
+
33
+ def reload
34
+ UpdateUriServlet.uri = ":reload"
35
+ end
36
+ end
37
+
38
+
39
+ class UpdateUriServlet < WEBrick::HTTPServlet::AbstractServlet
40
+ @@uri = "/index.html"
41
+ @@update_time = ""
42
+
43
+ def do_GET(req, res)
44
+ res['content-type'] = "text/plain"
45
+ res.body = @@uri + "\n" + @@update_time
46
+ end
47
+
48
+ def self.uri=(uri)
49
+ @@uri = uri
50
+ update_time
51
+ end
52
+
53
+ def self.update_time
54
+ @@update_time = Time.now.to_s
55
+ end
56
+
57
+ end
58
+
59
+ class AutoServlet < WEBrick::HTTPServlet::AbstractServlet
60
+ def do_GET(req, res)
61
+ res['content-type'] = "text/html"
62
+ html = File.dirname(__FILE__) + "/resources/auto.html"
63
+ res.body = File.read(html)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,278 @@
1
+ module SmallCage
2
+ class Loader
3
+ DEFAULT_TEMPLATE = "default"
4
+ DIR_PROP_FILE = "_dir.smc"
5
+ MAX_DEPTH = 100
6
+
7
+ attr_reader :root, :target, :erb_base
8
+
9
+ def initialize(target)
10
+ target = Pathname.new(target.to_s.strip.gsub(%r{(.+)/$}, '\1'))
11
+ target = real_target(target)
12
+
13
+ @target = target # absolute
14
+ @root = self.class.find_root(target) # absolute
15
+ @templates_dir = @root + "_smc/templates"
16
+ @helpers_dir = @root + "_smc/helpers"
17
+ @filters_dir = @root + "_smc/filters"
18
+ @erb_base = load_erb_base
19
+ @filters = load_filters
20
+ end
21
+
22
+ # return root dir Pathname object.
23
+ def self.find_root(path, depth = MAX_DEPTH)
24
+ unless path.exist?
25
+ raise "Not found: " + path.to_s
26
+ end
27
+ d = path.realpath
28
+
29
+ if d.file?
30
+ d = d.parent
31
+ end
32
+
33
+ i = 0
34
+ loop do
35
+ if d.join("_smc").directory?
36
+ return d
37
+ end
38
+ break if d.root?
39
+ d = d.parent
40
+
41
+ i += 1
42
+ break if depth <= i
43
+ end
44
+
45
+ raise "Root not found: " + path
46
+ end
47
+
48
+ def load(path)
49
+ unless path.exist?
50
+ raise "Not found: " + path.to_s
51
+ end
52
+
53
+ docpath = SmallCage::DocumentPath.new(@root, path)
54
+
55
+ result = {}
56
+ if path.file?
57
+ unless docpath.smc?
58
+ raise "Path is not smc file: " + docpath.to_s
59
+ end
60
+
61
+ path_smc = docpath.path
62
+ path_out = docpath.outfile.path
63
+ uri_smc = docpath.uri
64
+ uri_out = docpath.outuri
65
+ source_path = path_smc
66
+
67
+ result["dirs"] = load_dirs(path)
68
+ result["template"] = DEFAULT_TEMPLATE
69
+ else # directory
70
+ path_smc = nil
71
+ path_out = path
72
+ uri_smc = nil
73
+ uri_out = docpath.uri
74
+ uri_out += "/" unless uri_out =~ %r{/$}
75
+ source_path = path + DIR_PROP_FILE
76
+
77
+ if source_path.file?
78
+ path_smc = source_path
79
+ uri_smc = SmallCage::DocumentPath.to_uri(@root, source_path)
80
+ end
81
+ end
82
+
83
+ add_smc_method(path_out, path_smc)
84
+ add_smc_method(uri_out, uri_smc)
85
+
86
+ result["path"] = path_out
87
+ result["uri"] = uri_out
88
+ result["arrays"] = []
89
+ result["strings"] = []
90
+
91
+ # target is directory and _dir.smc is not exist.
92
+ return result unless source_path.exist?
93
+
94
+ source = source_path.read
95
+ return result if source.strip.empty?
96
+
97
+ begin
98
+ obj = YAML.load_stream(source)
99
+ return result if obj.nil?
100
+ rescue => e
101
+ raise "Can't load file: #{source_path} / #{e}"
102
+ end
103
+
104
+ obj.documents.each do |o|
105
+ if o.is_a? Hash
106
+ result = result.merge(o)
107
+ elsif o.is_a? Array
108
+ result["arrays"] << o
109
+ else
110
+ result["strings"] << o.to_s
111
+ end
112
+ end
113
+
114
+ return result
115
+ end
116
+
117
+ def load_dirs(path)
118
+ result = []
119
+ loop do
120
+ path = path.parent
121
+ result.unshift load(path)
122
+ break if path.join("_smc").directory?
123
+ raise "Root directory not found!" if path.root?
124
+ end
125
+ return result
126
+ end
127
+
128
+ def template_path(name)
129
+ result = @templates_dir + "#{name}.rhtml"
130
+ return nil unless result.file?
131
+ return result
132
+ end
133
+
134
+ def each_smc_obj
135
+ each_smc_file do |path|
136
+ next if path.directory?
137
+ next if path.basename.to_s == DIR_PROP_FILE
138
+ obj = load(path)
139
+ yield obj
140
+ end
141
+ end
142
+
143
+ def each_smc_file
144
+ if @target.directory?
145
+ p = Pathname.new(@target)
146
+ Dir.chdir(@target) do
147
+ Dir.glob("**/*.smc") do |f|
148
+ yield p + f
149
+ end
150
+ end
151
+ else
152
+ yield @target
153
+ end
154
+ end
155
+
156
+ def each_not_smc_file
157
+ if @target.directory?
158
+ p = Pathname.new(@target)
159
+ Dir.chdir(@target) do
160
+ Dir.glob("**/*") do |f|
161
+ f = p + f
162
+ next if f.directory?
163
+ next if f.to_s =~ %r{/_smc/}
164
+ next if f.to_s =~ %r{\.smc$}
165
+ yield SmallCage::DocumentPath.new(@root, p + f)
166
+ end
167
+ end
168
+ else
169
+ return if @target.to_s =~ %r{/_smc/}
170
+ return if @target.to_s =~ %r{\.smc$}
171
+ yield SmallCage::DocumentPath.new(@root, @target)
172
+ end
173
+ end
174
+
175
+ def real_target(target)
176
+ return target.realpath if target.directory?
177
+ return target.realpath if target.file? and target.to_s =~ /\.smc$/
178
+
179
+ tmp = Pathname.new(target.to_s + ".smc")
180
+ return tmp.realpath if tmp.file?
181
+
182
+ raise "Target not found: " + target.to_s
183
+ end
184
+ private :real_target
185
+
186
+
187
+ def load_erb_base
188
+ result = Class.new(SmallCage::ErbBase)
189
+ class << result
190
+ def include_helpers(anon_module, mod_names)
191
+ smc_module = anon_module.const_get("SmallCage")
192
+ mod_names.each do |name|
193
+ helper_module = smc_module.const_get(name)
194
+ include helper_module
195
+ end
196
+ end
197
+ end
198
+
199
+ helpers = load_anonymous(@helpers_dir, %r{([^/]+_helper)\.rb$})
200
+ result.include_helpers(helpers[:module], helpers[:names])
201
+
202
+ return result
203
+ end
204
+ private :load_erb_base
205
+
206
+ def load_anonymous(dir, rex)
207
+ module_names = []
208
+
209
+ mod = Module.new
210
+ Dir.entries(dir).sort.each do |h|
211
+ next unless h =~ rex
212
+
213
+ # create anonymous module.
214
+ module_name = $1.camelize
215
+
216
+ src = File.read("#{dir}/#{h}")
217
+ begin
218
+ mod.module_eval(src, "#{dir}/#{h}")
219
+ rescue => ex
220
+ puts ex.to_s # TODO show error
221
+ load("#{dir}/#{h}", true) # try to know error line number.
222
+ raise "Can't load #{dir}/#{h} / line# unknown"
223
+ end
224
+ module_names << module_name
225
+ end
226
+
227
+ return { :module => mod, :names => module_names }
228
+ end
229
+ private :load_anonymous
230
+
231
+ def filters(name)
232
+ if @filters[name].nil?
233
+ return []
234
+ end
235
+ return @filters[name]
236
+ end
237
+
238
+ def load_filters
239
+ result = {}
240
+ return {} unless @filters_dir.directory?
241
+
242
+ filters = load_anonymous(@filters_dir, %r{([^/]+_filter)\.rb$})
243
+
244
+ config = load_filters_config
245
+ config.each do |filter_type,filter_list|
246
+ result[filter_type] = []
247
+ smc_module = filters[:module].const_get("SmallCage")
248
+ filter_list.each do |fc|
249
+ fc = { "name" => fc } if fc.is_a? String
250
+ filter_class = smc_module.const_get(fc["name"].camelize)
251
+ result[filter_type] << filter_class.new(fc)
252
+ end
253
+ end
254
+ return result
255
+ end
256
+ private :load_filters
257
+
258
+ def load_filters_config
259
+ path = @filters_dir.join("filters.yml")
260
+ return {} unless path.file?
261
+ return YAML.load(path.read())
262
+ end
263
+ private :load_filters_config
264
+
265
+ def add_smc_method(obj, value)
266
+ obj.instance_eval do
267
+ @__smallcage ||= {}
268
+ @__smallcage[:smc] = value
269
+ end
270
+
271
+ def obj.smc
272
+ return @__smallcage.nil? ? nil : @__smallcage[:smc]
273
+ end
274
+ end
275
+ private :add_smc_method
276
+
277
+ end
278
+ end
@@ -0,0 +1,13 @@
1
+
2
+ # From active-support/inflector.rb
3
+ class String
4
+ def camelize(first_letter_in_uppercase = true)
5
+ s = self
6
+ if first_letter_in_uppercase
7
+ s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
8
+ else
9
+ s[0..0] + s.camelize[1..-1]
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,19 @@
1
+ class SmallCage::Renderer
2
+
3
+ def initialize(loader)
4
+ @loader = loader
5
+ end
6
+
7
+ def render(name, obj)
8
+ path = @loader.template_path(name)
9
+ return nil if path.nil?
10
+ return render_string(path.read, obj)
11
+ end
12
+
13
+ def render_string(str, obj)
14
+ erb_class = ERB.new(str, nil, '-').def_class(@loader.erb_base, "erb")
15
+ result = erb_class.new(@loader, self, obj).erb
16
+ return result
17
+ end
18
+
19
+ end
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+ <title>SmallCage Project Files</title>
7
+ </head>
8
+ <body>
9
+
10
+ <h1>SmallCage Project Files</h1>
11
+
12
+ <ul class="files">
13
+ <%- entries.each do |e| -%>
14
+ <li><a href="<%= e %>"><%= e %></a></li>
15
+ <%- end -%>
16
+ </ul>
17
+
18
+ </body>
19
+ </html>