class Inkcite::Renderer::Base

Constants

BACKGROUND_COLOR

Constants for style and property names with dashes in them.

BACKGROUND_GRADIENT
BACKGROUND_GRADIENT_POSITION
BACKGROUND_GRADIENT_SHAPE
BACKGROUND_IMAGE
BACKGROUND_POSITION
BACKGROUND_REPEAT
BACKGROUND_SIZE
BORDER_BOTTOM
BORDER_COLLAPSE
BORDER_COLOR
BORDER_LEFT
BORDER_RADIUS
BORDER_RIGHT
BORDER_SPACING
BORDER_STYLE
BORDER_TOP
BORDER_WIDTH
BOX_SHADOW
CIRCLE
DIMENSIONS

Attribute and CSS dimensions

DIRECTIONS

CSS direction suffixes including nil/empty for convenience.

FONT_FAMILY
FONT_SIZE
FONT_WEIGHT
JUSTIFY

Constant for justified text alignment.

LETTER_SPACING
LINEAR

For gradients

LINE_HEIGHT
MARGIN
MARGIN_BOTTOM
MARGIN_LEFT
MARGIN_RIGHT
MARGIN_TOP
MAX_HEIGHT
MAX_WIDTH
MSO_HIDE
MSO_PADDING_ALT
NONE
OUTLOOK_SRC

Name of the property that allows an outlook-specific src to be specified for an image.

PADDING_X
PADDING_Y
POUND_SIGN

Common value declarations

RADIAL
TEXT_ALIGN
TEXT_DECORATION
TEXT_JUSTIFY
TEXT_SHADOW
TEXT_SHADOW_BLUR
TEXT_SHADOW_OFFSET
VERTICAL_ALIGN
WEBKIT_ANIMATION
WHITE_SPACE
ZERO_WIDTH_NON_BREAKING_SPACE

Zero-width non-breaking character

ZERO_WIDTH_SPACE

Zero-width space character

Public Instance Methods

render(tag, opt, ctx) click to toggle source
# File lib/inkcite/renderer/base.rb, line 80
def render tag, opt, ctx
  raise "Not implemented: #{tag} #{opts}"
end

Protected Instance Methods

detect(*opts) click to toggle source

Convenience proxy

# File lib/inkcite/renderer/base.rb, line 87
def detect *opts
  Util.detect(*opts)
end
detect_bgcolor(opt, default=nil) click to toggle source
# File lib/inkcite/renderer/base.rb, line 104
def detect_bgcolor opt, default=nil
  bgcolor = detect(opt[:bgcolor], opt[BACKGROUND_COLOR], default)
  none?(bgcolor) ? nil : hex(bgcolor)
end
detect_bggradient(opt, default=nil) click to toggle source
# File lib/inkcite/renderer/base.rb, line 109
def detect_bggradient opt, default=nil
  bggradient = detect(opt[:gradient], opt[:bggradient], opt[BACKGROUND_GRADIENT])
  none?(bggradient) ? nil : hex(bggradient)
end
detect_font(att, font, opt, parent, ctx) click to toggle source
# File lib/inkcite/renderer/base.rb, line 91
def detect_font att, font, opt, parent, ctx
  val = detect(opt[att], ctx["#{font}-#{att}"], parent ? parent[att] : nil)

  # Sometimes font values reference other defined values so we need
  # to run them through the renderer to resolve them.
  val = Inkcite::Renderer.render(val, ctx)

  # Convience
  val = nil if none?(val)

  val
end
hex(color) click to toggle source

Convenience pass-thru to Renderer's static helper method.

# File lib/inkcite/renderer/base.rb, line 115
def hex color
  Renderer.hex(color)
end
if_mso(html) click to toggle source
# File lib/inkcite/renderer/base.rb, line 119
def if_mso html
  %Q({outlook-only}#{html.to_s}{/outlook-only})
end
mix_animation(element, opt, ctx) click to toggle source
# File lib/inkcite/renderer/base.rb, line 127
def mix_animation element, opt, ctx

  animation = opt[:animation]
  unless none?(animation)
    element.style[:animation] = animation
    element.style[WEBKIT_ANIMATION] = animation
  end
end
mix_background(element, opt, ctx) click to toggle source

Sets the element's in-line bgcolor style if it has been defined in the provided options.

# File lib/inkcite/renderer/base.rb, line 138
def mix_background element, opt, ctx

  # Background color of the image, if populated.
  bgcolor = detect_bgcolor(opt)

  # Set the background color if the element has one.
  element.style[BACKGROUND_COLOR] = bgcolor if bgcolor

  # Automatically include background gradient support when
  # mixing in background color.
  mix_background_gradient element, opt, ctx

end
mix_background_gradient(element, opt, ctx) click to toggle source
# File lib/inkcite/renderer/base.rb, line 152
def mix_background_gradient element, opt, ctx

  # Background gradient support
  bggradient = detect_bggradient(opt)
  return if none?(bggradient)

  # As a shortcut a gradient can be specified simply by designating
  # both a bgcolor and the gradient color - this will insert a radial
  # gradient automatically.
  if bggradient.start_with?('#')

    # If a bgcolor is provided, the gradient goes bgcolor -> bggradient.
    # Otherwise, it goes bggradient->darker(bggradient)
    bgcolor = detect_bgcolor(opt)
    center_color = bgcolor ? bgcolor : bggradient
    outer_color = bgcolor ? bggradient : Util.darken(bggradient)

    # The default position of the gradient when not specified
    # by the designer.
    default_position = 'center'

    shape = opt[BACKGROUND_GRADIENT_SHAPE] || LINEAR
    if shape == LINEAR
      type = LINEAR
      shape = 'to '

      # Linear gradients default to the bottom.
      default_position = 'bottom'

    else
      type = RADIAL
      shape = "#{shape} at "
    end

    position = detect(opt[BACKGROUND_GRADIENT_POSITION], default_position)

    bggradient = %Q(#{type}-gradient(#{shape}#{position}, #{center_color}, #{outer_color}))
  end

  element.style[BACKGROUND_IMAGE] = bggradient

end
mix_border(element, opt, ctx) click to toggle source
# File lib/inkcite/renderer/base.rb, line 195
def mix_border element, opt, ctx
  mix_directional element, element.style, opt, ctx, :border
end
mix_border_radius(element, opt, ctx) click to toggle source
# File lib/inkcite/renderer/base.rb, line 199
def mix_border_radius element, opt, ctx

  border_radius = opt[BORDER_RADIUS].to_i
  element.style[BORDER_RADIUS] = px(border_radius) if border_radius > 0

end
mix_directional(element, into, opt, ctx, opt_key, css_key=nil, as_px=false) click to toggle source

Helper to mix CSS properties that can be defined as either a singular shorthand (e.g. border) or in one or more of the compass directions (e.g. border-top, border-left).

# File lib/inkcite/renderer/base.rb, line 209
def mix_directional element, into, opt, ctx, opt_key, css_key=nil, as_px=false

  css_key = opt_key if css_key.nil?

  # Iterate through each of the possible directions (including blank)
  # and apply them each to the element's style hash.
  DIRECTIONS.each do |dir|
    dir_opt_key = add_directional_suffix(opt_key, dir)
    dir_css_key = add_directional_suffix(css_key, dir)
    value = opt[dir_opt_key]
    next if value.blank?

    value = px(value) if as_px
    into[dir_css_key] = value
  end

end
mix_font(element, opt, ctx, parent=nil) click to toggle source
# File lib/inkcite/renderer/base.rb, line 227
def mix_font element, opt, ctx, parent=nil

  # Always ensure we have a parent to inherit from.
  parent ||= {}

  # Check for a font in either the element's specified options or inherit a setting from
  # from the parent if provided.
  font = detect(opt[:font], parent[:font])

  # Fonts can be disabled on individual cells if the parent table
  # has set one for the entire table.
  font = nil if none?(font)

  font_family = detect_font(FONT_FAMILY, font, opt, parent, ctx)
  element.style[FONT_FAMILY] = font_family unless font_family.blank?

  font_size = detect_font(FONT_SIZE, font, opt, parent, ctx)
  element.style[FONT_SIZE] = px(font_size) unless font_size.blank?

  color = detect_font(:color, font, opt, parent, ctx)
  element.style[:color] = hex(color) unless color.blank?

  line_height = detect_font(LINE_HEIGHT, font, opt, parent, ctx)
  element.style[LINE_HEIGHT] = px(line_height) unless line_height.blank?

  font_weight = detect_font(FONT_WEIGHT, font, opt, parent, ctx)
  element.style[FONT_WEIGHT] = font_weight unless font_weight.blank?

  letter_spacing = detect_font(LETTER_SPACING, font, opt, parent, ctx)
  element.style[LETTER_SPACING] = px(letter_spacing) unless none?(letter_spacing)

  # With font support comes text shadow support.
  mix_text_shadow element, opt, ctx

  font
end
mix_margins(element, opt, ctx, outlookCompatible=true) click to toggle source
# File lib/inkcite/renderer/base.rb, line 264
def mix_margins element, opt, ctx, outlookCompatible=true

  # Outlook supports Margin, not margin.
  mix_directional element, element.style, opt, ctx, :margin, outlookCompatible ? :Margin : :margin, true

end
mix_text_align(element, opt, ctx) click to toggle source

Text alignment - left, right, center.

# File lib/inkcite/renderer/base.rb, line 272
def mix_text_align element, opt, ctx

  align = detect(opt[:align] || opt[TEXT_ALIGN])
  return if none?(align)

  element.style[TEXT_ALIGN] = align

  mix_text_justify(element, opt, ctx) if align == JUSTIFY

end
mix_text_justify(element, opt, ctx) click to toggle source
# File lib/inkcite/renderer/base.rb, line 283
def mix_text_justify element, opt, ctx

  text_justify = opt[TEXT_JUSTIFY]
  element.style[TEXT_JUSTIFY] = text_justify unless none?(text_justify)

end
mix_text_shadow(element, opt, ctx) click to toggle source
# File lib/inkcite/renderer/base.rb, line 290
def mix_text_shadow element, opt, ctx

  shadow = detect(opt[:shadow], opt[TEXT_SHADOW])
  return if shadow.blank?

  # Allow shadows to be disabled because sometimes a child element (like an
  # image within a cell or an entire cell within a table) wants to disable
  # the shadowing forced by a parent.
  if none?(shadow)
    element.style[TEXT_SHADOW] = shadow

  else

    shadow_offset = detect(opt[TEXT_SHADOW_OFFSET], ctx[TEXT_SHADOW_OFFSET], 1)
    shadow_blur = detect(opt[TEXT_SHADOW_BLUR], ctx[TEXT_SHADOW_BLUR], 0)

    element.style[TEXT_SHADOW] = "0 #{px(shadow_offset)} #{px(shadow_blur)} #{hex(shadow)}"

  end

end
none?(val) click to toggle source
# File lib/inkcite/renderer/base.rb, line 123
def none? val
  val.blank? || val == NONE
end
pct(val) click to toggle source
# File lib/inkcite/renderer/base.rb, line 312
def pct val
  "#{val}%"
end
px(val) click to toggle source
# File lib/inkcite/renderer/base.rb, line 316
def px val
  Renderer.px(val)
end
quote(val) click to toggle source
# File lib/inkcite/renderer/base.rb, line 320
def quote val
  Renderer.quote(val)
end
render_tag(tag, attributes=nil, styles=nil) click to toggle source
# File lib/inkcite/renderer/base.rb, line 324
def render_tag tag, attributes=nil, styles=nil

  # Convert the style hash into CSS style attribute.
  unless styles.blank?
    attributes ||= {}
    attributes[:style] = quote(Renderer.render_styles(styles))
  end

  # Check to see if this is a self-closing tag.
  self_close = attributes && attributes.delete(:self_close) == true

  html = "<#{tag}"

  unless attributes.blank?

    # Make sure multiple classes are handled properly.
    classes = attributes[:class]
    attributes[:class] = quote([*classes].join(' ')) unless classes.blank?

    html << SPACE + Renderer.join_hash(attributes)

  end

  html << '/' if self_close
  html << '>'

  html
end

Private Instance Methods

add_directional_suffix(key, dir) click to toggle source

Helper method which adds the directional suffix (e.g. top) to the provided key (border) and converts to a symbol.

# File lib/inkcite/renderer/base.rb, line 357
def add_directional_suffix key, dir

  # Nothing to do if the direction isn't provided.
  return key if dir.blank?

  # Need to convert the key to a string since it is likely
  # a symbol that has been provided.
  dir_key = ''
  dir_key << key.to_s
  dir_key << '-'
  dir_key << dir.to_s
  dir_key.to_sym
end