middleman-spellcheck 0.9.0 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fea98d00ab58220965c1e2b8118063d0fbf50b13
4
- data.tar.gz: e35c46312d5c3a4afafea88635142e982d920368
3
+ metadata.gz: d50552923d8b8b4e3f9f0bcdc9a6f17f5229ecf9
4
+ data.tar.gz: fdd05ae0af2f6c4bcd0ca9674c28e226456c510c
5
5
  SHA512:
6
- metadata.gz: ae6225286fc01dbcfd6abe17f91b3b3b99f0250a1ed3ea2bbc8d2eb9b499af404826262b57e14146931318904b21dc65b51a3836cad6c7f3405b12e68c1cbfe6
7
- data.tar.gz: 694260deefae946b9b7c8d76aeb3eb17ae7ffd4edbda7fb81c361113daac96dcacd32ac66917dd291b41cd30b4e461a19d682351f143bf60b49bad4d790a3c55
6
+ metadata.gz: 14cb5229c5da423142e23b3efe3cd0d5d7f3e2e5b0c099211e20ad3e677a3031d778cb8cf3e83a0c225c32722ec6b2f3d758c6c9911e5c70fe7b9d4480f065d1
7
+ data.tar.gz: e04e1cf5302675eaac3d9d06161fb0b0a2307ff24a3c10d93a8e7b95f655a954f01f021e1009220e4fdd9e7a9f7dc81748a89ecf8b9fdc2e59f2378cc5d9ab1e
data/README.md CHANGED
@@ -25,31 +25,50 @@ middleman spellcheck source/blog/
25
25
 
26
26
  ## Usage
27
27
 
28
- You can spellcheck only some resources using a regex with the URL:
28
+ There are several ways to select what content will be checked.
29
29
 
30
- ```ruby
31
- activate :spellcheck, page: "documentation/*" # you can use regexes, too, e.g. /post_[1-9]/
32
- ```
30
+ 1. To spellcheck only some resources using a regex with the URL:
33
31
 
34
- You can limit which tags the spell checker will only run through:
32
+ ```ruby
33
+ activate :spellcheck, page: "documentation/*" # you can use regexes, too, e.g. /post_[1-9]/
34
+ ```
35
35
 
36
- ```ruby
37
- activate :spellcheck, tags: :p # pass an array of tags if you have more!
38
- ```
36
+ 2. To limit which tags the spell checker will only run through:
39
37
 
40
- If there are some words that you would like to be allowed
38
+ ```ruby
39
+ activate :spellcheck, tags: :p # pass an array of tags if you have more!
40
+ ```
41
41
 
42
- ```ruby
43
- activate :spellcheck, allow: ["Gooby", "pls"]
44
- ```
42
+ 3. To ignore sections by using css selectors
43
+ For example, to ignore all sections with a class of `CodeRay`:
44
+
45
+ ```ruby
46
+ activate :spellcheck, ignore_selector: '.CodeRay'
47
+ ```
48
+
49
+ Or to ignore all tables in a document:
50
+
51
+ ```ruby
52
+ activate :spellcheck, ignore_selector: 'table'
53
+ ```
45
54
 
46
- Middleman-spellcheck automatically ignores `.css`, `.js`, & `.coffee` file
55
+ Or to ignore all `<p class="technical-jargon">`:
56
+ ```ruby
57
+ activate :spellcheck, ignore_selector: 'p.technical-jargon'
58
+ ```
59
+
60
+ To ignore multiple selectors, seperate them with a comma
61
+ ```ruby
62
+ activate :spellcheck, ignore_selector: 'p.technical-jargon, .CodeRay'
63
+ ```
64
+
65
+ 4. Middleman-spellcheck automatically ignores `.css`, `.js`, & `.coffee` file
47
66
  extensions. If there are some additional file type extensions that you would
48
67
  like to skip:
49
68
 
50
- ```ruby
51
- activate :spellcheck, ignored_exts: [".xml", ".png"]
52
- ```
69
+ ```ruby
70
+ activate :spellcheck, ignored_exts: [".xml", ".png"]
71
+ ```
53
72
 
