yard-spellcheck 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.*
3
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown --title "yard-spellcheck Documentation" --protected
data/ChangeLog.md ADDED
@@ -0,0 +1,7 @@
1
+ ### 0.1.0 / 2011-01-25
2
+
3
+ * Initial release:
4
+ * Added {YARD::Spellcheck::Checker}.
5
+ * Added {YARD::Spellcheck::Printer}.
6
+ * Added {YARD::CLI::Spellcheck}.
7
+
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Hal Brodigan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # yard-spellcheck
2
+
3
+ * [Homepage](http://github.com/postmodern/yard-spellcheck)
4
+ * [Issues](http://github.com/postmodern/yard-spellcheck/issues)
5
+ * [Email](postmodern.mod3 at gmail.com)
6
+
7
+ ## Description
8
+
9
+ Spellcheck your YARD documentation.
10
+
11
+ ## Synopsis
12
+
13
+ $ yard-spellcheck
14
+
15
+ ## Requirements
16
+
17
+ * [yard](http://github.com/lsegal/yard) ~> 0.6.0
18
+ * [ffi-hunspell](http://github.com/postmodern/ffi-hunspell) ~> 0.2.0
19
+
20
+ ## Install
21
+
22
+ $ gem install yard-spellcheck
23
+
24
+ ## Copyright
25
+
26
+ Copyright (c) 2011 Hal Brodigan
27
+
28
+ See {file:LICENSE.txt} for details.
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ gem 'ore-tasks', '~> 0.3.0'
6
+ require 'ore/tasks'
7
+
8
+ Ore::Tasks.new
9
+ rescue LoadError => e
10
+ STDERR.puts e.message
11
+ STDERR.puts "Run `gem install ore-tasks` to install 'ore/tasks'."
12
+ end
13
+
14
+ begin
15
+ gem 'rspec', '~> 2.4.0'
16
+ require 'rspec/core/rake_task'
17
+
18
+ RSpec::Core::RakeTask.new
19
+ rescue LoadError => e
20
+ task :spec do
21
+ abort "Please run `gem install rspec` to install RSpec."
22
+ end
23
+ end
24
+ task :default => :spec
25
+
26
+ begin
27
+ gem 'yard', '~> 0.6.0'
28
+ require 'yard'
29
+
30
+ YARD::Rake::YardocTask.new
31
+ rescue LoadError => e
32
+ task :yard do
33
+ abort "Please run `gem install yard` to install YARD."
34
+ end
35
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'yard'
4
+ require 'yard/cli/spellcheck'
5
+
6
+ YARD::CLI::Spellcheck.run(*ARGV)
data/gemspec.yml ADDED
@@ -0,0 +1,20 @@
1
+ name: yard-spellcheck
2
+ version: 0.1.0
3
+ summary: Spellcheck your YARD documentat
4
+ description:
5
+ Adds the 'spellcheck' command to YARD, which will spellcheck every
6
+ docstring within your documentation.
7
+
8
+ license: MIT
9
+ authors: Postmodern
10
+ email: postmodern.mod3@gmail.com
11
+ homepage: http://github.com/postmodern/yard-spellcheck
12
+ has_yard: true
13
+
14
+ dependencies:
15
+ yard: ~> 0.6.0
16
+ ffi-hunspell: ~> 0.2.0
17
+
18
+ development_dependencies:
19
+ ore-tasks: ~> 0.3.0
20
+ rspec: ~> 2.4.0
@@ -0,0 +1,99 @@
1
+ require 'yard/spellcheck/checker'
2
+ require 'yard/spellcheck/printer'
3
+
4
+ module YARD
5
+ module CLI
6
+ #
7
+ # The `yard-spellcheck` command.
8
+ #
9
+ class Spellcheck < Command
10
+
11
+ # The spellchecker.
12
+ attr_reader :checker
13
+
14
+ #
15
+ # Initializes the spellcheck command.
16
+ #
17
+ def initialize
18
+ @checker = YARD::Spellcheck::Checker.new
19
+ @names = []
20
+ @stats = false
21
+ end
22
+
23
+ #
24
+ # The command description.
25
+ #
26
+ # @return [String]
27
+ # Description.
28
+ #
29
+ def description
30
+ 'Spellchecks YARD documentation'
31
+ end
32
+
33
+ #
34
+ # Runs the spellcheck command.
35
+ #
36
+ # @param [Array<String>] args
37
+ # The arguments for the command.
38
+ #
39
+ def run(*args)
40
+ optparse(*args)
41
+
42
+ @checker.check!(@names) do |element,typos|
43
+ print_typos element, typos
44
+ end
45
+
46
+ if @stats
47
+ puts "Statistics"
48
+ print_stats @checker
49
+ end
50
+ end
51
+
52
+ protected
53
+
54
+ include YARD::Spellcheck::Printer
55
+
56
+ #
57
+ # Parses the command options.
58
+ #
59
+ # @param [Array<String>] args
60
+ # The arguments for the command.
61
+ #
62
+ def optparse(*args)
63
+ opts = OptionParser.new
64
+ opts.banner = "Usage: yard spellcheck [options]"
65
+ opts.separator ""
66
+ opts.separator description
67
+ opts.separator ""
68
+
69
+ opts.on('-D','--dict-dir','Dictionary directory') do |dir|
70
+ FFI::Hunspell.directories << File.expand_path(dir)
71
+ end
72
+
73
+ opts.on('-c','--check [CLASS | MODULE]','Classes/Modules to spellcheck') do |name|
74
+ @names << name
75
+ end
76
+
77
+ opts.on('-L','--lang LANG','Language to spellcheck for') do |lang|
78
+ @checker.lang = lang
79
+ end
80
+
81
+ opts.on('-I','--ignore WORD','Words to ignore') do |word|
82
+ @checker.ignored << word
83
+ end
84
+
85
+ opts.on('-a','--add WORD [...]','Adds a word') do |word|
86
+ @checker.added << word
87
+ end
88
+
89
+ opts.on('-S','--statistics','Print statistics') do
90
+ @stats = true
91
+ end
92
+
93
+ common_options(opts)
94
+ parse_options(opts,args)
95
+ end
96
+
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,184 @@
1
+ require 'ffi/hunspell'
2
+ require 'set'
3
+ require 'yard'
4
+
5
+ module YARD
6
+ module Spellcheck
7
+ #
8
+ # Handles loading and spellchecking YARD Documentation.
9
+ #
10
+ class Checker
11
+
12
+ # YARD tags to not spellcheck.
13
+ SKIP_TAGS = Set['example', 'since', 'see', 'api']
14
+
15
+ # The Regexp to use for scanning in words.
16
+ WORD_REGEXP = /[^\W_][[^\W_]'-]*[^\W_]/
17
+
18
+ # The language to spellcheck against.
19
+ attr_accessor :lang
20
+
21
+ # The words to ignore.
22
+ attr_reader :ignore
23
+
24
+ # The words to add to the dictionary.
25
+ attr_reader :added
26
+
27
+ # The known words from the documentation.
28
+ attr_reader :known
29
+
30
+ # The misspelled words.
31
+ attr_reader :misspelled
32
+
33
+ #
34
+ # Initializes the spellchecker.
35
+ #
36
+ # @param [Hash] options
37
+ # Additional options.
38
+ #
39
+ # @option options [String, Symbol] :lang (FFI::Hunspell.lang)
40
+ # The language to spellcheck against.
41
+ #
42
+ # @option options [Array, Set] :ignore
43
+ # The words to ignore.
44
+ #
45
+ # @option options [Array, Set] :add
46
+ # The words to add to the dictionary.
47
+ #
48
+ def initialize(options={})
49
+ @lang = options.fetch(:lang,FFI::Hunspell.lang)
50
+ @ignore = Set[]
51
+ @added = Set[]
52
+
53
+ if options[:ignore]
54
+ @ignored += options[:add]
55
+ end
56
+
57
+ if options[:add]
58
+ @added += options[:add]
59
+ end
60
+
61
+ @known = Set[]
62
+ @misspelled = Hash.new { |hash,key| hash[key] = 0 }
63
+ end
64
+
65
+ #
66
+ # Spellchecks the YARD Documentation.
67
+ #
68
+ # @param [Array<String>] names
69
+ # The Classes/Modules to spellcheck.
70
+ #
71
+ # @yield [element, typos]
72
+ # The given block will be passed each element and any typos found.
73
+ #
74
+ # @yieldparam [YARD::Docstring, YARD::Tag] element
75
+ # An element from the YARD Documentation.
76
+ #
77
+ # @yieldparam [Set<String>] typos
78
+ # Any typos found within the element.
79
+ #
80
+ # @return [Enumerator]
81
+ # If no block is given, an Enumerator will be returned.
82
+ #
83
+ def check!(names=[],&block)
84
+ return enum_for(:check!) unless block
85
+
86
+ # load the YARD cache
87
+ YARD::Registry.load!
88
+
89
+ # clear any statistics from last run
90
+ @known.clear
91
+ @misspelled.clear
92
+
93
+ # load known Class and Module names
94
+ YARD::Registry.all(:class, :module).each do |obj|
95
+ obj.path.split('::').each { |name| @known << name }
96
+ end
97
+
98
+ FFI::Hunspell.dict(@lang) do |dict|
99
+ # add user specified words
100
+ @added.each { |word| dict.add(word) }
101
+
102
+ unless names.empty?
103
+ names.each do |name|
104
+ if (obj = YARD::Registry.at(name))
105
+ spellcheck_object(obj,dict,&block)
106
+ end
107
+ end
108
+ else
109
+ YARD::Registry.each do |obj|
110
+ spellcheck_object(obj,dict,&block)
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ protected
117
+
118
+ #
119
+ # Spellchecks a YARD Documentation object.
120
+ #
121
+ # @param [YARD::CodeObject::Base] obj
122
+ # The YARD Documentation object.
123
+ #
124
+ # @param [FFI::Hunspell::Dictionary] dict
125
+ # The dictionary to spellcheck against.
126
+ #
127
+ # @yield [element, typos]
128
+ # The given block will be passed each element and any typos found.
129
+ #
130
+ # @yieldparam [YARD::Docstring, YARD::Tag] element
131
+ # An element from the YARD Documentation.
132
+ #
133
+ # @yieldparam [Set<String>] typos
134
+ # Any typos found within the element.
135
+ #
136
+ def spellcheck_object(obj,dict)
137
+ docstring = obj.docstring
138
+
139
+ unless (typos = spellcheck(docstring,dict)).empty?
140
+ yield docstring, typos
141
+ end
142
+
143
+ docstring.tags.each do |tag|
144
+ next if SKIP_TAGS.include?(tag.tag_name)
145
+
146
+ if tag.text
147
+ unless (typos = spellcheck(tag.text,dict)).empty?
148
+ yield tag, typos
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ #
155
+ # Spellchecks a piece of text.
156
+ #
157
+ # @param [String] text
158
+ # The text to spellcheck.
159
+ #
160
+ # @param [FFI::Hunspell::Dictionary] dict
161
+ # The dictionary to use.
162
+ #
163
+ # @return [Set<String>]
164
+ # The misspelled words from the text.
165
+ #
166
+ def spellcheck(text,dict)
167
+ typos = Set[]
168
+
169
+ text.scan(WORD_REGEXP).each do |word|
170
+ next if (@known.include?(word) || @ignore.include?(word))
171
+
172
+ if (@misspelled.has_key?(word) || !dict.valid?(word))
173
+ @misspelled[word] += 1
174
+
175
+ typos << word
176
+ end
177
+ end
178
+
179
+ return typos
180
+ end
181
+
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,91 @@
1
+ require 'yard/spellcheck/checker'
2
+
3
+ module YARD
4
+ module Spellcheck
5
+ #
6
+ # Provides methods for printing the typos found in YARD Documentation.
7
+ #
8
+ module Printer
9
+ # Highlights text
10
+ HIGHLIGHT = "\e[31m\e[4m"
11
+
12
+ # Unhighlights text
13
+ UNHIGHLIGHT = "\e[0m"
14
+
15
+ #
16
+ # Prints typos in a YARD Documentation element.
17
+ #
18
+ # @param [YARD::Docstring, YARD::Tags::Tag] element
19
+ # The element that the typos occurred in.
20
+ #
21
+ # @param [Set<String>] typos
22
+ # The typos that were found in the element.
23
+ #
24
+ def print_typos(element,typos)
25
+ case element
26
+ when YARD::Docstring
27
+ line = if element.line_range
28
+ element.line_range.first
29
+ else
30
+ 1
31
+ end
32
+
33
+ puts "Typos in #{element.object} (#{element.object.file}:#{line})"
34
+
35
+ print_text line, element, typos
36
+ when YARD::Tags::Tag
37
+ puts "Typos in @#{element.tag_name} #{element.name} (#{element.object.file}:#{element.object.line})"
38
+
39
+ print_text element.object.line, element.text, typos
40
+ end
41
+ end
42
+
43
+ #
44
+ # Prints text containing typos.
45
+ #
46
+ # @param [Integer] line_number
47
+ # The line number that the text starts on.
48
+ #
49
+ # @param [String] text
50
+ # The text to print.
51
+ #
52
+ # @param [Set<String>] typos
53
+ # The typos that occurred within the text.
54
+ #
55
+ def print_text(line_number,text,typos)
56
+ # highlight the typos
57
+ highlighted = text.gsub(Checker::WORD_REGEXP) do |word|
58
+ if typos.include?(word)
59
+ "#{HIGHLIGHT}#{word}#{UNHIGHLIGHT}"
60
+ else
61
+ word
62
+ end
63
+ end
64
+
65
+ puts ''
66
+
67
+ # print the lines
68
+ highlighted.each_line do |line|
69
+ puts " #{line_number} #{line}"
70
+ line_number += 1
71
+ end
72
+
73
+ puts ''
74
+ end
75
+
76
+ #
77
+ # Prints statistics gathered by the spellchecker.
78
+ #
79
+ # @param [Checker] checker
80
+ # The spellchecker.
81
+ #
82
+ def print_stats(checker)
83
+ stats = checker.misspelled.sort_by { |word,count| -count }
84
+
85
+ stats.each_with_index do |(word,count),index|
86
+ puts " #{index + 1}. #{word} (#{count})"
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,4 @@
1
+ require 'yard'
2
+ require 'yard/cli/spellcheck'
3
+
4
+ YARD::CLI::CommandParser.commands[:spellcheck] = YARD::CLI::Spellcheck
@@ -0,0 +1,2 @@
1
+ gem 'rspec', '~> 2.4.0'
2
+ require 'rspec'
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ begin
4
+ Ore::Specification.new do |gemspec|
5
+ # custom logic here
6
+ end
7
+ rescue NameError
8
+ begin
9
+ require 'ore/specification'
10
+ retry
11
+ rescue LoadError
12
+ STDERR.puts "The 'yard-spellcheck.gemspec' file requires Ore."
13
+ STDERR.puts "Run `gem install ore-core` to install Ore."
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yard-spellcheck
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Postmodern
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-25 00:00:00 -08:00
18
+ default_executable: yard-spellcheck
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: yard
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 6
31
+ - 0
32
+ version: 0.6.0
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: ffi-hunspell
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 0
45
+ - 2
46
+ - 0
47
+ version: 0.2.0
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: ore-tasks
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ - 3
61
+ - 0
62
+ version: 0.3.0
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: rspec
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ~>
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 2
75
+ - 4
76
+ - 0
77
+ version: 2.4.0
78
+ type: :development
79
+ version_requirements: *id004
80
+ description: Adds the 'spellcheck' command to YARD, which will spellcheck every docstring within your documentation.
81
+ email: postmodern.mod3@gmail.com
82
+ executables:
83
+ - yard-spellcheck
84
+ extensions: []
85
+
86
+ extra_rdoc_files:
87
+ - README.md
88
+ - ChangeLog.md
89
+ - LICENSE.txt
90
+ files:
91
+ - .document
92
+ - .rspec
93
+ - .yardopts
94
+ - ChangeLog.md
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - bin/yard-spellcheck
99
+ - gemspec.yml
100
+ - lib/yard-spellcheck.rb
101
+ - lib/yard/cli/spellcheck.rb
102
+ - lib/yard/spellcheck/checker.rb
103
+ - lib/yard/spellcheck/printer.rb
104
+ - spec/spec_helper.rb
105
+ - yard-spellcheck.gemspec
106
+ has_rdoc: yard
107
+ homepage: http://github.com/postmodern/yard-spellcheck
108
+ licenses:
109
+ - MIT
110
+ post_install_message:
111
+ rdoc_options: []
112
+
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ requirements: []
132
+
133
+ rubyforge_project: yard-spellcheck
134
+ rubygems_version: 1.3.7
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Spellcheck your YARD documentat
138
+ test_files: []
139
+