Skip to content

Commit 9230efc

Browse files
authored
Merge pull request #32 from blocknotes/v0.6.0
v0.6.0
2 parents 56baa11 + 5f87d29 commit 9230efc

15 files changed

Lines changed: 176 additions & 50 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ CSS attributes (dimensional units are ignored and considered in pixel):
9090
- **top**: see *position (absolute)*
9191
- **width**: for *img* tag, support also percentage, ex. `<img src="image.jpg" style="width: 50%; height: 200px"/>`
9292

93+
The above attributes supports the `initial` value to reset them to their original value.
94+
9395
For colors, the supported formats are:
9496
- 3 hex digits, ex. `color: #FB1`;
9597
- 6 hex digits, ex. `color: #abcdef`;

lib/prawn_html/attributes.rb

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# frozen_string_literal: true
22

33
require 'ostruct'
4+
require 'set'
45

56
module PrawnHtml
67
class Attributes < OpenStruct
7-
attr_reader :styles
8+
attr_reader :initial, :styles
89

910
STYLES_APPLY = {
1011
block: %i[align bottom leading left margin_left padding_left position right top],
@@ -19,13 +20,13 @@ class Attributes < OpenStruct
1920
'color' => { key: :color, set: :convert_color },
2021
'font-family' => { key: :font, set: :unquote },
2122
'font-size' => { key: :size, set: :convert_size },
22-
'font-style' => { key: :styles, set: :append_styles },
23-
'font-weight' => { key: :styles, set: :append_styles },
23+
'font-style' => { key: :styles, set: :append_styles, values: %i[italic] },
24+
'font-weight' => { key: :styles, set: :append_styles, values: %i[bold] },
2425
'href' => { key: :link, set: :copy_value },
2526
'letter-spacing' => { key: :character_spacing, set: :convert_float },
2627
'list-style-type' => { key: :list_style_type, set: :unquote },
27-
'text-decoration' => { key: :styles, set: :append_text_decoration },
28-
'vertical-align' => { key: :styles, set: :append_styles },
28+
'text-decoration' => { key: :styles, set: :append_styles, values: %i[underline] },
29+
'vertical-align' => { key: :styles, set: :append_styles, values: %i[subscript superscript] },
2930
'white-space' => { key: :white_space, set: :convert_symbol },
3031
# tag opening styles
3132
'break-before' => { key: :break_before, set: :convert_symbol },
@@ -44,7 +45,9 @@ class Attributes < OpenStruct
4445
'position' => { key: :position, set: :convert_symbol },
4546
'right' => { key: :right, set: :convert_size, options: :width },
4647
'text-align' => { key: :align, set: :convert_symbol },
47-
'top' => { key: :top, set: :convert_size, options: :height }
48+
'top' => { key: :top, set: :convert_size, options: :height },
49+
# special styles
50+
'text-decoration-line-through' => { key: :callback, set: :callback_strike_through }
4851
}.freeze
4952

5053
STYLES_MERGE = %i[margin_left padding_left].freeze
@@ -53,6 +56,7 @@ class Attributes < OpenStruct
5356
def initialize(attributes = {})
5457
super
5558
@styles = {} # result styles
59+
@initial = Set.new
5660
end
5761

5862
# Processes the data attributes
@@ -74,6 +78,33 @@ def merge_text_styles!(text_styles, options: {})
7478
process_styles(hash_styles, options: options) unless hash_styles.empty?
7579
end
7680

81+
# Remove an attribute value from the context styles
82+
#
83+
# @param context_styles [Hash] hash of the context styles that will be updated
84+
# @param rule [Hash] rule from the STYLES_LIST to lookup in the context style for value removal
85+
def remove_value(context_styles, rule)
86+
if rule[:set] == :append_styles
87+
context_styles[rule[:key]] -= rule[:values] if context_styles[:styles]
88+
else
89+
default = Context::DEFAULT_STYLES[rule[:key]]
90+
default ? (context_styles[rule[:key]] = default) : context_styles.delete(rule[:key])
91+
end
92+
end
93+
94+
# Update context styles applying the initial rules (if set)
95+
#
96+
# @param context_styles [Hash] hash of the context styles that will be updated
97+
#
98+
# @return [Hash] the update context styles
99+
def update_styles(context_styles)
100+
initial.each do |rule|
101+
next unless rule
102+
103+
remove_value(context_styles, rule)
104+
end
105+
context_styles
106+
end
107+
77108
class << self
78109
# Merges attributes
79110
#
@@ -105,29 +136,30 @@ def parse_styles(styles)
105136
def process_styles(hash_styles, options:)
106137
hash_styles.each do |key, value|
107138
rule = evaluate_rule(key, value)
139+
next unless rule
140+
108141
apply_rule!(merged_styles: @styles, rule: rule, value: value, options: options)
109142
end
110143
@styles
111144
end
112145

113146
def evaluate_rule(rule_key, attr_value)
114-
rule = STYLES_LIST[rule_key]
115-
if rule && rule[:set] == :append_text_decoration
116-
return { key: :callback, set: :callback_strike_through } if attr_value == 'line-through'
117-
118-
return { key: :styles, set: :append_styles }
119-
end
120-
rule
147+
key = nil
148+
key = 'text-decoration-line-through' if rule_key == 'text-decoration' && attr_value == 'line-through'
149+
key ||= rule_key
150+
STYLES_LIST[key]
121151
end
122152

123153
def apply_rule!(merged_styles:, rule:, value:, options:)
124-
return unless rule
154+
return (@initial << rule) if value == 'initial'
125155

