New upstream version 2.8.0

parent 384703b1
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
.config .config
.yardoc .yardoc
Gemfile.lock Gemfile.lock
gemfiles/*.lock
InstalledFiles InstalledFiles
_yardoc _yardoc
coverage coverage
......
language: ruby language: ruby
sudo: false
cache: bundler
bundler_args: --path ../../vendor/bundle
before_install: addons:
- sudo apt-get update -qq apt:
- sudo apt-get install -qq libicu-dev sources:
- libicu-dev
- kalakris-cmake
packages:
- cmake
script: "bundle exec rake" script: bundle exec rake
gemfile:
- gemfiles/rails_5.gemfile
- gemfiles/rails_4.gemfile
- gemfiles/rails_3.gemfile
rvm: rvm:
- 1.9.2 - 2.4.0
- 1.9.3 - 2.3.1
- 2.0.0 - 2.2.5
- 2.1.1 - ruby-head
- ree
matrix: matrix:
fast_finish: true fast_finish: true
allow_failures: allow_failures:
- rvm: ree - rvm: ruby-head
exclude:
- gemfile: gemfiles/rails_4.gemfile
rvm: 2.4.0
- gemfile: gemfiles/rails_3.gemfile
rvm: 2.4.0
appraise 'rails-3' do
gem 'rack', '< 2'
gem 'rails', '3.2.22.2'
end
appraise 'rails-4' do
gem 'rack', '< 2'
gem 'rails', '~> 4.2.6'
end
appraise 'rails-5' do
gem 'rails', '~> 5.0.0'
end
# CHANGELOG # CHANGELOG
## 2.6.0
* Switch from github-markdown to CommonMark #274
* Fixed a few warnings
## 2.5.0
* Ruby 2.4 support. Backwards compatible, but bumped minor version so projects can choose to lock at older version [#268](https://github.com/jch/html-pipeline/pull/268)
## 2.4.2
* Make EmojiFilter generated img tag HTML attributes configurable [#258](https://github.com/jch/html-pipeline/pull/258)
## 2.4.1
* Regression in EmailReplyPipeline: unfiltered content is being omitted [#253](https://github.com/jch/html-pipeline/pull/253)
## 2.4.0
* Optionally filter email addresses [#247](https://github.com/jch/html-pipeline/pull/247)
## 2.3.0
* Add option to pass in an anchor icon, instead of using octicons [#244](https://github.com/jch/html-pipeline/pull/244)
## 2.2.4
* Use entire namespace so MissingDependencyError constant is resolved [#243](https://github.com/jch/html-pipeline/pull/243)
## 2.2.3
* raise MissingDependencyError instead of aborting on missing dependency [#241](https://github.com/jch/html-pipeline/pull/241)
* Fix typo [#239](https://github.com/jch/html-pipeline/pull/239)
* Test against Ruby 2.3.0 on Travis CI [#238](https://github.com/jch/html-pipeline/pull/238)
* use travis containers [#237](https://github.com/jch/html-pipeline/pull/237)
## 2.2.2
* Fix for calling mention_link_filter with only one argument [#230](https://github.com/jch/html-pipeline/pull/230)
* Add html-pipeline-linkify_github to 3rd Party Extensions in README [#228](https://github.com/jch/html-pipeline/pull/228)
## 2.2.1
* Soften Nokogiri dependency to versions ">= 1.4" [#208](https://github.com/jch/html-pipeline/pull/208)
## 2.2.0
* Only allow cite attribute on blockquote and restrict schemes [#223](https://github.com/jch/html-pipeline/pull/223)
## 2.1.0
* Whitelist schemes for longdesc [#221](https://github.com/jch/html-pipeline/pull/221)
* Extract emoji image tag generation to own method [#195](https://github.com/jch/html-pipeline/pull/195)
* Update README.md [#211](https://github.com/jch/html-pipeline/pull/211)
* Add ImageFilter for image url to img tag conversion [#207](https://github.com/jch/html-pipeline/pull/207)
## 2.0
**New**
* Implement new EmojiFilter context option: ignored_ancestor_tags to accept more ignored tags. [#170](https://github.com/jch/html-pipeline/pull/170) @JuanitoFatas
* Add GitHub flavor Markdown Task List extension [#162](https://github.com/jch/html-pipeline/pull/162) @simeonwillbanks
* @mention allow for custom regex to identify usernames. [#157](https://github.com/jch/html-pipeline/pull/157) @brittballard
* EmojiFilter now requires gemoji ~> 2. [#159](https://github.com/jch/html-pipeline/pull/159) @jch
**Changes**
* Restrict nokogiri to >= 1.4, <= 1.6.5 [#176](https://github.com/jch/html-pipeline/pull/176) @simeonwillbanks
* MentionFilter#link_to_mentioned_user: Replace String introspection with Regexp match [#172](https://github.com/jch/html-pipeline/pull/172) @simeonwillbanks
* Whitelist summary and details element. [#171](https://github.com/jch/html-pipeline/pull/171) @JuanitoFatas
* Support ~login for MentionFilter. [#167](https://github.com/jch/html-pipeline/pull/167) @JuanitoFatas
* Revert "Search for text nodes on DocumentFragments without root tags" [#158](https://github.com/jch/html-pipeline/pull/158) @jch
* Drop support for ruby ree, 1.9.2, 1.9.3 [#156](https://github.com/jch/html-pipeline/pull/156) @jch
* Skip EmojiFilter in `<tt>` tags [#147](https://github.com/jch/html-pipeline/pull/147) @moskvax
* Use Linguist lexers [#153](https://github.com/jch/html-pipeline/pull/153) @pchaigno
* Constrain Active Support >= 2, < 5 [#180](https://github.com/jch/html-pipeline/pull/180) @jch
## 1.11.0 ## 1.11.0
* Search for text nodes on DocumentFragments without root tags #146 Razer6 * Search for text nodes on DocumentFragments without root tags #146 Razer6
* Don't filter @mentions in <style> tags #145 jch * Don't filter @mentions in `<style>` tags #145 jch
* Prefer `http_url` in HttpsFilter. `base_url` still works. #142 bkeepers * Prefer `http_url` in HttpsFilter. `base_url` still works. #142 bkeepers
* Remove duplicate check in EmojiFilter #141 Razer6 * Remove duplicate check in EmojiFilter #141 Razer6
......
source "https://rubygems.org" source 'https://rubygems.org'
# Specify your gem's dependencies in html-pipeline.gemspec # Specify your gem's dependencies in html-pipeline.gemspec
gemspec gemspec
group :development do group :development do
gem "bundler" gem 'appraisal'
gem "rake" gem 'bundler'
gem 'rake'
end end
group :test do group :test do
gem "minitest", "~> 5.3" gem 'commonmarker', '~> 0.16', require: false
gem "rinku", "~> 1.7", :require => false gem 'email_reply_parser', '~> 0.5', require: false
gem "gemoji", "~> 1.0", :require => false gem 'gemoji', '~> 2.0', require: false
gem "RedCloth", "~> 4.2.9", :require => false gem 'minitest'
gem "github-markdown", "~> 0.5", :require => false gem 'RedCloth', '~> 4.2.9', require: false
gem "email_reply_parser", "~> 0.5", :require => false gem 'rinku', '~> 1.7', require: false
gem 'sanitize', '~> 2.0', require: false
if RUBY_VERSION < "2.1.0" gem 'escape_utils', '~> 1.0', require: false
gem "escape_utils", "~> 0.3", :require => false gem 'rouge', '~> 3.1', require: false
gem "github-linguist", "~> 2.6.2", :require => false
else
gem "escape_utils", "~> 1.0", :require => false
gem "github-linguist", "~> 2.10", :require => false
end
if RUBY_VERSION < "1.9.2"
gem "sanitize", ">= 2", "< 2.0.4", :require => false
gem "nokogiri", ">= 1.4", "< 1.6"
else
gem "sanitize", "~> 2.0", :require => false
end
if RUBY_VERSION < "1.9.3"
gem "activesupport", ">= 2", "< 4"
end
end end
# HTML::Pipeline [![Build Status](https://secure.travis-ci.org/jch/html-pipeline.png)](http://travis-ci.org/jch/html-pipeline) # HTML::Pipeline [![Build Status](https://travis-ci.org/jch/html-pipeline.svg?branch=master)](https://travis-ci.org/jch/html-pipeline)
GitHub HTML processing filters and utilities. This module includes a small GitHub HTML processing filters and utilities. This module includes a small
framework for defining DOM based content filters and applying them to user framework for defining DOM based content filters and applying them to user
...@@ -78,13 +78,11 @@ Prints: ...@@ -78,13 +78,11 @@ Prints:
```html ```html
<p>This is <em>great</em>:</p> <p>This is <em>great</em>:</p>
<div class="highlight"> <pre><code>some_code(:first)
<pre><span class="n">some_code</span><span class="p">(</span><span class="ss">:first</span><span class="p">)</span> </code></pre>
</pre>
</div>
``` ```
To generate CSS for HTML formatted code, use the [pygments.rb](https://github.com/tmm1/pygments.rb#usage) `#css` method. `pygments.rb` is a dependency of the `SyntaxHighlightFilter`. To generate CSS for HTML formatted code, use the [Rouge CSS Theme](https://github.com/jneen/rouge#css-theme-options) `#css` method. `rouge` is a dependency of the `SyntaxHighlightFilter`.
Some filters take an optional **context** and/or **result** hash. These are Some filters take an optional **context** and/or **result** hash. These are
used to pass around arguments and metadata between filters in a pipeline. For used to pass around arguments and metadata between filters in a pipeline. For
...@@ -141,6 +139,7 @@ NonGFMMarkdownPipeline = Pipeline.new(MarkdownPipeline.filters, ...@@ -141,6 +139,7 @@ NonGFMMarkdownPipeline = Pipeline.new(MarkdownPipeline.filters,
# Pipelines aren't limited to the web. You can use them for email # Pipelines aren't limited to the web. You can use them for email
# processing also. # processing also.
HtmlEmailPipeline = Pipeline.new [ HtmlEmailPipeline = Pipeline.new [
PlainTextInputFilter,
ImageMaxWidthFilter ImageMaxWidthFilter
], {} ], {}
...@@ -164,7 +163,7 @@ EmojiPipeline = Pipeline.new [ ...@@ -164,7 +163,7 @@ EmojiPipeline = Pipeline.new [
* `MarkdownFilter` - convert markdown to html * `MarkdownFilter` - convert markdown to html
* `PlainTextInputFilter` - html escape text and wrap the result in a div * `PlainTextInputFilter` - html escape text and wrap the result in a div
* `SanitizationFilter` - whitelist sanitize user markup * `SanitizationFilter` - whitelist sanitize user markup
* `SyntaxHighlightFilter` - [code syntax highlighter](#syntax-highlighting) * `SyntaxHighlightFilter` - code syntax highlighter
* `TextileFilter` - convert textile to html * `TextileFilter` - convert textile to html
* `TableOfContentsFilter` - anchor headings with name attributes and generate Table of Contents html unordered list linking headings * `TableOfContentsFilter` - anchor headings with name attributes and generate Table of Contents html unordered list linking headings
...@@ -172,21 +171,21 @@ EmojiPipeline = Pipeline.new [ ...@@ -172,21 +171,21 @@ EmojiPipeline = Pipeline.new [
Filter gem dependencies are not bundled; you must bundle the filter's gem Filter gem dependencies are not bundled; you must bundle the filter's gem
dependencies. The below list details filters with dependencies. For example, dependencies. The below list details filters with dependencies. For example,
`SyntaxHighlightFilter` uses [github-linguist](https://github.com/github/linguist) `SyntaxHighlightFilter` uses [rouge](https://github.com/jneen/rouge)
to detect and highlight languages. For example, to use the `SyntaxHighlightFilter`, to detect and highlight languages. For example, to use the `SyntaxHighlightFilter`,
add the following to your Gemfile: add the following to your Gemfile:
```ruby ```ruby
gem 'github-linguist' gem 'rouge'
``` ```
* `AutolinkFilter` - `rinku` * `AutolinkFilter` - `rinku`
* `EmailReplyFilter` - `escape_utils`, `email_reply_parser` * `EmailReplyFilter` - `escape_utils`, `email_reply_parser`
* `EmojiFilter` - `gemoji` * `EmojiFilter` - `gemoji`
* `MarkdownFilter` - `github-markdown` * `MarkdownFilter` - `commonmarker`
* `PlainTextInputFilter` - `escape_utils` * `PlainTextInputFilter` - `escape_utils`
* `SanitizationFilter` - `sanitize` * `SanitizationFilter` - `sanitize`
* `SyntaxHighlightFilter` - `github-linguist` * `SyntaxHighlightFilter` - `rouge`
* `TextileFilter` - `RedCloth` * `TextileFilter` - `RedCloth`
_Note:_ See [Gemfile](/Gemfile) `:test` block for version requirements. _Note:_ See [Gemfile](/Gemfile) `:test` block for version requirements.
...@@ -233,13 +232,33 @@ If you have an idea for a filter, propose it as ...@@ -233,13 +232,33 @@ If you have an idea for a filter, propose it as
whether the filter is a common enough use case to belong in this gem, or should be whether the filter is a common enough use case to belong in this gem, or should be
built as an external gem. built as an external gem.
* [html-pipeline-asciidoc_filter](https://github.com/asciidoctor/html-pipeline-asciidoc_filter) - asciidoc support Here are some extensions people have built:
* [html-pipeline-asciidoc_filter](https://github.com/asciidoctor/html-pipeline-asciidoc_filter)
* [jekyll-html-pipeline](https://github.com/gjtorikian/jekyll-html-pipeline)
* [nanoc-html-pipeline](https://github.com/burnto/nanoc-html-pipeline)
* [html-pipeline-bitly](https://github.com/dewski/html-pipeline-bitly)
* [html-pipeline-cite](https://github.com/lifted-studios/html-pipeline-cite)
* [tilt-html-pipeline](https://github.com/bradgessler/tilt-html-pipeline)
* [html-pipeline-wiki-link'](https://github.com/lifted-studios/html-pipeline-wiki-link) - WikiMedia-style wiki links
* [task_list](https://github.com/github/task_list) - GitHub flavor Markdown Task List
* [html-pipeline-nico_link](https://github.com/rutan/html-pipeline-nico_link) - An HTML::Pipeline filter for [niconico](http://www.nicovideo.jp) description links
* [html-pipeline-gitlab](https://gitlab.com/gitlab-org/html-pipeline-gitlab) - This gem implements various filters for html-pipeline used by GitLab
* [html-pipeline-youtube](https://github.com/st0012/html-pipeline-youtube) - An HTML::Pipeline filter for YouTube links
* [html-pipeline-flickr](https://github.com/st0012/html-pipeline-flickr) - An HTML::Pipeline filter for Flickr links
* [html-pipeline-vimeo](https://github.com/dlackty/html-pipeline-vimeo) - An HTML::Pipeline filter for Vimeo links
* [html-pipeline-hashtag](https://github.com/mr-dxdy/html-pipeline-hashtag) - An HTML::Pipeline filter for hashtags
* [html-pipeline-linkify_github](https://github.com/jollygoodcode/html-pipeline-linkify_github) - An HTML::Pipeline filter to autolink GitHub urls
* [html-pipeline-redcarpet_filter](https://github.com/bmikol/html-pipeline-redcarpet_filter) - Render Markdown source text into Markdown HTML using Redcarpet
* [html-pipeline-typogruby_filter](https://github.com/bmikol/html-pipeline-typogruby_filter) - Add Typogruby text filters to your HTML::Pipeline
* [korgi](https://github.com/jodeci/korgi) - HTML::Pipeline filters for links to Rails resources
## Instrumenting ## Instrumenting
Filters and Pipelines can be set up to be instrumented when called. The pipeline Filters and Pipelines can be set up to be instrumented when called. The pipeline
must be setup with an [ActiveSupport::Notifications] must be setup with an
(http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) [ActiveSupport::Notifications](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html)
compatible service object and a name. New pipeline objects will default to the compatible service object and a name. New pipeline objects will default to the
`HTML::Pipeline.default_instrumentation_service` object. `HTML::Pipeline.default_instrumentation_service` object.
...@@ -285,6 +304,36 @@ service.subscribe "call_pipeline.html_pipeline" do |event, start, ending, transa ...@@ -285,6 +304,36 @@ service.subscribe "call_pipeline.html_pipeline" do |event, start, ending, transa
end end
``` ```
## FAQ
### 1. Why doesn't my pipeline work when there's no root element in the document?
To make a pipeline work on a plain text document, put the `PlainTextInputFilter`
at the beginning of your pipeline. This will wrap the content in a `div` so the
filters have a root element to work with. If you're passing in an HTML fragment,
but it doesn't have a root element, you can wrap the content in a `div`
yourself. For example:
```ruby
EmojiPipeline = Pipeline.new [
PlainTextInputFilter, # <- Wraps input in a div and escapes html tags
EmojiFilter
], context
plain_text = "Gutentag! :wave:"
EmojiPipeline.call(plain_text)
html_fragment = "This is outside of an html element, but <strong>this isn't. :+1:</strong>"
EmojiPipeline.call("<div>#{html_fragment}</div>") # <- Wrap your own html fragments to avoid escaping
```
### 2. How do I customize a whitelist for `SanitizationFilter`s?
`SanitizationFilter::WHITELIST` is the default whitelist used if no `:whitelist`
argument is given in the context. The default is a good starting template for
you to add additional elements. You can either modify the constant's value, or
re-define your own constant and pass that in via the context.
## Contributing ## Contributing
Please review the [Contributing Guide](https://github.com/jch/html-pipeline/blob/master/CONTRIBUTING.md). Please review the [Contributing Guide](https://github.com/jch/html-pipeline/blob/master/CONTRIBUTING.md).
...@@ -307,6 +356,9 @@ Project is a member of the [OSS Manifesto](http://ossmanifesto.org/). ...@@ -307,6 +356,9 @@ Project is a member of the [OSS Manifesto](http://ossmanifesto.org/).
This section is for gem maintainers to cut a new version of the gem. This section is for gem maintainers to cut a new version of the gem.
* update lib/html/pipeline/version.rb to next version number X.X.X following [semver](http://semver.org). * create a new branch named `release-x.y.z` where `x.y.z` follows [semver](http://semver.org)
* update CHANGELOG.md. Get latest changes with `git log --oneline vLAST_RELEASE..HEAD | grep Merge` * update lib/html/pipeline/version.rb to next version number X.X.X
* update CHANGELOG.md. Prepare a draft with `script/changelog`
* push branch and create a new pull request
* after tests are green, merge to master
* on the master branch, run `script/release` * on the master branch, run `script/release`
#!/usr/bin/env rake #!/usr/bin/env rake
require "bundler/gem_tasks" require 'rubygems'
require 'bundler/setup'
require 'bundler/gem_tasks'
require 'rake/testtask' require 'rake/testtask'
Rake::TestTask.new do |t| Rake::TestTask.new do |t|
t.libs << "test" t.libs << 'test'
t.test_files = FileList['test/**/*_test.rb'] t.test_files = FileList['test/**/*_test.rb']
t.verbose = true t.verbose = true
t.warning = false
end end
task :default => :test task default: :test
\ No newline at end of file
...@@ -4,23 +4,23 @@ require 'html/pipeline' ...@@ -4,23 +4,23 @@ require 'html/pipeline'
require 'optparse' require 'optparse'
# Accept "help", too # Accept "help", too
ARGV.map!{|a| a == "help" ? "--help" : a } .map! { |a| a == 'help' ? '--help' : a }
OptionParser.new do |opts| onParser.new do |opts|
opts.banner = <<-HELP.gsub(/^ /, '') opts.banner = <<-HELP.gsub(/^ /, '')
Usage: html-pipeline [-h] [-f] Usage: html-pipeline [-h] [-f]
html-pipeline [FILTER [FILTER [...]]] < file.md html-pipeline [FILTER [FILTER [...]]] < file.md
cat file.md | html-pipeline [FILTER [FILTER [...]]] cat file.md | html-pipeline [FILTER [FILTER [...]]]
HELP HELP
opts.separator "Options:" opts.separator 'Options:'
opts.on("-f", "--filters", "List the available filters") do opts.on('-f', '--filters', 'List the available filters') do
filters = HTML::Pipeline.constants.grep(/\w+Filter$/). filters = HTML::Pipeline.constants.grep(/\w+Filter$/)
map{|f| f.to_s.gsub(/Filter$/,'') } .map { |f| f.to_s.gsub(/Filter$/, '') }
# Text filter doesn't work, no call method # Text filter doesn't work, no call method
filters -= ["Text"] filters -= ['Text']
abort <<-HELP.gsub(/^ /, '') abort <<-HELP.gsub(/^ /, '')
Available filters: Available filters:
...@@ -38,12 +38,12 @@ if ARGV.empty? ...@@ -38,12 +38,12 @@ if ARGV.empty?
HTML::Pipeline::ImageMaxWidthFilter, HTML::Pipeline::ImageMaxWidthFilter,
HTML::Pipeline::EmojiFilter, HTML::Pipeline::EmojiFilter,
HTML::Pipeline::AutolinkFilter, HTML::Pipeline::AutolinkFilter,
HTML::Pipeline::TableOfContentsFilter, HTML::Pipeline::TableOfContentsFilter
] ]
# Add syntax highlighting if linguist is present # Add syntax highlighting if rouge is present
begin begin
require 'linguist' require 'rouge'
filters << HTML::Pipeline::SyntaxHighlightFilter filters << HTML::Pipeline::SyntaxHighlightFilter
rescue LoadError rescue LoadError
end end
...@@ -52,7 +52,7 @@ else ...@@ -52,7 +52,7 @@ else
def filter_named(name) def filter_named(name)
case name case name
when "Text" when 'Text'
raise NameError # Text filter doesn't work, no call method raise NameError # Text filter doesn't work, no call method
end end
...@@ -70,9 +70,9 @@ else ...@@ -70,9 +70,9 @@ else
end end
context = { context = {
:asset_root => "/assets", asset_root: '/assets',
:base_url => "/", base_url: '/',
:gfm => true gfm: true
} }
puts HTML::Pipeline.new(filters, context).call(ARGF.read)[:output] puts HTML::Pipeline.new(filters, context).call(ARGF.read)[:output]
# -*- encoding: utf-8 -*-
require File.expand_path("../lib/html/pipeline/version", __FILE__) require File.expand_path('../lib/html/pipeline/version', __FILE__)
Gem::Specification.new do |gem| Gem::Specification.new do |gem|
gem.name = "html-pipeline" gem.name = 'html-pipeline'
gem.version = HTML::Pipeline::VERSION gem.version = HTML::Pipeline::VERSION
gem.license = "MIT" gem.license = 'MIT'
gem.authors = ["Ryan Tomayko", "Jerry Cheung"] gem.authors = ['Ryan Tomayko', 'Jerry Cheung']
gem.email = ["ryan@github.com", "jerry@github.com"] gem.email = ['ryan@github.com', 'jerry@github.com']
gem.description = %q{GitHub HTML processing filters and utilities} gem.description = 'GitHub HTML processing filters and utilities'
gem.summary = %q{Helpers for processing content through a chain of filters} gem.summary = 'Helpers for processing content through a chain of filters'
gem.homepage = "https://github.com/jch/html-pipeline" gem.homepage = 'https://github.com/jch/html-pipeline'
gem.files = `git ls-files`.split $/ gem.files = `git ls-files -z`.split("\x0").reject { |f| f =~ %r{^(test|gemfiles|script)/} }
gem.test_files = gem.files.grep(%r{^test}) gem.require_paths = ['lib']
gem.require_paths = ["lib"]
gem.add_dependency "nokogiri", "~> 1.4" gem.add_dependency 'activesupport', '>= 2'
gem.add_dependency "activesupport", ">= 2" gem.add_dependency 'nokogiri', '>= 1.4'
gem.post_install_message = <<msg gem.post_install_message = <<msg
------------------------------------------------- -------------------------------------------------
......
require "nokogiri" require 'nokogiri'
require "active_support/xml_mini/nokogiri" # convert Documents to hashes require 'active_support/xml_mini/nokogiri' # convert Documents to hashes
module HTML module HTML
# GitHub HTML processing filters and utilities. This module includes a small # GitHub HTML processing filters and utilities. This module includes a small
...@@ -32,6 +32,7 @@ module HTML ...@@ -32,6 +32,7 @@ module HTML
autoload :EmailReplyFilter, 'html/pipeline/email_reply_filter' autoload :EmailReplyFilter, 'html/pipeline/email_reply_filter'
autoload :EmojiFilter, 'html/pipeline/emoji_filter' autoload :EmojiFilter, 'html/pipeline/emoji_filter'
autoload :HttpsFilter, 'html/pipeline/https_filter' autoload :HttpsFilter, 'html/pipeline/https_filter'
autoload :ImageFilter, 'html/pipeline/image_filter'
autoload :ImageMaxWidthFilter, 'html/pipeline/image_max_width_filter' autoload :ImageMaxWidthFilter, 'html/pipeline/image_max_width_filter'
autoload :MarkdownFilter, 'html/pipeline/markdown_filter' autoload :MarkdownFilter, 'html/pipeline/markdown_filter'
autoload :MentionFilter, 'html/pipeline/@mention_filter' autoload :MentionFilter, 'html/pipeline/@mention_filter'
...@@ -42,6 +43,14 @@ module HTML ...@@ -42,6 +43,14 @@ module HTML
autoload :TableOfContentsFilter, 'html/pipeline/toc_filter' autoload :TableOfContentsFilter, 'html/pipeline/toc_filter'
autoload :TextFilter, 'html/pipeline/text_filter' autoload :TextFilter, 'html/pipeline/text_filter'
class MissingDependencyError < RuntimeError; end
def self.require_dependency(name, requirer)
require name
rescue LoadError => e
raise MissingDependencyError,
"Missing dependency '#{name}' for #{requirer}. See README.md for details.\n#{e.class.name}: #{e}"
end
# Our DOM implementation. # Our DOM implementation.
DocumentFragment = Nokogiri::HTML::DocumentFragment DocumentFragment = Nokogiri::HTML::DocumentFragment
...@@ -66,7 +75,8 @@ module HTML ...@@ -66,7 +75,8 @@ module HTML
# Public: String name for this Pipeline. Defaults to Class name. # Public: String name for this Pipeline. Defaults to Class name.
attr_writer :instrumentation_name attr_writer :instrumentation_name
def instrumentation_name def instrumentation_name
@instrumentation_name || self.class.name return @instrumentation_name if defined?(@instrumentation_name)
@instrumentation_name = self.class.name
end end
class << self class << self
...@@ -75,7 +85,7 @@ module HTML ...@@ -75,7 +85,7 @@ module HTML
end end
def initialize(filters, default_context = {}, result_class = nil) def initialize(filters, default_context = {}, result_class = nil)
raise ArgumentError, "default_context cannot be nil" if default_context.nil? raise ArgumentError, 'default_context cannot be nil' if default_context.nil?
@filters = filters.flatten.freeze @filters = filters.flatten.freeze
@default_context = default_context.freeze @default_context = default_context.freeze
@result_class = result_class || Hash @result_class = result_class || Hash
...@@ -98,9 +108,9 @@ module HTML ...@@ -98,9 +108,9 @@ module HTML
context = @default_context.merge(context) context = @default_context.merge(context)
context = context.freeze context = context.freeze
result ||= @result_class.new result ||= @result_class.new
payload = default_payload :filters => @filters.map(&:name), payload = default_payload filters: @filters.map(&:name),
:context => context, :result => result context: context, result: result
instrument "call_pipeline.html_pipeline", payload do instrument 'call_pipeline.html_pipeline', payload do
result[:output] = result[:output] =
@filters.inject(html) do |doc, filter| @filters.inject(html) do |doc, filter|
perform_filter(filter, doc, context, result) perform_filter(filter, doc, context, result)
...@@ -115,9 +125,9 @@ module HTML ...@@ -115,9 +125,9 @@ module HTML
# #
# Returns the result of the filter. # Returns the result of the filter.
def perform_filter(filter, doc, context, result) def perform_filter(filter, doc, context, result)
payload = default_payload :filter => filter.name, payload = default_payload filter: filter.name,
:context => context, :result => result context: context, result: result
instrument "call_filter.html_pipeline", payload do instrument 'call_filter.html_pipeline', payload do
filter.call(doc, context, result) filter.call(doc, context, result)
end end
end end
...@@ -168,13 +178,13 @@ module HTML ...@@ -168,13 +178,13 @@ module HTML
# #
# Returns a Hash. # Returns a Hash.
def default_payload(payload = {}) def default_payload(payload = {})
{:pipeline => instrumentation_name}.merge(payload) { pipeline: instrumentation_name }.merge(payload)
end end
end end
end end
# XXX nokogiri monkey patches for 1.8 # XXX nokogiri monkey patches for 1.8
if not ''.respond_to?(:force_encoding) unless ''.respond_to?(:force_encoding)
class Nokogiri::XML::Node class Nokogiri::XML::Node
# Work around an issue with utf-8 encoded data being erroneously converted to # Work around an issue with utf-8 encoded data being erroneously converted to
# ... some other shit when replacing text nodes. See 'utf-8 output 2' in # ... some other shit when replacing text nodes. See 'utf-8 output 2' in
...@@ -186,8 +196,8 @@ if not ''.respond_to?(:force_encoding) ...@@ -186,8 +196,8 @@ if not ''.respond_to?(:force_encoding)
replace_without_encoding_fix(replacement) replace_without_encoding_fix(replacement)
end end
alias_method :replace_without_encoding_fix, :replace alias replace_without_encoding_fix replace
alias_method :replace, :replace_with_encoding_fix alias replace replace_with_encoding_fix
def swap(replacement) def swap(replacement)
replace(replacement) replace(replacement)
......
...@@ -11,6 +11,8 @@ module HTML ...@@ -11,6 +11,8 @@ module HTML
# mention. # mention.
# :info_url - Used to link to "more info" when someone mentions @mention # :info_url - Used to link to "more info" when someone mentions @mention
# or @mentioned. # or @mentioned.
# :username_pattern - Used to provide a custom regular expression to
# identify usernames
# #
class MentionFilter < Filter class MentionFilter < Filter
# Public: Find user @mentions in text. See # Public: Find user @mentions in text. See
...@@ -27,46 +29,52 @@ module HTML ...@@ -27,46 +29,52 @@ module HTML
# the original text. # the original text.
#