diff --git a/lib/phlex/sgml.rb b/lib/phlex/sgml.rb index 1f68d5fd..fe627e14 100644 --- a/lib/phlex/sgml.rb +++ b/lib/phlex/sgml.rb @@ -416,14 +416,7 @@ def __attributes__(attributes, buffer = +"") when :style buffer << " " << name << '="' << __styles__(v).gsub('"', """) << '"' else - __attributes__( - v.transform_keys { |subkey| - case subkey - when Symbol then"#{name}-#{subkey.name.tr('_', '-')}" - else "#{name}-#{subkey}" - end - }, buffer - ) + __nested_attributes__(v, "#{name}-", buffer) end when Array value = case k @@ -454,6 +447,50 @@ def __attributes__(attributes, buffer = +"") buffer end + # @api private + # + # Provides the nested-attributes case for serializing out attributes. + # This allows us to skip many of the checks the `__attributes__` method must perform. + def __nested_attributes__(attributes, base_name, buffer = +"") + attributes.each do |k, v| + next unless v + + name = case k + when String then k + when Symbol then k.name.tr("_", "-") + else raise ArgumentError.new("Attribute keys should be Strings or Symbols") + end + + case v + when true + buffer << " " << base_name << name + when String + buffer << " " << base_name << name << '="' << v.gsub('"', """) << '"' + when Symbol + buffer << " " << base_name << name << '="' << v.name.gsub('"', """) << '"' + when Integer, Float + buffer << " " << base_name << name << '="' << v.to_s << '"' + when Hash + __nested_attributes__(v, "#{base_name}-#{name}-", buffer) + when Array + buffer << " " << base_name << name << '="' << v.compact.join(" ").gsub('"', """) << '"' + when Set + buffer << " " << base_name << name << '="' << v.to_a.compact.join(" ").gsub('"', """) << '"' + else + value = if v.respond_to?(:to_phlex_attribute_value) + v.to_phlex_attribute_value + elsif v.respond_to?(:to_str) + v.to_str + else + v.to_s + end + buffer << " " << base_name << name << '="' << value.gsub('"', """) << '"' + end + + buffer + end + end + # @api private def __classes__(c) case c