refactor command/gem details into implementation classes
Charlie Somerville charlie@charliesomerville.com
Wed, 04 Dec 2013 11:19:42 +1100
4 files changed,
112 insertions(+),
85 deletions(-)
M
lib/github/markup.rb
→
lib/github/markup.rb
@@ -1,83 +1,35 @@
-begin - require 'open3_detach' -rescue LoadError - require 'open3' -end +require "github/markup/command_implementation" +require "github/markup/gem_implementation" module GitHub module Markup extend self - @@markups = {} - @@deferred_markups = [] + @@markups = [] def preload! - @@deferred_markups.each do |loader| - loader.call - end - @@deferred_markups = [] + # TODO end def render(filename, content = nil) content ||= File.read(filename) - if proc = renderer(filename) - proc[content] + if impl = renderer(filename) + impl.render(content) else content end end def markup(file, pattern, opts = {}, &block) - loader = proc do - begin - require file.to_s - add_markup(pattern, &block) - true - rescue LoadError - false - end - end - - if opts[:eager] - loader.call - else - @@deferred_markups << loader - add_markup pattern do |*args| - @@deferred_markups.delete(loader) - loader.call - block.call(*args) - end - true - end + @@markups << GemImplementation.new(pattern, file, &block) end def command(command, regexp, &block) - command = command.to_s - if File.exists?(file = File.dirname(__FILE__) + "/commands/#{command}") command = file end - add_markup(regexp) do |content| - rendered = execute(command, content) - rendered = rendered.to_s.empty? ? content : rendered - - if block && block.arity == 2 - # If the block takes two arguments, pass new content and old - # content. - block.call(rendered, content) - elsif block - # One argument is just the new content. - block.call(rendered) - else - # No block? No problem! - rendered - end - end - end - - def add_markup(regexp, &block) - @@markups[regexp] = block + @@markups << CommandImplementation.new(regexp, command, &block) end def can_render?(filename)@@ -85,35 +37,9 @@ !!renderer(filename)
end def renderer(filename) - @@markups.each do |key, value| - if Regexp.compile("\\.(#{key})$") =~ filename - return value - end - end - nil - end - - def renderer_name(filename) - @@markups.each do |key, value| - if Regexp.compile("\\.(#{key})$") =~ filename - return key - end - end - nil - end - - def execute(command, target) - out = '' - Open3.popen3(command) do |stdin, stdout, _| - stdin.puts target - stdin.close - out = stdout.read - end - out.gsub("\r", '') - rescue Errno::EPIPE - "" - rescue Errno::ENOENT - "" + @@markups.find { |impl| + impl.match?(filename) + } end # Define markups
A
lib/github/markup/command_implementation.rb
@@ -0,0 +1,52 @@
+begin + require "open3_detach" +rescue LoadError + require "open3" +end + +require "github/markup/implementation" + +module GitHub + module Markup + class CommandImplementation < Implementation + attr_reader :command, :block + + def initialize(regexp, command, &block) + super regexp + @command = command.to_s + @block = block + end + + def render(content) + rendered = execute(command, content) + rendered = rendered.to_s.empty? ? content : rendered + call_block(rendered, content) + end + + private + def call_block(rendered, content) + if block && block.arity == 2 + block.call(rendered, content) + elsif block + block.call(rendered) + else + rendered + end + end + + def execute(command, target) + out = '' + Open3.popen3(command) do |stdin, stdout, _| + stdin.puts target + stdin.close + out = stdout.read + end + out.gsub("\r", '') + rescue Errno::EPIPE + "" + rescue Errno::ENOENT + "" + end + end + end +end
A
lib/github/markup/gem_implementation.rb
@@ -0,0 +1,26 @@
+require "github/markup/implementation" + +module GitHub + module Markup + class GemImplementation < Implementation + attr_reader :gem_name, :renderer + + def initialize(regexp, gem_name, &renderer) + super regexp + @gem_name = gem_name.to_s + @renderer = renderer + end + + def load + return if @loaded + require gem_name + @loaded = true + end + + def render(content) + load + renderer.call(content) + end + end + end +end
A
lib/github/markup/implementation.rb
@@ -0,0 +1,23 @@
+module GitHub + module Markup + class Implementation + attr_reader :regexp + + def initialize(regexp) + @regexp = regexp + end + + def load + # no-op by default + end + + def render(content) + raise NotImplementedError, "subclasses of GitHub::Markup::Implementation must define #render" + end + + def match?(filename) + Regexp.compile("\\.(#{regexp})$") =~ filename + end + end + end +end