card/lib/cardio/mod/module_template.rb
module Cardio
class Mod
# ModuleTemplate is an abstract class to build ruby modules out of
# deckos dsl for sets and set patterns.
# {Loader::SetTemplate} and {Loader::SetPatternTemplate} inherit
# from it and adapt the template to their needs.
class ModuleTemplate
def initialize modules, content_path, strategy
modules = Array.wrap modules
@pattern = modules.shift
@modules = modules
@content = ::File.read content_path
@content_path = content_path
@strategy = strategy
end
# Evaluates the module in the top level namespace.
def build
eval to_s, TOPLEVEL_BINDING, @content_path, offset
end
# @return [String] the ruby code to build the modal
def to_s
simple_load? ? @content : processed_content
end
def processed_content
capture_module_comment if @strategy.clean_comments?
module_content
end
# Just run the code of the source.
# Don't use the path to the file as module hierarchy.
def simple_load?
@content =~ /\A#!\s?simple load/
end
private
# find all comment lines at the beginning of a mod file, up to the first
# non-comment line. (These will be inserted before the module declaration,
# so that Yard will interpret them as a module comment.)
def capture_module_comment
content_lines = @content.split "\n"
comment_lines = []
content_lines.each do |line|
comment?(line) ? comment_lines << content_lines.shift : break
end
@content = content_lines.join "\n"
@module_comment = comment_lines.join "\n"
end
def comment? line
line.match?(/^ *\#/)
end
# loader template must implement #preamble_bits
def preamble
preamble_bits.join "\n"
end
def module_comment
return "" unless @strategy.clean_comments?
@module_comment = nil if @module_comment.blank?
[auto_comment, @module_comment].compact.join "\n"
end
def module_content
# for unknown reasons strip_heredoc doesn't work properly
# and with trailing whitespace code like `=begin` fails
<<~RUBY.strip_heredoc
# -*- encoding : utf-8 -*-
#{preamble}
#{@content}
#{postamble}
# ~~ generated from #{@content_path} ~~
RUBY
end
end
end
end