Skip to content

Commit

Permalink
resolves asciidoctor#1737 add backlink from bibref to first reference…
Browse files Browse the repository at this point in the history
… to that entry in the document
  • Loading branch information
mojavelinux committed May 30, 2022
1 parent b2e0607 commit a981139
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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::
Expand Down
12 changes: 8 additions & 4 deletions lib/asciidoctor/pdf/converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -2373,20 +2374,23 @@ def convert_inline_anchor node
if (text = ref.xreftext node.attr 'xrefstyle', nil, true)&.include? '<a'
text = text.gsub DropAnchorRx, ''
end
backref = %(<a id="_bibref_ref_#{refid}">#{DummyText}</a>) if ref.inline? && ref.type == :bibref && (@bibref_refs.add? refid)
@resolving_xref = nil
end
%(<a anchor="#{derive_anchor_from_id refid}">#{text || "[#{refid}]"}</a>).gsub ']', '&#93;'
%(#{backref || ''}<a anchor="#{derive_anchor_from_id refid}">#{text || "[#{refid}]"}</a>).gsub ']', '&#93;'
else
%(<a anchor="#{doc.attr 'pdf-anchor'}">#{node.text || '[^top&#93;'}</a>)
end
when :ref
# NOTE: destination is created inside callback registered by FormattedTextTransform#build_fragment
%(<a id="#{node.id}">#{DummyText}</a>)
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}])
%(<a id="#{node.id}">#{DummyText}</a>#{reftext})
reftext = (reftext = node.reftext) ? %([#{reftext}]) : %([#{id}])
reftext = %(<a anchor="_bibref_ref_#{id}">#{reftext}</a>) if @bibref_refs.include? id
# NOTE: destination is created inside callback registered by FormattedTextTransform#build_fragment
%(<a id="#{id}">#{DummyText}</a>#{reftext})
else
log :warn, %(unknown anchor type: #{node.type.inspect})
nil
Expand Down
27 changes: 27 additions & 0 deletions spec/list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 <<bar>>.
Did you read <<bar>>?
<<<
[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

0 comments on commit a981139

Please sign in to comment.