lib/prawn_html/context.rb
# frozen_string_literal: true module PrawnHtml class Context < Array DEFAULT_STYLES = { size: 16 * PX }.freeze attr_reader :previous_tag attr_accessor :last_text_node # Init the Context def initialize(*_args) super @last_text_node = false @merged_styles = nil @previous_tag = nil end # Add an element to the context # # Set the parent for the previous element in the chain. # Run `on_context_add` callback method on the added element. # # @param element [Tag] the element to add # # @return [Context] the context updated def add(element) element.parent = last push(element) element.on_context_add(self) if element.respond_to?(:on_context_add) @merged_styles = nil self end # Evaluate before content # # @return [String] before content string def before_content (last.respond_to?(:before_content) && last.before_content) || '' end # Merges the context block styles # # @return [Hash] the hash of merged styles def block_styles each_with_object({}) do |element, res| element.block_styles.each do |key, value| Attributes.merge_attr!(res, key, value) end end end # Merge the context styles for text nodes # # @return [Hash] the hash of merged styles def merged_styles @merged_styles ||= each_with_object(DEFAULT_STYLES.dup) do |element, res| evaluate_element_styles(element, res) element.update_styles(res) end end # :nocov: def inspect map(&:class).map(&:to_s).join(', ') end # :nocov: # Remove the last element from the context def remove_last last.on_context_remove(self) if last.respond_to?(:on_context_remove) @merged_styles = nil @last_text_node = false @previous_tag = last pop end # White space is equal to 'pre'? # # @return [boolean] white space property of the last element is equal to 'pre' def white_space_pre? last && last.styles[:white_space] == :pre end private def evaluate_element_styles(element, res) styles = element.styles.slice(*Attributes::STYLES_APPLY[:text_node]) styles.each do |key, val| if res.include?(key) && res[key].is_a?(Array) res[key] += val else res[key] = val end end end end end