laydown 0.4.0 → 0.5.0

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.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 jbe
1
+ Copyright (c) 2011 jbe
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -14,32 +14,49 @@
14
14
  # | | | oo |
15
15
  #'''''''''''''''''''''''''''''******
16
16
 
17
- # $ gem install laydown
17
+ Bored of writing the same html boilerplate every time you make a new app?
18
18
 
19
- Laydown is a simple template language for defining quick HTML5 layouts in Ruby. Never write the same old boilerplate again.
19
+ How about something like this?
20
+
21
+ # $ gem install laydown
22
+
23
+  
20
24
 
21
25
  require 'laydown'
22
26
 
23
- layout = Laydown.new do |_|
24
- _.charset 'some crazy charset'
25
- _.title 'A man in a cave'
26
- _.description 'A man is sitting in a cave.'
27
- _.keywords 'man, cave, mystery', @keywords
28
- _.favicon '/maninacave.png'
29
- _.css '/maninacave/style.css'
30
- _.css @css, '/site.css'
31
- _.js @js
32
- _.inline_js 'alert("Grrr");'
33
- _.head '<meta generator="FlushFlox Super Deluxe">'
34
- _.ga_code 'UA-8079526-5' # google analytics
35
- _.body_class @body_class
36
- end
37
-
38
- @css = 'somesheet.css'
39
- @body_class = 'front'
40
-
41
- layout.render(self) { '<p>this comes in the body</p>' }
27
+ layout = Laydown.new(
28
+ charset: 'utf-8' # default
29
+ title: 'A man in a #{@where}',
30
+ description: 'Very interesting',
31
+ favicon: 'pill.png',
32
+ keywords: 'man, #{@keywords}',
33
+
34
+ css: ['site.css', '#{@css}'],
35
+ js: ['app.js', '#{@js}'],
36
+ inline_js: ['alert("#{msg}");'],
37
+
38
+ head: '<meta soundtrack="Piazzolla">',
39
+ body: '#{yield}', # default
40
+ body_class: 'dark',
41
+ ga_code: 'ga-some-number'
42
+ )
43
+
44
+ # ----------------------------
45
+
46
+ @where = 'cave'
47
+ @keywords = 'cave, interesting'
48
+ @css = 'somesheet.css'
49
+
50
+ layout.render(self, :msg => 'hello') { '<p>body text</p>' }
42
51
  # => your html5 layout
43
52
 
44
- The block given to `Laydown.new` will be evaluated in the context passed to the `render` method.
53
+ ### Features
54
+
55
+ * Fast
56
+ * Small footprint
57
+ * Built on Temple and Tilt
58
+
59
+ ### Copyright
45
60
 
61
+ Copyright (c) 2011 Jostein Berre Eliassen.
62
+ See LICENCE for details. (MIT licence)
data/Rakefile CHANGED
@@ -5,13 +5,13 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "laydown"
8
- gem.summary = %Q{Pure Ruby HTML5 layout DSL for microframeworks.}
9
- gem.description = %Q{Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those of us who has written basically the same html head 200 times and feels like minimalism.}
8
+ gem.summary = %Q{Make HTML5 layouts quickly with plain Ruby.}
9
+ gem.description = %Q{Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those who has written the same layout too many times.}
10
10
  gem.email = "post@jostein.be"
11
11
  gem.homepage = "http://github.com/jbe/laydown"
12
12
  gem.authors = ["jbe"]
13
- gem.add_dependency "backports" #, ">= 0"
14
- gem.add_development_dependency "tenjin", ">= 0"
13
+ gem.add_dependency "temple" #, ">= 0"
14
+ gem.add_development_dependency "slim", ">= 0"
15
15
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
16
  end
17
17
  Jeweler::GemcutterTasks.new
@@ -20,25 +20,15 @@ rescue LoadError
20
20
  end
21
21
 
22
22
  namespace :build do
23
- desc 'Builds Tenjin templates'
23
+ desc 'Builds slim template'
24
24
  task :template do
25
+ require 'slim'
26
+ src = File.read('template.slim')
27
+ engine = Slim::Engine.new()
28
+ compiled = engine.compile(src)
25
29
 
