html-pipeline 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +5 -0
- data/README.md +24 -20
- data/lib/html/pipeline.rb +42 -14
- data/lib/html/pipeline/version.rb +1 -1
- data/test/helpers/mocked_instrumentation_service.rb +3 -1
- data/test/html/pipeline_test.rb +29 -7
- metadata +2 -2
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
GitHub HTML processing filters and utilities. This module includes a small
|
4
4
|
framework for defining DOM based content filters and applying them to user
|
5
|
-
provided content.
|
5
|
+
provided content. Read an introduction about this project in
|
6
|
+
[this blog post](https://github.com/blog/1311-html-pipeline-chainable-content-filters).
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
@@ -197,9 +198,10 @@ Pipeline.new [ RootRelativeFilter ], { :base_url => 'http://somehost.com' }
|
|
197
198
|
|
198
199
|
## Instrumenting
|
199
200
|
|
200
|
-
|
201
|
-
[ActiveSupport::Notifications]
|
202
|
-
|
201
|
+
Filters and Pipelines can be set up to be instrumented when called. The pipeline
|
202
|
+
must be setup with an [ActiveSupport::Notifications]
|
203
|
+
(http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html)
|
204
|
+
compatible service object and a name. New pipeline objects will default to the
|
203
205
|
`HTML::Pipeline.default_instrumentation_service` object.
|
204
206
|
|
205
207
|
``` ruby
|
@@ -208,10 +210,12 @@ service = ActiveSupport::Notifications
|
|
208
210
|
|
209
211
|
# instrument a specific pipeline
|
210
212
|
pipeline = HTML::Pipeline.new [MarkdownFilter], context
|
211
|
-
pipeline.
|
213
|
+
pipeline.setup_instrumentation "MarkdownPipeline", service
|
212
214
|
|
213
|
-
# or
|
215
|
+
# or set default instrumentation service for all new pipelines
|
214
216
|
HTML::Pipeline.default_instrumentation_service = service
|
217
|
+
pipeline = HTML::Pipeline.new [MarkdownFilter], context
|
218
|
+
pipeline.setup_instrumentation "MarkdownPipeline"
|
215
219
|
```
|
216
220
|
|
217
221
|
Filters are instrumented when they are run through the pipeline. A
|
@@ -221,7 +225,11 @@ instrumentation call.
|
|
221
225
|
|
222
226
|
``` ruby
|
223
227
|
service.subscribe "call_filter.html_pipeline" do |event, start, ending, transaction_id, payload|
|
228
|
+
payload[:pipeline] #=> "MarkdownPipeline", set with `setup_instrumentation`
|
224
229
|
payload[:filter] #=> "MarkdownFilter"
|
230
|
+
payload[:context] #=> context Hash
|
231
|
+
payload[:result] #=> instance of result class
|
232
|
+
payload[:result][:output] #=> output HTML String or Nokogiri::DocumentFragment
|
225
233
|
end
|
226
234
|
```
|
227
235
|
|
@@ -229,10 +237,19 @@ The full pipeline is also instrumented:
|
|
229
237
|
|
230
238
|
``` ruby
|
231
239
|
service.subscribe "call_pipeline.html_pipeline" do |event, start, ending, transaction_id, payload|
|
240
|
+
payload[:pipeline] #=> "MarkdownPipeline", set with `setup_instrumentation`
|
232
241
|
payload[:filters] #=> ["MarkdownFilter"]
|
242
|
+
payload[:doc] #=> HTML String or Nokogiri::DocumentFragment
|
243
|
+
payload[:context] #=> context Hash
|
244
|
+
payload[:result] #=> instance of result class
|
245
|
+
payload[:result][:output] #=> output HTML String or Nokogiri::DocumentFragment
|
233
246
|
end
|
234
247
|
```
|
235
248
|
|
249
|
+
## Documentation
|
250
|
+
|
251
|
+
Full reference documentation can be [found here](http://rubydoc.info/gems/html-pipeline/frames).
|
252
|
+
|
236
253
|
## Development
|
237
254
|
|
238
255
|
To see what has changed in recent versions, see the [CHANGELOG](https://github.com/jch/html-pipeline/blob/master/CHANGELOG.md).
|
@@ -250,21 +267,8 @@ rake test
|
|
250
267
|
4. Push to the branch (`git push origin my-new-feature`)
|
251
268
|
5. Create new [Pull Request](https://help.github.com/articles/using-pull-requests)
|
252
269
|
|
253
|
-
|
254
|
-
## TODO
|
255
|
-
|
256
|
-
* test whether emoji filter works on heroku
|
257
|
-
* test whether nokogiri monkey patch is still necessary
|
258
|
-
|
259
270
|
## Contributors
|
260
271
|
|
261
|
-
|
262
|
-
* [Jake Boxer](mailto:jake@github.com)
|
263
|
-
* [Joshua Peek](mailto:josh@joshpeek.com)
|
264
|
-
* [Kyle Neath](mailto:kneath@gmail.com)
|
265
|
-
* [Rob Sanheim](mailto:rsanheim@gmail.com)
|
266
|
-
* [Simon Rozet](mailto:simon@rozet.name)
|
267
|
-
* [Vicent Martí](mailto:tanoku@gmail.com)
|
268
|
-
* [Risk :danger: Olson](mailto:technoweenie@gmail.com)
|
272
|
+
Thanks to all of [these contributors](https://github.com/jch/html-pipeline/graphs/contributors).
|
269
273
|
|
270
274
|
Project is a member of the [OSS Manifesto](http://ossmanifesto.org/).
|
data/lib/html/pipeline.rb
CHANGED
@@ -25,7 +25,6 @@ module HTML
|
|
25
25
|
# some semblance of type safety.
|
26
26
|
class Pipeline
|
27
27
|
autoload :VERSION, 'html/pipeline/version'
|
28
|
-
autoload :Pipeline, 'html/pipeline/pipeline'
|
29
28
|
autoload :Filter, 'html/pipeline/filter'
|
30
29
|
autoload :AbsoluteSourceFilter, 'html/pipeline/absolute_source_filter'
|
31
30
|
autoload :BodyContent, 'html/pipeline/body_content'
|
@@ -65,6 +64,12 @@ module HTML
|
|
65
64
|
# Set an ActiveSupport::Notifications compatible object to enable.
|
66
65
|
attr_accessor :instrumentation_service
|
67
66
|
|
67
|
+
# Public: String name for this Pipeline. Defaults to Class name.
|
68
|
+
attr_writer :instrumentation_name
|
69
|
+
def instrumentation_name
|
70
|
+
@instrumentation_name || self.class.name
|
71
|
+
end
|
72
|
+
|
68
73
|
class << self
|
69
74
|
# Public: Default instrumentation service for new pipeline objects.
|
70
75
|
attr_accessor :default_instrumentation_service
|
@@ -94,7 +99,9 @@ module HTML
|
|
94
99
|
context = @default_context.merge(context)
|
95
100
|
context = context.freeze
|
96
101
|
result ||= @result_class.new
|
97
|
-
|
102
|
+
payload = default_payload :filters => @filters.map(&:name),
|
103
|
+
:context => context, :result => result
|
104
|
+
instrument "call_pipeline.html_pipeline", payload do
|
98
105
|
result[:output] =
|
99
106
|
@filters.inject(html) do |doc, filter|
|
100
107
|
perform_filter(filter, doc, context, result)
|
@@ -109,22 +116,13 @@ module HTML
|
|
109
116
|
#
|
110
117
|
# Returns the result of the filter.
|
111
118
|
def perform_filter(filter, doc, context, result)
|
112
|
-
|
119
|
+
payload = default_payload :filter => filter.name,
|
120
|
+
:context => context, :result => result
|
121
|
+
instrument "call_filter.html_pipeline", payload do
|
113
122
|
filter.call(doc, context, result)
|
114
123
|
end
|
115
124
|
end
|
116
125
|
|
117
|
-
# Internal: if the `instrumentation_service` object is set, instruments the
|
118
|
-
# block, otherwise the block is ran without instrumentation.
|
119
|
-
#
|
120
|
-
# Returns the result of the provided block.
|
121
|
-
def instrument(event, payload = nil)
|
122
|
-
return yield unless instrumentation_service
|
123
|
-
instrumentation_service.instrument event, payload do
|
124
|
-
yield
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
126
|
# Like call but guarantee the value returned is a DocumentFragment.
|
129
127
|
# Pipelines may return a DocumentFragment or a String. Callers that need a
|
130
128
|
# DocumentFragment should use this method.
|
@@ -143,6 +141,36 @@ module HTML
|
|
143
141
|
output.to_s
|
144
142
|
end
|
145
143
|
end
|
144
|
+
|
145
|
+
# Public: setup instrumentation for this pipeline.
|
146
|
+
#
|
147
|
+
# Returns nothing.
|
148
|
+
def setup_instrumentation(name = nil, service = nil)
|
149
|
+
self.instrumentation_name = name
|
150
|
+
self.instrumentation_service =
|
151
|
+
service || self.class.default_instrumentation_service
|
152
|
+
end
|
153
|
+
|
154
|
+
# Internal: if the `instrumentation_service` object is set, instruments the
|
155
|
+
# block, otherwise the block is ran without instrumentation.
|
156
|
+
#
|
157
|
+
# Returns the result of the provided block.
|
158
|
+
def instrument(event, payload = nil)
|
159
|
+
payload ||= default_payload
|
160
|
+
return yield(payload) unless instrumentation_service
|
161
|
+
instrumentation_service.instrument event, payload do |payload|
|
162
|
+
yield payload
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Internal: Default payload for instrumentation.
|
167
|
+
#
|
168
|
+
# Accepts a Hash of additional payload data to be merged.
|
169
|
+
#
|
170
|
+
# Returns a Hash.
|
171
|
+
def default_payload(payload = {})
|
172
|
+
{:pipeline => instrumentation_name}.merge(payload)
|
173
|
+
end
|
146
174
|
end
|
147
175
|
end
|
148
176
|
|
@@ -5,11 +5,13 @@ class MockedInstrumentationService
|
|
5
5
|
subscribe event
|
6
6
|
end
|
7
7
|
def instrument(event, payload = nil)
|
8
|
-
|
8
|
+
payload ||= {}
|
9
|
+
res = yield payload
|
9
10
|
events << [event, payload, res] if @subscribe == event
|
10
11
|
res
|
11
12
|
end
|
12
13
|
def subscribe(event)
|
13
14
|
@subscribe = event
|
15
|
+
@events
|
14
16
|
end
|
15
17
|
end
|
data/test/html/pipeline_test.rb
CHANGED
@@ -5,7 +5,7 @@ class HTML::PipelineTest < Test::Unit::TestCase
|
|
5
5
|
Pipeline = HTML::Pipeline
|
6
6
|
class TestFilter
|
7
7
|
def self.call(input, context, result)
|
8
|
-
input
|
8
|
+
input.reverse
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -17,24 +17,28 @@ class HTML::PipelineTest < Test::Unit::TestCase
|
|
17
17
|
|
18
18
|
def test_filter_instrumentation
|
19
19
|
service = MockedInstrumentationService.new
|
20
|
-
service.subscribe "call_filter.html_pipeline"
|
20
|
+
events = service.subscribe "call_filter.html_pipeline"
|
21
21
|
@pipeline.instrumentation_service = service
|
22
|
-
filter("hello")
|
23
|
-
event, payload, res =
|
22
|
+
filter(body = "hello")
|
23
|
+
event, payload, res = events.pop
|
24
24
|
assert event, "event expected"
|
25
25
|
assert_equal "call_filter.html_pipeline", event
|
26
26
|
assert_equal TestFilter.name, payload[:filter]
|
27
|
+
assert_equal @pipeline.class.name, payload[:pipeline]
|
28
|
+
assert_equal body.reverse, payload[:result][:output]
|
27
29
|
end
|
28
30
|
|
29
31
|
def test_pipeline_instrumentation
|
30
32
|
service = MockedInstrumentationService.new
|
31
|
-
service.subscribe "call_pipeline.html_pipeline"
|
33
|
+
events = service.subscribe "call_pipeline.html_pipeline"
|
32
34
|
@pipeline.instrumentation_service = service
|
33
|
-
filter("hello")
|
34
|
-
event, payload, res =
|
35
|
+
filter(body = "hello")
|
36
|
+
event, payload, res = events.pop
|
35
37
|
assert event, "event expected"
|
36
38
|
assert_equal "call_pipeline.html_pipeline", event
|
37
39
|
assert_equal @pipeline.filters.map(&:name), payload[:filters]
|
40
|
+
assert_equal @pipeline.class.name, payload[:pipeline]
|
41
|
+
assert_equal body.reverse, payload[:result][:output]
|
38
42
|
end
|
39
43
|
|
40
44
|
def test_default_instrumentation_service
|
@@ -46,6 +50,24 @@ class HTML::PipelineTest < Test::Unit::TestCase
|
|
46
50
|
Pipeline.default_instrumentation_service = nil
|
47
51
|
end
|
48
52
|
|
53
|
+
def test_setup_instrumentation
|
54
|
+
assert_nil @pipeline.instrumentation_service
|
55
|
+
|
56
|
+
service = MockedInstrumentationService.new
|
57
|
+
events = service.subscribe "call_pipeline.html_pipeline"
|
58
|
+
@pipeline.setup_instrumentation name = 'foo', service
|
59
|
+
|
60
|
+
assert_equal service, @pipeline.instrumentation_service
|
61
|
+
assert_equal name, @pipeline.instrumentation_name
|
62
|
+
|
63
|
+
filter(body = 'foo')
|
64
|
+
|
65
|
+
event, payload, res = events.pop
|
66
|
+
assert event, "expected event"
|
67
|
+
assert_equal name, payload[:pipeline]
|
68
|
+
assert_equal body.reverse, payload[:result][:output]
|
69
|
+
end
|
70
|
+
|
49
71
|
def filter(input)
|
50
72
|
@pipeline.call(input)
|
51
73
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: html-pipeline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-04-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: gemoji
|