Class: MasterView::Analyzer::Listener

Inherits:
Object
  • Object
show all
Includes:
Common, DirectiveHelpers, REXML::SAX2Listener
Defined in:
lib/masterview/analyzer.rb

Constant Summary

Constants included from Common

Common::ImportToNonImportDir, Common::NonImportToImportDir

Constants included from DirectiveHelpers

DirectiveHelpers::CRLF, DirectiveHelpers::ERB_CONTENT_END, DirectiveHelpers::ERB_CONTENT_START, DirectiveHelpers::ERB_EVAL_END, DirectiveHelpers::ERB_EVAL_START

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Common

#calc_hash, #convert_import_to_non_import_dirs, #convert_non_import_to_import_dirs, #src_hash

Methods included from DirectiveHelpers

#delete_last_in_parent, #find_last_in_parent, #find_string_val_in_string_hash, #parse, #quote, #quote_if, #render_partial_name_to_file_name

Constructor Details

#initialize(options = {}) ⇒ Listener

Returns a new instance of Listener.



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/masterview/analyzer.rb', line 136

def initialize( options = {} )
  @depth = 0
  @stack = []
  @list = []
  @prolog = [] # prolog if any
  @content = options[:content_hash] || {}
  @options = options
  @only_check_hash = options[:only_check_hash] || false
  @builder = Builder.new(@content)
  @default_extname = options[:default_extname] || ::MasterView::IOMgr.erb.default_extension
  @keyword_expander = KeywordExpander.new
  @keyword_expander.set_template_pathname( options[:template_pathname], @default_extname ) if options[:template_pathname]
  mv_ns = DirectiveRegistry.current.mv_namespace_prefix
  @mv_processing_directives = {
    # attribute_qname => directive_type_flags
    mv_ns+'generate' => { :partial => false, :import => false },
    mv_ns+'gen_partial' => { :partial => true, :import => false },
    mv_ns+'import' => { :partial => false, :import => true },
    mv_ns+'import_render' => { :partial => true, :import => true },
  }
  @mv_import_directive_mappings = {
    # mv:import and mv:import_render get mapped to generate directives during analysis
    mv_ns+'import_render' => mv_ns+'gen_partial',
    mv_ns+'import' => mv_ns+'generate',
  }
  Log.debug { "only_check_hash => true" } if @only_check_hash
end

Instance Attribute Details

#contentObject

Returns the value of attribute content.



134
135
136
# File 'lib/masterview/analyzer.rb', line 134

def content
  @content
end

#listObject

Returns the value of attribute list.



134
135
136
# File 'lib/masterview/analyzer.rb', line 134

def list
  @list
end

Instance Method Details

#cdata(content) ⇒ Object



244
245
246
# File 'lib/masterview/analyzer.rb', line 244

def cdata(content)
  (@stack.last.buffer << '<![CDATA[' << content << ']]>') unless @stack.empty?
end

#characters(text) ⇒ Object



236
237
238
# File 'lib/masterview/analyzer.rb', line 236

def characters(text)
  @stack.last.buffer << text unless @stack.empty?
end

#comment(comment) ⇒ Object



240
241
242
# File 'lib/masterview/analyzer.rb', line 240

def comment(comment)
  @stack.last.buffer << '<!--' << comment << '-->' unless @stack.empty?
end

#doctype(name, pub_sys, long_name, uri) ⇒ Object



176
177
178
179
180
181
182
183
184
185
# File 'lib/masterview/analyzer.rb', line 176

def doctype(name, pub_sys, long_name, uri)
  xml_doctype = []
  xml_doctype << '<!DOCTYPE'
  xml_doctype << name
  xml_doctype << pub_sys unless pub_sys.nil?
  xml_doctype << %Q["#{long_name}"] unless long_name.nil?
  xml_doctype << %Q["#{uri}"] unless uri.nil?
  doctype_str = xml_doctype.join(' ')+'>'
  @prolog << doctype_str
end

#end_documentObject



265
266
267
# File 'lib/masterview/analyzer.rb', line 265

def end_document
  #todo
end

#end_element(uri, localname, qname) ⇒ Object



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/masterview/analyzer.rb', line 248

def end_element(uri, localname, qname)
  unless @stack.empty?
    if @stack.last.buffer.last == '>' && MasterView::TemplateProcessing::Renderer::XHTMLEmptyElementNameSet.include?(qname) #collapse
      @stack.last.buffer.pop
      @stack.last.buffer << '/>'
    else
      @stack.last.buffer << '</' << "#{qname}>" #must output </ as separate string so simplify_empty_elements can find it, though currently not using simplify_empty_elements in rebuilding only in parser for generation
    end
  end

  if @stack.last && @depth == @stack.last.depth
    store_last_buffer true
    @stack.pop
  end
  @depth -= 1
