diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 3061a1848..89c07feea 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -9,6 +9,7 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/master[ * fix crash when image_width is defined in theme (#995) * fix crash when toc is enabled and toc-title attribute is unset +* correctly map legacy Font Awesome icon names when icon set is not specified (#1157) * coerce color values in theme that contain uppercase letters (#1149) * ensure base font color is set * use more robust mechanism to detect an empty page; tare content stream after adding page background color or image diff --git a/lib/asciidoctor-pdf/converter.rb b/lib/asciidoctor-pdf/converter.rb index 2eed04722..71922059d 100644 --- a/lib/asciidoctor-pdf/converter.rb +++ b/lib/asciidoctor-pdf/converter.rb @@ -2248,22 +2248,29 @@ def convert_inline_icon node else size_attr = '' end - begin - if icon_set == 'fa' + if icon_set == 'fa' + # legacy name from Font Awesome < 5 + if (remapped_icon_name = resolve_legacy_icon_name icon_name) + requested_icon_name = icon_name + icon_set, icon_name = remapped_icon_name.split '-', 2 + glyph = (icon_font_data icon_set).unicode icon_name + logger.info { %(#{requested_icon_name} icon found in deprecated fa icon set; using #{icon_name} from #{icon_set} icon set instead) } + # new name in Font Awesome >= 5 (but document is configured to use fa icon set) + else font_data = nil - resolved_icon_set = FontAwesomeIconSets.find {|candidate| (font_data = icon_font_data candidate).unicode icon_name rescue nil } - if resolved_icon_set + if (resolved_icon_set = FontAwesomeIconSets.find {|candidate| (font_data = icon_font_data candidate).unicode icon_name rescue nil }) icon_set = resolved_icon_set - logger.info { %(#{icon_name} icon found in deprecated fa icon set; use #{icon_set} icon set instead) } - else - raise + glyph = font_data.unicode icon_name + logger.info { %(#{icon_name} icon not found in deprecated fa icon set; using match found in #{resolved_icon_set} icon set instead) } end - else - font_data = icon_font_data icon_set end + else + glyph = (icon_font_data icon_set).unicode icon_name rescue nil + end + if glyph # TODO support rotate and flip attributes - %(#{font_data.unicode icon_name}) - rescue + %(#{glyph}) + else logger.warn %(#{icon_name} is not a valid icon name in the #{icon_set} icon set) %([#{node.attr 'alt'}]) end diff --git a/lib/asciidoctor-pdf/prawn_ext/extensions.rb b/lib/asciidoctor-pdf/prawn_ext/extensions.rb index 10630988c..1871eed62 100644 --- a/lib/asciidoctor-pdf/prawn_ext/extensions.rb +++ b/lib/asciidoctor-pdf/prawn_ext/extensions.rb @@ -302,6 +302,10 @@ def icon_font_data family ::Prawn::Icon::FontData.load self, family end + def resolve_legacy_icon_name name + ::Prawn::Icon::Compatibility::SHIMS[%(fa-#{name})] + end + def calc_line_metrics line_height = 1, font = self.font, font_size = self.font_size line_height_length = line_height * font_size leading = line_height_length - font_size diff --git a/spec/icon_spec.rb b/spec/icon_spec.rb new file mode 100644 index 000000000..833ff841d --- /dev/null +++ b/spec/icon_spec.rb @@ -0,0 +1,55 @@ +require_relative 'spec_helper' + +describe 'Asciidoctor::PDF::Converter - Icon' do + it 'should use icon name from specified icon set' do + pdf = to_pdf <<~'EOS', analyze: true + :icons: font + :icon-set: fas + + A icon:wrench[] ought to fix it. + EOS + wink_text = pdf.find_text ?\uf0ad + (expect wink_text).to have_size 1 + (expect wink_text[0][:font_name]).to eql 'FontAwesome5Free-Solid' + end + + it 'should use icon name as alt text and warn if icon name not found in icon set' do + (expect { + pdf = to_pdf <<~'EOS', analyze: true + :icons: font + :icon-set: fas + + icon:no-such-icon[] will surely fail. + EOS + text = pdf.text + (expect text).to have_size 1 + (expect text[0][:string]).to eql '[no such icon] will surely fail.' + }).to log_message severity: :WARN, message: 'no-such-icon is not a valid icon name in the fas icon set' + end + + it 'should remap legacy icon name if icon set is not specified and report remapping' do + (expect { + pdf = to_pdf <<~'EOS', analyze: true + :icons: font + + Click the icon:hdd-o[] icon to see your files. + EOS + hdd_text = pdf.find_text ?\uf0a0 + (expect hdd_text).to have_size 1 + (expect hdd_text[0][:font_name]).to eql 'FontAwesome5Free-Regular' + }).to log_message severity: :INFO, message: 'hdd-o icon found in deprecated fa icon set; using hdd from far icon set instead', using_log_level: :INFO + end + + it 'should resolve non-legacy icon name if icon set is not specified and report icon set in which it was found' do + (expect { + pdf = to_pdf <<~'EOS', analyze: true + :icons: font + + Time to upgrade your icon set icon:smile-wink[] + EOS + wink_text = pdf.find_text ?\uf4da + (expect wink_text).to have_size 1 + (expect wink_text[0][:font_name]).to eql 'FontAwesome5Free-Regular' + }).to log_message severity: :INFO, message: 'smile-wink icon not found in deprecated fa icon set; using match found in far icon set instead', using_log_level: :INFO + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7b3b6aadc..c429bb4a8 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -440,7 +440,7 @@ def compute_image_differences reference, actual, difference = nil RSpec::Matchers.define :log_message do |expected| match notify_expectation_failures: true do |actual| - with_memory_logger do |logger| + with_memory_logger expected[:using_log_level] do |logger| actual.call (expect logger).to have_message expected if logger true