rdoc-spellcheck 1.0

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.
Binary file
@@ -0,0 +1,17 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ Autotest.add_hook :initialize do |at|
6
+ at.testlib = 'minitest/autorun'
7
+ at.add_exception '.git'
8
+
9
+ def at.path_to_classname s
10
+ sep = File::SEPARATOR
11
+ f = s.sub(/^test#{sep}/, '').sub(/\.rb$/, '').split(sep)
12
+ f = f.map { |path| path.split(/_|(\d+)/).map { |seg| seg.capitalize }.join }
13
+ f = f.map { |path| path =~ /^Test/ ? path : "Test#{path}" }
14
+ f.join('::').gsub('Rdoc', 'RDoc')
15
+ end
16
+ end
17
+
File without changes
@@ -0,0 +1,5 @@
1
+ === 1.0 / 2012-04-05
2
+
3
+ * Major enhancements
4
+ * Birthday!
5
+
@@ -0,0 +1,8 @@
1
+ .autotest
2
+ History.rdoc
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ lib/rdoc/discover.rb
7
+ lib/rdoc/generator/spellcheck.rb
8
+ test/test_rdoc_generator_spellcheck.rb
@@ -0,0 +1,80 @@
1
+ = rdoc-spellcheck
2
+
3
+ home :: https://github.com/drbrain/rdoc-spellcheck
4
+ rdoc :: http://docs.seattlerb.org/rdoc-spellcheck
5
+ bugs :: https://github.com/drbrain/rdoc-spellcheck/issues
6
+
7
+ == Description
8
+
9
+ rdoc-spellcheck checks your documentation for spelling errors. File, class,
10
+ and method names are automatically excluded from the results and you can add
11
+ your own words to the default word list.
12
+
13
+ == Features
14
+
15
+ * Checks documentation for pages, classes, modules, methods, constants, etc.
16
+ * Prints a report showing each misspelled word and correction suggestions
17
+
18
+ == Problems
19
+
20
+ rdoc-spellcheck depends on aspell for which development has ceased despite
21
+ messages to the contrary. I've submitted two pull requests to the
22
+ hunspell-ffi gem that should allow it to become a usable replacement for the
23
+ raspell gem. (The currently released hunspell-ffi does not appear to support
24
+ private or session dictionaries.)
25
+
26
+ For some projects it seems there are too many false positives for names and
27
+ programming words. I've reduced this somewhat by automatically including many
28
+ programming words in the session dictionary. One solution involves switching
29
+ to hunspell which appears to have better-maintained word dictionaries. The
30
+ other involves exploring an upper threshold for the edit distance between a
31
+ given word and its suggestion.
32
+
33
+ == Synopsis
34
+
35
+ $ rdoc -f spellcheck lib *.rdoc
36
+
37
+ == Requirements
38
+
39
+ * rdoc
40
+ * libaspell -- See https://github.com/evan/raspell/blob/master/README.rdoc for
41
+ installation instructions for aspell
42
+
43
+ == Install
44
+
45
+ sudo gem install rdoc-spellcheck
46
+
47
+ == Developers
48
+
49
+ After checking out the source, run:
50
+
51
+ $ rake newb
52
+
53
+ This task will install any missing dependencies, run the tests/specs,
54
+ and generate the RDoc.
55
+
56
+ == License
57
+
58
+ (The MIT License)
59
+
60
+ Copyright (c) Eric Hodel
61
+
62
+ Permission is hereby granted, free of charge, to any person obtaining
63
+ a copy of this software and associated documentation files (the
64
+ 'Software'), to deal in the Software without restriction, including
65
+ without limitation the rights to use, copy, modify, merge, publish,
66
+ distribute, sublicense, and/or sell copies of the Software, and to
67
+ permit persons to whom the Software is furnished to do so, subject to
68
+ the following conditions:
69
+
70
+ The above copyright notice and this permission notice shall be
71
+ included in all copies or substantial portions of the Software.
72
+
73
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
74
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
75
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
76
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
77
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
78
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
79
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
80
+
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.plugin :minitest
7
+ Hoe.plugin :git
8
+ Hoe.plugin :travis
9
+
10
+ Hoe.spec 'rdoc-spellcheck' do
11
+ developer 'Eric Hodel', 'drbrain@segment7.net'
12
+
13
+ rdoc_locations <<
14
+ 'docs.seattlerb.org:/data/www/docs.seattlerb.org/rdoc-spellcheck/'
15
+
16
+ # Too lazy to make Unicode Regexps work on Ruby 1.8 and 1.9
17
+ spec_extras['required_ruby_version'] = '>= 1.9.2'
18
+
19
+ dependency 'raspell', '~> 1.3'
20
+ dependency 'rdoc', '~> 3.12'
21
+ end
22
+
23
+ # vim: syntax=ruby
@@ -0,0 +1,2 @@
1
+ require 'rdoc/generator/spellcheck'
2
+
@@ -0,0 +1,714 @@
1
+ # coding: UTF-8
2
+
3
+ require 'raspell'
4
+
5
+ ##
6
+ # A spell checking generator for RDoc.
7
+ #
8
+ # This generator creates a report of misspelled words. You can use it to find
9
+ # when you acidentally make a typo. For example, this line contains one.
10
+
11
+ class RDoc::Generator::Spellcheck
12
+
13
+ RDoc::RDoc.add_generator self
14
+
15
+ ##
16
+ # This version of rdoc-spellcheck
17
+
18
+ VERSION = '1.0'
19
+
20
+ ##
21
+ # A list of common words that aspell may not include, but are commonly used
22
+ # in ruby programs.
23
+ #--
24
+ # Please keep this list sorted in your pull requests
25
+
26
+ DEFAULT_WORDS = %w[
27
+ API
28
+ ArgumentError
29
+ CGI
30
+ DES
31
+ ECDSA
32
+ EOFError
33
+ ERb
34
+ Encoding::CompatibilityError
35
+ Encoding::ConverterNotFoundError
36
+ Encoding::InvalidByteSequenceError
37
+ Encoding::UndefinedConversionError
38
+ EncodingError
39
+ Errno::E2BIG
40
+ Errno::EACCES
41
+ Errno::EADDRINUSE
42
+ Errno::EADDRNOTAVAIL
43
+ Errno::EAFNOSUPPORT
44
+ Errno::EAGAIN
45
+ Errno::EALREADY
46
+ Errno::EAUTH
47
+ Errno::EBADF
48
+ Errno::EBADMSG
49
+ Errno::EBADRPC
50
+ Errno::EBUSY
51
+ Errno::ECANCELED
52
+ Errno::ECHILD
53
+ Errno::ECONNABORTED
54
+ Errno::ECONNREFUSED
55
+ Errno::ECONNRESET
56
+ Errno::EDEADLK
57
+ Errno::EDESTADDRREQ
58
+ Errno::EDOM
59
+ Errno::EDQUOT
60
+ Errno::EEXIST
61
+ Errno::EFAULT
62
+ Errno::EFBIG
63
+ Errno::EFTYPE
64
+ Errno::EHOSTDOWN
65
+ Errno::EHOSTUNREACH
66
+ Errno::EIDRM
67
+ Errno::EILSEQ
68
+ Errno::EINPROGRESS
69
+ Errno::EINTR
70
+ Errno::EINVAL
71
+ Errno::EIO
72
+ Errno::EISCONN
73
+ Errno::EISDIR
74
+ Errno::ELOOP
75
+ Errno::EMFILE
76
+ Errno::EMLINK
77
+ Errno::EMSGSIZE
78
+ Errno::EMULTIHOP
79
+ Errno::ENAMETOOLONG
80
+ Errno::ENEEDAUTH
81
+ Errno::ENETDOWN
82
+ Errno::ENETRESET
83
+ Errno::ENETUNREACH
84
+ Errno::ENFILE
85
+ Errno::ENOATTR
86
+ Errno::ENOBUFS
87
+ Errno::ENODATA
88
+ Errno::ENODEV
89
+ Errno::ENOENT
90
+ Errno::ENOEXEC
91
+ Errno::ENOLCK
92
+ Errno::ENOLINK
93
+ Errno::ENOMEM
94
+ Errno::ENOMSG
95
+ Errno::ENOPROTOOPT
96
+ Errno::ENOSPC
97
+ Errno::ENOSR
98
+ Errno::ENOSTR
99
+ Errno::ENOSYS
100
+ Errno::ENOTBLK
101
+ Errno::ENOTCONN
102
+ Errno::ENOTDIR
103
+ Errno::ENOTEMPTY
104
+ Errno::ENOTRECOVERABLE
105
+ Errno::ENOTSOCK
106
+ Errno::ENOTSUP
107
+ Errno::ENOTTY
108
+ Errno::ENXIO
109
+ Errno::EOPNOTSUPP
110
+ Errno::EOVERFLOW
111
+ Errno::EOWNERDEAD
112
+ Errno::EPERM
113
+ Errno::EPFNOSUPPORT
114
+ Errno::EPIPE
115
+ Errno::EPROCLIM
116
+ Errno::EPROCUNAVAIL
117
+ Errno::EPROGMISMATCH
118
+ Errno::EPROGUNAVAIL
119
+ Errno::EPROTO
120
+ Errno::EPROTONOSUPPORT
121
+ Errno::EPROTOTYPE
122
+ Errno::ERANGE
123
+ Errno::EREMOTE
124
+ Errno::EROFS
125
+ Errno::ERPCMISMATCH
126
+ Errno::ESHUTDOWN
127
+ Errno::ESOCKTNOSUPPORT
128
+ Errno::ESPIPE
129
+ Errno::ESRCH
130
+ Errno::ESTALE
131
+ Errno::ETIME
132
+ Errno::ETIMEDOUT
133
+ Errno::ETOOMANYREFS
134
+ Errno::ETXTBSY
135
+ Errno::EUSERS
136
+ Errno::EXDEV
137
+ Errno::NOERROR
138
+ Exception
139
+ FIXME
140
+ FQDN
141
+ FiberError
142
+ FileUtils
143
+ FloatDomainError
144
+ GPL
145
+ IETF
146
+ IOError
147
+ IndexError
148
+ Interrupt
149
+ KeyError
150
+ LoadError
151
+ LocalJumpError
152
+ MSDN
153
+ Math::DomainError
154
+ NTFS
155
+ NUL
156
+ NameError
157
+ NoMemoryError
158
+ NoMethodError
159
+ NoMethodError
160
+ NotImplementedError
161
+ O'Reilly
162
+ PHP
163
+ PNG
164
+ POSIX
165
+ PRNG
166
+ README
167
+ RangeError
168
+ RegexpError
169
+ RuntimeError
170
+ SIGABRT
171
+ SIGALRM
172
+ SIGBUS
173
+ SIGCHLD
174
+ SIGCLD
175
+ SIGCONT
176
+ SIGEMT
177
+ SIGEXIT
178
+ SIGFPE
179
+ SIGHUP
180
+ SIGILL
181
+ SIGINFO
182
+ SIGINT
183
+ SIGIO
184
+ SIGIOT
185
+ SIGKILL
186
+ SIGPIPE
187
+ SIGPROF
188
+ SIGQUIT
189
+ SIGSEGV
190
+ SIGSTOP
191
+ SIGSYS
192
+ SIGTERM
193
+ SIGTRAP
194
+ SIGTSTP
195
+ SIGTTIN
196
+ SIGTTOU
197
+ SIGURG
198
+ SIGUSR1
199
+ SIGUSR2
200
+ SIGVTALRM
201
+ SIGWINCH
202
+ SIGXCPU
203
+ SIGXFSZ
204
+ SMTP
205
+ SMTPS
206
+ ScriptError
207
+ SecurityError
208
+ SignalException
209
+ StandardError
210
+ StopIteration
211
+ StringIO
212
+ SyntaxError
213
+ SystemCallError
214
+ SystemExit
215
+ SystemStackError
216
+ ThreadError
217
+ TypeError
218
+ URI
219
+ UUCP
220
+ VCS
221
+ Wikipedia
222
+ XHTML
223
+ ZeroDivisionError
224
+ Zlib
225
+ accessor
226
+ accessors
227
+ argf
228
+ argv
229
+ ary
230
+ authenticators
231
+ baz
232
+ bom
233
+ bzip
234
+ canonicalization
235
+ cfg
236
+ cpp
237
+ crlf
238
+ cryptographic
239
+ csh
240
+ daemonizing
241
+ decrypt
242
+ decrypted
243
+ decrypter
244
+ decrypting
245
+ decrypts
246
+ deprecations
247
+ dereferenced
248
+ deserialization
249
+ deserialize
250
+ deserialized
251
+ deserializes
252
+ deserializing
253
+ dev
254
+ druby
255
+ dRuby
256
+ dup
257
+ duplexed
258
+ elsif
259
+ emacs
260
+ encodings
261
+ encrypter
262
+ endian
263
+ env
264
+ erb
265
+ finalized
266
+ finalizer
267
+ finalizers
268
+ globals
269
+ gsub
270
+ gzip
271
+ gzipped
272
+ http
273
+ https
274
+ img
275
+ incrementing
276
+ initializer
277
+ inlining
278
+ instantiation
279
+ irb
280
+ iso
281
+ ivar
282
+ kbd
283
+ klass
284
+ klasses
285
+ lang
286
+ lexing
287
+ lookup
288
+ lossy
289
+ mailto
290
+ matz
291
+ mktmpdir
292
+ natively
293
+ newb
294
+ nonces
295
+ perl
296
+ popup
297
+ proleptic
298
+ proxied
299
+ pwd
300
+ racc
301
+ radian
302
+ radians
303
+ radix
304
+ rbw
305
+ redistributions
306
+ refactor
307
+ refactored
308
+ reinitializes
309
+ resized
310
+ rhtml
311
+ rsync
312
+ serializable
313
+ startup
314
+ stderr
315
+ stdin
316
+ stdout
317
+ struct
318
+ succ
319
+ sudo
320
+ tmpdir
321
+ tokenizer
322
+ tokenizes
323
+ txt
324
+ unbuffered
325
+ unescape
326
+ unescapes
327
+ uniq
328
+ unmaintained
329
+ unmarshal
330
+ unmarshalled
331
+ unmarshalling
332
+ unordered
333
+ untagged
334
+ untrusted
335
+ utf
336
+ validator
337
+ validators
338
+ versioning
339
+ visibilities
340
+ www
341
+ yacc
342
+ ]
343
+
344
+ ##
345
+ # OptionParser validator for Aspell language dictionaries
346
+
347
+ SpellLanguage = Object.new
348
+
349
+ attr_accessor :minimum_word_length # :nodoc:
350
+
351
+ attr_reader :spell # :nodoc:
352
+
353
+ ##
354
+ # Adds rdoc-spellcheck options to the rdoc command
355
+
356
+ def self.setup_options options
357
+ default_language, = ENV['LANG'].split '.'
358
+
359
+ options.spell_add_words = false
360
+ options.spell_language = default_language
361
+ options.spell_minimum_word_length = 4
362
+ options.spell_source_dir = Dir.pwd
363
+ options.quiet = true # suppress statistics
364
+
365
+ op = options.option_parser
366
+
367
+ op.accept SpellLanguage do |language|
368
+ found = Aspell.list_dicts.find do |dict|
369
+ dict.name == language
370
+ end
371
+
372
+ raise OptionParser::InvalidArgument,
373
+ "dictionary #{language} not installed" unless found
374
+
375
+ language
376
+ end
377
+
378
+ op.separator nil
379
+ op.separator 'Spellcheck options:'
380
+ op.separator nil
381
+
382
+ op.on('--spell-add-words [WORDLIST]',
383
+ 'Adds words to the aspell personal wordlist.',
384
+ 'The word list may be a comma-separated',
385
+ 'list of words which must contain multiple',
386
+ 'words, a file or empty to read words from',
387
+ 'stdin') do |wordlist|
388
+ words = if wordlist.nil? then
389
+ $stdin.read.split
390
+ elsif wordlist =~ /,/ then
391
+ wordlist.split ','
392
+ else
393
+ open wordlist do |io|
394
+ io.read.split
395
+ end
396
+ end
397
+
398
+ options.spell_add_words = words
399
+ end
400
+
401
+ op.separator nil
402
+
403
+ op.on('--[no-]spell-aggregate-all',
404
+ 'Show aggregate counts for all misspellings.') do |aggregate_all|
405
+ options.spell_aggregate_all = aggregate_all
406
+ end
407
+
408
+ op.separator nil
409
+
410
+ op.on('--spell-language=LANGUAGE', SpellLanguage,
411
+ 'Language to use for spell checking.',
412
+ "The default language is #{default_language}") do |language|
413
+ options.spell_language = language
414
+ end
415
+
416
+ op.separator nil
417
+
418
+ op.on('--spell-minimum-word-length=LENGTH', Integer,
419
+ 'Minimum length of a word to spell check.',
420
+ "The default is #{options.spell_minimum_word_length}") do |length|
421
+ options.spell_minimum_word_length = length
422
+ end
423
+ end
424
+
425
+ def initialize options # :not-new:
426
+ @options = options
427
+
428
+ @encoding = @options.encoding
429
+ @aggregate_all = @options.spell_aggregate_all
430
+ @minimum_word_length = @options.spell_minimum_word_length
431
+ @source_dir = @options.spell_source_dir
432
+
433
+ @misspellings = Hash.new 0
434
+
435
+ @spell = Aspell.new @options.spell_language, nil, nil, @encoding.name
436
+ @spell.suggestion_mode = Aspell::NORMAL
437
+ @spell.set_option 'run-together', 'true'
438
+
439
+ if words = @options.spell_add_words then
440
+ words.each do |word|
441
+ @spell.add_to_personal word
442
+ end
443
+
444
+ @spell.save_all_word_lists
445
+ end
446
+ end
447
+
448
+ ##
449
+ # Adds +name+ to the dictionary, splitting the word on '_' (a character
450
+ # Aspell does not allow)
451
+
452
+ def add_name name
453
+ name.scan(/[a-z]+/i) do |part|
454
+ @spell.add_to_session part
455
+ end
456
+ end
457
+
458
+ ##
459
+ # Returns a report of misspelled words in +comment+. The report contains
460
+ # each misspelled word and its offset in the comment's text.
461
+
462
+ def find_misspelled comment
463
+ report = []
464
+
465
+ comment.text.scan(/\p{L}[\p{L}']+\p{L}/i) do |word|
466
+ next if $&.length < @minimum_word_length
467
+ offset = $`.length # store
468
+
469
+ word = $` if word =~ /'s$/i
470
+
471
+ next if @spell.check word
472
+
473
+ offset = offset.zero? ? 0 : offset + 1
474
+
475
+ report << [word, offset]
476
+
477
+ @misspellings[word] += 1
478
+ end
479
+
480
+ report
481
+ end
482
+
483
+ ##
484
+ # Creates the spelling report
485
+
486
+ def generate files
487
+ setup_dictionary
488
+
489
+ report = []
490
+
491
+ RDoc::TopLevel.all_classes_and_modules.each do |mod|
492
+ mod.comment_location.each do |comment, location|
493
+ report.concat misspellings_for(mod.definition, comment, location)
494
+ end
495
+
496
+ mod.each_include do |incl|
497
+ name = "#{incl.parent.full_name}.include #{incl.name}"
498
+
499
+ report.concat misspellings_for(name, incl.comment, incl.file)
500
+ end
501
+
502
+ mod.each_constant do |const|
503
+ # TODO add missing RDoc::Constant#full_name
504
+ name = const.parent ? const.parent.full_name : '(unknown)'
505
+ name = "#{name}::#{const.name}"
506
+
507
+ report.concat misspellings_for(name, const.comment, const.file)
508
+ end
509
+
510
+ mod.each_attribute do |attr|
511
+ name = "#{attr.parent.full_name}.#{attr.definition} :#{attr.name}"
512
+
513
+ report.concat misspellings_for(name, attr.comment, attr.file)
514
+ end
515
+
516
+ mod.each_method do |meth|
517
+ report.concat misspellings_for(meth.full_name, meth.comment, meth.file)
518
+ end
519
+ end
520
+
521
+ RDoc::TopLevel.all_files.each do |file|
522
+ report.concat misspellings_for(nil, file.comment, file)
523
+ end
524
+
525
+ if @misspellings.empty? then
526
+ puts 'No misspellings found'
527
+ else
528
+ puts report.join "\n"
529
+ puts
530
+
531
+ num_width = @misspellings.values.max.to_s.length
532
+ order = @misspellings.sort_by do |word, count|
533
+ [-count, word]
534
+ end
535
+
536
+ order = order.first 10 unless @aggregate_all
537
+
538
+ puts 'Aggregate misspellings:'
539
+ order.each do |word, count|
540
+ puts "%*d %s" % [num_width, count, word]
541
+ end
542
+
543
+ total = @misspellings.values.inject :+
544
+
545
+ puts
546
+ puts "Total misspellings: #{total}"
547
+ end
548
+ end
549
+
550
+ ##
551
+ # Determines the line and column of the misspelling in +comment+ at +offset+
552
+ # in the +file+.
553
+
554
+ def location_of text, offset, file
555
+ last_newline = text[0, offset].rindex "\n"
556
+ start_of_line = last_newline ? last_newline + 1 : 0
557
+
558
+ line_text = text[start_of_line..offset]
559
+
560
+ full_path = File.expand_path file.absolute_name, @source_dir
561
+
562
+ file_content = RDoc::Encoding.read_file full_path, @encoding
563
+
564
+ raise "[bug] Unable to read #{full_path}" unless file_content
565
+
566
+ file_content.each_line.with_index do |line, index|
567
+ if line =~ /#{Regexp.escape line_text}/ then
568
+ column = $`.length + line_text.length
569
+ return index, column
570
+ end
571
+ end
572
+
573
+ # TODO typos in include file
574
+
575
+ nil
576
+ end
577
+
578
+ ##
579
+ # Returns a report of misspellings the +comment+ at +location+ for
580
+ # documentation item +name+
581
+
582
+ def misspellings_for name, comment, location
583
+ out = []
584
+
585
+ return out if comment.empty?
586
+
587
+ misspelled = find_misspelled comment
588
+
589
+ return out if misspelled.empty?
590
+
591
+ if name then
592
+ out << "#{name} in #{location.full_name}:"
593
+ else
594
+ out << "In #{location.full_name}:"
595
+ end
596
+
597
+ out << nil
598
+
599
+ out.concat misspelled.flat_map { |word, offset|
600
+ suggestion = suggestion_text comment.text, word, offset
601
+ line, column = location_of word, offset, location
602
+
603
+ if line then
604
+ ["#{location.absolute_name}:#{line}:#{column}", suggestion]
605
+ else
606
+ ["(via include)", suggestion]
607
+ end
608
+ }
609
+
610
+ out
611
+ end
612
+
613
+ ##
614
+ # Adds file names, class names, module names, method names, etc. from the
615
+ # documentation tree to the session spelling dictionary.
616
+
617
+ def setup_dictionary
618
+ DEFAULT_WORDS.each do |word|
619
+ add_name word
620
+ end
621
+
622
+ RDoc::TopLevel.all_classes_and_modules.each do |mod|
623
+ add_name mod.name
624
+
625
+ mod.each_include do |incl|
626
+ add_name incl.name
627
+ end
628
+
629
+ mod.each_constant do |const|
630
+ add_name const.name
631
+ end
632
+
633
+ mod.each_attribute do |attr|
634
+ add_name attr.name
635
+ end
636
+
637
+ mod.each_method do |meth|
638
+ add_name meth.name
639
+ add_name meth.params if meth.params
640
+ add_name meth.block_params if meth.block_params
641
+ end
642
+ end
643
+
644
+ RDoc::TopLevel.all_files.each do |file|
645
+ file.absolute_name.split(%r%[/\\.]%).each do |part|
646
+ add_name part
647
+ end
648
+ end
649
+ end
650
+
651
+ ##
652
+ # Creates suggestion text for the misspelled +word+ at +offset+ in +text+
653
+
654
+ def suggestion_text text, word, offset
655
+ prefix = offset - 10
656
+ prefix = 0 if prefix < 0
657
+
658
+ text =~ /\A.{#{prefix}}(.{0,10})#{Regexp.escape word}(.{0,10})/m
659
+
660
+ before = "#{prefix.zero? ? nil : '...'}#{$1}"
661
+ after = "#{$2}#{$2.length < 10 ? nil : '...'}"
662
+
663
+ highlight = "\e[1;31m#{word}\e[m"
664
+
665
+ suggestions = @spell.suggest(word).first 5
666
+
667
+ <<-TEXT
668
+ "#{before}#{highlight}#{after}"
669
+
670
+ "#{word}" suggestions:
671
+ \t#{suggestions.join ', '}
672
+
673
+ TEXT
674
+ rescue => e
675
+ $stderr.puts "[bug] #{e.class}: #{e.message}"
676
+ $stderr.puts
677
+ $stderr.puts "word: #{word}"
678
+ $stderr.puts "offset: #{offset}"
679
+ $stderr.puts ">>>> start text <<<<\n#{text}\n>>>>> end text <<<<<"
680
+ raise
681
+ end
682
+
683
+ end
684
+
685
+ class RDoc::Options
686
+
687
+ ##
688
+ # Enables addition of words to the personal wordlist
689
+
690
+ attr_accessor :spell_add_words
691
+
692
+ ##
693
+ # Display all found misspellings instead of the top ten.
694
+
695
+ attr_accessor :spell_aggregate_all
696
+
697
+ ##
698
+ # The Aspell dictionary language to use. Defaults to the language in the
699
+ # LANG environment variable.
700
+
701
+ attr_accessor :spell_language
702
+
703
+ ##
704
+ # The minimum length of a word for spell checking.
705
+
706
+ attr_accessor :spell_minimum_word_length
707
+
708
+ ##
709
+ # The directory spellcheck was run from which contains all the source files.
710
+
711
+ attr_accessor :spell_source_dir
712
+
713
+ end
714
+