54
73
  To select a dictionary used by a spellchecker, use lang: option. For
55
74
  example, to use Polish dictionary, use:
@@ -60,12 +79,15 @@ activate :spellcheck, lang: "pl"
60
79
 
61
80
  If you define the ``lang`` metadata in your pages / articles, then spellcheck will use those language.
62
81
 
63
- Middleman-spellcheck can issue many warnings if you run it over a new
64
- content. If you want to give yourself a chance to fix mistakes gradually and
65
- not fail each time you build, use :dontfail flag:
82
+ ## Options
83
+
84
+
85
+ For warnings only (allow build to pass), use `dontfail` option.
86
+ This is helpful when you want to give yourself a chance to fix mistakes or false hits gradually and
87
+ not fail each time you build.
66
88
 
67
89
  ```ruby
68
- activate :spellcheck, lang: "en", dontfail: 1
90
+ activate :spellcheck, dontfail: 1
69
91
  ```
70
92
 
71
93
  You can also disable the automatic spellcheck after build (and only run manual checks from the command line):
@@ -89,9 +111,84 @@ who encountered issues, useful might be debug: option, which will turn on
89
111
  extensive amount of debugging.
90
112
 
91
113
  ```ruby
92
- activate :spellcheck, debug: 1
114
+ activate :spellcheck, lang: "en", debug: 1
93
115
  ```
94
116
 
117
+ If there are some words that you would like to be allowed you can pass them to the allow option as an array. **Depricated - Please see the "Fixing spelling mistakes" section for now prefered way to include allowed words
118
+
119
+ ```ruby
120
+ activate :spellcheck, allow: ["Gooby", "pls"]
121
+ ```
122
+
123
+ You can also pass a regex to the `ignore_regex` option. Any match will be ignored.
124
+ For example to remove words in quotes
125
+ ```ruby
126
+ activate :spellcheck, lang: "en", ignore_regex: /\s('|")\w*('|")(\s|\.|,)/
127
+ ```
128
+
129
+ ## Fixing spelling mistakes & false positives
130
+
131
+ The `middleman-spellchecker` extension is likely to generate large number
132
+ of false-positives, e.g.: words which the spellchecker will consider
133
+ incorrect (not present in a dictionary), which yet may have a valid meaning
134
+ in the article's context. Common problems are acronyms, technical terms and
135
+ names. To solve this, `middleman-spellcheck` offers two solutions:
136
+
137
+ 1. The `spellcheck_allow_file` file, which points to the path with a file
138
+ containing words considered correct. Author of the website may decide which
139
+ words are allowed to be used site-wide. Example: if you write a lot about
140
+ IBM products, this file would have names such as "IBM", "AIX" or "DB/2".
141
+ Add the words one word per line without quotes.
142
+
143
+ To set the global file, use the following clause in your `config.rb`:
144
+
145
+ ```set :spellcheck_allow_file, "./data/words_allowed.txt"```
146
+
147
+ 2. The `spellcheck-allow` keyword in a frontmatter, which will work in the
148
+ context of this particular article, but not other articles. Example: your
149
+ blog is about IBM, but 1 article is about AirBnB. You'd put `AirBnB` into
150
+ your front-matter.
151
+
152
+
153
+ To use 2nd solution, add the following to your frontmatter:
154
+
155
+ ```
156
+ title: "Blog about IBM"
157
+ ...
158
+ spellcheck-allow:
159
+ - "AirBnB"```
160
+
161
+ Another example
162
+
163
+ ```
164
+ title: "Some time ago"
165
+ ...
166
+ spellcheck-allowed:
167
+ - GitHub
168
+ - Linux
169
+ ```
170
+
171
+ The `middleman-spellcheck` also comes with a simple CLI for fixing many
172
+ problems in your articles. To invoke:
173
+
174
+ ```middleman spellcheck source/blog/2015-11-01-nginx-on-travis-ci.md --fix```
175
+
176
+ This will pull up simple CLI menu and for each misspelled word, you'll have
177
+ a following choice
178
+
179
+ | Key to press | Effect |
180
+ |--------------|--------|
181
+ | g | Add the word to the `spellcheck_allow_file` |
182
+ | f | Add the word to this article's front-matter |
183
+ | i | Ignore the word for now and deal with it later |
184
+
185
+
186
+ After the run is finished, `middleman-spellchecker` will write a fixed file
187
+ to `source/blog/2015-11-01-nginx-on-travis-ci.md.fixed`. This is a safe
188
+ choice for not creating damage. If you don't want to fiddle with it, the
189
+ `--inplace` switch will make changes dynamically, and the input file will
190
+ get overwritten.
191
+
95
192
  ## Contributing
