From 1bacc378684cd4b5b9bf9a11146222b820b57296 Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Sat, 23 Nov 2024 03:16:06 -0700 Subject: [PATCH] resolves #59 track header attributes in source document and assign to source_header_attributes property on Document instance --- CHANGELOG.adoc | 6 ++++++ lib/asciidoctor/reducer/extensions.rb | 2 ++ .../reducer/header_attribute_tracker.rb | 16 ++++++++++++++++ spec/extensions_spec.rb | 1 + spec/reducer_spec.rb | 13 ++++++++++++- 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 lib/asciidoctor/reducer/header_attribute_tracker.rb diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 4678912..4a90f4c 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -4,6 +4,12 @@ This document provides a curated view of the changes to Asciidoctor Reducer in each release. For a detailed view of what has changed, refer to the {url-repo}/commits/main[commit history] on GitHub. +== Unreleased + +=== Added + +* Track header attributes in source document and assign to `source_header_attributes` attr reader on Document instance (#59) + == 1.0.6 (2024-02-12) - @mojavelinux === Fixed diff --git a/lib/asciidoctor/reducer/extensions.rb b/lib/asciidoctor/reducer/extensions.rb index 21f6ef9..d88710f 100644 --- a/lib/asciidoctor/reducer/extensions.rb +++ b/lib/asciidoctor/reducer/extensions.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'asciidoctor' unless defined? Asciidoctor.load +require_relative 'header_attribute_tracker' require_relative 'preprocessor' require_relative 'tree_processor' @@ -10,6 +11,7 @@ module Extensions def group proc do + document.extend HeaderAttributeTracker next if document.options[:reduced] # group invoked again if includes are found and sourcemap option is true preprocessor Preprocessor tree_processor TreeProcessor diff --git a/lib/asciidoctor/reducer/header_attribute_tracker.rb b/lib/asciidoctor/reducer/header_attribute_tracker.rb new file mode 100644 index 0000000..04345cb --- /dev/null +++ b/lib/asciidoctor/reducer/header_attribute_tracker.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Asciidoctor::Reducer + module HeaderAttributeTracker + def self.extended instance + instance.singleton_class.send :attr_reader, :source_header_attributes + end + + def finalize_header(*) # rubocop:disable Style/MethodDefParentheses + @source_header_attributes = @attributes_modified.each_with_object({}) do |name, accum| + accum[name] = @attributes[name] + end + super + end + end +end diff --git a/spec/extensions_spec.rb b/spec/extensions_spec.rb index 2855134..98ad9d7 100644 --- a/spec/extensions_spec.rb +++ b/spec/extensions_spec.rb @@ -7,6 +7,7 @@ (expect group).to be_a Proc doc = Asciidoctor.load [] reg = (Asciidoctor::Extensions.create described_class.key, &group).activate doc + (expect doc.singleton_class.ancestors.map(&:name)).to include 'Asciidoctor::Reducer::HeaderAttributeTracker' (expect reg.preprocessors).to have_size 1 (expect reg.tree_processors).to have_size 1 end diff --git a/spec/reducer_spec.rb b/spec/reducer_spec.rb index 573648a..02fb4dd 100644 --- a/spec/reducer_spec.rb +++ b/spec/reducer_spec.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true describe Asciidoctor::Reducer do + let :empty_hash do + {} + end + it 'should be able to require library from Ruby process' do # NOTE asciidoctor/reducer/version will already be required by Bundler script_file = fixture_file 'print_version.rb' @@ -43,6 +47,7 @@ (expect doc.attr 'docname').to eql (input_file_basename '.adoc') (expect doc.attr 'docfile').to eql input_file (expect doc.attr 'docdir').to eql (File.dirname input_file) + (expect doc.source_header_attributes).to eql empty_hash end) end end @@ -61,6 +66,7 @@ (expect doc.options[:reduced]).to be_falsy (expect doc.sourcemap).to be_falsy (expect doc.blocks[0].source_location).to be_nil + (expect doc.source_header_attributes).to eql empty_hash end) end end @@ -1704,6 +1710,7 @@ (expect (doc.attr? 'sectnums')).to be true (expect (doc.attr? 'icons', 'font')).to be true (expect (doc.attr? 'toc')).to be true + (expect doc.source_header_attributes).to eql 'sectnums' => '', 'icons' => 'font', 'toc' => '' end) end end @@ -1811,6 +1818,7 @@ run_scenario do input_source <<~'END' = Book Title + :chaptersdir: ignored include::{chaptersdir}/ch1.adoc[] END @@ -1818,6 +1826,7 @@ reduce_options attributes: 'chaptersdir=chapters', sourcemap: true expected_source <<~'END' = Book Title + :chaptersdir: ignored == Chapter One @@ -1828,7 +1837,9 @@ delegate.call doc blocks = doc.find_by {|it| it.context != :document } (expect blocks).to have_size 3 - (expect (blocks.map {|it| it.lineno })).to eql [1, 3, 5] + (expect (blocks.map {|it| it.lineno })).to eql [1, 4, 6] + # the hash is empty since the attribute is hard set by the API + (expect doc.source_header_attributes).to eql empty_hash end) end end