summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorklonfish <1299450+klonfish@users.noreply.github.com>2021-02-27 23:36:03 +0100
committerGitHub <noreply@github.com>2021-02-27 15:36:03 -0700
commit481228b7afd8fcaebb3298fac50ef7849f16f82d (patch)
tree6daab8744100d841ce1919f05d403a15ed5c88a8
parent1bcce7d47b44041deebcf5b8b61cbd2e193d5dca (diff)
resolves #1880 allow theme to customize quotation mark characters (PR #1713)
Co-authored-by: Dan Allen <dan.j.allen@gmail.com>
-rw-r--r--CHANGELOG.adoc1
-rw-r--r--docs/theming-guide.adoc21
-rw-r--r--lib/asciidoctor/pdf/converter.rb14
-rw-r--r--spec/formatted_text_formatter_spec.rb55
4 files changed, 88 insertions, 3 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index e45c44d9..35c35911 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -61,6 +61,7 @@ Enhancements::
* add support for power operator in theme (with same precedence as multiply and divide) (#1813)
* include floor and ceil match characters in fallback font (#1832) (*@oddhack*)
* allow horizontal and vertical lines of table grid to be styled independently (#1875) (*@hextremist*)
+* allow theme to define the characters for typographical quotation marks (#1880) (*@klonfish*)
Bug Fixes::
diff --git a/docs/theming-guide.adoc b/docs/theming-guide.adoc
index 4affba3c..b0356ee5 100644
--- a/docs/theming-guide.adoc
+++ b/docs/theming-guide.adoc
@@ -1555,6 +1555,27 @@ The keys in this category control the general spacing between elements where a m
|vertical-spacing: 10
|===
+[#keys-quotes]
+=== Quotes
+
+The keys in this category define the characters to use for typographic quotation marks (i.e., quotes).
+
+[cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+3+|[#key-prefix-quotes]*Key Prefix:* <<key-prefix-quotes,quotes>>
+
+|quotes
+|<<quoted-string,Quoted string[double-open, double-close, single-open, single-close]>> +
+(default: ['\&#8220;', '\&#8221;', '\&#8216;', '\&#8217;'])
+|quotes:
+- '&#x00ab;'
+- '&#x00bb;'
+- '&#x2039;'
+- '&#x203a;'
+|===
+
[#keys-link]
=== Link
diff --git a/lib/asciidoctor/pdf/converter.rb b/lib/asciidoctor/pdf/converter.rb
index 2f0de615..cbf2f4d1 100644
--- a/lib/asciidoctor/pdf/converter.rb
+++ b/lib/asciidoctor/pdf/converter.rb
@@ -102,6 +102,7 @@ module Asciidoctor
'circled' => (?\u2460..?\u2473).to_a,
'filled' => (?\u2776..?\u277f).to_a + (?\u24eb..?\u24f4).to_a,
}
+ TypographicQuotes = %w(&#8220; &#8221; &#8216; &#8217;)
SimpleAttributeRefRx = /(?<!\\)\{\w+(?:-\w+)*\}/
MeasurementRxt = '\\d+(?:\\.\\d+)?(?:in|cm|mm|p[txc])?'
MeasurementPartsRx = /^(\d+(?:\.\d+)?)(in|mm|cm|p[txc])?$/
@@ -472,6 +473,11 @@ module Asciidoctor
theme.title_page_authors_delimiter ||= ', '
theme.title_page_revision_delimiter ||= ', '
theme.toc_hanging_indent ||= 0
+ if ::Array === (quotes = theme.quotes)
+ TypographicQuotes.each_with_index {|char, idx| quotes[idx] ||= char }
+ else
+ theme.quotes = TypographicQuotes
+ end
theme
end
@@ -2660,6 +2666,8 @@ module Asciidoctor
end
def convert_inline_quoted node
+ theme = load_theme node.document
+
case node.type
when :emphasis
open, close, is_tag = ['<em>', '</em>', true]
@@ -2672,9 +2680,9 @@ module Asciidoctor
when :subscript
open, close, is_tag = ['<sub>', '</sub>', true]
when :double
- open, close, is_tag = ['&#8220;', '&#8221;', false]
+ open, close, is_tag = [theme.quotes[0], theme.quotes[1], false]
when :single
- open, close, is_tag = ['&#8216;', '&#8217;', false]
+ open, close, is_tag = [theme.quotes[2], theme.quotes[3], false]
when :mark
open, close, is_tag = ['<mark>', '</mark>', true]
else
@@ -2684,7 +2692,7 @@ module Asciidoctor
inner_text = node.text
if (role = node.role)
- if (text_transform = (load_theme node.document)[%(role_#{role}_text_transform)])
+ if (text_transform = theme[%(role_#{role}_text_transform)])
inner_text = transform_text inner_text, text_transform
end
quoted_text = is_tag ? %(#{open.chop} class="#{role}">#{inner_text}#{close}) : %(<span class="#{role}">#{open}#{inner_text}#{close}</span>)
diff --git a/spec/formatted_text_formatter_spec.rb b/spec/formatted_text_formatter_spec.rb
index d7aaf3a9..3f1f3e09 100644
--- a/spec/formatted_text_formatter_spec.rb
+++ b/spec/formatted_text_formatter_spec.rb
@@ -1035,4 +1035,59 @@ describe Asciidoctor::PDF::FormattedText::Formatter do
(expect default_section_text[1][:font_color]).to eql '333333'
end
end
+
+ describe 'typographic quotes' do
+ it 'should use double curved quotes by default' do
+ pdf = to_pdf '"`Double quoted`"', analyze: true
+ (expect pdf.text[0][:string]).to eql %(\u201cDouble quoted\u201d)
+ end
+
+ it 'should use single curved quotes by default' do
+ pdf = to_pdf '\'`Single quoted`\'', analyze: true
+ (expect pdf.text[0][:string]).to eql %(\u2018Single quoted\u2019)
+ end
+
+ it 'should use user-defined double quotation marks if specified' do
+ pdf_theme = { quotes: %w(&#x00ab; &#x00bb;) }
+ pdf = to_pdf '"`Double quoted`"', pdf_theme: pdf_theme, analyze: true
+ (expect pdf.text[0][:string]).to eql %(\u00abDouble quoted\u00bb)
+ end
+
+ it 'should use user-defined single quotation marks if specified' do
+ pdf_theme = { quotes: %w(&#x00ab; &#x00bb; &#x2039; &#x203a;) }
+ pdf = to_pdf '\'`Single quoted`\'', pdf_theme: pdf_theme, analyze: true
+ (expect pdf.text[0][:string]).to eql %(\u2039Single quoted\u203a)
+ end
+
+ it 'should use single curved quotes by default if theme only specifies double quotation marks' do
+ pdf_theme = { quotes: %w(&#x00ab; &#x00bb;) }
+ pdf = to_pdf '\'`Single quoted`\'', pdf_theme: pdf_theme, analyze: true
+ (expect pdf.text[0][:string]).to eql %(\u2018Single quoted\u2019)
+ end
+
+ it 'should not use the closing single quotation mark as apostrophe' do
+ pdf_theme = { quotes: %w(&#x00ab; &#x00bb; &#x2039; &#x203a;) }
+ pdf = to_pdf <<~'EOS', pdf_theme: pdf_theme, analyze: true
+ Apostrophes`' substitution shouldn`'t match '`single quoted`'
+ EOS
+ (expect pdf.text[0][:string]).to eql %(Apostrophes\u2019 substitution shouldn\u2019t match \u2039single quoted\u203a)
+ end
+
+ it 'should use user-defined quotation marks in the TOC' do
+ pdf_theme = { quotes: %w(&#x00ab; &#x00bb; &#x2039; &#x203a;) }
+ pdf = to_pdf <<~'EOS', pdf_theme: pdf_theme, analyze: true
+ = Document '`Title`'
+ :doctype: book
+ :toc:
+
+ == "`Double Quoted`"
+
+ == '`Single Quoted`'
+
+ EOS
+ (expect (pdf.find_text %(Document \u2039Title\u203a))).to have_size 1
+ (expect (pdf.find_text %(\u00abDouble Quoted\u00bb))).to have_size 2
+ (expect (pdf.find_text %(\u2039Single Quoted\u203a))).to have_size 2
+ end
+ end
end