diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2019-07-30 04:03:59 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-30 04:03:59 -0600 |
| commit | c0b694f1fe88747934e4bc681b60fc5ce9278c4b (patch) | |
| tree | fbf766d57ff1974928c19e70c51a9d0031440580 | |
| parent | 9c3857272cd158fe122683a97a716b7638af1596 (diff) | |
resolves #368 add theming support to (inline) roles on phrases (PR #1178)
| -rw-r--r-- | CHANGELOG.adoc | 1 | ||||
| -rw-r--r-- | docs/theming-guide.adoc | 61 | ||||
| -rw-r--r-- | lib/asciidoctor-pdf/formatted_text/transform.rb | 18 | ||||
| -rw-r--r-- | spec/text_formatter_spec.rb | 43 |
4 files changed, 123 insertions, 0 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index b75161ac..f66f47de 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -22,6 +22,7 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/master[ * add support for link on image in running content (#1002) * allow theme to disable font kerning * add support for default theme alignment for tables (#1164) +* add theming support to (inline) roles on phrases (#368) * allow theme to customize style of titles in running content (#1044) * route AFM font warning through Asciidoctor logger * upgrade code font (M+ 1mn) to TESTFLIGHT-63a diff --git a/docs/theming-guide.adoc b/docs/theming-guide.adoc index 83ee1096..5b3183e8 100644 --- a/docs/theming-guide.adoc +++ b/docs/theming-guide.adoc @@ -949,6 +949,67 @@ Each time a theme is loaded, the keys are overlaid onto the keys from the previo - ./brand-theme.yml |=== +[#keys-role] +=== Role + +The keys in the `role` category define custom roles for formatting. +The name of the role is the first subkey level. +The role name may not contain a hyphen or underscore. +The keys under the role are the concrete theming properties. + +Here's an example of a role for making text red: + +[source,yaml] +---- +role: + red: + font-color: #ff0000 +---- + +This role can be used as follows: + +[source,asciidoc] +---- +Error text is shown in [.red]#red#. +---- + +Currently, custom roles only apply to inline phrases and only support changing the font properties. + +[cols="3,4,5l"] +|=== +|Key |Value Type |Example + +3+|[#key-prefix-role]*Key Prefix:* <<key-prefix-role,role-<name> >> + +|font-color +|<<colors,Color>> + +(default: _inherit_) +|role: + red: + font-color: #ff0000 + +|font-family +|<<fonts,Font family name>> + +(default: Courier) +|role: + label: + font-family: M+ 1mn + +|font-size +|<<values,Number>> + +(default: _inherit_) +|role: + large: + font-size: 12 + +|font-style +|<<font-styles,Font style>> + +(default: _inherit_) +|role: + heavy: + font-style: bold +|=== + [#keys-page] === Page diff --git a/lib/asciidoctor-pdf/formatted_text/transform.rb b/lib/asciidoctor-pdf/formatted_text/transform.rb index 51894065..45ee11b8 100644 --- a/lib/asciidoctor-pdf/formatted_text/transform.rb +++ b/lib/asciidoctor-pdf/formatted_text/transform.rb @@ -15,6 +15,12 @@ class Transform } CharRefRx = /&(?:(#{CharEntityTable.keys * ?|})|#(?:(\d\d\d{0,4})|x([a-f\d][a-f\d][a-f\d]{0,3})));/ TextDecorationTable = { 'underline' => :underline, 'line-through' => :strikethrough } + ThemeKeyToFragmentProperty = { + 'font_color' => :color, + 'font_family' => :font, + 'font_size' => :size, + 'font_style' => :styles, + } #DummyText = ?\u0000 def initialize(options = {}) @@ -65,6 +71,16 @@ class Transform styles: to_styles(theme.link_font_style, theme.link_text_decoration), }.compact, } + theme.each_pair.reduce @theme_settings do |accum, (key, val)| + if (key = key.to_s).start_with? 'role_' + role, key = (key.slice 5, key.length).split '_', 2 + if (prop = ThemeKeyToFragmentProperty[key]) + val = to_styles val if prop == :styles + (accum[role] ||= {})[prop] = val + end + end + accum + end else @theme_settings = { button: { font: 'Courier', styles: [:bold].to_set }, @@ -279,6 +295,8 @@ class Transform styles << :underline when 'line-through' styles << :strikethrough + else + fragment.update(@theme_settings[class_name]) {|k, oval, nval| k == :styles ? oval.merge(nval) : oval } if @theme_settings.key? class_name end end if attrs.key?(:class) fragment.delete(:styles) if styles.empty? diff --git a/spec/text_formatter_spec.rb b/spec/text_formatter_spec.rb index e313ab33..ae0ffcc4 100644 --- a/spec/text_formatter_spec.rb +++ b/spec/text_formatter_spec.rb @@ -134,5 +134,48 @@ describe Asciidoctor::PDF::FormattedText::Formatter do to_file = to_pdf_file '*を*', 'text-formatter-fallback-font.pdf', attribute_overrides: { 'pdf-theme' => 'default-with-fallback-font' } (expect to_file).to visually_match 'text-formatter-fallback-font.pdf' end + + it 'should allow theme to control formatting apply to phrase by role' do + pdf_theme = { + role_red_font_color: 'ff0000', + role_red_font_style: 'bold', + role_blue_font_color: '0000ff', + role_blue_font_style: 'bold_italic', + } + pdf = to_pdf 'Roses are [.red]_red_, violets are [.blue]#blue#.', pdf_theme: pdf_theme, analyze: true + + red_text = (pdf.find_text 'red')[0] + blue_text = (pdf.find_text 'blue')[0] + (expect red_text[:font_color]).to eql 'FF0000' + (expect red_text[:font_name]).to eql 'NotoSerif-BoldItalic' + (expect blue_text[:font_color]).to eql '0000FF' + (expect blue_text[:font_name]).to eql 'NotoSerif-BoldItalic' + end + + it 'should append font style configured for role to current style' do + pdf_theme = { + role_quick_font_style: 'italic', + } + pdf = to_pdf '*That was [.quick]#quick#.*', pdf_theme: pdf_theme, analyze: true + + glorious_text = (pdf.find_text 'quick')[0] + (expect glorious_text[:font_name]).to eql 'NotoSerif-BoldItalic' + end + + it 'should support theming multiple roles on a single phrase' do + pdf_theme = { + role_bold_font_style: 'bold', + role_italic_font_style: 'italic', + role_blue_font_color: '0000ff', + role_mono_font_family: 'Courier', + role_tiny_font_size: 8, + } + pdf = to_pdf '[.bold.italic.blue.mono.tiny]#text#', pdf_theme: pdf_theme, analyze: true + + formatted_text = (pdf.find_text 'text')[0] + (expect formatted_text[:font_name]).to eql 'Courier-BoldOblique' + (expect formatted_text[:font_color]).to eql '0000FF' + (expect formatted_text[:font_size]).to eql 8 + end end end |
