erbside 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+