26
- require 'haml'
27
- src = File.read('template/default.haml')
28
- compiled = Haml::Engine.new(src).precompiled
29
- File.open('lib/laydown/template.rb', 'w') do |f|
30
- f.write <<-RUBY
31
- require 'haml'
32
- #require 'haml/helpers'
33
- #require 'haml/util'
34
- #require 'haml/buffer'
35
- extend Haml::Helpers
36
- _hamlout = @haml_buffer = Haml::Buffer.new(@haml_buffer)
37
- RUBY
38
- f.write(compiled)
39
- f.write "@haml_buffer = @haml_buffer.upper"
30
+ File.open('lib/template.rb', 'w') do |f|
31
+ f.write compiled
40
32
  end
41
-
42
- #sh 'rbtenjin -s templates/default_layout.tenjin.html > lib/templates/default_layout.rb'
43
33
  end
44
34
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.5.0
data/laydown.gemspec CHANGED
@@ -5,12 +5,12 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{laydown}
8
- s.version = "0.4.0"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["jbe"]
12
- s.date = %q{2011-02-03}
13
- s.description = %q{Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those of us who has written basically the same html head 200 times and feels like minimalism.}
12
+ s.date = %q{2011-02-20}
13
+ s.description = %q{Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those who has written the same layout too many times.}
14
14
  s.email = %q{post@jostein.be}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
@@ -25,12 +25,14 @@ Gem::Specification.new do |s|
25
25
  "VERSION",
26
26
  "laydown.gemspec",
27
27
  "lib/laydown.rb",
28
- "spec/laydown_spec.rb"
28
+ "lib/template.rb",
29
+ "spec/laydown_spec.rb",
30
+ "template.slim"
29
31
  ]
