Class: MasterView::TemplateProcessing::Renderer
- Inherits:
-
Object
- Object
- MasterView::TemplateProcessing::Renderer
- Includes:
- DirectiveHelpers
- Defined in:
- lib/masterview/parser.rb
Overview
A Renderer is configured for a template parser to control the output generated from the template source document. The renderer is responsible for managing directive processing and output generation in response to document event notifications from the SAX source document parser.
Constant Summary collapse
- XHTMLEmptyElementNameSet =
Set of element names that can be simplified. Used in simplify_empty_elements. Only simplify elements that are specified in the DTD as being empty, collapsing others can cause parsing or rendering problems in browsers. www.w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict base, meta, link, hr, br, param, img, area, input, col
%w{ base meta link hr br param img area input col }.to_set
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
-
#default_extension ⇒ Object
readonly
Returns the value of attribute default_extension.
-
#default_render_handler ⇒ Object
Returns the value of attribute default_render_handler.
-
#directive_load_path ⇒ Object
readonly
:nodoc:.
-
#directives_registry ⇒ Object
readonly
:nodoc:.
-
#keyword_expander ⇒ Object
readonly
Returns the value of attribute keyword_expander.
-
#mv_gen_partial_attr ⇒ Object
readonly
Returns the value of attribute mv_gen_partial_attr.
-
#mv_gen_replace_attr ⇒ Object
readonly
Returns the value of attribute mv_gen_replace_attr.
-
#mv_generate_attr ⇒ Object
readonly
Returns the value of attribute mv_generate_attr.
-
#mv_insert_generated_comment_attr ⇒ Object
readonly
Returns the value of attribute mv_insert_generated_comment_attr.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#prolog ⇒ Object
array of strings containing the xml prolog for a doc, on the root this might contain xml declaration and doctype, etc.
-
#render_levels ⇒ Object
Returns the value of attribute render_levels.
-
#serializer ⇒ Object
Returns the value of attribute serializer.
-
#template_full_pathname ⇒ Object
readonly
Returns the value of attribute template_full_pathname.
-
#template_pathname ⇒ Object
readonly
Returns the value of attribute template_pathname.
Instance Method Summary collapse
- #append_content(type, content) ⇒ Object
-
#append_raw(raw_output) ⇒ Object
does not call any directives, direct output.
-
#append_to_prolog(str) ⇒ Object
initialize (if necessary) and append string to xml_prolog array.
- #capitalize_first_letter(string) ⇒ Object
-
#initialize(options = {}) ⇒ Renderer
constructor
A new instance of Renderer.
-
#initialize_directives(load_path) ⇒ Object
Process the directive load_path, re-requiring any new entries and preparing processing context for the current template.
- #modes ⇒ Object
- #pop_level ⇒ Object
- #pop_tag ⇒ Object
- #push_level(render_level) ⇒ Object
- #push_tag(tag_name, attributes) ⇒ Object
- #select_active_directives(tag_name, attributes, mode) ⇒ Object
-
#simplify_empty_elements(content) ⇒ Object
Simplify (collapse) empty elements so that <foo></foo> from rexml parsing ends up being <foo/> .
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 = {}) ⇒ Renderer
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
# File 'lib/masterview/parser.rb', line 303 def initialize( = {} ) @options = @template_pathname = [:template_pathname] @template_full_pathname = IOMgr.template.path(self.template_pathname).full_pathname if self.template_pathname @default_render_handler = SimpleRenderHandler.new @render_levels = [ RenderLevel.new( [RenderMode.new] ) ] serializer = [:serializer] || DefaultSerializer self.serializer = serializer.is_a?(Class) ? serializer.new() : serializer #one can pass in Serializer class or an instance @default_extension = ([:output_mio_tree]) ? [:output_mio_tree].default_extension : IOMgr.erb.default_extension @keyword_expander = KeywordExpander.new @keyword_expander.set_template_pathname(self.template_pathname, @default_extension) self.initialize_directives( [:directive_load_path] ) end |
Instance Attribute Details
#default_extension ⇒ Object (readonly)
Returns the value of attribute default_extension.
290 291 292 |
# File 'lib/masterview/parser.rb', line 290 def default_extension @default_extension end |
#default_render_handler ⇒ Object
Returns the value of attribute default_render_handler.
291 292 293 |
# File 'lib/masterview/parser.rb', line 291 def default_render_handler @default_render_handler end |
#directive_load_path ⇒ Object (readonly)
:nodoc:
293 294 295 |
# File 'lib/masterview/parser.rb', line 293 def directive_load_path @directive_load_path end |
#directives_registry ⇒ Object (readonly)
:nodoc:
294 295 296 |
# File 'lib/masterview/parser.rb', line 294 def directives_registry @directives_registry end |
#keyword_expander ⇒ Object (readonly)
Returns the value of attribute keyword_expander.
290 291 292 |
# File 'lib/masterview/parser.rb', line 290 def @keyword_expander end |
#mv_gen_partial_attr ⇒ Object (readonly)
Returns the value of attribute mv_gen_partial_attr.
296 297 298 |
# File 'lib/masterview/parser.rb', line 296 def mv_gen_partial_attr @mv_gen_partial_attr end |
#mv_gen_replace_attr ⇒ Object (readonly)
Returns the value of attribute mv_gen_replace_attr.
296 297 298 |
# File 'lib/masterview/parser.rb', line 296 def mv_gen_replace_attr @mv_gen_replace_attr end |
#mv_generate_attr ⇒ Object (readonly)
Returns the value of attribute mv_generate_attr.
296 297 298 |
# File 'lib/masterview/parser.rb', line 296 def mv_generate_attr @mv_generate_attr end |
#mv_insert_generated_comment_attr ⇒ Object (readonly)
Returns the value of attribute mv_insert_generated_comment_attr.
297 298 299 |
# File 'lib/masterview/parser.rb', line 297 def mv_insert_generated_comment_attr @mv_insert_generated_comment_attr end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
287 288 289 |
# File 'lib/masterview/parser.rb', line 287 def @options end |
#prolog ⇒ Object
array of strings containing the xml prolog for a doc, on the root this might contain xml declaration and doctype, etc.
301 302 303 |
# File 'lib/masterview/parser.rb', line 301 def prolog @prolog end |
#render_levels ⇒ Object
Returns the value of attribute render_levels.
291 292 293 |
# File 'lib/masterview/parser.rb', line 291 def render_levels @render_levels end |
#serializer ⇒ Object
Returns the value of attribute serializer.
291 292 293 |
# File 'lib/masterview/parser.rb', line 291 def serializer @serializer end |
#template_full_pathname ⇒ Object (readonly)
Returns the value of attribute template_full_pathname.
288 289 290 |
# File 'lib/masterview/parser.rb', line 288 def template_full_pathname @template_full_pathname end |
#template_pathname ⇒ Object (readonly)
Returns the value of attribute template_pathname.
288 289 290 |
# File 'lib/masterview/parser.rb', line 288 def template_pathname @template_pathname end |
Instance Method Details
#append_content(type, content) ⇒ Object
377 378 379 380 381 382 383 |
# File 'lib/masterview/parser.rb', line 377 def append_content(type, content) modes.each do |mode| if mode.tag mode.tag.content << mode.render_directives( type, mode.tag.create_context(:content_part => content) ) end end end |
#append_raw(raw_output) ⇒ Object
does not call any directives, direct output
386 387 388 389 390 391 392 |
# File 'lib/masterview/parser.rb', line 386 def append_raw(raw_output) modes.each do |mode| if mode.tag mode.tag.content << raw_output end end end |
#append_to_prolog(str) ⇒ Object
initialize (if necessary) and append string to xml_prolog array
468 469 470 471 |
# File 'lib/masterview/parser.rb', line 468 def append_to_prolog(str) self.prolog ||= [] self.prolog << str end |
#capitalize_first_letter(string) ⇒ Object
453 454 455 |
# File 'lib/masterview/parser.rb', line 453 def capitalize_first_letter(string) string[0,1].upcase + string[1..-1] end |
#initialize_directives(load_path) ⇒ Object
Process the directive load_path, re-requiring any new entries and preparing processing context for the current template.
Note that any directives that were already required (and loaded) will still be in memory because these are not reset. (i.e., there is not currently a cache vs. reload config option for directive implementations in the way that rails provides for class loading).
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
# File 'lib/masterview/parser.rb', line 330 def initialize_directives( load_path ) #:nodoc: using_current_load_path = (load_path == MasterView::DirectiveLoadPath.current) # ordinary configuration sets up std load path and directives registry for the app session # ??provide hook here for testing alt load paths and config overrides? is this right?? @directives_registry = using_current_load_path ? MasterView::DirectiveRegistry.current : MasterView::DirectiveRegistry.new #ISSUE: do we really need/want to run this o n *every* parse? # Probably ought to have some cache config option like dev/production class loading # [DJL 02-Oct-2006] @directives_registry.process_directives_load_path( load_path ) #?? unless using_current_load_path?? # bind the names of the standard mv template-manipulation directives mv_ns = @directives_registry.mv_namespace_prefix @mv_generate_attr = mv_ns+'generate' @mv_gen_partial_attr = mv_ns+'gen_partial' @mv_gen_replace_attr = mv_ns+'gen_replace' @mv_insert_generated_comment_attr = mv_ns+'insert_generated_comment' #??@mv_import_attr = mv_ns+'import' #??@mv_import_render_attr = mv_ns+'import_render' end |
#modes ⇒ Object
354 355 356 |
# File 'lib/masterview/parser.rb', line 354 def modes @render_levels.last.render_modes end |
#pop_level ⇒ Object
394 395 396 |
# File 'lib/masterview/parser.rb', line 394 def pop_level @render_levels.pop end |
#pop_tag ⇒ Object
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/masterview/parser.rb', line 398 def pop_tag need_to_pop_level = false modes.each do |mode| mode.tag.etag << mode.render_directives(:etag) content = [] content << mode.tag.stag << mode.tag.content << mode.tag.etag content = simplify_empty_elements content last_tag = mode..pop if mode..empty? unless mode.output.nil? @serializer.serialize(mode, last_tag) need_to_pop_level = true end else #add it to the parent mode.tag.content << content end end pop_level if need_to_pop_level end |
#push_level(render_level) ⇒ Object
358 359 360 |
# File 'lib/masterview/parser.rb', line 358 def push_level(render_level) @render_levels.push render_level end |
#push_tag(tag_name, attributes) ⇒ Object
362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/masterview/parser.rb', line 362 def push_tag(tag_name, attributes) tag_prolog = nil unless prolog.nil? tag_prolog = prolog.join("\n") self.prolog = nil # clear now that we have used it, only needs to be applied to this tag end modes.each do |mode| attributes_copy = attributes.clone #these get changed in select_active_directives directives = select_active_directives(tag_name, attributes_copy, mode) parent = (mode..empty?) ? nil : mode.tag mode..push Tag.new(directives, tag_name, attributes_copy, mode.mode_type, parent, tag_prolog, self) mode.tag.stag << mode.render_directives(:stag) end end |
#select_active_directives(tag_name, attributes, mode) ⇒ Object
457 458 459 460 461 462 463 464 465 |
# File 'lib/masterview/parser.rb', line 457 def select_active_directives(tag_name, attributes, mode) selected = DirectiveSet.new directive_processors = directives_registry.construct_directive_processors( tag_name, attributes ) sorted_directives = directive_processors.sort do |dp1,dp2| dp1.priority <=> dp2.priority end sorted_directives << @default_render_handler #insure this is last selected << sorted_directives end |
#simplify_empty_elements(content) ⇒ Object
Simplify (collapse) empty elements so that <foo></foo> from rexml parsing ends up being <foo/> . Only simplify elements that are specified in the DTD as being empty, collapsing others can cause parsing or rendering problems in browsers. Uses constant XHTMLEmptyElementNameSet to find elements that should be collapsed. www.w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict xhtml-1.0-Strict empty elements are: base, meta, link, hr, br, param, img, area, input, col
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 |
# File 'lib/masterview/parser.rb', line 426 def simplify_empty_elements(content) #relies on the fact that > and </ are individual strings and are back to back with nothing in between ret = [] current_element_name = nil next_to_last = nil last = nil content.flatten! content.each do |item| if next_to_last == '>' && last == '</' && XHTMLEmptyElementNameSet.include?(current_element_name) # collapse ret.pop #remove '>' ret.pop #remove '</' ret << ' />' # adding in a space to make xhtml more compatible with html editors and older browsers else ret << item end unless item.nil? if !item.starts_with?('</') && item.starts_with?('<') current_element_name = /^<(\S*)/.match(item)[1] # depending on what is after < this might be empty string elsif last && last.starts_with?('</') current_element_name = nil end end next_to_last = last last = item end ret end |