erbside 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.
@@ -0,0 +1,249 @@
1
+ module Erbside
2
+
3
+ # Base class for all the inline parsers.
4
+ #
5
+ class Inline
6
+
7
+ # C L A S S - M E T H O D S
8
+
9
+ #
10
+ def self.factory(file)
11
+ map[File.extname(file)]
12
+ end
13
+
14
+ #
15
+ def self.map
16
+ @map ||= (
17
+ register.inject({}) do |hash, base|
18
+ base.extensions.each do |ext|
19
+ hash[ext] = base
20
+ end
21
+ hash
22
+ end
23
+ )
24
+ end
25
+
26
+ def self.register
27
+ @register ||= []
28
+ end
29
+
30
+ def self.inherited(base)
31
+ register << base
32
+ end
33
+
34
+ def self.extensions ; raise ; end
35
+
36
+ #
37
+ def self.extension_list
38
+ register.map{ |x| x.extensions }.flatten
39
+ end
40
+
41
+ # R E Q U I R E M E N T S
42
+
43
+ require 'pathname'
44
+ require 'erb'
45
+
46
+ require 'erbside/context'
47
+ require 'erbside/inline/bash'
48
+ require 'erbside/inline/cpp'
49
+ require 'erbside/inline/css'
50
+ require 'erbside/inline/sgml'
51
+ require 'erbside/inline/js'
52
+ require 'erbside/inline/ruby'
53
+
54
+
55
+ # C O N S T A N T S
56
+
57
+ #
58
+ TAG = 'erb'
59
+
60
+
61
+ # A T T R I B U T E S
62
+
63
+ #
64
+ attr :file
65
+
66
+ #
67
+ attr :type
68
+
69
+ #
70
+ attr :context
71
+
72
+ # The rendered result.
73
+ attr :result
74
+
75
+
76
+ # I N I T I A L I Z E
77
+
78
+ #
79
+ def initialize(file)
80
+ @file = Pathname.new(file)
81
+ @type = @file.extname
82
+
83
+ @context = Context.new(@file)
84
+ end
85
+
86
+ #
87
+ def content
88
+ @content ||= File.read(file)
89
+ end
90
+
91
+ #
92
+ def render
93
+ @result = render_result
94
+ end
95
+
96
+ #
97
+ def render_template(text)
98
+ #Dir.chdir(file.parent) do
99
+ context.render(text)
100
+ #end
101
+ end
102
+
103
+ #
104
+ def relative_output(dir=nil)
105
+ dir = dir || Dir.pwd
106
+ output.sub(dir+'/', '')
107
+ end
108
+
109
+ #
110
+ def exist?
111
+ File.exist?(output)
112
+ end
113
+
114
+ # Has the file changed?
115
+ def changed?
116
+ if exist?
117
+ File.read(output) != result
118
+ else
119
+ true
120
+ end
121
+ end
122
+
123
+ # Save result to file.
124
+ def save
125
+ File.open(output, 'w'){ |f| f << result }
126
+ end
127
+
128
+ # Output file (same as the input file).
129
+ def output
130
+ file
131
+ end
132
+
133
+ #
134
+ def render_result
135
+ text = content
136
+ text = render_sides(text)
137
+ text = render_blocks(text)
138
+ end
139
+
140
+ #
141
+ def remarker
142
+ raise
143
+ end
144
+
145
+ #
146
+ def remarker_multiline
147
+ raise
148
+ end
149
+
150
+ #
151
+ def line_match
152
+ rem = Regexp.escape(remarker)
153
+ /^(\ *)(.*?)(\ *)(#{rem})(\ *)(:#{TAG})(\+\d*)?(:)(.*?\S.*?)$/
154
+ end
155
+
156
+ #
157
+ def render_sides(text)
158
+ index = 0
159
+ result = ''
160
+
161
+ text.scan(line_match) do |m|
162
+ md = $~
163
+
164
+ indent = md[1]
165
+ front = md[2]
166
+ remark = [ md[3], md[4], md[5], md[6], md[7], md[8], md[9] ].join('')
167
+ tmplt = md[9].strip
168
+ count = md[7]
169
+
170
+ render = render_template(tmplt)
171
+
172
+ result << text[index...md.begin(0)]
173
+ result << format_side(indent, front, remark, tmplt, render, count)
174
+
175
+ #index = md.end(0)
176
+ i = md.end(0) + 1
177
+ count.to_i.times{ i = text[i..-1].index(/(\n|\Z)/) + i + 1 }
178
+ index = i
179
+ end
180
+
181
+ result << text[index..-1].to_s
182
+ result
183
+ end
184
+
185
+ #
186
+ def format_side(indent, front, remark, tmplt, render, multi=nil)
187
+ size = render.count("\n")
188
+ if multi || size > 0
189
+ indent + remark.sub(/:#{TAG}(\+\d+)?:/, ":#{TAG}+#{size+1}:") + "\n" + render + "\n"
190
+ else
191
+ if tmplt =~ /^\s*\^/
192
+ b = tmplt.index('^') + 1
193
+ e = tmplt.index(/[<{]/) || - 1
194
+ m = tmplt[b...e]
195
+ i = front.index(m)
196
+ render = front[0...i] + render.sub('^','')
197
+ end
198
+ indent + render + remark.sub(/:#{TAG}(\+\d+)?:/, ":#{TAG}:") + "\n"
199
+ end
200
+ end
201
+
202
+ #
203
+ def block_match
204
+ b = Regexp.escape(remarker_block_begin)
205
+ e = Regexp.escape(remarker_block_end)
206
+ %r{^(#{b})(\s*)(:#{TAG})(\+\d*)?(\:)(\s*\n)((?m:.*?))(\n#{e})}
207
+ end
208
+
209
+ #
210
+ def render_blocks(text)
211
+ index = 0
212
+ result = ''
213
+
214
+ text.scan(block_match) do |m|
215
+ md = $~
216
+
217
+ #indent = ""
218
+ #front = nil
219
+ remark = md[0]
220
+ pad = md[2]
221
+ count = md[4]
222
+ tmplt = md[7]
223
+
224
+ render = render_template(tmplt)
225
+
226
+ result << text[index...md.begin(0)]
227
+ result << format_block(pad, tmplt, render)
228
+
229
+ i = md.end(0) + 1
230
+ count.to_i.times{ i = text[i..-1].index(/(\n|\Z)/) + i + 1 }
231
+ index = i
232
+ end
233
+
234
+ result << text[index..-1].to_s
235
+ result
236
+ end
237
+
238
+ #
239
+ def format_block(pad, template, render)
240
+ size = render.count("\n") + 1
241
+ b = remarker_block_begin
242
+ e = remarker_block_end
243
+ "#{b}#{pad}:#{TAG}+#{size}:\n#{template}\n#{e}\n#{render}\n"
244
+ end
245
+
246
+ end
247
+
248
+ end
249
+
@@ -0,0 +1,33 @@
1
+ module Erbside
2
+
3
+ require 'erbside/inline'
4
+
5
+ # Bash Adapter
6
+ class Bash < Inline
7
+
8
+ EXTENSIONS = %w{.sh}
9
+
10
+ #
11
+ def self.extensions
12
+ EXTENSIONS
13
+ end
14
+
15
+ #
16
+ def remarker
17
+ '#'
18
+ end
19
+
20
+ #
21
+ def remarker_block_begin
22
+ '#=begin'
23
+ end
24
+
25
+ #
26
+ def remarker_block_end
27
+ '#=end'
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
@@ -0,0 +1,32 @@
1
+ module Erbside
2
+
3
+ require 'erbside/inline'
4
+
5
+ # C/C++ Adapter
6
+ class Cpp < Inline
7
+
8
+ EXTENSIONS = %w{ .c .cpp }
9
+
10
+ def self.extensions
11
+ EXTENSIONS
12
+ end
13
+
14
+ #
15
+ def remarker
16
+ '//'
17
+ end
18
+
19
+ #
20
+ def remarker_block_begin
21
+ '/*'
22
+ end
23
+
24
+ #
25
+ def remarker_block_end
26
+ '*/'
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
@@ -0,0 +1,34 @@
1
+ module Erbside
2
+
3
+ require 'erbside/inline'
4
+
5
+ # CSS Adapter
6
+ class CSS < Inline
7
+
8
+ #
9
+ EXTENSIONS = %w{.css}
10
+
11
+ #
12
+ def self.extensions
13
+ EXTENSIONS
14
+ end
15
+
16
+ #
17
+ def remarker
18
+ '//'
19
+ end
20
+
21
+ #
22
+ def remarker_block_begin
23
+ '/*'
24
+ end
25
+
26
+ #
27
+ def remarker_block_end
28
+ '*/'
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,34 @@
1
+ module Erbside
2
+
3
+ require 'erbside/inline'
4
+
5
+ # Javascript Adapter
6
+ class Javascript < Inline
7
+
8
+ #
9
+ EXTENSIONS = %w{.js}
10
+
11
+ #
12
+ def self.extensions
13
+ EXTENSIONS
14
+ end
15
+
16
+ #
17
+ def remarker
18
+ '//'
19
+ end
20
+
21
+ #
22
+ def remarker_block_begin
23
+ '/*'
24
+ end
25
+
26
+ #
27
+ def remarker_block_end
28
+ '*/'
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,34 @@
1
+ module Erbside
2
+
3
+ require 'erbside/inline'
4
+
5
+ # Ruby
6
+ class Ruby < Inline
7
+
8
+ #
9
+ EXTENSIONS = %w{.rb}
10
+
11
+ # Ruby file extensions.
12
+ def self.extensions
13
+ EXTENSIONS
14
+ end
15
+
16
+ #
17
+ def remarker
18
+ '#'
19
+ end
20
+
21
+ #
22
+ def remarker_block_begin
23
+ '=begin'
24
+ end
25
+
26
+ #
27
+ def remarker_block_end
28
+ '=end'
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,135 @@
1
+ module Erbside
2
+
3
+ require 'erbside/inline'
4
+
5
+ # XML and HTML
6
+ class SGML < Inline
7
+
8
+ EXTENSIONS = %w{ .html .xml }
9
+
10
+ #
11
+ def self.extensions
12
+ EXTENSIONS
13
+ end
14
+
15
+ #
16
+ def remarker
17
+ '<!--'
18
+ end
19
+
20
+ #
21
+ def remarker_block_begin
22
+ '<!--'
23
+ end
24
+
25
+ #
26
+ def remarker_block_end
27
+ '-->'
28
+ end
29
+
30
+ #
31
+ def line_match
32
+ rem = Regexp.escape(remarker)
33
+ /^(\ *)(.*?)(\ *)(#{rem})(\ *)(:#{TAG})()?(:)(.*?\S.*?)(-->)$/
34
+ end
35
+
36
+ =begin
37
+ #
38
+ def render_result
39
+ text = content
40
+ text = render_backs(text)
41
+ text = render_blocks(text)
42
+ end
43
+
44
+ #
45
+ BACKS = /^(\ *)(.*?\S.*?)(\ *)(<!--)(\ *)(:till:)(.*?)(-->)$/
46
+
47
+ #
48
+ def render_backs(text)
49
+ index = 0
50
+ result = ''
51
+
52
+ text.scan(BACKS) do |m|
53
+ md = $~
54
+
55
+ indent = md[1]
56
+ front = md[2]
57
+ remark = [ md[3], md[4], md[5], md[6], md[7], md[8] ].join('')
58
+ tmplt = md[7].strip
59
+ count = nil
60
+
61
+ render = render_template(tmplt)
62
+
63
+ result << text[index...md.begin(0)]
64
+ result << format_back(indent, front, remark, tmplt, render)
65
+
66
+ #index = md.end(0)
67
+ i = md.end(0) + 1
68
+ count.to_i.times{ i = text[i..-1].index("\n") + i + 1 }
69
+ index = i
70
+ end
71
+
72
+ result << text[index..-1]
73
+ result
74
+ end
75
+
76
+ #
77
+ BLOCKS = /^(\ *)(<!--)(\ *)(:till)(\+\d*)?(\:)(.*?)(-->)/m
78
+
79
+ #
80
+ def render_blocks(text)
81
+ index = 0
82
+ result = ''
83
+
84
+ text.scan(BLOCKS) do |m|
85
+ md = $~
86
+
87
+ indent = md[1]
88
+ #front = nil
89
+ remark = [ md[1], md[2], md[3], md[4], md[5], md[6], md[7], md[8] ].join('')
90
+ tmplt = md[7].strip
91
+ count = md[5]
92
+
93
+ render = render_template(tmplt)
94
+
95
+ result << text[index...md.begin(0)]
96
+ result << format_block(indent, remark, tmplt, render)
97
+
98
+ #index = md.end(0)
99
+ i = md.end(0) + 1
100
+ count.to_i.times{ i = text[i..-1].index("\n") + i + 1 }
101
+ index = i
102
+ end
103
+
104
+ result << text[index..-1]
105
+ result
106
+ end
107
+
108
+ #
109
+ def format_back(indent, front, remark, tmplt, render)
110
+ size = render.count("\n")
111
+ if size > 0
112
+ format_block(indent, remark, tmplt, front + render)
113
+ else
114
+ if tmplt =~ /^\s*\^/
115
+ b = tmplt.index('^') + 1
116
+ e = tmplt.index(/[<{]/) || - 1
117
+ m = tmplt[b...e]
118
+ i = front.index(m)
119
+ render = front[0...i] + render.sub('^','')
120
+ end
121
+ indent + render + remark.sub(/:till(\+\d+)?:/, ":till:") + "\n"
122
+ end
123
+ end
124
+
125
+ #
126
+ def format_block(indent, remark, tmplt, render)
127
+ size = render.count("\n")
128
+ indent + remark.sub(/:till(\+\d+)?:/, ":till+#{size+1}:") + "\n" + render +"\n"
129
+ end
130
+ =end
131
+
132
+ end
133
+
134
+ end
135
+