lib/cadenza/library/blocks.rb
# frozen_string_literal: true
module Cadenza
# This exception is raised when a block is referred to but is not defined
BlockNotDefinedError = Class.new(Cadenza::Error)
module Library
# The logic for storing and calling blocks is found in this module
module Blocks
# @!attribute [r] blocks
# @return [Hash] the block names mapped to their implementing procs
def blocks
@blocks ||= {}
end
# looks up the block by name
#
# @raise [BlockNotDefinedError] if the block can not be found
# @param [Symbol] name the name of the block to look up
# @return [Proc] the block implementation
def lookup_block(name)
blocks.fetch(name.to_sym) { raise BlockNotDefinedError, "undefined block '#{name}'" }
end
# defines a generic block proc with the given name
#
# @param [Symbol] name the name for the template to use for this block
# @yield [Context, Array, *args] the block will receive the context object,
# a list of Node objects (it's children), and
# a variable number of aarguments passed to
# the block.
# @return nil
def define_block(name, &block)
blocks[name.to_sym] = block
nil
end
# creates an alias of the given block name under a different name
#
# @raise [BlockNotDefinedError] if the original block name isn't defined
# @param [Symbol] original_name the original name of the block
# @param [Symbol] alias_name the new name of the block
# @return nil
def alias_block(original_name, alias_name)
define_block alias_name, &lookup_block(original_name)
end
# calls the defined generic block proc with the given name and children
# nodes.
#
# @raise [BlockNotDefinedError] if the named block does not exist
# @param [Symbol] name the name of the block to evaluate
# @param [Array] nodes the child nodes of the block
# @param [Array, []] params a list of parameters to pass to the block
# when calling it.
# @return [String] the result of evaluating the block
def evaluate_block(name, context, nodes, parameters)
lookup_block(name).call(context, nodes, parameters)
end
end
end
end