96
193
 
97
194
  1. Fork it
@@ -1,10 +1,75 @@
1
1
  module Middleman
2
2
  module Cli
3
- # This class provides an "spellchecl" command for the middleman CLI.
3
+ # This class provides a "spellcheck" command for the middleman CLI.
4
4
  class Spellcheck < Thor
5
5
  include Thor::Actions
6
+
7
+ check_unknown_options!
8
+
9
+ namespace :spellcheck
10
+
11
+ no_commands {
12
+ def misspell_ask(misspell, allow_file)
13
+ if not options[:fix]
14
+ return false
15
+ end
16
+
17
+ print "-" * 70, "\n"
18
+ print "'#{misspell[:word]}' is misspelled. What to do?:\n"
19
+ print "g\tadd allowed word to '#{allow_file}'\n" if allow_file
20
+ print "f\tadd allowed word to frontmatter\n"
21
+ print "i\tignore word (deal with it later)\n"
22
+
23
+ print "Select option and press ENTER:\n"
24
+ STDIN.gets()[0]
25
+ end
26
+
27
+ def misspell_fixes_global(resource, words_allow_global, allow_file)
28
+ open(allow_file, 'a') { |f|
29
+ words_allow_global.each do |w|
30
+ f.puts "#{w}\t#\t#{resource.source_file}\n"
31
+ end
32
+ }
33
+ end
34
+
35
+ def misspell_fixes_frontmatter(resource, words_allow_frontmatter)
36
+ data = File.read(resource.source_file)
37
+ if options[:inplace] then fn_ext = "" else ".fixed" end
38
+ fn_fixed = "#{resource.source_file}#{fn_ext}"
39
+ fixed = File.open(fn_fixed, "w")
40
+ sep_tag_cnt = 0
41
+ had_spellcheck_tag = false
42
+ data.each_line do |line|
43
+ if line =~ /^\-\-\-$/ then
44
+ sep_tag_cnt += 1
45
+ end
46
+ if line =~ /spellcheck-allow:/ then
47
+ had_spellcheck_tag = true
48
+ end
49
+
50
+ if sep_tag_cnt == 2 then
51
+ if had_spellcheck_tag == false then
52
+ fixed.puts "spellcheck-allow:\n"
53
+ end
54
+ words_allow_frontmatter.each do |w|
55
+ fixed.puts "- \"#{w}\"\n"
56
+ end
57
+ fixed.puts "---\n"
58
+ sep_tag_cnt = nil
59
+ else
60
+ fixed.puts line
61
+ end
62
+ end
63
+ fixed.close()
64
+ print "Fixed spellchecked file written to #{fn_fixed}\n"
65
+ end
66
+ }
67
+
6
68
  namespace :spellcheck
7
69
  desc "spellcheck FILE", "Run spellcheck on given file or path"
70
+ method_option "fix", :type => :boolean, :aliases => "-f", :desc => "Fix spelling error interactively"
71
+ method_option "inplace", :type => :boolean, :aliases => "-i", :desc => "Modify files in place (dangerous)"
72
+
8
73
  def spellcheck(*paths)
9
74
  app = ::Middleman::Application.server.inst
10
75
 
@@ -14,18 +79,40 @@ module Middleman
14
79
  }
15
80
  }
16
81
  if resources.empty?
17
- $stderr.puts "File / Directory #{path} not exist"
82
+ $stderr.puts "File / Directory #{paths} not exist"
18
83
  exit 1
19
84
  end
20
85
  ext = app.extensions[:spellcheck]