30
32
  s.homepage = %q{http://github.com/jbe/laydown}
31
33
  s.require_paths = ["lib"]
32
34
  s.rubygems_version = %q{1.3.7}
33
- s.summary = %q{Pure Ruby HTML5 layout DSL for microframeworks.}
35
+ s.summary = %q{Make HTML5 layouts quickly with plain Ruby.}
34
36
  s.test_files = [
35
37
  "spec/laydown_spec.rb"
36
38
  ]
@@ -40,15 +42,15 @@ Gem::Specification.new do |s|
40
42
  s.specification_version = 3
41
43
 
42
44
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
- s.add_runtime_dependency(%q<backports>, [">= 0"])
44
- s.add_development_dependency(%q<tenjin>, [">= 0"])
45
+ s.add_runtime_dependency(%q<temple>, [">= 0"])
46
+ s.add_development_dependency(%q<slim>, [">= 0"])
45
47
  else
46
- s.add_dependency(%q<backports>, [">= 0"])
47
- s.add_dependency(%q<tenjin>, [">= 0"])
48
+ s.add_dependency(%q<temple>, [">= 0"])
49
+ s.add_dependency(%q<slim>, [">= 0"])
48
50
  end
49
51
  else
50
- s.add_dependency(%q<backports>, [">= 0"])
51
- s.add_dependency(%q<tenjin>, [">= 0"])
52
+ s.add_dependency(%q<temple>, [">= 0"])
53
+ s.add_dependency(%q<slim>, [">= 0"])
52
54
  end
53
55
  end
54
56
 
data/lib/laydown.rb CHANGED
@@ -1,131 +1,88 @@
1
1
 
2
- require 'backports'
2
+ require 'tilt'
3
+ require 'temple/utils'
3
4
 
4
5
 
5
6
  module Laydown
6
- TOPOBJECT = defined?(BasicObject) ? BasicObject : Object
7
7
 
8
- def self.new(&blk)
9
- Template.new(&blk)
10
- end
11
-
12
- class Template
13
- def initialize(&blk)
14
- @layout = blk
8
+ DEFAULT_TEMPLATE = {
9
+ :charset => 'utf-8',
10
+ :title => nil,
11
+ :description => nil,
12
+ :favicon => nil,
13
+ :keywords => nil,
14
+ :css => [],
15
+ :js => [],
16
+ :inline_js => [],
17
+ :head => [],
18
+ :body_class => nil,
19
+ :body => '#{yield}',
20
+ :ga_code => nil
21
+ }
22
+
23
+ def self.compile(template={})
24
+
25
+ template = DEFAULT_TEMPLATE.merge(template)
26
+
27
+ [:charset, :title, :description, :favicon,
28
+ :keywords, :body_class, :body, :ga_code
29
+ ].each do |k|
30
+ template[k] = case template[k]
31
+ when Array then template[k].join(template[k] == :keywords ? ', ' : '')
32
+ when String then template[k]
33
+ else template[k].to_s
34
+ end
15
35
  end
16
36
 
17
- def render(scope=Object.new, &blk)
18
- dsl = ::Laydown::DSL.new
19
- scope.instance_exec(dsl, &@layout)
20
- Renderer.new(dsl._captured_values, &blk).render
37
+ [:css, :js, :inline_js, :head].each do |k|
38
+ template[k] = Array(template[k]).flatten.compact
21
39
  end
22
- end
23
-
24
- class DSL
25
- TARGETS = %w{
26
- charset lang title description favicon keywords css js
27
- inline_js head body ga_code body_class
28
- }
29
40
 
30
- attr_reader :_captured_values
31
-
32
- def initialize
33
- @_captured_values = Hash.new { [] }
34
- end
35
-
36
- def _laydown(name, *values)
37
- @_captured_values[name] += values
41
+ compiled = read_raw_template.gsub(/data\[:([a-zA-Z0-9_]+)\]/) do |m|
42
+ val = template[:"#{$1}"]
43
+ case val
44
+ when String then interpolatize(val)
45
+ when nil then 'nil'
46
+ when Array then interpolatize(
47
+ val.map {|v| v.to_s }
48
+ )
49
+ else val.to_s
50
+ end
38
51
  end
39
52
 
40
- TARGETS.each do |name|
41
- class_eval <<-RUBY
42
- def #{name}(*a); _laydown('#{name}', *a); end
43
- RUBY
44
- end
53
+ puts compiled
54
+ compiled
45
55
  end
46
56
 
47
- class Renderer
48
-
49
- def initialize(v)
50
-
51
- @charset = v['charset'].first || 'utf-8'
52
- @lang = v['lang'].first
53
- @title = v['title'].compact.join(' &ndash; ')
54
- @favicon = v['favicon'].first
55
- @description = v['description'].compact.join(' ') if v['description']
56
- @keywords = v['keywords'].compact.join(', ') if v['keywords']
57
- @css = v['css'].compact
58
- @js = v['js'].compact
59
- @inline_js = v['inline_js'].compact
60
- @head = v['head'].compact.join("\n")
61
- @ga_code = v['ga_code'].first
62
- @body_class = v['body_class'].compact.join(' ') if v['body_class']
63
- @body = [block_given? ? yield : nil, v['body']].
64
- flatten.compact.join("\n")
65
- end
57
+ def self.new(hsh={})
58
+ Template.new(hsh)
59
+ end
66
60
 
67
- def render
68
- "<!DOCTYPE html>\n" +
69
- _(:html, {:lang => @lang},
70
- _(:head, {},
71
- _(:meta, {:charset => @charset}) +
72
- _(:title, {}, @title) +
73
- (@favicon ?
74
- _(:link, {:rel => 'shortcut icon', :href => @favicon}) : '') +
75
- (@description ?
76
- _(:meta, {:description => @description}) : '') +
77
- (@keywords ?
78
- _(:meta, {:keywords => @keywords}) : '') +
79
- @css.map do |url|
80
- _(:link, {:rel => :stylesheet, :type => 'text/css', :href => url})
81
- end.join +
82
- @js.map do |url|
83
- _(:script, {:type => 'text/javascript', :src => url}, '')
84
- end.join +
85
- @inline_js.map do |code|
86
- _(:script, {:type => 'text/javascript'}, code)
87
- end.join +
88
- (@ga_code ? google_analytics_js : '') +
89
- @head
90
- ) +
91
- _(:body, {:class => @body_class},
92
- @body
93
- )
94
- )
95
- end
61
+ def self.read_raw_template
62
+ File.read(File.join(
63
+ File.dirname(__FILE__), 'template.rb'
64
+ ))
65
+ end
96
66
 
67
+ def self.interpolatize(obj)
68
+ puts obj
69
+ obj.inspect.gsub(/\\#\{/, '#{')
70
+ end
97
71
 
98
- # html helpers
72
+ class Template < Tilt::Template
99
73
 
100
- def _(name, props={}, contents=nil)
101
- tag_str = name.to_s + prop_str(props)
102
- if contents
103
- "<#{tag_str}>\n#{contents}\n</#{name}>\n"
104
- else
105
- "<#{tag_str}/>\n"
106
- end
74
+ def initialize(hsh)
75
+ super(nil, 1, hsh) { '' } # tilt hack
107
76
  end
108
77
 
109
- def prop_str(hsh)
110
- return '' if hsh.values.compact.empty?
111
- ' ' + hsh.map do |k,v|
112
- "#{k.to_s}='#{v.to_s}'" if v
113
- end.compact.join(' ')
78
+ def prepare
79
+ @src = Laydown.compile(options)
114
80
  end
115
81
 
116
- def google_analytics_js
117
- <<-JS
118
- var _gaq = _gaq || [];
119
- _gaq.push(['_setAccount', '#{@ga_code}']);
120
- _gaq.push(['_trackPageview']);
121
- (function() {
122
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
123
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
124
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
125
- })();
126
- JS
82
+ def precompiled_template(locals)
83
+ @src
127
84
  end
128
-
129
85
  end
130
86
  end
131
87
 
88
+
data/lib/template.rb ADDED
@@ -0,0 +1,46 @@
1
+ _buf = [] ; _temple_pre_tags = /<pre|<textarea/ ; _buf << ("<!DOCTYPE html><html><head>") ;
2
+ ;
3
+ ;
4
+ ; if data[:title] ;
5
+ ; _buf << ("<title>#{data[:title]}"\
6
+ ""\
7
+ "</title>") ; end ; if data[:favicon] ;
8
+ ; _buf << ("<link rel=\"shortcut icon\" url=\"#{Temple::Utils.escape_html((data[:favicon]))}\">"\
9
+ ""\
10
+ "") ; end ; if data[:description] ;
11
+ ; _buf << ("<meta content=\"#{Temple::Utils.escape_html((data[:description]))}\" name=\"description\">"\
12
+ ""\
13
+ "") ; end ; if data[:keywords] ;
14
+ ; _buf << ("<meta content=\"#{Temple::Utils.escape_html((data[:keywords]))}\" name=\"keywords\">"\
15
+ ""\
16
+ "") ; end ; data[:css].flatten.each do |url| ;
17
+ ; unless url == '' ;
18
+ ; _buf << ("<link href=\"#{Temple::Utils.escape_html((url))}\" rel=\"stylesheet\" type=\"text/css\">"\
19
+ ""\
20
+ "") ; end ; end ; data[:js].flatten.each do |url| ;
21
+ ; unless url == '' ;
22
+ ; _buf << ("<script src=\"#{Temple::Utils.escape_html((url))}\" type=\"text/javascript\"></script>"\
23
+ ""\
24
+ "") ; end ; end ; if data[:inline_js] && !data[:inline_js].empty? ;
25
+ ; _buf << ("<script type=\"text/javascript\">") ;
26
+ ; data[:inline_js].flatten.each do |code| ;
27
+ ; unless code == '' ;
28
+ ; _buf << (code) ;
29
+ ;
30
+ ; end ; end ; _buf << ("</script>") ; end ; if data[:head] ;
31
+ ; _buf << (data[:head]) ;
32
+ ;
33
+ ; end ; _buf << ("</head><body class=\"#{Temple::Utils.escape_html((data[:body_class]))}\">"\
34
+ "#{data[:body]}"\
35
+ ""\
36
+ "") ; if data[:ga_code] ;
37
+ ;
38
+ ; _buf << ("<script type=\"text/javascript\">var _gaq = _gaq || [];\n_gaq.push(['_setAccount', '"\
39
+ "#{Temple::Utils.escape_html((data[:ga_code]))}']);\n_gaq.push(['_trackPageview']);\n(function() {\nvar ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\nga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\nvar s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n})();</script>"\
40
+ ""\
41
+ ""\
42
+ ""\
43
+ ""\
44
+ ""\
45
+ ""\
46
+ "") ; end ; _buf << ("</body></html>") ; _buf = _buf.join
data/spec/laydown_spec.rb CHANGED
@@ -5,25 +5,27 @@ require 'laydown'
5
5
  describe Laydown do
6
6
 
7
7
  subject do
8
- Laydown.new do |_|
9
- _.charset 'iso-piso'
10
- _.title 'Apple sucks'
11
- _.description 'Yes, it does. And so do their fans.'
12
- _.favicon 'applesuck.png'
13
- _.keywords 'apple suck lol'
14
- _.css 'applesuck.css'
15
- _.js 'applesuck.js'
16
- _.inline_js "alert('#{@msg}');"
17
- _.head '<meta generator="Ubuntu">'
18
- _.body @body
19
- _.ga_code 'GA-UGGABUGGA'
20
- end
8
+ Laydown.new(
9
+ charset: 'iso-pam-pa-la-la',
10
+ title: 'Apple sucks #{@reason}',
11
+ description: 'And so do their fans.',
12
+ favicon: 'applesuck.png',
13
+ keywords: 'apple suck lol #{@keywords}',
14
+
15
+ css: ['applesuck.css', '#{@css}'],
16
+ js: ['applesuck.js', '#{@js}'],
17
+ inline_js: 'alert("#{@msg}");',
18
+
19
+ head: '<meta generator="Ubuntu">',
20
+ body: '#{yield}',
21
+ ga_code: 'GA-UGGABUGGA'
22
+ )
21
23
  end
22
24
 
23
25
  it 'generates properly' do
24
- @msg = 'lol @ iPhone'
25
- @body = '<p>Seriously.</p>'
26
- str = subject.render(self)
26
+ @reason = 'just because'
27
+ @msg = 'boo'
28
+ str = subject.render(self) { 'This is the body.' }
27
29
  str.should == nil
28
30
 
29
31
  #str.match(/lang="en"/).should
data/template.slim ADDED
@@ -0,0 +1,45 @@
1
+ ! doctype html
2
+ html
3
+ head
4
+ - if data[:title]
5
+ title == data[:title]
6
+
7
+ - if data[:favicon]
8
+ link rel="shortcut icon" url=data[:favicon]
9
+
10
+ - if data[:description]
11
+ meta name="description" content=data[:description]
12
+
13
+ - if data[:keywords]
14
+ meta name="keywords" content=data[:keywords]
15
+
16
+ - data[:css].flatten.each do |url|
17
+ - unless url == ''
18
+ link rel="stylesheet" type='text/css' href=url
19
+
20
+ - data[:js].flatten.each do |url|
21
+ - unless url == ''
22
+ script type="text/javascript" src=url
23
+
24
+ - if data[:inline_js] && !data[:inline_js].empty?
25
+ script type="text/javascript"
26
+ - data[:inline_js].flatten.each do |code|
27
+ - unless code == ''
28
+ == code
29
+
30
+ - if data[:head]
31
+ == data[:head]
32
+
33
+ body class=data[:body_class]
34
+ == data[:body]
35
+
36
+ - if data[:ga_code]
37
+ javascript:
38
+ var _gaq = _gaq || [];
39
+ _gaq.push(['_setAccount', '#{data[:ga_code]}']);
40
+ _gaq.push(['_trackPageview']);
41
+ (function() {
42
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
43
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
44
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
45
+ })();
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 4
7
+ - 5
8
8
  - 0
9
- version: 0.4.0
9
+ version: 0.5.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - jbe
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-02-03 00:00:00 +01:00
17
+ date: 2011-02-20 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: backports
21
+ name: temple
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  none: false
@@ -31,7 +31,7 @@ dependencies:
31
31
  type: :runtime
32
32
  version_requirements: *id001
33
33
  - !ruby/object:Gem::Dependency
34
- name: tenjin
34
+ name: slim
35
35
  prerelease: false
36
36
  requirement: &id002 !ruby/object:Gem::Requirement
37
37
  none: false
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: "0"
44
44
  type: :development
45
45
  version_requirements: *id002
46
- description: Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those of us who has written basically the same html head 200 times and feels like minimalism.
46
+ description: Provides a simple Ruby DSL for defining HTML5 layouts for web apps. For those who has written the same layout too many times.
47
47
  email: post@jostein.be
48
48
  executables: []
49
49
 
@@ -61,7 +61,9 @@ files:
61
61
  - VERSION
62
62
  - laydown.gemspec
63
63
  - lib/laydown.rb
64
+ - lib/template.rb
64
65
  - spec/laydown_spec.rb
66
+ - template.slim
65
67
  has_rdoc: true
66
68
  homepage: http://github.com/jbe/laydown
67
69
  licenses: []
@@ -93,6 +95,6 @@ rubyforge_project:
93
95
  rubygems_version: 1.3.7
94
96
  signing_key:
95
97
  specification_version: 3
96
- summary: Pure Ruby HTML5 layout DSL for microframeworks.
98
+ summary: Make HTML5 layouts quickly with plain Ruby.
97
99
  test_files:
98
100
  - spec/laydown_spec.rb