Class: Erbside::Inline

Inherits:
Object
  • Object
show all
Defined in:
lib/erbside/inline.rb

Overview

Base class for all the inline parsers.

TODO: Split this into two classes, one for inline and one for blocks.

Direct Known Subclasses

Bash, CSS, Cpp, Javascript, Ruby, SGML

Constant Summary collapse

TAG =
'erb'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file, *resources) ⇒ Inline

Returns a new instance of Inline.



83
84
85
86
87
88
# File 'lib/erbside/inline.rb', line 83

def initialize(file, *resources)
  @file   = Pathname.new(file)
  @type   = @file.extname

  @context = Context.new(@file, resources)
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



74
75
76
# File 'lib/erbside/inline.rb', line 74

def context
  @context
end

#fileObject (readonly)

Returns the value of attribute file.



68
69
70
# File 'lib/erbside/inline.rb', line 68

def file
  @file
end

#resultObject (readonly)

The rendered result.



77
78
79
# File 'lib/erbside/inline.rb', line 77

def result
  @result
end

#typeObject (readonly)

Returns the value of attribute type.



71
72
73
# File 'lib/erbside/inline.rb', line 71

def type
  @type
end

Class Method Details

.extension_listObject



41
42
43
# File 'lib/erbside/inline.rb', line 41

def self.extension_list
  register.map{ |x| x.extensions }.flatten
end

.extensionsObject

Raises:

  • (NotImplementedError)


36
37
38
# File 'lib/erbside/inline.rb', line 36

def self.extensions
  raise NotImplementedError
end

.factory(file) ⇒ Object



11
12
13
# File 'lib/erbside/inline.rb', line 11

def self.factory(file)
  map[File.extname(file)]
end

.inherited(base) ⇒ Object



31
32
33
# File 'lib/erbside/inline.rb', line 31

def self.inherited(base)
  register << base
end

.mapObject



16
17
18
19
20
21
22
23
24
25
# File 'lib/erbside/inline.rb', line 16

def self.map
  @map ||= (
    register.inject({}) do |hash, base|
      base.extensions.each do |ext|
        hash[ext] = base
      end
      hash
    end
  )
end

.registerObject



27
28
29
# File 'lib/erbside/inline.rb', line 27

def self.register
  @register ||= []
end

Instance Method Details

#block_matchObject



208
209
210
211
212
# File 'lib/erbside/inline.rb', line 208

