erbside 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +11 -0
- data/LICENSE +206 -0
- data/PROFILE +27 -0
- data/README +88 -0
- data/VERSION +1 -0
- data/bin/erbside +3 -0
- data/lib/erbside.rb +57 -0
- data/lib/erbside/context.rb +46 -0
- data/lib/erbside/inline.rb +249 -0
- data/lib/erbside/inline/bash.rb +33 -0
- data/lib/erbside/inline/cpp.rb +32 -0
- data/lib/erbside/inline/css.rb +34 -0
- data/lib/erbside/inline/js.rb +34 -0
- data/lib/erbside/inline/ruby.rb +34 -0
- data/lib/erbside/inline/sgml.rb +135 -0
- data/lib/erbside/metadata.rb +122 -0
- data/lib/erbside/runner.rb +128 -0
- data/lib/plugins/syckle/erbside.rb +45 -0
- data/test/functional/applique/env.rb +33 -0
- data/test/functional/bash.rdoc +57 -0
- data/test/functional/cli.rdoc +14 -0
- data/test/functional/cpp.rdoc +50 -0
- data/test/functional/css.rdoc +53 -0
- data/test/functional/javascript.rdoc +52 -0
- data/test/functional/ruby.rdoc +57 -0
- data/test/functional/sgml.rdoc +61 -0
- data/test/unit/fixture/inline.rb +29 -0
- data/test/unit/fixture/inline_complex.rb +0 -0
- data/test/unit/inline_test.rb +14 -0
- metadata +111 -0
@@ -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
|
+
|