diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 1690933c7..91b5c53a2 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -5,6 +5,12 @@ This document provides a high-level view of the changes to the {project-name} by release. For a detailed view of what has changed, refer to the {url-repo}/commits/main[commit history] on GitHub. +== Unreleased + +Enhancements:: + +* add backlink from bibref to first reference to that entry in the document (#1737) + == 2.0.6 (2022-05-30) - @mojavelinux Bug Fixes:: diff --git a/lib/asciidoctor/pdf/converter.rb b/lib/asciidoctor/pdf/converter.rb index a5a33b798..72d29e7de 100644 --- a/lib/asciidoctor/pdf/converter.rb +++ b/lib/asciidoctor/pdf/converter.rb @@ -400,6 +400,7 @@ def init_pdf doc @list_bullets = [] @bottom_gutters = [{}] @rendered_footnotes = [] + @bibref_refs = ::Set.new @conum_glyphs = ConumSets[@theme.conum_glyphs || 'circled'] || (@theme.conum_glyphs.split ',').map do |r| from, to = r.lstrip.split '-', 2 to ? ((get_char from)..(get_char to)).to_a : [(get_char from)] @@ -2373,9 +2374,10 @@ def convert_inline_anchor node if (text = ref.xreftext node.attr 'xrefstyle', nil, true)&.include? '#{DummyText}) if ref.inline? && ref.type == :bibref && (@bibref_refs.add? refid) @resolving_xref = nil end - %(#{text || "[#{refid}]"}).gsub ']', ']' + %(#{backref || ''}#{text || "[#{refid}]"}).gsub ']', ']' else %(#{node.text || '[^top]'}) end @@ -2383,10 +2385,12 @@ def convert_inline_anchor node # NOTE: destination is created inside callback registered by FormattedTextTransform#build_fragment %(#{DummyText}) when :bibref - # NOTE: destination is created inside callback registered by FormattedTextTransform#build_fragment + id = node.id # NOTE: technically node.text should be node.reftext, but subs have already been applied to text - reftext = (reftext = node.reftext) ? %([#{reftext}]) : %([#{node.id}]) - %(#{DummyText}#{reftext}) + reftext = (reftext = node.reftext) ? %([#{reftext}]) : %([#{id}]) + reftext = %(#{reftext}) if @bibref_refs.include? id + # NOTE: destination is created inside callback registered by FormattedTextTransform#build_fragment + %(#{DummyText}#{reftext}) else log :warn, %(unknown anchor type: #{node.type.inspect}) nil diff --git a/spec/list_spec.rb b/spec/list_spec.rb index 3b4b9882e..cfc19fbab 100644 --- a/spec/list_spec.rb +++ b/spec/list_spec.rb @@ -2112,5 +2112,32 @@ (expect lines).to include 'The recommended reading includes [1].' (expect lines).to include '▪ [1] Bar, Foo. All The Things. 2010.' end + + it 'should create bidirectional links between bibref reference and entry' do + pdf = to_pdf <<~'EOS' + The recommended reading includes <>. + + Did you read <>? + + <<< + + [bibliography] + == Bibliography + + * [[[bar]]] Bar, Foo. All The Things. 2010. + * [[[baz]]] Baz. The Rest of the Story. 2020. + EOS + + forward_refs = get_annotations pdf, 1 + (expect forward_refs).to have_size 2 + (expect forward_refs.map {|it| it[:Dest] }.uniq).to eql %w(bar) + ids = (get_names pdf).keys + (expect ids).to include '_bibref_ref_bar' + (expect ids).to include 'bar' + (expect ids).to include 'baz' + back_refs = get_annotations pdf, 2 + (expect back_refs).to have_size 1 + (expect back_refs[0][:Dest]).to eql '_bibref_ref_bar' + end end end