86
+
87
+ allow_file = app.config.defines_setting?(:spellcheck_allow_file) ?
88
+ app.config[:spellcheck_allow_file] : nil
89
+ if options[:fix] then
90
+ print "Spellchecker fix mode on! Will attempt to white-list some words\n"
91
+ end
21
92
  resources.each do |resource|
22
- say_status :spellcheck, "Running spell checker for #{resource.url}", :blue
93
+ say_status :spellcheck, "Running spell checker for #{resource.source_file}", :blue
23
94
  current_misspelled = ext.spellcheck_resource(resource)
95
+
96
+ words_allow_frontmatter = []
97
+ words_allow_global = []
24
98
  current_misspelled.each do |misspell|
25
- say_status :misspell, ext.error_message(misspell), :red
99
+ fix = misspell_ask(misspell, allow_file)
100
+ was_fixed = true
101
+ if fix == 'g' then words_allow_global << misspell[:word]
102
+ elsif fix == 'f' then words_allow_frontmatter << misspell[:word]
103
+ else was_fixed = false end
104
+
105
+ if was_fixed
106
+ say_status :spellcheck, "Fixed word #{misspell[:word]}"
107
+ else
108
+ say_status :misspell, ext.error_message(misspell), :red
109
+ end
26
110
  end
111
+ misspell_fixes_global(resource, words_allow_global, allow_file) unless words_allow_global.empty?
112
+ misspell_fixes_frontmatter(resource, words_allow_frontmatter) unless words_allow_frontmatter.empty?
27
113
  end
28
114
  end
115
+
29
116
  end
30
117
  end
31
118
  end
@@ -6,14 +6,17 @@ module Middleman
6
6
  module Spellcheck
7
7
  class SpellcheckExtension < Extension
8
8
  REJECTED_EXTS = %w(.css .js .coffee)
9
+ ALLOWED_WORDS = []
9
10
  option :page, "/*", "Run only pages that match the regex through the spellchecker"
10
11
  option :tags, [], "Run spellcheck only on some tags from the output"
11
12
  option :allow, [], "Allow specific words to be misspelled"
12
13
  option :ignored_exts, [], "Ignore specific extensions (ex: '.xml')"
14
+ option :ignore_regex, false, "Ignore regex matches"
15
+ option :ignore_selector, false, "Ignore nodes with a css selector"
13
16
  option :lang, "en", "Language for spellchecking"
14
17
  option :cmdargs, "", "Pass alternative command line arguments"
15
18
  option :debug, 0, "Enable debugging (for developers only)"
16
- option :dontfail, 0, "Don't fail when misspelled words are found"
19
+ option :dontfail, false, "Don't fail because misspelled words are found"
17
20
  option :run_after_build, true, "Run Spellcheck after build"
18
21
 
19
22
  def after_build(builder)
@@ -32,13 +35,14 @@ module Middleman
32
35
  total_misspelled += current_misspelled
33
36
  end
34
37
 
35
- unless total_misspelled.empty?
36
- estr = "Build failed. There are spelling errors."
38
+ builder.say_status :spellcheck, "Spellchecks done. #{total_misspelled.length} misspelling(s) found.", :blue
39
+
40
+ unless total_misspelled.empty?
37
41
  if options.dontfail
38
- print "== :dontfail set! Will issue warning only, but not fail.\n"
39
- print estr, "\n"
42
+ builder.say_status :spellcheck, "dontfail is set! Builder will ignore misspellings.", :yellow
40
43
  else
41
- raise Thor::Error, estr
44
+ desc = "Build failed. There are spelling errors."
45
+ raise Thor::Error, desc
42
46
  end
43
47
  end
44
48
  end
@@ -48,6 +52,10 @@ module Middleman
48
52
  doc = Nokogiri::HTML.fragment(rendered_resource)
49
53
  doc.search('code,style,script').each(&:remove)
50
54
 
55
+ if options.ignore_selector
56
+ doc.css(options.ignore_selector).each(&:remove)
57
+ end
58
+
51
59
  if options.tags.empty?
52
60
  doc.text
53
61
  else
@@ -55,6 +63,14 @@ module Middleman
55
63
  end
