html-proofer 1.6.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/README.md +74 -56
- data/Rakefile +4 -6
- data/bin/htmlproof +46 -36
- data/html-proofer.gemspec +22 -22
- data/lib/html/proofer/check_runner/issue.rb +62 -0
- data/lib/html/proofer/{check.rb → check_runner.rb} +11 -19
- data/lib/html/proofer/checkable.rb +42 -28
- data/lib/html/proofer/checks/favicon.rb +6 -6
- data/lib/html/proofer/checks/html.rb +11 -12
- data/lib/html/proofer/checks/images.rb +11 -11
- data/lib/html/proofer/checks/links.rb +30 -28
- data/lib/html/proofer/checks/scripts.rb +7 -8
- data/lib/html/proofer/log.rb +38 -0
- data/lib/html/proofer/url_validator.rb +135 -0
- data/lib/html/proofer/utils.rb +24 -0
- data/lib/html/proofer/version.rb +1 -1
- data/lib/html/proofer.rb +95 -199
- data/spec/html/proofer/command_spec.rb +82 -0
- data/spec/html/proofer/favicon_spec.rb +20 -20
- data/spec/html/proofer/fixtures/images/srcSetCheck.html +7 -0
- data/spec/html/proofer/fixtures/images/srcSetIgnorable.html +13 -0
- data/spec/html/proofer/fixtures/images/srcSetMissingAlt.html +7 -0
- data/spec/html/proofer/fixtures/images/srcSetMissingImage.html +7 -0
- data/spec/html/proofer/fixtures/links/erstiebegru/314/210/303/237ung.html +1 -0
- data/spec/html/proofer/fixtures/links/erstiebegr/303/274/303/237ung.html +1 -0
- data/spec/html/proofer/fixtures/links/file.foo +11 -0
- data/spec/html/proofer/fixtures/links/folder/multiples/catalog/file.html +8 -0
- data/spec/html/proofer/fixtures/links/folder/multiples/javadoc/file.html +8 -0
- data/spec/html/proofer/fixtures/links/nodupe.html +1 -1
- data/spec/html/proofer/fixtures/links/redirected_error.html +1 -0
- data/spec/html/proofer/fixtures/links/rootLink/rootLink.html +0 -1
- data/spec/html/proofer/fixtures/links/urlencoded-href.html +2 -0
- data/spec/html/proofer/fixtures/links/utf8Link.html +2 -0
- data/spec/html/proofer/fixtures/utils/lang-jp.html +1 -0
- data/spec/html/proofer/html_spec.rb +25 -25
- data/spec/html/proofer/images_spec.rb +59 -35
- data/spec/html/proofer/links_spec.rb +152 -109
- data/spec/html/proofer/scripts_spec.rb +17 -17
- data/spec/html/proofer/utils_spec.rb +14 -0
- data/spec/html/proofer_spec.rb +58 -38
- data/spec/spec_helper.rb +13 -6
- metadata +39 -7
- data/lib/html/proofer/checks.rb +0 -15
- data/lib/html/proofer/issue.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e94fed7b3cb30e272c5de25511ad9604e2a9663
|
4
|
+
data.tar.gz: d2ba44ef2943e993d69906089e374ae51013ff4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f65536fcc74006b51ca34ecc77b048ea59608a2a055c4961afaa086d92c3fe09cc2056de5b7d2a5546f37ec0d6586bec29d1fd7fd05607aaaae3c777cf60172
|
7
|
+
data.tar.gz: ca131c1f0a7d06da44a40a7e714ece99821102153c158f130d909d226a86347ce10745d87b62954cdf71657188459fffef8b7410a949a5134b0ee9236ead3ec9
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -22,6 +22,47 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
**NOTE:** When installation speed matters, set `NOKOGIRI_USE_SYSTEM_LIBRARIES` to `true` in your environment. This is useful for increasing the speed of your Continuous Integration builds.
|
24
24
|
|
25
|
+
### Real-life examples
|
26
|
+
|
27
|
+
Project | Repository
|
28
|
+
:--- | :---
|
29
|
+
[Raspberry Pi documentation](http://www.raspberrypi.org/documentation/) | [raspberrypi/documentation]( https://github.com/raspberrypi/documentation)
|
30
|
+
[Open Whisper Systems website](https://whispersystems.org/) | [WhisperSystems/whispersystems.org](https://github.com/WhisperSystems/whispersystems.org)
|
31
|
+
[Jekyll website](http://jekyllrb.com/) | [jekyll/jekyll](https://github.com/jekyll/jekyll)
|
32
|
+
|
33
|
+
## What's Tested?
|
34
|
+
|
35
|
+
### Images
|
36
|
+
|
37
|
+
`img` elements:
|
38
|
+
|
39
|
+
* Whether all your images have alt tags
|
40
|
+
* Whether your internal image references are not broken
|
41
|
+
* Whether external images are showing
|
42
|
+
|
43
|
+
### Links
|
44
|
+
|
45
|
+
`a`, `link` elements:
|
46
|
+
|
47
|
+
* Whether your internal links are not broken; this includes hash references (`#linkToMe`)
|
48
|
+
* Whether external links are working
|
49
|
+
|
50
|
+
### Scripts
|
51
|
+
|
52
|
+
`script` elements:
|
53
|
+
|
54
|
+
* Whether your internal script references are not broken
|
55
|
+
* Whether external scripts are loading
|
56
|
+
|
57
|
+
### Favicon
|
58
|
+
|
59
|
+
Checks if your favicons are valid. This is an optional feature, set the `check_favicon` option to turn it on.
|
60
|
+
|
61
|
+
### HTML
|
62
|
+
|
63
|
+
Nokogiri looks at the markup and [provides errors](http://www.nokogiri.org/tutorials/ensuring_well_formed_markup.html) when parsing your document.
|
64
|
+
This is an optional feature, set the `check_html` option to enable validation errors from Nokogiri.
|
65
|
+
|
25
66
|
## Usage
|
26
67
|
|
27
68
|
### Using in a script
|
@@ -35,7 +76,7 @@ require 'html/pipeline'
|
|
35
76
|
require 'find'
|
36
77
|
|
37
78
|
# make an out dir
|
38
|
-
Dir.mkdir("out") unless File.
|
79
|
+
Dir.mkdir("out") unless File.exist?("out")
|
39
80
|
|
40
81
|
pipeline = HTML::Pipeline.new [
|
41
82
|
HTML::Pipeline::MarkdownFilter,
|
@@ -90,79 +131,47 @@ Don't have or want a `Rakefile`? You _could_ also do something like the followin
|
|
90
131
|
htmlproof ./_site
|
91
132
|
```
|
92
133
|
|
93
|
-
### Real-life examples
|
94
|
-
|
95
|
-
Project | Repository
|
96
|
-
:--- | :---
|
97
|
-
[Raspberry Pi documentation](http://www.raspberrypi.org/documentation/) | [raspberrypi/documentation]( https://github.com/raspberrypi/documentation)
|
98
|
-
[Open Whisper Systems website](https://whispersystems.org/) | [WhisperSystems/whispersystems.org](https://github.com/WhisperSystems/whispersystems.org)
|
99
|
-
[Jekyll website](http://jekyllrb.com/) | [jekyll/jekyll](https://github.com/jekyll/jekyll)
|
100
|
-
|
101
|
-
## What's Tested?
|
102
|
-
|
103
|
-
### Images
|
104
|
-
|
105
|
-
`img` elements:
|
106
|
-
|
107
|
-
* Whether all your images have alt tags
|
108
|
-
* Whether your internal image references are not broken
|
109
|
-
* Whether external images are showing
|
110
|
-
|
111
|
-
### Links
|
112
|
-
|
113
|
-
`a`, `link` elements:
|
114
|
-
|
115
|
-
* Whether your internal links are not broken; this includes hash references (`#linkToMe`)
|
116
|
-
* Whether external links are working
|
117
|
-
|
118
|
-
### Scripts
|
119
|
-
|
120
|
-
`script` elements:
|
121
|
-
|
122
|
-
* Whether your internal script references are not broken
|
123
|
-
* Whether external scripts are loading
|
124
|
-
|
125
|
-
### HTML
|
126
|
-
|
127
|
-
Nokogiri looks at the markup and [provides errors](http://www.nokogiri.org/tutorials/ensuring_well_formed_markup.html) when parsing your document.
|
128
|
-
This is an optional feature, set the `validate_html` option to enable validation errors from Nokogiri.
|
129
|
-
|
130
134
|
## Configuration
|
131
135
|
|
132
136
|
The `HTML::Proofer` constructor takes an optional hash of additional options:
|
133
137
|
|
134
138
|
| Option | Description | Default |
|
135
139
|
| :----- | :---------- | :------ |
|
140
|
+
| `alt_ignore` | An array of Strings or RegExps containing `img`s whose missing `alt` tags are safe to ignore. | `[]` |
|
141
|
+
| `check_external_hash` | Checks whether external hashes exist (even if the website exists). This slows the checker down. | `false` |
|
142
|
+
|`checks_to_ignore`| An array of Strings indicating which checks you'd like to not perform. | `[]`
|
143
|
+
| `directory_index_file` | Sets the file to look for when a link refers to a directory. | `index.html` |
|
136
144
|
| `disable_external` | If `true`, does not run the external link checker, which can take a lot of time. | `false` |
|
145
|
+
| `error_sort` | Defines the sort order for error output. Can be `:path`, `:desc`, or `:status`. | `:path`
|
137
146
|
| `ext` | The extension of your HTML files including the dot. | `.html`
|
138
|
-
| `favicon` | Enables the favicon checker. | `false` |
|
139
|
-
| `followlocation` | Follows external redirections. Amends missing trailing slashes to internal directories. | `true` |
|
140
|
-
| `directory_index_file` | Sets the file to look for when a link refers to a directory. | `index.html` |
|
141
|
-
| `href_ignore` | An array of Strings or RegExps containing `href`s that are safe to ignore. Note that non-HTTP(S) URIs are always ignored. | `[]` |
|
142
|
-
| `alt_ignore` | An array of Strings or RegExps containing `img`s whose missing `alt` tags are safe to ignore. | `[]` |
|
143
147
|
| `file_ignore` | An array of Strings or RegExps containing file paths that are safe to ignore. | `[]` |
|
148
|
+
| `href_ignore` | An array of Strings or RegExps containing `href`s that are safe to ignore. Note that non-HTTP(S) URIs are always ignored. | `[]` |
|
144
149
|
| `href_swap` | A hash containing key-value pairs of `RegExp => String`. It transforms links that match `RegExp` into `String` via `gsub`. | `{}` |
|
145
|
-
| `verbose` | If `true`, outputs extra information as the checking happens. Useful for debugging. | `false` |
|
146
150
|
| `only_4xx` | Only reports errors for links that fall within the 4xx status code range. | `false` |
|
147
|
-
| `
|
148
|
-
| `
|
151
|
+
| `check_favicon` | Enables the favicon checker. | `false` |
|
152
|
+
| `check_html` | Enables HTML validation errors from Nokogiri | `false` |
|
153
|
+
| `verbose` | If `true`, outputs extra information as the checking happens. Useful for debugging. | `false` |
|
149
154
|
|
150
|
-
### Configuring Typhoeus
|
155
|
+
### Configuring Typhoeus and Hydra
|
151
156
|
|
152
|
-
You can
|
157
|
+
[Typhoeus](https://github.com/typhoeus/typhoeus) is used to make fast, parallel requests to external URLs. You can pass in any of Typhoeus' options for the external link checks with the options namespace of `:typhoeus`. For example:
|
153
158
|
|
154
159
|
``` ruby
|
155
|
-
HTML::Proofer.new("out/", {:ext => ".htm", :verbose => true, :ssl_verifyhost => 2 })
|
160
|
+
HTML::Proofer.new("out/", {:ext => ".htm", :typhoeus => { :verbose => true, :ssl_verifyhost => 2 } })
|
156
161
|
```
|
157
162
|
|
158
163
|
This sets `HTML::Proofer`'s extensions to use _.htm_, and gives Typhoeus a configuration for it to be verbose, and use specific SSL settings. Check [the Typhoeus documentation](https://github.com/typhoeus/typhoeus#other-curl-options) for more information on what options it can receive.
|
159
164
|
|
165
|
+
You can similarly pass in a `:hydra` option with a hash configuration for Hydra.
|
166
|
+
|
167
|
+
The default value is `typhoeus => { :followlocation => true }`.
|
168
|
+
|
160
169
|
### Configuring Parallel
|
161
170
|
|
162
|
-
[Parallel](https://github.com/grosser/parallel) is being used to speed
|
171
|
+
[Parallel](https://github.com/grosser/parallel) is being used to speed internal file checks. You can pass in any of its options with the options "namespace" `:parallel`. For example:
|
163
172
|
|
164
173
|
``` ruby
|
165
|
-
HTML::Proofer.new("out/", {:ext => ".htm", :
|
174
|
+
HTML::Proofer.new("out/", {:ext => ".htm", :parallel => { :in_processes => 3} })
|
166
175
|
```
|
167
176
|
|
168
177
|
`:in_processes => 3` will be passed into Parallel as a configuration option.
|
@@ -185,14 +194,23 @@ bin/htmlproof www.google.com,www.github.com --as-links
|
|
185
194
|
|
186
195
|
Add the `data-proofer-ignore` attribute to any tag to ignore it from the checks.
|
187
196
|
|
197
|
+
|
198
|
+
``` html
|
199
|
+
<a href="http://notareallink" data-proofer-ignore>Not checked.</a>
|
200
|
+
```
|
201
|
+
|
188
202
|
## Custom tests
|
189
203
|
|
190
|
-
Want to write your own test? Sure! Just create two classes--one that inherits from `HTML::Proofer::
|
204
|
+
Want to write your own test? Sure! Just create two classes--one that inherits from `HTML::Proofer::CheckRunner`, and another that inherits from `HTML::Proofer::Checkable`.
|
205
|
+
|
206
|
+
The `CheckRunner` subclass must define one method called `run`. This is called on your content, and is responsible for performing the validation on whatever elements you like. When you catch a broken issue, call `add_issue(message)` to explain the error.
|
207
|
+
|
208
|
+
The `Checkable` subclass defines various helper methods you can use as part of your test. Usually, you'll want to instantiate it within `run`. You have access to all of your element's attributes.
|
191
209
|
|
192
210
|
Here's an example custom test that protects against `mailto` links that point to `octocat@github.com`:
|
193
211
|
|
194
212
|
``` ruby
|
195
|
-
class
|
213
|
+
class OctocatLinkCheck < ::HTML::Proofer::Checkable
|
196
214
|
|
197
215
|
def mailto?
|
198
216
|
return false if @data_ignore_proofer || @href.nil? || @href.empty?
|
@@ -205,14 +223,14 @@ class OctocatLink < ::HTML::Proofer::Checkable
|
|
205
223
|
|
206
224
|
end
|
207
225
|
|
208
|
-
class MailToOctocat < ::HTML::Proofer::
|
226
|
+
class MailToOctocat < ::HTML::Proofer::CheckRunner
|
209
227
|
|
210
228
|
def run
|
211
229
|
@html.css('a').each do |l|
|
212
|
-
link =
|
230
|
+
link = OctocatLinkCheck.new l, "octocat_link", self
|
213
231
|
|
214
232
|
if link.mailto? && link.octocat?
|
215
|
-
return
|
233
|
+
return add_issue("Don't email the Octocat directly!")
|
216
234
|
end
|
217
235
|
end
|
218
236
|
end
|
data/Rakefile
CHANGED
@@ -12,12 +12,10 @@ task :proof_readme do
|
|
12
12
|
require 'redcarpet'
|
13
13
|
|
14
14
|
redcarpet = Redcarpet::Markdown.new Redcarpet::Render::HTML.new({}), {}
|
15
|
-
html = redcarpet.render File.
|
15
|
+
html = redcarpet.render File.read('README.md')
|
16
16
|
|
17
|
-
mkdir_p
|
18
|
-
File.
|
19
|
-
file.puts html
|
20
|
-
end
|
17
|
+
mkdir_p 'out'
|
18
|
+
File.write('out/README.html', html)
|
21
19
|
|
22
|
-
HTML::Proofer.new(
|
20
|
+
HTML::Proofer.new('./out').run
|
23
21
|
end
|
data/bin/htmlproof
CHANGED
@@ -1,59 +1,69 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
STDOUT.sync = true
|
3
3
|
|
4
|
-
|
4
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w( .. lib ))
|
5
5
|
|
6
6
|
require 'html/proofer'
|
7
7
|
require 'mercenary'
|
8
|
-
require
|
8
|
+
require 'rubygems'
|
9
|
+
|
10
|
+
def to_regex?(item)
|
11
|
+
if item.start_with? '/' and item.end_with? '/'
|
12
|
+
Regexp.new item[1...-1]
|
13
|
+
else
|
14
|
+
item
|
15
|
+
end
|
16
|
+
end
|
9
17
|
|
10
18
|
Mercenary.program(:htmlproof) do |p|
|
11
|
-
p.version Gem::Specification
|
12
|
-
p.description
|
19
|
+
p.version Gem::Specification.load(File.join(File.dirname(__FILE__), '..', 'html-proofer.gemspec')).version
|
20
|
+
p.description %(Test your rendered HTML files to make sure they're accurate.)
|
13
21
|
p.syntax 'htmlproof PATH [options]'
|
14
22
|
|
15
|
-
p.description
|
16
|
-
|
17
|
-
p.option '
|
18
|
-
p.option '
|
19
|
-
p.option '
|
20
|
-
p.option '
|
21
|
-
p.option '
|
22
|
-
p.option '
|
23
|
-
p.option '
|
24
|
-
p.option '
|
25
|
-
p.option '
|
23
|
+
p.description 'Runs the HTML-Proofer suite on the files in PATH. For more details, see the README.'
|
24
|
+
|
25
|
+
p.option 'as_links', '--as-links', 'Assumes that `PATH` is a comma-separated array of links to check.'
|
26
|
+
p.option 'alt_ignore', '--alt-ignore image1,[image2,...]', Array, 'Comma-separated list of Strings or RegExps containing `img`s whose missing `alt` tags are safe to ignore'
|
27
|
+
p.option 'checks_to_ignore', '--checks-to-ignore check1,[check2,...]', Array, ' An array of Strings indicating which checks you\'d like to not perform.'
|
28
|
+
p.option 'check_external_hash', '--check-external-hash', 'Checks whether external hashes exist (even if the website exists). This slows the checker down (default: `false`).'
|
29
|
+
p.option 'directory_index_file', '--directory-index-file', String, 'Sets the file to look for when a link refers to a directory. (default: `index.html`)'
|
30
|
+
p.option 'disable_external', '--disable-external', 'Disables the external link checker (default: `false`)'
|
31
|
+
p.option 'error_sort', '--error-sort SORT', 'Defines the sort order for error output. Can be `path`, `desc`, or `status` (default: `path`).'
|
32
|
+
p.option 'ext', '--ext EXT', String, 'The extension of your HTML files (default: `.html`)'
|
33
|
+
p.option 'file_ignore', '--file-ignore file1,[file2,...]', Array, 'Comma-separated list of Strings or RegExps containing file paths that are safe to ignore'
|
34
|
+
p.option 'href_ignore', '--href-ignore link1,[link2,...]', Array, 'Comma-separated list of Strings or RegExps containing `href`s that are safe to ignore.'
|
35
|
+
p.option 'href_swap', '--href-swap re:string,[re:string,...]', Array, 'Comma-separated list of key-value pairs of `RegExp:String`. Transforms links matching `RegExp` into `String`'
|
36
|
+
p.option 'only_4xx', '--only-4xx', 'Only reports errors for links that fall within the 4x status code range.'
|
37
|
+
p.option 'check_favicon', '--check-favicon', 'Enables the favicon checker (default: `false`).'
|
38
|
+
p.option 'check_html', '--check-html', 'Enables HTML validation errors from Nokogiri (default: `false`).'
|
26
39
|
p.option 'verbose', '--verbose', 'Enables more verbose logging.'
|
27
|
-
p.option 'directory_index_file', '--directory_index_file', 'Sets the file to look for when a link refers to a directory.'
|
28
|
-
p.option 'validate_html', '--validate_html', 'Enables HTML validation errors from Nokogiri (default: `false`).'
|
29
|
-
p.option 'check_external_hash', '--check_external_hash', 'Checks whether external hashes exist (even if the website exists). This slows the checker down (default: `false`).'
|
30
40
|
|
31
41
|
p.action do |args, opts|
|
32
|
-
args = [
|
42
|
+
args = ['.'] if args.empty?
|
33
43
|
path = args.first
|
34
44
|
|
35
45
|
options = {}
|
36
|
-
|
37
|
-
|
46
|
+
|
47
|
+
# prepare every to go to proofer
|
48
|
+
p.options.select { |o| !opts[o.config_key].nil? }.each do |option|
|
49
|
+
if option.return_type.to_s == 'Array' # TODO: is_a? doesn't work here?
|
50
|
+
opts[option.config_key] = opts[option.config_key].map { |i| to_regex?(i) }
|
51
|
+
end
|
52
|
+
options[option.config_key.to_sym] = opts[option.config_key]
|
53
|
+
end
|
54
|
+
|
55
|
+
# some minor manipulation of a special option
|
56
|
+
unless opts['href_swap'].nil?
|
38
57
|
options[:href_swap] = {}
|
39
|
-
opts[
|
40
|
-
pair = s.split(
|
41
|
-
options[:href_swap][
|
58
|
+
opts['href_swap'].each do |s|
|
59
|
+
pair = s.split(':')
|
60
|
+
options[:href_swap][Regexp.new(pair[0])] = pair[1]
|
42
61
|
end
|
43
62
|
end
|
44
63
|
|
45
|
-
options[:
|
46
|
-
|
47
|
-
|
48
|
-
options[:disable_external] = opts["disable_external"] unless opts["disable_external"].nil?
|
49
|
-
options[:only_4xx] = opts["only_4xx"] unless opts["only_4xx"].nil?
|
50
|
-
options[:favicon] = opts["favicon"] unless opts["favicon"].nil?
|
51
|
-
options[:verbose] = opts["verbose"] unless opts["verbose"].nil?
|
52
|
-
options[:directory_index_file] = opts["directory_index_file"] unless opts["directory_index_file"].nil?
|
53
|
-
options[:validate_html] = opts["validate_html"] unless opts["validate_html"].nil?
|
54
|
-
options[:check_external_hash] = opts["check_external_hash"] unless opts["check_external_hash"].nil?
|
55
|
-
|
56
|
-
path = path.delete(' ').split(",") if opts["as-links"]
|
64
|
+
options[:error_sort] = opts['error-sort'].to_sym unless opts['error-sort'].nil?
|
65
|
+
|
66
|
+
path = path.delete(' ').split(',') if opts['as_links']
|
57
67
|
|
58
68
|
HTML::Proofer.new(path, options).run
|
59
69
|
end
|
data/html-proofer.gemspec
CHANGED
@@ -1,31 +1,31 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
3
3
|
require 'html/proofer/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
|
-
gem.name =
|
6
|
+
gem.name = 'html-proofer'
|
7
7
|
gem.version = HTML::Proofer::VERSION
|
8
|
-
gem.authors = [
|
9
|
-
gem.email = [
|
10
|
-
gem.description = %
|
11
|
-
gem.summary = %
|
12
|
-
gem.homepage =
|
13
|
-
gem.license =
|
14
|
-
gem.executables = [
|
15
|
-
gem.files = `git ls-files`.split(
|
8
|
+
gem.authors = ['Garen Torikian']
|
9
|
+
gem.email = ['gjtorikian@gmail.com']
|
10
|
+
gem.description = %(Test your rendered HTML files to make sure they're accurate.)
|
11
|
+
gem.summary = %(A set of tests to validate your HTML output. These tests check if your image references are legitimate, if they have alt tags, if your internal links are working, and so on. It's intended to be an all-in-one checker for your documentation output.)
|
12
|
+
gem.homepage = 'https://github.com/gjtorikian/html-proofer'
|
13
|
+
gem.license = 'MIT'
|
14
|
+
gem.executables = ['htmlproof']
|
15
|
+
gem.files = `git ls-files -z`.split("\x0")
|
16
16
|
gem.test_files = gem.files.grep(%r{^(spec)/})
|
17
|
-
gem.require_paths = [
|
17
|
+
gem.require_paths = ['lib']
|
18
18
|
|
19
|
-
gem.add_dependency
|
20
|
-
gem.add_dependency
|
21
|
-
gem.add_dependency
|
22
|
-
gem.add_dependency
|
23
|
-
gem.add_dependency
|
24
|
-
gem.add_dependency
|
25
|
-
gem.add_dependency
|
19
|
+
gem.add_dependency 'mercenary', '~> 0.3.2'
|
20
|
+
gem.add_dependency 'nokogiri', '~> 1.5'
|
21
|
+
gem.add_dependency 'colored', '~> 1.2'
|
22
|
+
gem.add_dependency 'typhoeus', '~> 0.6.7'
|
23
|
+
gem.add_dependency 'yell', '~> 2.0'
|
24
|
+
gem.add_dependency 'parallel', '~> 1.3'
|
25
|
+
gem.add_dependency 'addressable', '~> 2.3'
|
26
26
|
|
27
|
-
gem.add_development_dependency
|
28
|
-
gem.add_development_dependency
|
29
|
-
gem.add_development_dependency
|
30
|
-
gem.add_development_dependency
|
27
|
+
gem.add_development_dependency 'redcarpet'
|
28
|
+
gem.add_development_dependency 'rspec', '~> 3.1'
|
29
|
+
gem.add_development_dependency 'rake'
|
30
|
+
gem.add_development_dependency 'awesome_print'
|
31
31
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class HTML::Proofer::CheckRunner
|
3
|
+
|
4
|
+
class Issue
|
5
|
+
attr_reader :path, :desc, :status, :line_number
|
6
|
+
|
7
|
+
def initialize(path, desc, line_number = nil, status = -1)
|
8
|
+
@line_number = line_number.nil? ? '' : " (line #{line_number})"
|
9
|
+
@path = path
|
10
|
+
@desc = desc
|
11
|
+
@status = status
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"#{@path}: #{@desc}#{@line_number}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class SortedIssues
|
20
|
+
attr_reader :issues
|
21
|
+
|
22
|
+
def initialize(issues, error_sort, logger)
|
23
|
+
@issues = issues
|
24
|
+
@error_sort = error_sort
|
25
|
+
@logger = logger
|
26
|
+
end
|
27
|
+
|
28
|
+
def sort_and_report
|
29
|
+
case @error_sort
|
30
|
+
when :path
|
31
|
+
sorted_issues = sort(:path, :desc)
|
32
|
+
report(sorted_issues, :path, :desc)
|
33
|
+
when :desc
|
34
|
+
sorted_issues = sort(:desc, :path)
|
35
|
+
report(sorted_issues, :desc, :path)
|
36
|
+
when :status
|
37
|
+
sorted_issues = sort(:status, :path)
|
38
|
+
report(sorted_issues, :status, :path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def sort(first_sort, second_sort)
|
43
|
+
issues.sort_by { |t| [t.send(first_sort), t.send(second_sort)] }
|
44
|
+
end
|
45
|
+
|
46
|
+
def report(sorted_issues, first_report, second_report)
|
47
|
+
matcher = nil
|
48
|
+
|
49
|
+
sorted_issues.each do |issue|
|
50
|
+
if matcher != issue.send(first_report)
|
51
|
+
@logger.log :error, :red, "- #{issue.send(first_report)}"
|
52
|
+
matcher = issue.send(first_report)
|
53
|
+
end
|
54
|
+
if first_report == :status
|
55
|
+
@logger.log :error, :red, " * #{issue}"
|
56
|
+
else
|
57
|
+
@logger.log :error, :red, " * #{issue.send(second_report)}#{issue.line_number}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'net/http'
|
3
|
-
require 'net/https'
|
4
|
-
require 'timeout'
|
5
|
-
require 'uri'
|
6
|
-
require 'typhoeus'
|
7
2
|
|
8
|
-
class HTML::Proofer
|
3
|
+
class HTML::Proofer
|
9
4
|
|
10
|
-
|
5
|
+
# Mostly handles issue management and collecting of external URLs.
|
6
|
+
class CheckRunner
|
11
7
|
|
12
|
-
attr_reader :issues, :src, :path, :options, :external_urls, :
|
8
|
+
attr_reader :issues, :src, :path, :options, :external_urls, :href_ignores, :alt_ignores
|
13
9
|
|
14
10
|
def initialize(src, path, html, opts={})
|
15
11
|
@src = src
|
@@ -17,21 +13,17 @@ class HTML::Proofer::Checks
|
|
17
13
|
@html = remove_ignored(html)
|
18
14
|
@options = opts
|
19
15
|
@issues = []
|
20
|
-
@
|
21
|
-
@
|
16
|
+
@href_ignores = @options[:href_ignore]
|
17
|
+
@alt_ignores = @options[:alt_ignore]
|
22
18
|
@external_urls = {}
|
23
19
|
end
|
24
20
|
|
25
21
|
def run
|
26
|
-
|
22
|
+
fail NotImplementedError, 'HTML::Proofer::CheckRunner subclasses must implement #run'
|
27
23
|
end
|
28
24
|
|
29
|
-
def add_issue(desc, status = -1)
|
30
|
-
@issues << Issue.new(@path, desc, status)
|
31
|
-
end
|
32
|
-
|
33
|
-
def output_filenames
|
34
|
-
Dir[@site.config[:output_dir] + '/**/*'].select{ |f| File.file?(f) }
|
25
|
+
def add_issue(desc, line_number = nil, status = -1)
|
26
|
+
@issues << Issue.new(@path, desc, line_number, status)
|
35
27
|
end
|
36
28
|
|
37
29
|
def add_to_external_urls(href)
|
@@ -42,7 +34,7 @@ class HTML::Proofer::Checks
|
|
42
34
|
end
|
43
35
|
end
|
44
36
|
|
45
|
-
def self.
|
37
|
+
def self.checks
|
46
38
|
classes = []
|
47
39
|
|
48
40
|
ObjectSpace.each_object(Class) do |c|
|
@@ -56,7 +48,7 @@ class HTML::Proofer::Checks
|
|
56
48
|
private
|
57
49
|
|
58
50
|
def remove_ignored(html)
|
59
|
-
html.css(
|
51
|
+
html.css('code, pre').each(&:unlink)
|
60
52
|
html
|
61
53
|
end
|
62
54
|
|