forked from TwP/webby
-
Notifications
You must be signed in to change notification settings - Fork 0
/
filters.rb
95 lines (77 loc) · 2.32 KB
/
filters.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# $Id$
module Webby
module Filters
class << self
# Register a handler for a filter
def register( filter, &block )
handlers[filter.to_s] = block
end
# Process input through filters
def process( renderer, page, input )
# Start a new cursor for this page
Cursor.new(renderer, page).start_for(input)
end
# Access a filter handler
def []( name )
handlers[name]
end
#######
private
#######
# The registered filter handlers
def handlers
@handlers ||= {}
end
# Instances of this class handle processing a set of filters
# for a given renderer and page.
# Note: The instance is passed as the second argument to filters
# that require two parameters and can be used to access
# information on the renderer, page, or filters being
# processed.
class Cursor
attr_reader :renderer, :page, :filters
def initialize(renderer, page)
@renderer, @page = renderer, page
@filters = Array(page.filter)
@log = Logging::Logger[Webby::Renderer]
@processed = 0
end
def start_for(input)
@renderer.instance_variable_set(:@_cursor, self)
filters.inject(input) do |result, filter|
handler = Filters[filter]
args = [result, self][0, handler.arity]
handle(filter, handler, *args)
end
ensure
@renderer.instance_variable_set(:@_cursor, nil)
end
# The list of filters yet to be processed
def remaining_filters
filters[@processed..-1]
end
# The name of the current filter
def current_filter
filters[@processed]
end
#######
private
#######
# Process arguments through a single filter
def handle(filter, handler, *args)
result = handler.call(*args)
@processed += 1
result
rescue NameError => e
@log.fatal "Name error in filter `#{filter}' (missing dependency?): #{e.message}"
exit 1
rescue => e
@log.fatal "Error in filter `#{filter}': #{e.message}"
exit 1
end
end # class Cursor
end # class << self
end # module Filters
end # module Webby
Webby.require_all_libs_relative_to(__FILE__)
# EOF