Skip to content

Commit

Permalink
resolves #1737 add backlink from bibref on bibliography entry to firs…
Browse files Browse the repository at this point in the history
…t reference to that entry in the document (PR #2221)
  • Loading branch information
mojavelinux authored Jun 5, 2022
1 parent 9aea4b7 commit 56ce434
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Enhancements::

* add `save_theme` helper to work with a copy of the theme within a scope (#2196)
* add support for `scale` attribute or `iw` unit on `pdfwidth` attribute on image macros (#1933)
* add backlink from bibref on bibliography entry to first reference to that entry in the document (#1737)

== 2.0.7 (2022-06-03) - @mojavelinux

Expand Down
14 changes: 10 additions & 4 deletions lib/asciidoctor/pdf/converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,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 @@ -2393,20 +2394,25 @@ def convert_inline_anchor node
if (text = ref.xreftext node.attr 'xrefstyle', nil, true)&.include? '<a'
text = text.gsub DropAnchorRx, ''
end
if ref.inline? && ref.type == :bibref && !scratch? && (@bibref_refs.add? refid)
anchor = %(<a id="_bibref_ref_#{refid}">#{DummyText}</a>)
end
@resolving_xref = nil
end
%(<a anchor="#{derive_anchor_from_id refid}">#{text || "[#{refid}]"}</a>).gsub ']', '&#93;'
%(#{anchor || ''}<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 first 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 56ce434

Please sign in to comment.