sal 0.1.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/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # sal.rb
2
+
3
+ sal.rb is a simple attribute language for Ruby.
4
+
5
+ ## What?
6
+
7
+ I haven't gotten to the docs for this project yet, but fortunately [sal.js](http://github.com/stonean/sal.js) does and sal.rb will act accordingly.
@@ -0,0 +1,35 @@
1
+ module Sal
2
+ # Compiles HTML into Temple::HTML expressions
3
+ # @api private
4
+ class Compiler < Filter
5
+
6
+ def on_sal_tag(ele, attrs, closed, content)
7
+ [:html, :tag, ele, attrs, closed, compile(content)]
8
+ end
9
+
10
+ def on_sal_code(code, tag, attrs, content)
11
+ tmp1, tmp2 = tmp_var(:sal), tmp_var(:sal)
12
+
13
+ [:multi,
14
+ [:block, "#{tmp1} = #{code}"],
15
+ [:block, "if #{tmp1}.kind_of?(String)"],
16
+ [:html, :tag, tag, attrs, false, [:dynamic, tmp1]],
17
+ [:block, "elsif #{tmp1}.kind_of?(Array)"],
18
+ [:block, "#{tmp1}.each do |#{tmp2}|"],
19
+ [:html, :tag, tag, ada(attrs, tmp2), false,
20
+ [:dynamic, "Sal.parse_for_html(#{tmp2})"]],
21
+ [:block, 'end'],
22
+ [:block, "else"],
23
+ [:html, :tag, tag, ada(attrs, tmp1), false,
24
+ [:dynamic, "Sal.parse_for_html(#{tmp1})"]],
25
+ [:block, 'end'],
26
+ ]
27
+ end
28
+
29
+ private
30
+
31
+ def ada(attrs, tmpvar)
32
+ attrs.dup << [:dynamic, "Sal.parse_for_attributes(#{tmpvar})"]
33
+ end
34
+ end
35
+ end
data/lib/sal/engine.rb ADDED
@@ -0,0 +1,16 @@
1
+ module Sal
2
+ class Engine < Temple::Engine
3
+ set_default_options :format => :html,
4
+ :generator => Temple::Generators::ArrayBuffer
5
+
6
+ use Sal::Parser, :file, :tabsize, :encoding
7
+ use Sal::Compiler
8
+ use Temple::HTML::Fast
9
+
10
+ filter :MultiFlattener # Collapse nested multis into single multi
11
+ filter :StaticMerger # Merge several statics into a single static
12
+ filter :DynamicInliner # Merge several static/dynamic into single dynamic
13
+
14
+ use(:Generator) { |exp| options[:generator].new(options).call(exp) }
15
+ end
16
+ end
data/lib/sal/filter.rb ADDED
@@ -0,0 +1,13 @@
1
+ module Sal
2
+ class Filter < Temple::Filter
3
+ temple_dispatch :sal
4
+
5
+ def on_sal_code(code, tag, attrs, content)
6
+ [:sal, :code, code, tag, attrs, content]
7
+ end
8
+
9
+ def on_sal_tag(tag, attrs, content)
10
+ [:sal, :tag, tag, attrs, content]
11
+ end
12
+ end
13
+ end
data/lib/sal/parser.rb ADDED
@@ -0,0 +1,103 @@
1
+ require 'nokogiri'
2
+
3
+ module Sal
4
+ class Parser
5
+ include Temple::Mixins::Options
6
+
7
+ set_default_options :tabsize => 4,
8
+ :encoding => 'utf-8'
9
+
10
+ class << self
11
+ #TODO: Remove node_types after fleshing out tests
12
+ def node_types
13
+ @node_types ||= define_node_types
14
+ end
15
+
16
+ private
17
+ def define_node_types
18
+ nt = {}
19
+ Nokogiri::XML::Node.constants.each do |name|
20
+ nt[eval("Nokogiri::XML::Node::#{name}")] = name if name =~ /_NODE$/
21
+ end
22
+ nt
23
+ end
24
+ end # class block
25
+
26
+ def initialize(options = {})
27
+ super
28
+ @tab = ' ' * @options[:tabsize]
29
+ end
30
+
31
+ # Compile the string to a Temple expression
32
+ #
33
+ # @param [String] str Html code
34
+ # @return [Array] Temple expression representing the code
35
+ def call(str)
36
+ if options[:encoding] && str.respond_to?(:encoding)
37
+ old = str.encoding
38
+ str = str.dup if str.frozen?
39
+ str.force_encoding(options[:encoding])
40
+ # Fall back to old encoding if new encoding is invalid
41
+ str.force_encoding(old_enc) unless str.valid_encoding?
42
+ end
43
+
44
+ result = [:multi]
45
+
46
+ doc = Nokogiri::XML(str)
47
+
48
+ parse_nodeset([result], doc)
49
+
50
+ result
51
+ end
52
+
53
+ private
54
+
55
+ def parse_nodeset(stacks, nodes)
56
+ nodes.children.each do |node|
57
+ tag = node.name
58
+
59
+ case node.type
60
+ when Nokogiri::XML::Node::ELEMENT_NODE
61
+ content = [:multi]
62
+ attrs, code = parse_attrs(node)
63
+ if code
64
+ stacks.last << [:sal, :code, code, tag, attrs, content]
65
+ else
66
+ stacks.last << [:sal, :tag, tag, attrs, false, content]
67
+ end
68
+ stacks << content
69
+ parse_nodeset(stacks, node)
70
+ stacks.pop
71
+ when Nokogiri::XML::Node::TEXT_NODE
72
+ str = node.text
73
+ if str.strip.empty?
74
+ stacks.last << [:newline]
75
+ else
76
+ stacks.last << [:static, str]
77
+ end
78
+ when Nokogiri::XML::Node::DTD_NODE
79
+ stacks.last << [:static, node.to_s]
80
+ when Nokogiri::XML::Node::COMMENT_NODE
81
+ stacks.last << [:html, :comment, [:static, node.text]]
82
+ else
83
+ raise "Unexpected node type: #{self.class.node_types[node.node_type]}"
84
+ end
85
+ end
86
+ end
87
+
88
+ def parse_attrs(node)
89
+ code = nil
90
+ attrs = []
91
+
92
+ node.attribute_nodes.each do |an|
93
+ if an.name == 'data-sal'
94
+ code = an.value
95
+ else
96
+ attrs << [an.name, [:static, an.value]]
97
+ end
98
+ end
99
+
100
+ return [:multi, [:html, :staticattrs] + attrs], code
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,13 @@
1
+ module Sal
2
+ # Tilt template implementation for sal
3
+ # @api public
4
+ Template = Temple::Templates::Tilt(Sal::Engine, :register_as => :sal)
5
+
6
+ if Object.const_defined?(:Rails)
7
+ RailsTemplate = Temple::Templates::Rails(Sal::Engine, :register_as => :sal)
8
+
9
+ RailsTemplate.set_default_options :generator => Temple::Generators::RailsOutputBuffer,
10
+ :disable_capture => true
11
+ end
12
+ end
13
+
@@ -0,0 +1,3 @@
1
+ module Sal
2
+ VERSION = '0.1.0'
3
+ end
data/lib/sal.rb ADDED
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ require 'temple'
4
+ require 'sal/parser'
5
+ require 'sal/filter'
6
+ require 'sal/compiler'
7
+ require 'sal/engine'
8
+ require 'sal/template'
9
+ require 'sal/version'
10
+
11
+ module Sal
12
+ class << self
13
+ def parse_for_attributes(result = nil)
14
+ return unless result.kind_of?(Hash)
15
+ " #{result.collect{ |k,v| "#{k}='#{v}'" unless k.to_s == 'html' }.compact.join(' ')}"
16
+ end
17
+
18
+ def parse_for_html(result = nil)
19
+ if result.kind_of?(String)
20
+ result
21
+ elsif result.kind_of?(Hash)
22
+ result.delete(:html)
23
+ end
24
+ end
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sal
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Stone
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-19 00:00:00 -04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: nokogiri
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: "1.4"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: temple
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: "0.2"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: tilt
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: "1.2"
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ description: sal.rb is an attribute language.
50
+ email:
51
+ - andy@stonean.com
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files:
57
+ - README.md
58
+ files:
59
+ - README.md
60
+ - lib/sal.rb
61
+ - lib/sal/compiler.rb
62
+ - lib/sal/engine.rb
63
+ - lib/sal/filter.rb
64
+ - lib/sal/parser.rb
65
+ - lib/sal/template.rb
66
+ - lib/sal/version.rb
67
+ has_rdoc: true
68
+ homepage: http://github.com/stonean/sal.rb
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options:
73
+ - --charset=UTF-8
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: "0"
88
+ requirements: []
89
+
90
+ rubyforge_project: sal
91
+ rubygems_version: 1.6.1
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: sal is a template language.
95
+ test_files: []
96
+