# frozen_string_literal: true
require_relative 'spec_helper'
describe 'Asciidoctor::PDF::Converter - Dest' do
it 'should not define a dest named __anchor-top if document has no body pages' do
pdf = to_pdf <<~'END'
= Document Title
:doctype: book
END
(expect get_names pdf).to be_empty
end
it 'should define a dest named __anchor-top at top of the first body page' do
pdf = to_pdf <<~'END'
= Document Title
:doctype: book
:toc:
preamble
== Chapter
content
END
(expect (top_dest = get_dest pdf, '__anchor-top')).not_to be_nil
(expect (top_dest[:page_number])).to be 3
_, page_height = get_page_size pdf, top_dest[:page_number]
(expect top_dest[:y]).to eql page_height
end
it 'should define a dest named toc at the top of the first toc page' do
pdf = to_pdf <<~'END'
= Document Title
:doctype: book
:toc:
== Chapter
END
(expect (toc_dest = get_dest pdf, 'toc')).not_to be_nil
(expect toc_dest[:page_number]).to be 2
_, page_height = get_page_size pdf, toc_dest[:page_number]
(expect toc_dest[:y]).to eql page_height
end
it 'should define a dest named toc at the location where the macro toc starts' do
pdf = to_pdf <<~'END'
= Document Title
:toc: macro
content before the toc
toc::[]
== Chapter
== Another Chapter
END
(expect (toc_dest = get_dest pdf, 'toc')).not_to be_nil
(expect (toc_dest[:page_number])).to be 1
_, page_height = get_page_size pdf, toc_dest[:page_number]
(expect toc_dest[:y]).to be < page_height
end
it 'should use the toc macro ID as the name of the dest for the macro toc' do
pdf = to_pdf <<~'END'
= Document Title
:toc: macro
content before the toc
[#macro-toc]
toc::[]
== Chapter
== Another Chapter
END
(expect get_names pdf).to have_key 'macro-toc'
end
it 'should define a dest at the top of a chapter page' do
pdf = to_pdf <<~'END'
= Document Title
:doctype: book
== Chapter
END
(expect (chapter_dest = get_dest pdf, '_chapter')).not_to be_nil
(expect (chapter_dest[:page_number])).to be 2
_, page_height = get_page_size pdf, chapter_dest[:page_number]
(expect chapter_dest[:y]).to eql page_height
end
it 'should define a dest at the top of a part page' do
pdf = to_pdf <<~'END'
= Document Title
:doctype: book
= Part 1
== Chapter
content
END
(expect (part_dest = get_dest pdf, '_part_1')).not_to be_nil
(expect (part_dest[:page_number])).to be 2
_, page_height = get_page_size pdf, part_dest[:page_number]
(expect part_dest[:y]).to eql page_height
end
it 'should define a dest at the top of page for section if section is at top of page' do
pdf = to_pdf <<~'END'
= Document Title
content
<<<
== Section
content
END
(expect (sect_dest = get_dest pdf, '_section')).not_to be_nil
(expect (sect_dest[:page_number])).to be 2
_, page_height = get_page_size pdf, sect_dest[:page_number]
(expect sect_dest[:y]).to eql page_height
end
it 'should define a dest at the top of content area if page does not start with a section' do
pdf_theme = { page_margin: 15 }
pdf = to_pdf <<~'END', pdf_theme: pdf_theme
[#p1]
content
END
(expect (para_dest = get_dest pdf, 'p1')).not_to be_nil
(expect (para_dest[:page_number])).to be 1
_, page_height = get_page_size pdf, para_dest[:page_number]
(expect para_dest[:y]).to eql page_height - 15
end
it 'should register dest for every block that has an ID' do
['', 'abstract', 'example', 'open', 'sidebar', 'quote', 'verse', 'listing', 'literal', 'NOTE'].each do |style|
pdf = to_pdf <<~END
[#{style}#disclaimer]
All views expressed are my own.
END
(expect get_names pdf).to have_key 'disclaimer'
end
end
it 'should register dest for table that has an ID' do
pdf = to_pdf <<~'END'
[#props]
|===
| Name | Value
| Foo | Bar
|===
END
(expect get_names pdf).to have_key 'props'
end
it 'should register dest for media macro that has an ID' do
{
image: 'tux.png',
svg: 'green-bar.svg',
video: 'webcast.mp4',
audio: 'podcast.mp3',
}.each do |macro_name, target|
pdf = to_pdf <<~END
[#media]
#{macro_name == :svg ? 'image' : macro_name.to_s}::#{target}[]
END
(expect get_names pdf).to have_key 'media'
end
end
it 'should register dest for unordered list that has an ID' do
pdf = to_pdf <<~'END'
[#takeaways]
* one
* two
END
(expect get_names pdf).to have_key 'takeaways'
end
it 'should register dest for ordered list that has an ID' do
pdf = to_pdf <<~'END'
[#takeaways]
. one
. two
END
(expect get_names pdf).to have_key 'takeaways'
end
it 'should register dest for description list that has an ID' do
pdf = to_pdf <<~'END'
[#takeaways]
reuse:: try to avoid binning it in the first place
recycle:: if you do bin it, make sure the material gets reused
END
(expect get_names pdf).to have_key 'takeaways'
end
it 'should register dest for callout list that has an ID' do
pdf = to_pdf <<~'END'
----
require 'asciidoctor-pdf' // <1>
Asciidoctor.convert_file 'doc.adoc', backend: 'pdf', safe: :safe // <2>
----
[#details]
<1> requires the library
<2> converts the document to PDF
END
(expect get_names pdf).to have_key 'details'
end
it 'should register dest for each section with implicit ID' do
pdf = to_pdf <<~'END'
== Fee
=== Fi
==== Fo
===== Fum
END
names = get_names pdf
(expect names).to have_key '_fee'
(expect names).to have_key '_fi'
(expect names).to have_key '_fo'
(expect names).to have_key '_fum'
end
it 'should register dest for each section with explicit ID' do
pdf = to_pdf <<~'END'
[#s-fee]
== Fee
[#s-fi]
=== Fi
[#s-fo]
==== Fo
[#s-fum]
===== Fum
END
names = get_names pdf
(expect names).to have_key 's-fee'
(expect names).to have_key 's-fi'
(expect names).to have_key 's-fo'
(expect names).to have_key 's-fum'
end
it 'should not register dest with auto-generated name for each section if sectids are disabled' do
pdf = to_pdf <<~'END'
:!sectids:
== Fee
=== Fi
==== Fo
===== Fum
END
names = get_names pdf
names.delete '__anchor-top'
(expect names).to have_size 4
names.each_key do |name|
(expect name).to start_with '__anchor-'
end
end
it 'should register dest for a discrete heading with an implicit ID' do
pdf = to_pdf <<~'END'
[discrete]
== Bundler
Use this procedure if you're using Bundler.
END
(expect get_names pdf).to have_key '_bundler'
end
it 'should not register dest for a discrete heading when sectids are disabled' do
pdf = to_pdf <<~'END'
:!sectids:
[discrete]
== Bundler
Use this procedure if you're using Bundler.
END
names = get_names pdf
names.delete '__anchor-top'
(expect names).to be_empty
end
it 'should register dest for a discrete heading with an explicit ID' do
pdf = to_pdf <<~'END'
[discrete#bundler]
== Bundler
Use this procedure if you're using Bundler.
END
(expect get_names pdf).to have_key 'bundler'
end
it 'should register dest for a link with an ID' do
pdf = to_pdf <<~'END'
see <>
<<<
https://asciidoctor.org[Asciidoctor,id=link]
END
(expect (link_dest = get_dest pdf, 'link')).not_to be_nil
(expect link_dest[:page_number]).to be 2
end
it 'should hex encode name for ID that contains non-ASCII characters' do
pdf = to_pdf '== Über Étudier'
hex_encoded_id = %(0x#{('_über_étudier'.unpack 'H*')[0]})
names = (get_names pdf).keys.reject {|k| k == '__anchor-top' }
(expect names).to have_size 1
name = names[0]
(expect name).to eql hex_encoded_id
end
it 'should define a dest at the location of an inline anchor' do
['[[details]]details', '[#details]#details#'].each do |details|
pdf = to_pdf <<~END
Here's the intro.
<<<
Here are all the #{details}.
END
(expect (phrase_dest = get_dest pdf, 'details')).not_to be_nil
(expect phrase_dest[:page_number]).to be 2
end
end
it 'should keep anchor with text if text is advanced to next page' do
pdf = to_pdf <<~END
jump to <>
#{(['paragraph'] * 25).join %(\n\n)}
#{(['paragraph'] * 16).join ' '} [#anchor]#supercalifragilisticexpialidocious#
END
(expect (phrase_dest = get_dest pdf, 'anchor')).not_to be_nil
(expect phrase_dest[:page_number]).to be 2
(expect (pdf.page phrase_dest[:page_number]).text).to eql 'supercalifragilisticexpialidocious'
end
it 'should not allocate space for anchor if font is missing glyph for null character' do
pdf_theme = {
extends: 'default',
font_catalog: {
'Missing Null' => {
'normal' => (fixture_file 'mplus1mn-regular-ascii.ttf'),
},
},
base_font_family: 'Missing Null',
}
pdf = to_pdf <<~'END', pdf_theme: pdf_theme, analyze: true
foo [#bar]#bar# #baz#
foo bar #baz#
END
baz_texts = pdf.find_text 'baz'
(expect baz_texts).to have_size 2
(expect baz_texts[0][:x]).to eql baz_texts[1][:x]
end
end