126156
if rule[:set] == :append_styles
127-
(merged_styles[rule[:key]] ||= []) << Utils.normalize_style(value)
157+
val = Utils.normalize_style(value)
158+
(merged_styles[rule[:key]] ||= []) << val if val
128159
else
129160
opts = rule[:options] ? options[rule[:options]] : nil
130-
merged_styles[rule[:key]] = Utils.send(rule[:set], value, options: opts)
161+
val = Utils.send(rule[:set], value, options: opts)
162+
merged_styles[rule[:key]] = val if val
131163
end
132164
end
133165
end

lib/prawn_html/context.rb

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
module PrawnHtml
44
class Context < Array
5-
DEF_FONT_SIZE = 16 * PX
5+
DEFAULT_STYLES = {
6+
size: 16 * PX
7+
}.freeze
68

79
attr_reader :previous_tag
810
attr_accessor :last_text_node
@@ -54,9 +56,9 @@ def block_styles
5456
# @return [Hash] the hash of merged styles
5557
def merged_styles
5658
@merged_styles ||=
57-
each_with_object(base_styles) do |element, res|
59+
each_with_object(DEFAULT_STYLES.dup) do |element, res|
5860
evaluate_element_styles(element, res)
59-
element.update_styles(res) if element.respond_to?(:update_styles)
61+
element.update_styles(res)
6062
end
6163
end
6264

@@ -71,12 +73,6 @@ def remove_last
7173

7274
private
7375

74-
def base_styles
75-
{
76-
size: DEF_FONT_SIZE
77-
}
78-
end
79-
8076
def evaluate_element_styles(element, res)
8177
styles = element.styles.slice(*Attributes::STYLES_APPLY[:text_node])
8278
styles.each do |key, val|

lib/prawn_html/document_renderer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def apply_callbacks(buffer)
129129
def adjust_leading(buffer, leading)
130130
return leading if leading
131131

132-
(buffer.map { |item| item[:size] || Context::DEF_FONT_SIZE }.max * 0.055).round(4)
132+
(buffer.map { |item| item[:size] || Context::DEFAULT_STYLES[:size] }.max * 0.055).round(4)
133133
end
134134

135135
def bounds(buffer, options, block_styles)

lib/prawn_html/tag.rb

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22

33
module PrawnHtml
44
class Tag
5+
extend Forwardable
6+
57
CALLBACKS = {
68
'Background' => Callbacks::Background,
79
'StrikeThrough' => Callbacks::StrikeThrough
810
}.freeze
11+
912
TAG_CLASSES = %w[A B Blockquote Body Br Code Del Div H Hr I Img Li Mark Ol P Pre Small Span Sub Sup U Ul].freeze
1013

14+
def_delegators :@attrs, :styles, :update_styles
15+
1116
attr_accessor :parent
1217
attr_reader :attrs, :tag
1318

@@ -45,6 +50,7 @@ def process_styles(element_styles: nil)
4550
attrs.merge_text_styles!(tag_styles, options: options) if respond_to?(:tag_styles)
4651
attrs.merge_text_styles!(element_styles, options: options) if element_styles
4752
attrs.merge_text_styles!(attrs.style, options: options)
53+
attrs.merge_text_styles!(extra_styles, options: options) if respond_to?(:extra_styles)
4854
end
4955

5056
# Styles to apply on tag closing
@@ -54,13 +60,6 @@ def tag_close_styles
5460
styles.slice(*Attributes::STYLES_APPLY[:tag_close])
5561
end
5662

57-
# Styles hash
58-
#
59-
# @return [Hash] hash of styles
60-
def styles
61-
attrs.styles
62-
end
63-
6463
# Styles to apply on tag opening
6564
#
6665
# @return [Hash] hash of styles to apply

lib/prawn_html/tags/a.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ module Tags
55
class A < Tag
66
ELEMENTS = [:a].freeze
77

8-
def tag_styles
9-
return unless attrs.href
8+
def extra_styles
9+
attrs.href ? "href: #{attrs.href}" : nil
10+
end
1011

12+
def tag_styles
1113
<<~STYLES
1214
color: #00E;
13-
href: #{attrs.href};
1415
text-decoration: underline;
1516
STYLES
1617
end

lib/prawn_html/tags/small.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ module Tags
55
class Small < Tag
66
ELEMENTS = [:small].freeze
77

8-
def update_styles(styles)
9-
size = (styles[:size] || Context::DEF_FONT_SIZE) * 0.85
10-
styles[:size] = size
11-
styles
8+
def update_styles(context_styles)
9+
size = (context_styles[:size] || Context::DEFAULT_STYLES[:size]) * 0.85
10+
context_styles[:size] = size
11+
super(context_styles)
1212
end
1313
end
1414
end

lib/prawn_html/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module PrawnHtml # :nodoc:
4-
VERSION = '0.5.0'
4+
VERSION = '0.6.0'
55
end

spec/integrations/blocks_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
RSpec.describe 'Blocks' do
44
let(:pdf) { Prawn::Document.new(page_size: 'A4', page_layout: :portrait) }
5-
let(:size) { PrawnHtml::Context::DEF_FONT_SIZE }
5+
let(:size) { PrawnHtml::Context::DEFAULT_STYLES[:size] }
66

77
before do
88
PrawnHtml.append_html(pdf, html)

spec/support/test_utils.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module TestUtils
44
extend self
55

6-
def adjust_leading(size = PrawnHtml::Context::DEF_FONT_SIZE)
6+
def adjust_leading(size = PrawnHtml::Context::DEFAULT_STYLES[:size])
77
(size * 0.055).round(4)
88
end
99

@@ -16,7 +16,7 @@ def default_font_family
1616
end
1717

1818
def default_font_size
19-
PrawnHtml::Context::DEF_FONT_SIZE
19+
PrawnHtml::Context::DEFAULT_STYLES[:size]
2020
end
2121

2222
def font_ascender(font_family: 'Helvetica', font_size: default_font_size)

0 commit comments

Comments
 (0)