polygon 0.0.1

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.
@@ -0,0 +1,5 @@
1
+ # 0.0.1 / FIX ME
2
+
3
+ * Enhancements
4
+
5
+ * Birthday!
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'http://rubygems.org'
2
+
3
+ group :runtime do
4
+ gem "sinatra", "~> 1.3"
5
+ gem "epath", "~> 0.2.0"
6
+ gem "json", ">= 0"
7
+ gem "wlang", "~> 0.10.2"
8
+ end
9
+
10
+ group :development do
11
+ gem "rake", "~> 0.9.2"
12
+ gem "bundler", "~> 1.0"
13
+ gem "rspec", "~> 2.10"
14
+ gem "yard", "~> 0.7.2"
15
+ gem "bluecloth", "~> 2.2"
16
+ end
@@ -0,0 +1,40 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ bluecloth (2.2.0)
5
+ diff-lcs (1.1.3)
6
+ epath (0.2.0)
7
+ json (1.7.3)
8
+ rack (1.4.1)
9
+ rack-protection (1.2.0)
10
+ rack
11
+ rake (0.9.2.2)
12
+ rspec (2.10.0)
13
+ rspec-core (~> 2.10.0)
14
+ rspec-expectations (~> 2.10.0)
15
+ rspec-mocks (~> 2.10.0)
16
+ rspec-core (2.10.1)
17
+ rspec-expectations (2.10.0)
18
+ diff-lcs (~> 1.1.3)
19
+ rspec-mocks (2.10.1)
20
+ sinatra (1.3.2)
21
+ rack (~> 1.3, >= 1.3.6)
22
+ rack-protection (~> 1.2)
23
+ tilt (~> 1.3, >= 1.3.3)
24
+ tilt (1.3.3)
25
+ wlang (0.10.2)
26
+ yard (0.7.5)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ bluecloth (~> 2.2)
33
+ bundler (~> 1.0)
34
+ epath (~> 0.2.0)
35
+ json
36
+ rake (~> 0.9.2)
37
+ rspec (~> 2.10)
38
+ sinatra (~> 1.3)
39
+ wlang (~> 0.10.2)
40
+ yard (~> 0.7.2)
@@ -0,0 +1,22 @@
1
+ # The MIT Licence
2
+
3
+ Copyright (c) 2012 - Bernard Lambeau
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ polygon.gemspec
2
+ polygon.noespec
3
+ CHANGELOG.md
4
+ Gemfile
5
+ Gemfile.lock
6
+ bin/**/*
7
+ lib/**/*
8
+ LICENCE.md
9
+ Manifest.txt
10
+ Rakefile
11
+ README.md
12
+ spec/**/*
13
+ tasks/**/*
14
+ test/**/*
@@ -0,0 +1,7 @@
1
+ # Polygon
2
+
3
+ A web framework powered by sinatra for mostly static websites
4
+
5
+ ## Links
6
+
7
+ http://github.com/blambeau/polygon
@@ -0,0 +1,11 @@
1
+ # We run tests by default
2
+ task :default => :test
3
+
4
+ #
5
+ # Install all tasks found in tasks folder
6
+ #
7
+ # See .rake files there for complete documentation.
8
+ #
9
+ Dir["tasks/*.rake"].each do |taskfile|
10
+ load taskfile
11
+ end
@@ -0,0 +1,23 @@
1
+ require "polygon/version"
2
+ require "polygon/loader"
3
+ #
4
+ # A web framework powered by sinatra for mostly static websites
5
+ #
6
+ module Polygon
7
+
8
+ def default_loader
9
+ @default_loader ||= ContentLoader.new.enable_all!
10
+ end
11
+ module_function :default_loader
12
+
13
+ def default_loader=(loader)
14
+ @default_loader = loader
15
+ end
16
+ module_function :default_loader=
17
+
18
+ end # module Polygon
19
+ require 'polygon/content_loader'
20
+ require 'polygon/content'
21
+ require 'polygon/helpers'
22
+ require 'polygon/base'
23
+
@@ -0,0 +1,22 @@
1
+ module Polygon
2
+ class Base < Sinatra::Base
3
+
4
+ configure do
5
+ set :static, Proc.new { root && root/:content/:static }
6
+ set :public_folder, Proc.new { root && root/:content/:static }
7
+ set :dynamic, Proc.new { root && root/:content/:dynamic }
8
+ set :templates, Proc.new { root && root/:design/:templates }
9
+ set :views, Proc.new { root && root/:design/:templates }
10
+ enable :logging
11
+ enable :raise_errors
12
+ disable :show_exceptions
13
+ end
14
+
15
+ get '/sitemap.xml' do
16
+ content_type "application/xml"
17
+ wlang :sitemap
18
+ end
19
+
20
+ helpers Polygon::Helpers
21
+ end # Base
22
+ end # module Polygon
@@ -0,0 +1,131 @@
1
+ require 'yaml'
2
+ require 'epath'
3
+ module Polygon
4
+ class Content
5
+
6
+ # Root of the content folders
7
+ attr_reader :path
8
+
9
+ # Underlying content loader
10
+ attr_reader :loader
11
+
12
+ # Creates a Content instance
13
+ def initialize(path, loader = Polygon.default_loader)
14
+ @path = path
15
+ @loader = loader
16
+ end
17
+
18
+ def entry(path)
19
+ if path.relative?
20
+ path = @path/path
21
+ elsif path.outside?(@path)
22
+ return nil
23
+ end
24
+ Entry.new(self, path)
25
+ end
26
+
27
+ class Entry
28
+
29
+ # The parent content
30
+ attr_reader :content
31
+
32
+ # Path to the file containing this content
33
+ attr_reader :path
34
+
35
+ def initialize(content, path)
36
+ @content, @path = content, path
37
+ end
38
+
39
+ def exist?
40
+ path.exist?
41
+ end
42
+
43
+ def /(arg)
44
+ content.entry(path/arg)
45
+ end
46
+
47
+ def ==(other)
48
+ other.is_a?(Entry) and
49
+ other.content == content and
50
+ other.path == path
51
+ end
52
+
53
+ def to_s
54
+ path.to_s
55
+ end
56
+
57
+ def to_hash(with_ancestors = true)
58
+ if with_ancestors
59
+ ancestors_or_self(true).inject({}) do |h,content|
60
+ merge(h, content.data)
61
+ end
62
+ else
63
+ data
64
+ end
65
+ end
66
+
67
+ protected
68
+
69
+ def loader
70
+ content.loader
71
+ end
72
+
73
+ def extensions
74
+ loader.extensions
75
+ end
76
+
77
+ def index_files
78
+ extensions.map{|ext| "index#{ext}"}
79
+ end
80
+
81
+ def parent
82
+ @parent ||= begin
83
+ return nil unless base = self/".."
84
+ idx = -1
85
+ if index?
86
+ idx = index_files.index(path.basename.to_s) - 1
87
+ base = base/".." if idx == -1
88
+ end
89
+ base ? base/index_files[idx] : nil
90
+ end
91
+ end
92
+
93
+ def ancestors_or_self(filter = false)
94
+ res = _ancestors_or_self
95
+ filter ? res.select{|f| f.path.exist?} : res
96
+ end
97
+
98
+ def _ancestors_or_self
99
+ return [ self ] unless parent
100
+ parent.ancestors_or_self + [ self ]
101
+ end
102
+
103
+ def index?
104
+ index_files.include?(path.basename.to_s)
105
+ end
106
+
107
+ def merge(left, right)
108
+ raise "Unexpected #{left.class} vs. #{right.class}" \
109
+ unless left.class == right.class
110
+ case left
111
+ when Array
112
+ (right | left).uniq
113
+ when Hash
114
+ left.merge(right){|k,l,r|
115
+ merge(l,r)
116
+ }
117
+ else
118
+ right
119
+ end
120
+ end
121
+
122
+ def data
123
+ loader.load(path).merge({
124
+ "__path__" => path,
125
+ "__url__" => path.relative_to(content.path).to_s[0..-(path.extname.length+1)]
126
+ })
127
+ end
128
+
129
+ end # class Entry
130
+ end # class Content
131
+ end # module Polygon
@@ -0,0 +1,78 @@
1
+ module Polygon
2
+ class ContentLoader
3
+
4
+ def register(*extensions, &loader)
5
+ raise ArgumentError, "Extensions expected" if extensions.empty?
6
+ loaders << [extensions, loader]
7
+ self
8
+ end
9
+
10
+ def extensions
11
+ loaders.map(&:first).flatten
12
+ end
13
+
14
+ def load(file)
15
+ file = Path(file)
16
+ unless l = loader(file)
17
+ raise "Unable to load #{file.basename} (unrecognized extension)"
18
+ end
19
+ l.call(file)
20
+ end
21
+
22
+ ################################################################### Loaders
23
+
24
+ def enable_yaml!(*ext)
25
+ require 'yaml'
26
+ ext = [".yml", ".yaml"] if ext.empty?
27
+ register(*ext) do |f|
28
+ YAML.load(f.read)
29
+ end
30
+ end
31
+
32
+ def enable_json!(*ext)
33
+ require 'json'
34
+ ext = [".json"] if ext.empty?
35
+ register(*ext) do |f|
36
+ JSON.load(f.read)
37
+ end
38
+ end
39
+
40
+ def enable_ruby!(*ext)
41
+ ext = [".rb", ".ruby"] if ext.empty?
42
+ register(*ext) do |f|
43
+ ::Kernel.eval(f.read, TOPLEVEL_BINDING, f.to_s)
44
+ end
45
+ end
46
+
47
+ def enable_yaml_front_matter!(*ext)
48
+ ext = [".md"] if ext.empty?
49
+ register(*ext) do |f|
50
+ content = f.read
51
+ if content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
52
+ YAML::load($1).merge("content" => $')
53
+ else
54
+ {"content" => content}
55
+ end
56
+ end
57
+ end
58
+
59
+ def enable_all!
60
+ enable_yaml!
61
+ enable_json!
62
+ enable_ruby!
63
+ enable_yaml_front_matter!
64
+ end
65
+
66
+ private
67
+
68
+ def loaders
69
+ @loaders ||= []
70
+ end
71
+
72
+ def loader(file, extname = Path(file).extname)
73
+ loader = loaders.find{|ext,_| ext.include?(extname)}
74
+ loader && loader.last
75
+ end
76
+
77
+ end # class ContentLoader
78
+ end # module Polygon
@@ -0,0 +1,20 @@
1
+ module Polygon
2
+ module Helpers
3
+
4
+ def static; settings.static; end
5
+ def dynamic; settings.dynamic; end
6
+ def templates; settings.templates; end
7
+
8
+ def default_wlang_context
9
+ { "environment" => settings.environment }
10
+ end
11
+
12
+ def wlang(tpl, ctx = {})
13
+ tpl = templates/"#{tpl}.whtml" if tpl.is_a?(Symbol)
14
+ ctx = (ctx && ctx.to_hash) || {}
15
+ ctx = default_wlang_context.to_hash.merge(ctx)
16
+ WLang::file_instantiate tpl, ctx
17
+ end
18
+
19
+ end # module Helpers
20
+ end # module Polygon
@@ -0,0 +1,4 @@
1
+ require "sinatra"
2
+ require "epath"
3
+ require "json"
4
+ require "wlang"
@@ -0,0 +1,14 @@
1
+ module Polygon
2
+ module Version
3
+
4
+ MAJOR = 0
5
+ MINOR = 0
6
+ TINY = 1
7
+
8
+ def self.to_s
9
+ [ MAJOR, MINOR, TINY ].join('.')
10
+ end
11
+
12
+ end
13
+ VERSION = Version.to_s
14
+ end
@@ -0,0 +1,192 @@
1
+ # We require your library, mainly to have access to the VERSION number.
2
+ # Feel free to set $version manually.
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
4
+ require "polygon/version"
5
+ $version = Polygon::Version.to_s
6
+
7
+ #
8
+ # This is your Gem specification. Default values are provided so that your library
9
+ # should be correctly packaged given what you have described in the .noespec file.
10
+ #
11
+ Gem::Specification.new do |s|
12
+
13
+ ################################################################### ABOUT YOUR GEM
14
+
15
+ # Gem name (required)
16
+ s.name = "polygon"
17
+
18
+ # Gem version (required)
19
+ s.version = $version
20
+
21
+ # A short summary of this gem
22
+ #
23
+ # This is displayed in `gem list -d`.
24
+ s.summary = "A web framework powered by sinatra for mostly static websites"
25
+
26
+ # A long description of this gem (required)
27
+ #
28
+ # The description should be more detailed than the summary. For example,
29
+ # you might wish to copy the entire README into the description.
30
+ s.description = "Polygon provides a framework with strong separation of concerns between \nclients, developers and web designers"
31
+
32
+ # The URL of this gem home page (optional)
33
+ s.homepage = "http://github.com/blambeau/polygon"
34
+
35
+ # Gem publication date (required but auto)
36
+ #
37
+ # Today is automatically used by default, uncomment only if
38
+ # you know what you do!
39
+ #
40
+ # s.date = Time.now.strftime('%Y-%m-%d')
41
+
42
+ # The license(s) for the library. Each license must be a short name, no
43
+ # more than 64 characters.
44
+ #
45
+ # s.licences = %w{}
46
+
47
+ # The rubyforge project this gem lives under (optional)
48
+ #
49
+ # s.rubyforge_project = nil
50
+
51
+ ################################################################### ABOUT THE AUTHORS
52
+
53
+ # The list of author names who wrote this gem.
54
+ #
55
+ # If you are providing multiple authors and multiple emails they should be
56
+ # in the same order.
57
+ #
58
+ s.authors = ["Bernard Lambeau"]
59
+
60
+ # Contact emails for this gem
61
+ #
62
+ # If you are providing multiple authors and multiple emails they should be
63
+ # in the same order.
64
+ #
65
+ # NOTE: Somewhat strangly this attribute is always singular!
66
+ # Don't replace by s.emails = ...
67
+ s.email = ["blambeau@gmail.com"]
68
+
69
+ ################################################################### PATHS, FILES, BINARIES
70
+
71
+ # Paths in the gem to add to $LOAD_PATH when this gem is
72
+ # activated (required).
73
+ #
74
+ # The default 'lib' is typically sufficient.
75
+ s.require_paths = ["lib"]
76
+
77
+ # Files included in this gem.
78
+ #
79
+ # By default, we take all files included in the Manifest.txt file on root
80
+ # of the project. Entries of the manifest are interpreted as Dir[...]
81
+ # patterns so that lazy people may use wilcards like lib/**/*
82
+ #
83
+ here = File.expand_path(File.dirname(__FILE__))
84
+ s.files = File.readlines(File.join(here, 'Manifest.txt')).
85
+ inject([]){|files, pattern| files + Dir[File.join(here, pattern.strip)]}.
86
+ collect{|x| x[(1+here.size)..-1]}
87
+
88
+ # Test files included in this gem.
89
+ #
90
+ s.test_files = Dir["test/**/*"] + Dir["spec/**/*"]
91
+
92
+ # The path in the gem for executable scripts (optional)
93
+ #
94
+ s.bindir = "bin"
95
+
96
+ # Executables included in the gem.
97
+ #
98
+ s.executables = (Dir["bin/*"]).collect{|f| File.basename(f)}
99
+
100
+ ################################################################### REQUIREMENTS & INSTALL
101
+ # Remember the gem version requirements operators and schemes:
102
+ # = Equals version
103
+ # != Not equal to version
104
+ # > Greater than version
105
+ # < Less than version
106
+ # >= Greater than or equal to
107
+ # <= Less than or equal to
108
+ # ~> Approximately greater than
109
+ #
110
+ # Don't forget to have a look at http://lmgtfy.com/?q=Ruby+Versioning+Policies
111
+ # for setting your gem version.
112
+ #
113
+ # For your requirements to other gems, remember that
114
+ # ">= 2.2.0" (optimistic: specify minimal version)
115
+ # ">= 2.2.0", "< 3.0" (pessimistic: not greater than the next major)
116
+ # "~> 2.2" (shortcut for ">= 2.2.0", "< 3.0")
117
+ # "~> 2.2.0" (shortcut for ">= 2.2.0", "< 2.3.0")
118
+ #
119
+
120
+ #
121
+ # One call to add_dependency('gem_name', 'gem version requirement') for each
122
+ # runtime dependency. These gems will be installed with your gem.
123
+ # One call to add_development_dependency('gem_name', 'gem version requirement')
124
+ # for each development dependency. These gems are required for developers
125
+ #
126
+ s.add_development_dependency("rake", "~> 0.9.2")
127
+ s.add_development_dependency("bundler", "~> 1.0")
128
+ s.add_development_dependency("rspec", "~> 2.10")
129
+ s.add_development_dependency("yard", "~> 0.7.2")
130
+ s.add_development_dependency("bluecloth", "~> 2.2")
131
+ s.add_dependency("sinatra", "~> 1.3")
132
+ s.add_dependency("epath", "~> 0.2.0")
133
+ s.add_dependency("json", ">= 0")
134
+ s.add_dependency("wlang", "~> 0.10.2")
135
+
136
+ # The version of ruby required by this gem
137
+ #
138
+ # Uncomment and set this if your gem requires specific ruby versions.
139
+ #
140
+ # s.required_ruby_version = ">= 0"
141
+
142
+ # The RubyGems version required by this gem
143
+ #
144
+ # s.required_rubygems_version = ">= 0"
145
+
146
+ # The platform this gem runs on. See Gem::Platform for details.
147
+ #
148
+ # s.platform = nil
149
+
150
+ # Extensions to build when installing the gem.
151
+ #
152
+ # Valid types of extensions are extconf.rb files, configure scripts
153
+ # and rakefiles or mkrf_conf files.
154
+ #
155
+ s.extensions = []
156
+
157
+ # External (to RubyGems) requirements that must be met for this gem to work.
158
+ # It’s simply information for the user.
159
+ #
160
+ s.requirements = nil
161
+
162
+ # A message that gets displayed after the gem is installed
163
+ #
164
+ # Uncomment and set this if you want to say something to the user
165
+ # after gem installation
166
+ #
167
+ s.post_install_message = nil
168
+
169
+ ################################################################### SECURITY
170
+
171
+ # The key used to sign this gem. See Gem::Security for details.
172
+ #
173
+ # s.signing_key = nil
174
+
175
+ # The certificate chain used to sign this gem. See Gem::Security for
176
+ # details.
177
+ #
178
+ # s.cert_chain = []
179
+
180
+ ################################################################### RDOC
181
+
182
+ # An ARGV style array of options to RDoc
183
+ #
184
+ # See 'rdoc --help' about this
185
+ #
186
+ s.rdoc_options = []
187
+
188
+ # Extra files to add to RDoc such as README
189
+ #
190
+ s.extra_rdoc_files = Dir["README.md"] + Dir["CHANGELOG.md"] + Dir["LICENCE.md"]
191
+
192
+ end