bade 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
1
+
2
+ require_relative 'node'
3
+ require_relative 'parser'
4
+ require_relative 'generator'
5
+ require_relative 'runtime'
6
+
7
+
8
+ module Bade
9
+ class Renderer
10
+ # @return [String]
11
+ #
12
+ attr_accessor :source_text
13
+
14
+ # @return [String]
15
+ #
16
+ attr_accessor :file_path
17
+
18
+ # @return [Hash]
19
+ #
20
+ attr_accessor :locals
21
+
22
+ # @param source [String]
23
+ #
24
+ # @return [self]
25
+ #
26
+ def self.from_source(source, file_path = nil)
27
+ inst = new
28
+ inst.source_text = source
29
+ inst.file_path = file_path
30
+ inst
31
+ end
32
+
33
+ # @param file [String, File]
34
+ #
35
+ # @return [self]
36
+ #
37
+ def self.from_file(file)
38
+ file_obj = if file.is_a?(String)
39
+ File.new(file, 'r')
40
+ else
41
+ file
42
+ end
43
+
44
+ from_source(file_obj.read, file_obj.path)
45
+ end
46
+
47
+
48
+ def initialize
49
+ # absolute path => document
50
+ @parsed_documents = {}
51
+ end
52
+
53
+
54
+ # ----------------------------------------------------------------------------- #
55
+ # DSL methods
56
+
57
+
58
+ # @param locals [Hash]
59
+ #
60
+ # @return [self]
61
+ #
62
+ def with_locals(locals = {})
63
+ self.locals = locals
64
+ self
65
+ end
66
+
67
+
68
+ # ----------------------------------------------------------------------------- #
69
+ # Getters
70
+
71
+ # @return [Bade::Node]
72
+ #
73
+ def root_document
74
+ @parsed ||= (
75
+ if file_path.nil?
76
+ _parse_document_from_text(source_text)
77
+ else
78
+ _parse_document_from_file(file_path)
79
+ end
80
+ )
81
+ end
82
+
83
+ # @return [String]
84
+ #
85
+ def lambda_string(new_line: '\n', indent: ' ')
86
+ RubyGenerator.document_to_lambda_string(root_document, new_line: new_line, indent: indent)
87
+ end
88
+
89
+
90
+ # ----------------------------------------------------------------------------- #
91
+ # Render
92
+
93
+ # @return [String]
94
+ #
95
+ def render(binding: nil, new_line: '\n', indent: ' ')
96
+ lambda_str = lambda_string(new_line: new_line, indent: indent)
97
+ scope = binding || Runtime::RenderBinding.new(locals || {}).get_binding
98
+
99
+ lambda_instance = eval(lambda_str, scope, file_path || '(__template__)')
100
+ lambda_instance.call
101
+ end
102
+
103
+
104
+
105
+ private
106
+
107
+ # @param file_path [String]
108
+ #
109
+ # @return [Bade::Document]
110
+ #
111
+ def _parse_document_from_file(file_path)
112
+ parser = Parser.new(file_path: file_path)
113
+
114
+ new_path = if File.exists?(file_path)
115
+ file_path
116
+ elsif File.exists?("#{file_path}.bade")
117
+ "#{file_path}.bade"
118
+ end
119
+
120
+ raise "Not existing file with path #{file_path}" if new_path.nil?
121
+
122
+ parsed_document = @parsed_documents[new_path]
123
+ return parsed_document unless parsed_document.nil?
124
+
125
+ document = parser.parse(File.read(new_path))
126
+
127
+ parser.dependency_paths.each do |path|
128
+ sub_path = File.expand_path(path, File.dirname(new_path))
129
+ document.sub_documents << _parse_document_from_file(sub_path)
130
+ end
131
+
132
+ document
133
+ end
134
+
135
+ # @param text [String]
136
+ #
137
+ # @return [Bade::Document]
138
+ #
139
+ def _parse_document_from_text(text)
140
+ parser = Parser.new
141
+ document = parser.parse(text)
142
+
143
+ raise 'You cannot use import when it is loaded from source text' if parser.dependency_paths.length > 0
144
+
145
+ document
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,11 @@
1
+
2
+ class Object
3
+ def self.attr_forw_accessor(name, forw_name)
4
+ define_method(name) {
5
+ self.send(forw_name)
6
+ }
7
+ define_method(name.to_s + '=') { |*args|
8
+ self.send(forw_name.to_s + '=', *args)
9
+ }
10
+ end
11
+ end
@@ -0,0 +1,74 @@
1
+ class String
2
+
3
+ # Creates new string surrounded by single quotes
4
+ #
5
+ # @return [String]
6
+ #
7
+ def single_quote
8
+ %('#{self}')
9
+ end
10
+
11
+
12
+ # Remove indent
13
+ #
14
+ # @param [Int] indent
15
+ # @param [Int] tabsize
16
+ #
17
+ def remove_indent(indent, tabsize)
18
+ self.dup.remove_indent!(indent, tabsize)
19
+ end
20
+
21
+
22
+ # Remove indent
23
+ #
24
+ # @param [Int] indent
25
+ # @param [Int] tabsize
26
+ #
27
+ def remove_indent!(indent, tabsize)
28
+ count = 0
29
+ self.each_char do |char|
30
+
31
+ if indent <= 0
32
+ break
33
+ elsif char == ' '
34
+ indent -= 1
35
+ elsif char == "\t"
36
+ if indent - tabsize < 0
37
+ raise StandardError, 'malformed tabs'
38
+ end
39
+
40
+ indent -= tabsize
41
+ else
42
+ break
43
+ end
44
+
45
+ count += 1
46
+ end
47
+
48
+ self[0 ... self.length] = self[count ... self.length]
49
+ end
50
+
51
+
52
+ # Calculate indent for line
53
+ #
54
+ # @param [Int] tabsize
55
+ #
56
+ # @return [Int] indent size
57
+ #
58
+ def get_indent(tabsize)
59
+ count = 0
60
+
61
+ self.each_char do |char|
62
+ if char == ' '
63
+ count += 1
64
+ elsif char == "\t"
65
+ count += tabsize
66
+ else
67
+ break
68
+ end
69
+ end
70
+
71
+ count
72
+ end
73
+
74
+ end
@@ -0,0 +1,40 @@
1
+
2
+ module Bade
3
+ module Runtime
4
+ class RuntimeError < ::StandardError; end
5
+
6
+ class Block
7
+
8
+ # @return [Proc]
9
+ #
10
+ attr_reader :block
11
+
12
+ # @return [String]
13
+ #
14
+ attr_reader :name
15
+
16
+ # @param [String] name
17
+ #
18
+ def initialize(name, &block)
19
+ @name = name
20
+ @block = lambda &block unless block.nil?
21
+ end
22
+
23
+ def call(*args)
24
+ @block.call(*args) unless @block.nil?
25
+ end
26
+
27
+ def call!(*args)
28
+ if @block.nil?
29
+ raise RuntimeError, "`#{@name}` must have block definition"
30
+ else
31
+ @block.call(*args)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def block(name, &block)
38
+ Runtime::Block.new(name, &block)
39
+ end
40
+ end
@@ -0,0 +1,53 @@
1
+
2
+ require_relative 'block'
3
+
4
+ module Bade
5
+ module Runtime
6
+ class RenderBinding
7
+ class KeyError < ::StandardError; end
8
+
9
+ # @param vars [Hash]
10
+ #
11
+ def initialize(vars = {})
12
+ @vars = vars
13
+ end
14
+
15
+ def method_missing(name, *args)
16
+ raise KeyError, "Not found value for key `#{name}'" unless @vars.key?(name)
17
+ @vars[name]
18
+ end
19
+
20
+ # @return [Binding]
21
+ #
22
+ def get_binding
23
+ binding
24
+ end
25
+
26
+ # Shortcut for creating blocks
27
+ #
28
+ def __create_block(*args, &block)
29
+ Bade::Runtime::Block.new(*args, &block)
30
+ end
31
+
32
+ # Escape input text with html escapes
33
+ #
34
+ # @param [String] text
35
+ #
36
+ # @return [String]
37
+ #
38
+ def html_escaped(text)
39
+ text.sub('&', '&amp;')
40
+ .sub('<', '&lt;')
41
+ .sub('>', '&gt;')
42
+ .sub('"', '&quot;')
43
+ end
44
+
45
+ def tag_render_attribute(name, *values)
46
+ values = values.compact
47
+ return if values.empty?
48
+
49
+ %Q{ #{name}="#{values.join(' ')}"}
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,7 @@
1
+
2
+ module Epuber
3
+ module Runtime
4
+ require_relative 'runtime/block'
5
+ require_relative 'runtime/render_binding'
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module Bade
3
+ VERSION = '0.1.3'
4
+ end
data/lib/bade.rb ADDED
@@ -0,0 +1,8 @@
1
+
2
+ module Bade
3
+ require_relative 'bade/version'
4
+
5
+ require_relative 'bade/parser'
6
+ require_relative 'bade/generator'
7
+ require_relative 'bade/renderer'
8
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bade
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Roman Kříž
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.4'
55
+ description:
56
+ email:
57
+ - samnung@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - Bade.gemspec
63
+ - Gemfile
64
+ - README.md
65
+ - lib/bade.rb
66
+ - lib/bade/document.rb
67
+ - lib/bade/generator.rb
68
+ - lib/bade/generator/html_generator.rb
69
+ - lib/bade/generator/ruby_generator.rb
70
+ - lib/bade/node.rb
71
+ - lib/bade/node/doctype_node.rb
72
+ - lib/bade/node/key_value_node.rb
73
+ - lib/bade/node/mixin_node.rb
74
+ - lib/bade/node/tag_node.rb
75
+ - lib/bade/parser.rb
76
+ - lib/bade/renderer.rb
77
+ - lib/bade/ruby_extensions/object.rb
78
+ - lib/bade/ruby_extensions/string.rb
79
+ - lib/bade/runtime.rb
80
+ - lib/bade/runtime/block.rb
81
+ - lib/bade/runtime/render_binding.rb
82
+ - lib/bade/version.rb
83
+ homepage: https://github.com/samnung/bade
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.4.5.1
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Minimalistic template engine for Ruby.
107
+ test_files: []
108
+ has_rdoc: