Module: Exclaim::Implementations

Extended by:
Implementations
Included in:
Implementations
Defined in:
lib/exclaim/implementations/if_helper.rb,
lib/exclaim/implementations/join_helper.rb,
lib/exclaim/implementations/let_component.rb,
lib/exclaim/implementations/each_component.rb,
lib/exclaim/implementations/text_component.rb,
lib/exclaim/implementations/vbox_component.rb,
lib/exclaim/implementations/image_component.rb,
lib/exclaim/implementations/paragraph_component.rb,
lib/exclaim/implementations/example_implementation_map.rb

Defined Under Namespace

Classes: Each

Constant Summary collapse

IF_HELPER =
->(config, _env) do
  # 'condition' is the shorthand property for this helper,
  # but "config['condition']" will return the falsy value nil if that key
  # does not exist in the config. That will happen when the condition is configured
  # with the shorthand property "{ '$if' => <some value> }"
  #
  # Therefore it is necessary to check for the 'condition' key to find configuration like
  # "{ 'condition' => false }" or an even explicit "{ 'condition' => nil }"
  # Then we fall back to the shorthand property if the 'condition' key does not exist.
  condition = if config.key?('condition')
                config['condition']
              else
                config['$if']
              end

  if condition
    config['then'] unless config['then'].nil?
  else
    config['else']
  end
end
JOIN_HELPER =
->(config, _env) do
  items = (config['items'] || config['$join']).to_a
  separator = config['separator'] || ''
  items.join(separator)
end
LET_COMPONENT =
->(config, _env, &render_child) do
  bindings = (config['bindings'] || config['$let']).to_h
  child_component = config['do']

  # This implementation passes only the configured bindings as the env for
  # the child component. As an alternative approach, it could merge the bindings
  # onto the parent env to make all values available to the child.
  render_child.call(child_component, bindings)
end
EACH_COMPONENT =
Each.new
TEXT_COMPONENT =
->(config, _env) { config['content'] || config['$text'] }
INDENT =
'  '
VBOX_COMPONENT =
->(config, env, &render_child) do
  first_line = '<div style="display: flex; flex-flow: column">'
  child_elements = (config['children'] || config['$vbox']).to_a
  child_lines = child_elements.flat_map do |child|
    result = render_child.call(child, env)
    result.lines.map { |line| "#{INDENT}#{line}" }
  end
  last_line = '</div>'

  # ensure each line ends with at least one newline to produce readable HTML
  lines = [first_line, *child_lines, last_line]
  lines.map { |line| line.end_with?("\n") ? line : "#{line}\n" }.join
end
IMAGE_COMPONENT =
->(config, _env) do
  source = config['source'] || config['$image']
  alt = config['alt']
  "<img src=\"#{source}\" alt=\"#{alt}\">"
end
PARAGRAPH_COMPONENT =
->(config, env, &render_child) do
  sentences = config['sentences'] || config['$paragraph']
  rendered_sentences = sentences.map do |sentence|
    result = render_child.call(sentence, env)
    result.end_with?('.') ? result : "#{result}."
  end
  "<p>#{rendered_sentences.join(' ')}</p>"
end

Instance Method Summary collapse

Instance Method Details

#example_implementation_mapObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/exclaim/implementations/example_implementation_map.rb', line 16

def example_implementation_map
  @example_implementation_map ||= begin
    {
      'each' => EACH_COMPONENT,
      'image' => IMAGE_COMPONENT,
      'if' => IF_HELPER,
      'join' => JOIN_HELPER,
      'let' => LET_COMPONENT,
      'paragraph' => PARAGRAPH_COMPONENT,
      'text' => TEXT_COMPONENT,
      'vbox' => VBOX_COMPONENT
    }
  end
end