end

#only_check_hash?Boolean

Returns:

  • (Boolean)


164
165
166
# File 'lib/masterview/analyzer.rb', line 164

def only_check_hash?
  @only_check_hash
end

#start_documentObject



172
173
174
# File 'lib/masterview/analyzer.rb', line 172

def start_document
  #todo
end

#start_element(uri, localname, qname, attributes) ⇒ Object



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/masterview/analyzer.rb', line 187

def start_element(uri, localname, qname, attributes)
  unescape_attributes!(attributes)
  @depth += 1

  # expand the target specification to the actual path for import/generate directives in case of rebuilding
  path = nil
  import = false
  page_attributes = { }
  @mv_processing_directives.each_pair { | mv_attr_name, directive_type_flags |
    if attributes.has_key?( mv_attr_name )
      expanded_attr_value = @keyword_expander.expand_keywords(attributes[mv_attr_name])
      attributes[mv_attr_name] = expanded_attr_value
      if directive_type_flags[:partial]
        partial = find_string_val_in_string_hash( expanded_attr_value, :partial )
        path = render_partial_name_to_file_name(partial, @default_extname)
        page_attributes[partial] = expanded_attr_value  # save all the page specific values of gen_partial and import_partial by path
        attributes[mv_attr_name] = ":partial => '#{partial}'" # exclude others for comparison will be put back
      else
        path = expanded_attr_value
      end
      import = directive_type_flags[:import]
      break
    end
  }

  if path
    store_last_buffer false
    @stack << StackEntry.new(path, @depth, import, page_attributes)
  end

  unless @stack.empty?
    @stack.last.buffer << "<#{qname}"
    sorted_attributes = attributes.sort do |a,b| # sort import and import_render like generate and gen_partial so hashs work
      a_working = a[0]
      b_working = b[0]
      working_cmp = [a_working, b_working].collect do |working|
        # mv:import and mv:import_render to generate directives
        working = @mv_import_directive_mappings.fetch(working, working)
        working
      end
      working_cmp[0] <=> working_cmp[1]
    end
    sorted_attributes.each do |name, value|
      @stack.last.buffer << " #{name}=\"#{value}\""
    end
    @stack.last.buffer << '>' #must output as separate string so simplify_empty_elements can find it
  end
end

#store_last_buffer(end_element) ⇒ Object



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/masterview/analyzer.rb', line 277

def store_last_buffer(end_element)
    unless @stack.empty?
      last_stack_entry = @stack.last
      last_stack_entry.inc_parts
      index = end_element ? -1 : last_stack_entry.parts-1
      data = last_stack_entry.buffer.join
      unless @prolog.empty?
        data = @prolog.join + data
        @prolog = []
      end

      hash_invalid = false;
      if last_stack_entry.import
        if only_check_hash?
          hash = src_hash(data)
          bdata = @builder.data(last_stack_entry.name, index)
          hash_invalid = src_hash(bdata) != hash
          if hash_invalid
            Log.debug { 'hash_invalid contents'}
            Log.debug { 'src='+bdata }
            Log.debug { 'imp='+data }
          end
          #hash_invalid = @builder.hash(last_stack_entry.name, index) != hash
        end
      elsif !only_check_hash?
        @content[last_stack_entry.name] ||= []
        @content[last_stack_entry.name] << ContentEntry.new(data)
      end

      last_stack_entry.buffer = []
      @list << ListEntry.new(last_stack_entry.name, index, last_stack_entry.import, last_stack_entry.page_attributes)

      if only_check_hash? #only set these flags if doing hash_check, not accurate for first round parse
        @list.last.hash_invalid = hash_invalid
      end
    end
end

#unescape_attributes!(attributes) ⇒ Object



269
270
271
272
273
274
# File 'lib/masterview/analyzer.rb', line 269

def unescape_attributes!(attributes)
  attributes.each do |name, value|
    value.replace CGI::unescapeHTML(value)
    value.gsub!('&apos;', '\'')
  end
end

#xmldecl(version, encoding, standalone) ⇒ Object



168
169
170
# File 'lib/masterview/analyzer.rb', line 168

def xmldecl(version, encoding, standalone)
  #todo
end