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.
- 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
|
+
|