html-pipeline-linuxfr 0.0.14
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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.travis.yml +13 -0
- data/CHANGELOG.md +51 -0
- data/Gemfile +9 -0
- data/LICENSE +22 -0
- data/README.md +294 -0
- data/Rakefile +11 -0
- data/bin/html-pipeline +80 -0
- data/html-pipeline-linuxfr.gemspec +24 -0
- data/lib/html/pipeline.rb +167 -0
- data/lib/html/pipeline/custom_links_filter.rb +47 -0
- data/lib/html/pipeline/filter.rb +166 -0
- data/lib/html/pipeline/linuxfr.rb +25 -0
- data/lib/html/pipeline/markdown_filter.rb +76 -0
- data/lib/html/pipeline/relative_links_filter.rb +18 -0
- data/lib/html/pipeline/sanitization_filter.rb +108 -0
- data/lib/html/pipeline/syntax_highlight_filter.rb +31 -0
- data/lib/html/pipeline/text_filter.rb +14 -0
- data/lib/html/pipeline/toc_filter.rb +61 -0
- data/lib/html/pipeline/version.rb +5 -0
- data/test/helpers/mocked_instrumentation_service.rb +17 -0
- data/test/html/pipeline/absolute_source_filter_test.rb +56 -0
- data/test/html/pipeline/camo_filter_test.rb +47 -0
- data/test/html/pipeline/image_max_width_filter_test.rb +50 -0
- data/test/html/pipeline/markdown_filter_test.rb +101 -0
- data/test/html/pipeline/mention_filter_test.rb +156 -0
- data/test/html/pipeline/plain_text_input_filter_test.rb +22 -0
- data/test/html/pipeline/sanitization_filter_test.rb +52 -0
- data/test/html/pipeline/toc_filter_test.rb +47 -0
- data/test/html/pipeline_test.rb +74 -0
- data/test/test_helper.rb +38 -0
- metadata +175 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 033bc6b272f00ce9e31413aa5ce53dca75d283eb
|
4
|
+
data.tar.gz: 08a21b2cace44a3ad54063f681b24920acbf81c6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9fcb61ff69a30338251cf2d4d44ae198a7839fa97cc0cdca4b47f57d2641c4b0a74b353cbef311d3cc6e621673b38fa0b4df259004ac47f33095a224d30058b2
|
7
|
+
data.tar.gz: 9fee4d49662195f04c30e95334ea7b0e9c966bc6d9d6844885e2dd88703758ace001a77230cb2fc3ef960afffec50aff6d9a911ab38a81da64c6a5d93d03f967
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
## 0.0.14
|
4
|
+
|
5
|
+
* Remove unused can_access_repo? method jch
|
6
|
+
|
7
|
+
## 0.0.13
|
8
|
+
|
9
|
+
* Update icon class name (only affects TOC pipeline) cameronmcefee #52
|
10
|
+
|
11
|
+
## 0.0.12
|
12
|
+
|
13
|
+
* add additional payload information for instrumentation mtodd #46
|
14
|
+
* generate and link to gem docs in README
|
15
|
+
|
16
|
+
## 0.0.11
|
17
|
+
|
18
|
+
* add instrumentation support. readme cleanup mtodd #45
|
19
|
+
|
20
|
+
## 0.0.10
|
21
|
+
|
22
|
+
* add bin/html-pipeline util indirect #44
|
23
|
+
* add result[:mentioned_usernames] for MentionFilter fachen #42
|
24
|
+
|
25
|
+
## 0.0.9
|
26
|
+
|
27
|
+
* bump escape_utils ~> 0.3, github-linguist ~> 2.6.2 brianmario #41
|
28
|
+
* remove nokogiri monkey patch for ruby >= 1.9 defunkt #40
|
29
|
+
|
30
|
+
## 0.0.8
|
31
|
+
|
32
|
+
* raise LoadError instead of printing to stderr if linguist is missing. gjtorikian #36
|
33
|
+
|
34
|
+
## 0.0.7
|
35
|
+
|
36
|
+
* optionally require github-linguist chrislloyd #33
|
37
|
+
|
38
|
+
## 0.0.6
|
39
|
+
|
40
|
+
* don't mutate markdown strings: jakedouglas #32
|
41
|
+
|
42
|
+
## 0.0.5
|
43
|
+
|
44
|
+
* fix li xss vulnerability in sanitization filter: vmg #31
|
45
|
+
* gemspec cleanup: nbibler #23, jbarnette #24
|
46
|
+
* doc updates: jch #16, pborreli #17, wickedshimmy #18, benubois #19, blackerby #21
|
47
|
+
* loosen gemoji dependency: josh #15
|
48
|
+
|
49
|
+
## 0.0.4
|
50
|
+
|
51
|
+
* initial public release
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 GitHub Inc. and Jerry Cheung
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,294 @@
|
|
1
|
+
# HTML::Pipeline, LinuxFr.org edition
|
2
|
+
|
3
|
+
LinuxFr.org uses markdown as its wiki syntax, but with some differences with
|
4
|
+
the standard markdown:
|
5
|
+
|
6
|
+
* the heading levels for titles range from `<h2>` to `<h5>`
|
7
|
+
* `[[Foobar]]` is transformed to a link to wikipedia (http://fr.wikipedia.org/wiki/Foobar)
|
8
|
+
* URL are automatically transformed in links
|
9
|
+
* words with several underscores are left unchanged (no italics)
|
10
|
+
* PHP Markdown Extra-style tables are supported
|
11
|
+
* external images are proxified
|
12
|
+
* and some other extensions
|
13
|
+
|
14
|
+
To do that, I hacked the html-pipeline from Github to remove some
|
15
|
+
dependencies and use custom filters.
|
16
|
+
|
17
|
+
----
|
18
|
+
|
19
|
+
The README.md of the original html-pipeline:
|
20
|
+
|
21
|
+
# HTML::Pipeline
|
22
|
+
|
23
|
+
GitHub HTML processing filters and utilities. This module includes a small
|
24
|
+
framework for defining DOM based content filters and applying them to user
|
25
|
+
provided content. Read an introduction about this project in
|
26
|
+
[this blog post](https://github.com/blog/1311-html-pipeline-chainable-content-filters).
|
27
|
+
|
28
|
+
## Installation
|
29
|
+
|
30
|
+
Add this line to your application's Gemfile:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
gem 'html-pipeline'
|
34
|
+
```
|
35
|
+
|
36
|
+
And then execute:
|
37
|
+
|
38
|
+
```sh
|
39
|
+
$ bundle
|
40
|
+
```
|
41
|
+
|
42
|
+
Or install it yourself as:
|
43
|
+
|
44
|
+
```sh
|
45
|
+
$ gem install html-pipeline
|
46
|
+
```
|
47
|
+
|
48
|
+
## Usage
|
49
|
+
|
50
|
+
This library provides a handful of chainable HTML filters to transform user
|
51
|
+
content into markup. A filter takes an HTML string or
|
52
|
+
`Nokogiri::HTML::DocumentFragment`, optionally manipulates it, and then
|
53
|
+
outputs the result.
|
54
|
+
|
55
|
+
For example, to transform Markdown source into Markdown HTML:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
require 'html/pipeline'
|
59
|
+
|
60
|
+
filter = HTML::Pipeline::MarkdownFilter.new("Hi **world**!")
|
61
|
+
filter.call
|
62
|
+
```
|
63
|
+
|
64
|
+
Filters can be combined into a pipeline which causes each filter to hand its
|
65
|
+
output to the next filter's input. So if you wanted to have content be
|
66
|
+
filtered through Markdown and be syntax highlighted, you can create the
|
67
|
+
following pipeline:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
pipeline = HTML::Pipeline.new [
|
71
|
+
HTML::Pipeline::MarkdownFilter,
|
72
|
+
HTML::Pipeline::SyntaxHighlightFilter
|
73
|
+
]
|
74
|
+
result = pipeline.call <<-CODE
|
75
|
+
This is *great*:
|
76
|
+
|
77
|
+
some_code(:first)
|
78
|
+
|
79
|
+
CODE
|
80
|
+
result[:output].to_s
|
81
|
+
```
|
82
|
+
|
83
|
+
Prints:
|
84
|
+
|
85
|
+
```html
|
86
|
+
<p>This is <em>great</em>:</p>
|
87
|
+
|
88
|
+
<div class="highlight">
|
89
|
+
<pre><span class="n">some_code</span><span class="p">(</span><span class="ss">:first</span><span class="p">)</span>
|
90
|
+
</pre>
|
91
|
+
</div>
|
92
|
+
```
|
93
|
+
|
94
|
+
Some filters take an optional **context** and/or **result** hash. These are
|
95
|
+
used to pass around arguments and metadata between filters in a pipeline. For
|
96
|
+
example, if you want don't want to use GitHub formatted Markdown, you can
|
97
|
+
pass an option in the context hash:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
filter = HTML::Pipeline::MarkdownFilter.new("Hi **world**!", :gfm => false)
|
101
|
+
filter.call
|
102
|
+
```
|
103
|
+
|
104
|
+
## Filters
|
105
|
+
|
106
|
+
* `MentionFilter` - replace `@user` mentions with links
|
107
|
+
* `AbsoluteSourceFilter` - replace relative image urls with fully qualified versions
|
108
|
+
* `AutoLinkFilter` - auto_linking urls in HTML
|
109
|
+
* `CamoFilter` - replace http image urls with [camo-fied](https://github.com/atmos/camo) https versions
|
110
|
+
* `EmailReplyFilter` - util filter for working with emails
|
111
|
+
* `EmojiFilter` - everyone loves [emoji](http://www.emoji-cheat-sheet.com/)!
|
112
|
+
* `HttpsFilter` - HTML Filter for replacing http github urls with https versions.
|
113
|
+
* `ImageMaxWidthFilter` - link to full size image for large images
|
114
|
+
* `MarkdownFilter` - convert markdown to html
|
115
|
+
* `PlainTextInputFilter` - html escape text and wrap the result in a div
|
116
|
+
* `SanitizationFilter` - whitelist sanitize user markup
|
117
|
+
* `SyntaxHighlightFilter` - [code syntax highlighter](#syntax-highlighting)
|
118
|
+
* `TextileFilter` - convert textile to html
|
119
|
+
* `TableOfContentsFilter` - anchor headings with name attributes
|
120
|
+
|
121
|
+
## Syntax highlighting
|
122
|
+
|
123
|
+
`SyntaxHighlightFilter` uses [github-linguist](https://github.com/github/linguist)
|
124
|
+
to detect and highlight languages. It isn't included as a dependency by default
|
125
|
+
because it's a large dependency and
|
126
|
+
[a hassle to build on heroku](https://github.com/jch/html-pipeline/issues/33).
|
127
|
+
To use the filter, add the following to your Gemfile:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
gem 'github-linguist'
|
131
|
+
```
|
132
|
+
|
133
|
+
## Examples
|
134
|
+
|
135
|
+
We define different pipelines for different parts of our app. Here are a few
|
136
|
+
paraphrased snippets to get you started:
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
# The context hash is how you pass options between different filters.
|
140
|
+
# See individual filter source for explanation of options.
|
141
|
+
context = {
|
142
|
+
:asset_root => "http://your-domain.com/where/your/images/live/icons",
|
143
|
+
:base_url => "http://your-domain.com"
|
144
|
+
}
|
145
|
+
|
146
|
+
# Pipeline providing sanitization and image hijacking but no mention
|
147
|
+
# related features.
|
148
|
+
SimplePipeline = Pipeline.new [
|
149
|
+
SanitizationFilter,
|
150
|
+
TableOfContentsFilter, # add 'name' anchors to all headers
|
151
|
+
CamoFilter,
|
152
|
+
ImageMaxWidthFilter,
|
153
|
+
SyntaxHighlightFilter,
|
154
|
+
EmojiFilter,
|
155
|
+
AutolinkFilter
|
156
|
+
], context
|
157
|
+
|
158
|
+
# Pipeline used for user provided content on the web
|
159
|
+
MarkdownPipeline = Pipeline.new [
|
160
|
+
MarkdownFilter,
|
161
|
+
SanitizationFilter,
|
162
|
+
CamoFilter,
|
163
|
+
ImageMaxWidthFilter,
|
164
|
+
HttpsFilter,
|
165
|
+
MentionFilter,
|
166
|
+
EmojiFilter,
|
167
|
+
SyntaxHighlightFilter
|
168
|
+
], context.merge(:gfm => true) # enable github formatted markdown
|
169
|
+
|
170
|
+
|
171
|
+
# Define a pipeline based on another pipeline's filters
|
172
|
+
NonGFMMarkdownPipeline = Pipeline.new(MarkdownPipeline.filters,
|
173
|
+
context.merge(:gfm => false))
|
174
|
+
|
175
|
+
# Pipelines aren't limited to the web. You can use them for email
|
176
|
+
# processing also.
|
177
|
+
HtmlEmailPipeline = Pipeline.new [
|
178
|
+
ImageMaxWidthFilter
|
179
|
+
], {}
|
180
|
+
|
181
|
+
# Just emoji.
|
182
|
+
EmojiPipeline = Pipeline.new [
|
183
|
+
HTMLInputFilter,
|
184
|
+
EmojiFilter
|
185
|
+
], context
|
186
|
+
```
|
187
|
+
|
188
|
+
## Extending
|
189
|
+
To write a custom filter, you need a class with a `call` method that inherits
|
190
|
+
from `HTML::Pipeline::Filter`.
|
191
|
+
|
192
|
+
For example this filter adds a base url to images that are root relative:
|
193
|
+
|
194
|
+
```ruby
|
195
|
+
require 'uri'
|
196
|
+
|
197
|
+
class RootRelativeFilter < HTML::Pipeline::Filter
|
198
|
+
|
199
|
+
def call
|
200
|
+
doc.search("img").each do |img|
|
201
|
+
next if img['src'].nil?
|
202
|
+
src = img['src'].strip
|
203
|
+
if src.start_with? '/'
|
204
|
+
img["src"] = URI.join(context[:base_url], src).to_s
|
205
|
+
end
|
206
|
+
end
|
207
|
+
doc
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
```
|
212
|
+
|
213
|
+
Now this filter can be used in a pipeline:
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
Pipeline.new [ RootRelativeFilter ], { :base_url => 'http://somehost.com' }
|
217
|
+
```
|
218
|
+
|
219
|
+
## Instrumenting
|
220
|
+
|
221
|
+
Filters and Pipelines can be set up to be instrumented when called. The pipeline
|
222
|
+
must be setup with an [ActiveSupport::Notifications]
|
223
|
+
(http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html)
|
224
|
+
compatible service object and a name. New pipeline objects will default to the
|
225
|
+
`HTML::Pipeline.default_instrumentation_service` object.
|
226
|
+
|
227
|
+
``` ruby
|
228
|
+
# the AS::Notifications-compatible service object
|
229
|
+
service = ActiveSupport::Notifications
|
230
|
+
|
231
|
+
# instrument a specific pipeline
|
232
|
+
pipeline = HTML::Pipeline.new [MarkdownFilter], context
|
233
|
+
pipeline.setup_instrumentation "MarkdownPipeline", service
|
234
|
+
|
235
|
+
# or set default instrumentation service for all new pipelines
|
236
|
+
HTML::Pipeline.default_instrumentation_service = service
|
237
|
+
pipeline = HTML::Pipeline.new [MarkdownFilter], context
|
238
|
+
pipeline.setup_instrumentation "MarkdownPipeline"
|
239
|
+
```
|
240
|
+
|
241
|
+
Filters are instrumented when they are run through the pipeline. A
|
242
|
+
`call_filter.html_pipeline` event is published once the filter finishes. The
|
243
|
+
`payload` should include the `filter` name. Each filter will trigger its own
|
244
|
+
instrumentation call.
|
245
|
+
|
246
|
+
``` ruby
|
247
|
+
service.subscribe "call_filter.html_pipeline" do |event, start, ending, transaction_id, payload|
|
248
|
+
payload[:pipeline] #=> "MarkdownPipeline", set with `setup_instrumentation`
|
249
|
+
payload[:filter] #=> "MarkdownFilter"
|
250
|
+
payload[:context] #=> context Hash
|
251
|
+
payload[:result] #=> instance of result class
|
252
|
+
payload[:result][:output] #=> output HTML String or Nokogiri::DocumentFragment
|
253
|
+
end
|
254
|
+
```
|
255
|
+
|
256
|
+
The full pipeline is also instrumented:
|
257
|
+
|
258
|
+
``` ruby
|
259
|
+
service.subscribe "call_pipeline.html_pipeline" do |event, start, ending, transaction_id, payload|
|
260
|
+
payload[:pipeline] #=> "MarkdownPipeline", set with `setup_instrumentation`
|
261
|
+
payload[:filters] #=> ["MarkdownFilter"]
|
262
|
+
payload[:doc] #=> HTML String or Nokogiri::DocumentFragment
|
263
|
+
payload[:context] #=> context Hash
|
264
|
+
payload[:result] #=> instance of result class
|
265
|
+
payload[:result][:output] #=> output HTML String or Nokogiri::DocumentFragment
|
266
|
+
end
|
267
|
+
```
|
268
|
+
|
269
|
+
## Documentation
|
270
|
+
|
271
|
+
Full reference documentation can be [found here](http://rubydoc.info/gems/html-pipeline/frames).
|
272
|
+
|
273
|
+
## Development
|
274
|
+
|
275
|
+
To see what has changed in recent versions, see the [CHANGELOG](https://github.com/jch/html-pipeline/blob/master/CHANGELOG.md).
|
276
|
+
|
277
|
+
```sh
|
278
|
+
bundle
|
279
|
+
rake test
|
280
|
+
```
|
281
|
+
|
282
|
+
## Contributing
|
283
|
+
|
284
|
+
1. [Fork it](https://help.github.com/articles/fork-a-repo)
|
285
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
286
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
287
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
288
|
+
5. Create new [Pull Request](https://help.github.com/articles/using-pull-requests)
|
289
|
+
|
290
|
+
## Contributors
|
291
|
+
|
292
|
+
Thanks to all of [these contributors](https://github.com/jch/html-pipeline/graphs/contributors).
|
293
|
+
|
294
|
+
Project is a member of the [OSS Manifesto](http://ossmanifesto.org/).
|
data/Rakefile
ADDED
data/bin/html-pipeline
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'html/pipeline'
|
3
|
+
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
# Accept "help", too
|
7
|
+
ARGV.map!{|a| a == "help" ? "--help" : a }
|
8
|
+
|
9
|
+
OptionParser.new do |opts|
|
10
|
+
opts.banner = <<-HELP.gsub(/^ /, '')
|
11
|
+
Usage: html-pipeline [-h] [-f]
|
12
|
+
html-pipeline [FILTER [FILTER [...]]] < file.md
|
13
|
+
cat file.md | html-pipeline [FILTER [FILTER [...]]]
|
14
|
+
HELP
|
15
|
+
|
16
|
+
opts.separator "Options:"
|
17
|
+
|
18
|
+
opts.on("-f", "--filters", "List the available filters") do
|
19
|
+
filters = HTML::Pipeline.constants.grep(/\w+Filter$/).
|
20
|
+
map{|f| f.to_s.gsub(/Filter$/,'') }
|
21
|
+
|
22
|
+
# Text filter doesn't work, no call method
|
23
|
+
filters -= ["Text"]
|
24
|
+
|
25
|
+
abort <<-HELP.gsub(/^ /, '')
|
26
|
+
Available filters:
|
27
|
+
#{filters.join("\n ")}
|
28
|
+
HELP
|
29
|
+
end
|
30
|
+
end.parse!
|
31
|
+
|
32
|
+
# Default to a GitHub-ish pipeline
|
33
|
+
if ARGV.empty?
|
34
|
+
|
35
|
+
filters = [
|
36
|
+
HTML::Pipeline::MarkdownFilter,
|
37
|
+
HTML::Pipeline::SanitizationFilter,
|
38
|
+
HTML::Pipeline::ImageMaxWidthFilter,
|
39
|
+
HTML::Pipeline::EmojiFilter,
|
40
|
+
HTML::Pipeline::AutolinkFilter,
|
41
|
+
HTML::Pipeline::TableOfContentsFilter,
|
42
|
+
]
|
43
|
+
|
44
|
+
# Add syntax highlighting if linguist is present
|
45
|
+
begin
|
46
|
+
require 'linguist'
|
47
|
+
filters << HTML::Pipeline::SyntaxHighlightFilter
|
48
|
+
rescue LoadError
|
49
|
+
end
|
50
|
+
|
51
|
+
else
|
52
|
+
|
53
|
+
def filter_named(name)
|
54
|
+
case name
|
55
|
+
when "Text"
|
56
|
+
raise NameError # Text filter doesn't work, no call method
|
57
|
+
when "Textile"
|
58
|
+
require "RedCloth" # Textile filter doesn't require RedCloth
|
59
|
+
end
|
60
|
+
|
61
|
+
HTML::Pipeline.const_get("#{name}Filter")
|
62
|
+
rescue NameError => e
|
63
|
+
abort "Unknown filter '#{name}'. List filters with the -f option."
|
64
|
+
end
|
65
|
+
|
66
|
+
filters = []
|
67
|
+
until ARGV.empty?
|
68
|
+
name = ARGV.shift
|
69
|
+
filters << filter_named(name)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
context = {
|
75
|
+
:asset_root => "/assets",
|
76
|
+
:base_url => "/",
|
77
|
+
:gfm => true
|
78
|
+
}
|
79
|
+
|
80
|
+
puts HTML::Pipeline.new(filters, context).call(ARGF.read)[:output]
|