56
64
  end
57
65
 
66
+ def regex_filter_content(text)
67
+ if options.ignore_regex
68
+ text.to_s.gsub options.ignore_regex , ' '
69
+ else
70
+ text
71
+ end
72
+ end
73
+
58
74
  def option_tags
59
75
  if options.tags.is_a? Array
60
76
  options.tags
@@ -85,26 +101,58 @@ module Middleman
85
101
  else
86
102
  options.lang
87
103
  end
88
- run_check(select_content(resource), lang)
104
+ run_check(resource, lang)
89
105
  end
90
106
 
91
- def run_check(text, lang)
107
+ def run_check(resource, lang)
108
+ text = select_content(resource)
109
+ text = regex_filter_content(text)
92
110
  results = Spellchecker.check(text, lang)
93
- results = exclude_allowed(results)
111
+ results = exclude_allowed(resource, results)
94
112
  results.reject { |entry| entry[:correct] }
95
113
  end
96
114
 
97
- def exclude_allowed(results)
98
- results.reject { |entry| option_allowed.include? entry[:word].downcase }
115
+ def exclude_allowed(resource, results)
116
+ results.reject { |entry| allowed_words(resource).include? entry[:word].downcase }
99
117
  end
100
118
 
101
- def option_allowed
102
- allowed = if options.allow.is_a? Array
119
+ def allowed_words(resource)
120
+ words_ok = if options.allow.is_a? Array
103
121
  options.allow
104
122
  else
105
123
  [options.allow]
106
124
  end
107
- allowed.map(&:downcase)
125
+ words_ok += allowed_words_frontmatter(resource)
126
+ words_ok += allowed_words_file
127
+ words_ok.map(&:downcase)
128
+ end
129
+
130
+ def allowed_words_frontmatter(resource)
131
+ words_ok = []
132
+ if resource.data.include?("spellcheck-allow") then
133
+ allowed_tmp = resource.data["spellcheck-allow"]
134
+ words_ok += if allowed_tmp.is_a? Array
135
+ allowed_tmp
136
+ else
137
+ [allowed_tmp]
138
+ end
139
+ end
140
+ words_ok
141
+ end
142
+
143
+ def allowed_words_file
144
+ allow_file = nil
145
+ if app.config.defines_setting?(:spellcheck_allow_file)
146
+ allow_file = app.config[:spellcheck_allow_file]
147
+ end
148
+ if ALLOWED_WORDS.empty? && allow_file != nil
149
+ lines = File.read(allow_file)
150
+ lines.split("\n").each do |line|
151
+ next if line =~ /^#/ or line =~ /^$/
152
+ ALLOWED_WORDS << line.partition('#').first.strip
153
+ end
154
+ end
155
+ ALLOWED_WORDS
108
156
  end
109
157
 
110
158
  def option_ignored_exts
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  class Spellchecker
2
4
  @@aspell_path = "aspell"
3
5
  @@aspell_cmdargs = ""
@@ -76,7 +78,8 @@ class Spellchecker
76
78
  text.gsub! '’', '\''
77
79
  sdbg "self.check got raw text:\n#{text}\n"
78
80
 
79
- words = text.split(/[^\p{L}']+/).select { |s|
81
+ #Split words and
82
+ words = text.split(/'?[^\p{L}']+'?/).select { |s|
80
83
  s != "" and s != "'s" and s != "'"
81
84
  }.uniq
82
85
  sdbg "self.check word array:\n#{words}\n"
@@ -1,5 +1,5 @@
1
1
  module Middleman
2
2
  module Spellcheck
3
- VERSION = "0.9.0"
3
+ VERSION = "0.9.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: middleman-spellcheck
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Zarea
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-03 00:00:00.000000000 Z
11
+ date: 2016-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: middleman-core
@@ -127,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
127
  version: '0'
128
128
  requirements: []
129
129
  rubyforge_project:
130
- rubygems_version: 2.2.2
130
+ rubygems_version: 2.4.8
131
131
  signing_key:
132
132
  specification_version: 4
133
133
  summary: Run spell checks as a build phase in middleman