lib/dryml/template.rb in dryml-1.4.0.pre8 vs lib/dryml/template.rb in dryml-2.0.0.pre1

- old
+ new

@@ -12,10 +12,12 @@ RUBY_NAME = "[a-zA-Z_][a-zA-Z0-9_]*" RUBY_NAME_RX = /^#{RUBY_NAME}$/ CODE_ATTRIBUTE_CHAR = "&" + NO_METADATA_TAGS = %w(doctype if else unless repeat do with name type-name) + SPECIAL_ATTRIBUTES = %w(param merge merge-params merge-attrs for-type if unless repeat part part-locals restore) @@ -395,13 +397,42 @@ start = "_tag_context(all_attributes) do #{setup_locals}" "#{start} " + # reproduce any line breaks in the start-tag so that line numbers are preserved - tag_newlines(el) + "%>" + children_to_erb(el) + "<% output_buffer; end" + tag_newlines(el) + "%>" + + wrap_tag_method_body_with_metadata(children_to_erb(el)) + + "<% output_buffer; end" end + # this function is now basically just a hook for DrymlFireMarker + def wrap_source_with_metadata(content, kind, name, *args) + content + end + + def wrap_tag_method_body_with_metadata(content) + name = @def_element.attributes['tag'] + for_ = @def_element.attributes['for'] + name += " for #{for_}" if for_ + wrap_source_with_metadata(content, "def", name, element_line_num(@def_element)) + end + + + def wrap_tag_call_with_metadata(el, content) + name = el.expanded_name + param = el.attributes['param'] + + if param == "&true" + name += " param" + elsif param + name += " param='#{param}'" + end + + wrap_source_with_metadata(content, "call", name, element_line_num(el)) + end + + def param_content_local_name(name) "_#{ruby_name name}__default_content" end @@ -572,11 +603,12 @@ "#{ruby_name name}(#{attributes}, #{parameters})" end end call = apply_control_attributes(call, el) - maybe_make_part_call(el, "<% concat(#{call}) %>") + call = maybe_make_part_call(el, "<% concat(#{call}) %>") + wrap_tag_call_with_metadata(el, call) end def merge_attribute(el) merge = el.attributes['merge'] @@ -586,10 +618,12 @@ def parameter_tags_hash(el, containing_tag_name=nil) call_type = nil + metadata_name = containing_tag_name || el.expanded_name + param_items = el.map do |node| case node when REXML::Text text = node.to_s unless text.blank? @@ -610,11 +644,11 @@ when :default_param_only dryml_exception("mixed parameter tags and non-parameter tags (did you forget a ':'?)", el) if is_parameter_tag end if is_parameter_tag - parameter_tag_hash_item(e) + ", " + parameter_tag_hash_item(e, metadata_name) + ", " end end end.join if call_type == :default_param_only || (call_type.nil? && param_items.length > 0) || (el.children.empty? && el.has_end_tag?) @@ -646,81 +680,90 @@ without_names = el.attributes.keys.map { |name| name =~ /^without-(.*)/ and $1 }.compact without_names.map { |name| ":#{ruby_name name}_replacement => proc {|__discard__| '' }, " }.join end - def parameter_tag_hash_item(el) + def parameter_tag_hash_item(el, metadata_name) name = el.name.dup if name.sub!(/^before-/, "") - before_parameter_tag_hash_item(name, el) + before_parameter_tag_hash_item(name, el, metadata_name) elsif name.sub!(/^after-/, "") - after_parameter_tag_hash_item(name, el) + after_parameter_tag_hash_item(name, el, metadata_name) elsif name.sub!(/^prepend-/, "") - prepend_parameter_tag_hash_item(name, el) + prepend_parameter_tag_hash_item(name, el, metadata_name) elsif name.sub!(/^append-/, "") - append_parameter_tag_hash_item(name, el) + append_parameter_tag_hash_item(name, el, metadata_name) else hash_key = ruby_name name hash_key += "_replacement" if el.attribute("replace") if (param_name = get_param_name(el)) - ":#{hash_key} => merge_tag_parameter(#{param_proc(el)}, all_parameters[:#{param_name}])" + ":#{hash_key} => merge_tag_parameter(#{param_proc(el, metadata_name)}, all_parameters[:#{param_name}])" else - ":#{hash_key} => #{param_proc(el)}" + ":#{hash_key} => #{param_proc(el, metadata_name)}" end end end - def before_parameter_tag_hash_item(name, el) + def before_parameter_tag_hash_item(name, el, metadata_name) param_name = get_param_name(el) dryml_exception("param declaration not allowed on 'before' parameters", el) if param_name content = children_to_erb(el) + "<% concat(#{param_restore_local_name(name)}.call({}, {})) %>" - ":#{ruby_name name}_replacement => #{replace_parameter_proc(el, content)}" + ":#{ruby_name name}_replacement => #{replace_parameter_proc(el, metadata_name, content)}" end - def after_parameter_tag_hash_item(name, el) + def after_parameter_tag_hash_item(name, el, metadata_name) param_name = get_param_name(el) dryml_exception("param declaration not allowed on 'after' parameters", el) if param_name content = "<% concat(#{param_restore_local_name(name)}.call({}, {})) %>" + children_to_erb(el) - ":#{ruby_name name}_replacement => #{replace_parameter_proc(el, content)}" + ":#{ruby_name name}_replacement => #{replace_parameter_proc(el, metadata_name, content)}" end - def append_parameter_tag_hash_item(name, el) + def append_parameter_tag_hash_item(name, el, metadata_name) ":#{ruby_name name} => proc { [{}, { :default => proc { |#{param_content_local_name(name)}| new_context { %>" + param_content_element(name) + children_to_erb(el) + "<% ; output_buffer } } } ] }" end - def prepend_parameter_tag_hash_item(name, el) + def prepend_parameter_tag_hash_item(name, el, metadata_name) ":#{ruby_name name} => proc { [{}, { :default => proc { |#{param_content_local_name(name)}| new_context { %>" + children_to_erb(el) + param_content_element(name) + "<% ; output_buffer } } } ] }" end def default_param_proc(el, containing_param_name=nil) content = children_to_erb(el) + content = wrap_source_with_metadata(content, "param", containing_param_name, + element_line_num(el)) if containing_param_name "proc { |#{param_content_local_name(el.dryml_name)}| new_context { %>#{content}<% ; output_buffer } #{tag_newlines(el)}}" end def param_restore_local_name(name) "_#{ruby_name name}_restore" end - def param_proc(el) + def wrap_replace_parameter(el, name) + wrap_source_with_metadata(children_to_erb(el), "replace", name, element_line_num(el)) + end + + + def param_proc(el, metadata_name_suffix) + metadata_name = "#{el.name} < #{metadata_name_suffix}" + nl = tag_newlines(el) if (repl = el.attribute("replace")) dryml_exception("replace attribute must not have a value", el) if repl.has_rhs? dryml_exception("replace parameters must not have attributes", el) if el.attributes.length > 1 - replace_parameter_proc(el, children_to_erb(el)) + replace_parameter_proc(el, metadata_name, children_to_erb(el)) else attributes = el.attributes.dup # Providing one of 'with' or 'field' but not the other should cancel out the other attributes[:with] = "&nil" if attributes.key?(:field) && !attributes.key?(:with) attributes[:field] = "&nil" if !attributes.key?(:field) && attributes.key?(:with) @@ -732,16 +775,17 @@ else ":#{ruby_name name} => #{attribute_to_ruby(value, el)}" end end.compact - nested_parameters_hash = parameter_tags_hash(el) + nested_parameters_hash = parameter_tags_hash(el, metadata_name) "proc { [{#{attribute_items * ', '}}, #{nested_parameters_hash}] #{nl}}" end end - def replace_parameter_proc(el, content=nil) + def replace_parameter_proc(el, metadata_name, content=nil) + content ||= wrap_replace_parameter(el, metadata_name) param_name = el.dryml_name.sub(/^(before|after|append|prepend)-/, "") "proc { |#{param_restore_local_name(param_name)}| new_context { %>#{content}<% ; output_buffer } #{tag_newlines(el)}}" end