diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 9067540e9..4e2055411 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -28,6 +28,7 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/master[ * allow theme to specify background image for running content (#356) * allow theme to specify border for admonition block (#444) * allow theme to specify background color for admonition block (#444) +* allow theme to specify background color and full border for quote and verse blocks (#1309) * allow text alignment roles to be used to control alignment of discrete heading * don't apply border to block if border width is not set (or nil) * use font color from pygments style for unhighlighted text (#1441) diff --git a/data/themes/base-theme.yml b/data/themes/base-theme.yml index 341d1bfe0..2b7e9dd8b 100644 --- a/data/themes/base-theme.yml +++ b/data/themes/base-theme.yml @@ -75,10 +75,10 @@ admonition_padding: [0, 12, 0, 12] admonition_label_font_style: bold admonition_label_text_transform: uppercase blockquote_border_color: 'EEEEEE' -blockquote_border_width: 4 +blockquote_border_left_width: 4 blockquote_padding: [6, 12, -6, 14] verse_border_color: 'EEEEEE' -verse_border_width: 4 +verse_border_left_width: 4 verse_padding: [6, 12, -6, 14] code_font_family: Courier code_font_size: 10.8 diff --git a/data/themes/default-theme.yml b/data/themes/default-theme.yml index edd8ea5ab..a0a52df10 100644 --- a/data/themes/default-theme.yml +++ b/data/themes/default-theme.yml @@ -173,15 +173,17 @@ admonition: blockquote: font_size: $base_font_size_large border_color: $base_border_color - border_width: 5 + border_width: 0 + border_left_width: 5 # FIXME disable negative padding bottom once margin collapsing is implemented - padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2] + padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_left_width / 2] cite_font_size: $base_font_size_small cite_font_color: 999999 verse: font_size: $blockquote_font_size border_color: $blockquote_border_color border_width: $blockquote_border_width + border_left_width: $blockquote_border_left_width padding: $blockquote_padding cite_font_size: $blockquote_cite_font_size cite_font_color: $blockquote_cite_font_color diff --git a/docs/theming-guide.adoc b/docs/theming-guide.adoc index 85610608a..6b1975675 100644 --- a/docs/theming-guide.adoc +++ b/docs/theming-guide.adoc @@ -2621,11 +2621,23 @@ The keys in this category control the arrangement and style of quote blocks. 3+|[#key-prefix-blockquote]*Key Prefix:* <> +|background-color +|<> + +(default: _not set_) +|blockquote: + background-color: #dddddd + |border-width^[1]^ |<> + +(default: 0) +|blockquote: + border-width: 0.5 + +|border-left-width^[1]^ +|<> + (default: 4) |blockquote: - border-width: 5 + border-left-width: 5 |border-color^[1]^ |<> + @@ -2720,7 +2732,8 @@ The keys in this category control the arrangement and style of quote blocks. text-transform: uppercase |=== -. Only applies to the left side. +. If border-left-width is non-zero, the border is only applied to the left side. +Otherwise, if border-width is non-zero, the border is drawn around the whole block. [#keys-verse] === Verse @@ -2733,11 +2746,23 @@ The keys in this category control the arrangement and style of verse blocks. 3+|[#key-prefix-verse]*Key Prefix:* <> +|background-color +|<> + +(default: _not set_) +|verse: + background-color: #dddddd + |border-width^[1]^ |<> + +(default: 0) +|verse: + border-width: 0.5 + +|border-left-width^[1]^ +|<> + (default: 4) |verse: - border-width: 5 + border-left-width: 5 |border-color^[1]^ |<> + @@ -2832,7 +2857,8 @@ The keys in this category control the arrangement and style of verse blocks. text-transform: uppercase |=== -. Only applies to the left side. +. If border-left-width is non-zero, the border is only applied to the left side. +Otherwise, if border-width is non-zero, the border is drawn around the whole block. [#keys-sidebar] === Sidebar diff --git a/lib/asciidoctor/pdf/converter.rb b/lib/asciidoctor/pdf/converter.rb index 9bc84588d..98714b15b 100644 --- a/lib/asciidoctor/pdf/converter.rb +++ b/lib/asciidoctor/pdf/converter.rb @@ -983,10 +983,60 @@ def convert_quote_or_verse node add_dest_for_block node if node.id theme_margin :block, :top category = node.context == :quote ? :blockquote : :verse - b_width = @theme[%(#{category}_border_width)] || 0 - b_color = @theme[%(#{category}_border_color)] + unless (b_left_width = @theme[%(#{category}_border_left_width)]) && b_left_width > 0 + b_left_width = nil + if (b_width = @theme[%(#{category}_border_width)]) + b_width = nil unless b_width > 0 + end + end + b_color = @theme[%(#{category}_border_color)] if b_width || b_left_width + bg_color = @theme[%(#{category}_background_color)] keep_together do |box_height = nil| push_scratch node.document if scratch? + if box_height && (b_width || bg_color) + # FIXME: due to the calculation error logged in #789, we must advance page even when content is split across pages + advance_page if box_height > cursor && !at_page_top? + float do + # TODO: move the multi-page logic to theme_fill_and_stroke_bounds + if b_width + if b_color == @page_bg_color # let page background cut into sidebar background + b_gap_color, b_shift = @page_bg_color, b_width + elsif (b_gap_color = bg_color) && b_gap_color != b_color + b_shift = 0 + else # let page background cut into border + b_gap_color, b_shift = @page_bg_color, 0 + end + else # let page background cut into sidebar background + b_shift, b_gap_color = (b_width = 0.5) * 0.5, @page_bg_color + end + b_radius = @theme[%(#{category}_border_radius)] || 0 + initial_page, remaining_height = true, box_height + while remaining_height > 0 + advance_page unless initial_page + fragment_height = [(available_height = cursor), remaining_height].min + bounding_box [0, available_height], width: bounds.width, height: fragment_height do + theme_fill_and_stroke_bounds category + unless b_width == 0 + indent b_radius, b_radius do + move_down b_shift + # dashed line to indicate continuation from previous page; swell line to cover background + stroke_horizontal_rule b_gap_color, line_width: b_width * 1.2, line_style: :dashed + move_up b_shift + end unless initial_page + if remaining_height > fragment_height + move_down fragment_height - b_shift + indent b_radius, b_radius do + # dashed line to indicate continuation to next page; swell line to cover background + stroke_horizontal_rule b_gap_color, line_width: b_width * 1.2, line_style: :dashed + end + end + end + end + remaining_height -= fragment_height + initial_page = false + end + end + end start_page_number = page_number start_cursor = cursor caption_height = node.title? ? (layout_caption node, category: category) : 0 @@ -1007,7 +1057,7 @@ def convert_quote_or_verse node end # FIXME: we want to draw graphics before content, but box_height is not reliable when spanning pages # FIXME: border extends to bottom of content area if block terminates at bottom of page - if box_height && b_width > 0 + if box_height && b_left_width page_spread = page_number - start_page_number + 1 end_cursor = cursor go_to_page start_page_number @@ -1034,7 +1084,7 @@ def convert_quote_or_verse node # NOTE: b_height is 0 when block terminates at bottom of page next if b_height == 0 bounding_box [0, y_draw], width: bounds.width, height: b_height do - stroke_vertical_rule b_color, line_width: b_width, at: b_width / 2.0 + stroke_vertical_rule b_color, line_width: b_left_width, at: b_left_width * 0.5 end end end diff --git a/spec/output/verse-border-and-background-color.pdf b/spec/output/verse-border-and-background-color.pdf new file mode 100644 index 000000000..31e13ddf2 Binary files /dev/null and b/spec/output/verse-border-and-background-color.pdf differ diff --git a/spec/quote_spec.rb b/spec/quote_spec.rb index b95acfa6d..c460fdcfe 100644 --- a/spec/quote_spec.rb +++ b/spec/quote_spec.rb @@ -17,8 +17,8 @@ (expect title_text[:x]).to eql 48.24 end - it 'should not draw left border if border_width is 0' do - pdf = to_pdf <<~'EOS', pdf_theme: { blockquote_border_width: 0 }, analyze: :line + it 'should not draw left border if border_left_width is 0' do + pdf = to_pdf <<~'EOS', pdf_theme: { blockquote_border_left_width: 0 }, analyze: :line ____ Let it be. ____ @@ -50,4 +50,37 @@ (expect quote_borders).to have_size 1 (expect quote_borders[0][:page_number]).to be 1 end + + it 'should apply specified background color', visual: true do + pdf_theme = { + blockquote_background_color: 'dddddd', + blockquote_border_color: 'aa0000', + } + to_file = to_pdf_file <<~'EOS', 'quote-background-color.pdf', pdf_theme: pdf_theme + ____ + Let it be. + + Let it be. + ____ + EOS + + (expect to_file).to visually_match 'quote-background-color.pdf' + end + + it 'should apply specified border and background color', visual: true do + pdf_theme = build_pdf_theme \ + blockquote_border_left_width: 0, + blockquote_border_width: 0.5, + blockquote_border_color: 'aa0000', + blockquote_background_color: 'dddddd' + pdf_theme.blockquote_padding = pdf_theme.sidebar_padding + to_file = to_pdf_file <<~'EOS', 'quote-border-and-background-color.pdf', pdf_theme: pdf_theme + [,Paul McCartney] + ____ + Let it be. + + Let it be. + ____ + EOS + + (expect to_file).to visually_match 'quote-border-and-background-color.pdf' + end end diff --git a/spec/reference/quote-background-color.pdf b/spec/reference/quote-background-color.pdf new file mode 100644 index 000000000..23c0050c1 Binary files /dev/null and b/spec/reference/quote-background-color.pdf differ diff --git a/spec/reference/quote-border-and-background-color.pdf b/spec/reference/quote-border-and-background-color.pdf new file mode 100644 index 000000000..4fc269878 Binary files /dev/null and b/spec/reference/quote-border-and-background-color.pdf differ diff --git a/spec/reference/verse-background-color.pdf b/spec/reference/verse-background-color.pdf new file mode 100644 index 000000000..e0f80a156 Binary files /dev/null and b/spec/reference/verse-background-color.pdf differ diff --git a/spec/reference/verse-border-and-background-color.pdf b/spec/reference/verse-border-and-background-color.pdf new file mode 100644 index 000000000..31e13ddf2 Binary files /dev/null and b/spec/reference/verse-border-and-background-color.pdf differ diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 933c3a377..25768199a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -200,9 +200,7 @@ def initialize end def append_line x, y - unless @color.nil? && @width.nil? - @lines << { page_number: @page_number, from: @from, to: { x: x, y: y }, color: @color, width: @width } - end + @lines << { page_number: @page_number, from: @from, to: { x: x, y: y }, color: @color, width: @width } unless @color.nil? && @width.nil? end def begin_new_subpath x, y diff --git a/spec/verse_spec.rb b/spec/verse_spec.rb index 4f7e04d82..4eae23052 100644 --- a/spec/verse_spec.rb +++ b/spec/verse_spec.rb @@ -36,8 +36,9 @@ (expect lines[2]).to eql %(\u00a0 go) end - it 'should not draw left border if border_width is 0' do - pdf = to_pdf <<~'EOS', pdf_theme: { blockquote_border_width: 0 }, analyze: :line + it 'should not draw left border if border_left_width is 0' do + pdf = to_pdf <<~'EOS', pdf_theme: { verse_border_left_width: 0 }, analyze: :line + [verse] ____ here we @@ -69,4 +70,38 @@ (expect text[0][:font_size]).to eql 10.5 (expect text[0][:font_color]).to eql '555555' end + + it 'should apply specified background color', visual: true do + pdf_theme = { + verse_background_color: 'dddddd', + verse_border_color: 'aa0000', + } + to_file = to_pdf_file <<~'EOS', 'verse-background-color.pdf', pdf_theme: pdf_theme + [verse] + ____ + Let it be. + Let it be. + ____ + EOS + + (expect to_file).to visually_match 'verse-background-color.pdf' + end + + it 'should apply specified border and background color', visual: true do + pdf_theme = build_pdf_theme \ + verse_border_left_width: 0, + verse_border_width: 0.5, + verse_border_color: 'aa0000', + verse_background_color: 'dddddd' + pdf_theme.blockquote_padding = pdf_theme.sidebar_padding + to_file = to_pdf_file <<~'EOS', 'verse-border-and-background-color.pdf', pdf_theme: pdf_theme + [verse,Paul McCartney] + ____ + Let it be. + Let it be. + ____ + EOS + + (expect to_file).to visually_match 'verse-border-and-background-color.pdf' + end end