lib/github/markup.rb (view raw)
1begin
2 require 'open3_detach'
3rescue LoadError
4 require 'open3'
5end
6
7module GitHub
8 module Markup
9 extend self
10 @@markups = {}
11 @@deferred_markups = []
12
13 def preload!
14 @@deferred_markups.each do |loader|
15 loader.call
16 end
17 @@deferred_markups = []
18 end
19
20 def render(filename, content = nil)
21 content ||= File.read(filename)
22
23 if proc = renderer(filename)
24 proc[content]
25 else
26 content
27 end
28 end
29
30 def markup(file, pattern, &block)
31 loader = proc do
32 require file.to_s
33 add_markup(pattern, &block)
34 end
35 @@deferred_markups << loader
36 add_markup pattern do |*args|
37 @@deferred_markups.delete(loader)
38 loader.call
39 block.call(*args)
40 end
41 true
42 rescue LoadError
43 false
44 end
45
46 def command(command, regexp, &block)
47 command = command.to_s
48
49 if File.exists?(file = File.dirname(__FILE__) + "/commands/#{command}")
50 command = file
51 end
52
53 add_markup(regexp) do |content|
54 rendered = execute(command, content)
55 rendered = rendered.to_s.empty? ? content : rendered
56
57 if block && block.arity == 2
58 # If the block takes two arguments, pass new content and old
59 # content.
60 block.call(rendered, content)
61 elsif block
62 # One argument is just the new content.
63 block.call(rendered)
64 else
65 # No block? No problem!
66 rendered
67 end
68 end
69 end
70
71 def add_markup(regexp, &block)
72 @@markups[regexp] = block
73 end
74
75 def can_render?(filename)
76 !!renderer(filename)
77 end
78
79 def renderer(filename)
80 @@markups.each do |key, value|
81 if Regexp.compile("\\.(#{key})$") =~ filename
82 return value
83 end
84 end
85 nil
86 end
87
88 def renderer_name(filename)
89 @@markups.each do |key, value|
90 if Regexp.compile("\\.(#{key})$") =~ filename
91 return key
92 end
93 end
94 nil
95 end
96
97 def execute(command, target)
98 out = ''
99 Open3.popen3(command) do |stdin, stdout, _|
100 stdin.puts target
101 stdin.close
102 out = stdout.read
103 end
104 out.gsub("\r", '')
105 rescue Errno::EPIPE
106 ""
107 rescue Errno::ENOENT
108 ""
109 end
110
111 # Define markups
112 markups_rb = File.dirname(__FILE__) + '/markups.rb'
113 instance_eval File.read(markups_rb), markups_rb
114 end
115end