From 612426420f688450c04f13fda4defaf062e45bff Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Wed, 29 Jun 2016 23:58:43 -0600 Subject: [PATCH] parse page attribute values individually (PR #115) --- lib/jekyll-asciidoc/integrator.rb | 14 ++++++++------ lib/jekyll-asciidoc/utils.rb | 22 +++++++++++++++++----- spec/jekyll-asciidoc_spec.rb | 26 +++++++++++++------------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/lib/jekyll-asciidoc/integrator.rb b/lib/jekyll-asciidoc/integrator.rb index 3a1ef90..ae4abbc 100644 --- a/lib/jekyll-asciidoc/integrator.rb +++ b/lib/jekyll-asciidoc/integrator.rb @@ -62,12 +62,14 @@ def integrate document, collection_name = nil document.data['author'] = doc.author if doc.author document.data['date'] = (::DateTime.parse doc.revdate).to_time if collection_name == 'posts' && (doc.attr? 'revdate') - len = @page_attr_prefix.length - unless (adoc_front_matter = doc.attributes - .select {|name| len.zero? || (name.start_with? @page_attr_prefix) } - .map {|name, val| %(#{len.zero? ? name : name[len..-1]}: #{Utils.prepare_yaml_value val}) }) - .empty? - document.data.update(::SafeYAML.load adoc_front_matter * NewLine) + no_prefix = (prefix_size = @page_attr_prefix.length).zero? + unless (adoc_header_data = doc.attributes + .each_with_object({}) {|(key, val), accum| + if no_prefix || ((key.start_with? @page_attr_prefix) && key = key[prefix_size..-1]) + accum[key] = ::String === val ? (Utils.parse_yaml_value val) : val + end + }).empty? + document.data.update adoc_header_data end case document.data['layout'] diff --git a/lib/jekyll-asciidoc/utils.rb b/lib/jekyll-asciidoc/utils.rb index 9f5eae4..dbc8286 100644 --- a/lib/jekyll-asciidoc/utils.rb +++ b/lib/jekyll-asciidoc/utils.rb @@ -52,16 +52,28 @@ def get_converter site site.find_converter_instance Converter end - def prepare_yaml_value val - return val unless ::String === val + # Parse the specified value as though it is a single-line value part of a + # YAML key/value pair. + # + # Attempt to parse the specified String value as though it is a + # single-line value part of a YAML key/value pair. If the value fails to + # parse, wrap the value in single quotes (after escaping any single + # quotes in the value) and parse it as a character sequence. If the value + # is empty, return an empty String. + # + # val - The String value to parse. + # + # Returns an [Object] parsed from the string-based YAML value or empty + # [String] if the specified value is empty. + def parse_yaml_value val if val.empty? - '\'\'' + '' else begin ::SafeYAML.load %(--- #{val}) - val rescue - (val.include? '\'') ? %(\'#{val.gsub '\'', '\'\''}\') : %(\'#{val}\') + val = val.gsub '\'', '\'\'' if val.include? '\'' + ::SafeYAML.load %(--- \'#{val}\') end end end diff --git a/spec/jekyll-asciidoc_spec.rb b/spec/jekyll-asciidoc_spec.rb index 90711c2..c40dd2a 100644 --- a/spec/jekyll-asciidoc_spec.rb +++ b/spec/jekyll-asciidoc_spec.rb @@ -121,23 +121,23 @@ end end - describe 'prepare YAML value' do + describe 'parse YAML value' do let :name do 'default_config' end - it 'should prepare YAML value from attribute value' do - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value '').to eql('\'\'') - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value 'true').to eql('true') - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value 'false').to eql('false') - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value '~').to eql('~') - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value '1').to eql('1') - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value '[one, two]').to eql('[one, two]') - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value 'John\'s House').to eql('John\'s House') - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value '\'bar\'').to eql('\'bar\'') - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value '\'').to eql('\'\'\'\'') - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value '-').to eql('\'-\'') - expect(::Jekyll::AsciiDoc::Utils.prepare_yaml_value '@').to eql('\'@\'') + it 'should parse string as YAML value' do + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value '').to eql('') + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value 'true').to be true + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value 'false').to be false + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value '~').to be_nil + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value '1').to eql(1) + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value '[one, two]').to eql(['one', 'two']) + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value 'John\'s House').to eql('John\'s House') + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value '\'bar\'').to eql('bar') + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value '\'').to eql('\'') + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value '-').to eql('-') + expect(::Jekyll::AsciiDoc::Utils.parse_yaml_value '@').to eql('@') end end