def block_match
  b = Regexp.escape(remarker_block_begin)
  e = Regexp.escape(remarker_block_end)
  %r{^()(#{b})(\s*)(:#{TAG})(\+\d*)?(\:)(\s*\n)((?m:.*?))(\n#{e})}
end

#block_parts(match_data) ⇒ Object



215
216
217
218
219
220
221
222
223
# File 'lib/erbside/inline.rb', line 215

def block_parts(match_data)
  { :indent   => match_data[1],
    :pad      => match_data[3],
    :count    => match_data[5],
    :space    => match_data[7],
    :template => match_data[8],
    :tail     => match_data[9]
  }
end

#changed?Boolean

Has the file changed?

Returns:

  • (Boolean)


119
120
121
122
123
124
125
# File 'lib/erbside/inline.rb', line 119

def changed?
  if exist?
    File.read(output) != result
  else
    true
  end
end

#contentObject



91
92
93
# File 'lib/erbside/inline.rb', line 91

def content
  @content ||= File.read(file)
end

#exist?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/erbside/inline.rb', line 114

def exist?
  File.exist?(output)
end

#format_block(parts, render) ⇒ Object



257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/erbside/inline.rb', line 257

def format_block(parts, render)
  indent, pad, space, template, tail = parts.values_at(:indent, :pad, :space, :template, :tail)

  size = render.count("\n") + 1

  b = remarker_block_begin
  e = remarker_block_end

  #if template.count("\n") > 0
    "#{indent}#{b}#{pad}:#{TAG}+#{size}:#{space}#{template}#{tail}\n#{render}\n"
  #else
  #  "#{indent}#{b}#{pad}:#{TAG}+#{size}: #{template} #{e}\n#{render}\n"
  #end
end

#format_side(indent, front, remark, tmplt, render, multi = nil) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/erbside/inline.rb', line 191

def format_side(indent, front, remark, tmplt, render, multi=nil)
  size = render.count("\n")
  if multi || size > 0
    indent + remark.sub(/:#{TAG}(\+\d+)?:/, ":#{TAG}+#{size+1}:") + "\n" + render + "\n"
  else
    if tmplt =~ /^\s*\^/
      b = tmplt.index('^') + 1
      e = tmplt.index(/[<{]/) || - 1
      m = tmplt[b...e]
      i = front.index(m)
      render = front[0...i] + render.sub('^','')
    end
    indent + render + remark.sub(/:#{TAG}(\+\d+)?:/, ":#{TAG}:") + "\n"
  end
end

#line_matchObject



155
156
157
158
# File 'lib/erbside/inline.rb', line 155

def line_match
  rem = Regexp.escape(remarker)
  /^(\ *)(.*?)(\ *)(#{rem})(\ *)(:#{TAG})(\+\d*)?(:)(.*?\S.*?)$/
end

#outputObject

Output file (same as the input file).



133
134
135
# File 'lib/erbside/inline.rb', line 133

def output
  file
end

#relative_output(dir = nil) ⇒ Object



108
109
110
111
# File 'lib/erbside/inline.rb', line 108

def relative_output(dir=nil)
  dir = dir || Dir.pwd
  output.sub(dir+'/', '')
end

#remarkerObject

Raises:

  • (NotImplementedError)


145
146
147
# File 'lib/erbside/inline.rb', line 145

def remarker
  raise NotImplementedError
end

#remarker_multilineObject

Raises:

  • (NotImplementedError)


150
151
152
# File 'lib/erbside/inline.rb', line 150

def remarker_multiline
  raise NotImplementedError
end

#renderObject



96
97
98
# File 'lib/erbside/inline.rb', line 96

def render
  @result = render_result
end

#render_blocks(text) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/erbside/inline.rb', line 226

def render_blocks(text)
  index  = 0
  result = ''

  text.scan(block_match) do |m|
    md = $~

    #remark = md[0]

    parts = block_parts(md)

    indent = parts[:indent]
    pad    = parts[:pad]
    count  = parts[:count]
    tmplt  = parts[:template]

    render = render_template(tmplt)

    result << text[index...md.begin(0)]
    result << format_block(parts, render)

    i = md.end(0) + 1
    count.to_i.times{ i = text[i..-1].index(/(\n|\Z)/) + i + 1 }
    index = i
  end

  result << text[index..-1].to_s
  result
end

#render_resultObject



138
139
140
141
142
# File 'lib/erbside/inline.rb', line 138

def render_result
  text = content
  text = render_sides(text)
  text = render_blocks(text)
end

#render_sides(text) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/erbside/inline.rb', line 161

def render_sides(text)
  index  = 0
  result = ''

  text.scan(line_match) do |m|
    md = $~

    indent = md[1]
    front  = md[2]
    #remark = [ md[3], md[4], md[5], md[6], md[7], md[8], md[9] ].join('')
    remark = md[3..-1].join('')
    tmplt  = md[9].strip
    count  = md[7].to_i

    render = render_template(tmplt)

    result << text[index...md.begin(0)]
    result << format_side(indent, front, remark, tmplt, render, !count.zero?)

    #index = md.end(0)
    i = md.end(0) + 1
    count.times{ i = text[i..-1].index(/(\n|\Z)/) + i + 1 }
    index = i
  end

  result << text[index..-1].to_s
  result
end

#render_template(text) ⇒ Object



101
102
103
104
105
# File 'lib/erbside/inline.rb', line 101

def render_template(text)
  #Dir.chdir(file.parent) do
    context.render(text)
  #end
end

#saveObject

Save result to file.



128
129
130
# File 'lib/erbside/inline.rb', line 128

def save
  File.open(output, 'w'){ |f| f << result }
end