docdiff 0.6.4 → 0.6.6

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -7
  3. data/Guardfile +4 -4
  4. data/Makefile +6 -7
  5. data/README.md +1 -0
  6. data/README_ja.md +1 -0
  7. data/Rakefile +6 -6
  8. data/bin/docdiff +2 -209
  9. data/devutil/Rakefile +12 -5
  10. data/devutil/char_by_charclass.rb +43 -20
  11. data/devutil/charclass_by_char.rb +40 -19
  12. data/devutil/jis0208.rb +263 -231
  13. data/devutil/jis0208_test.rb +196 -0
  14. data/doc/news.md +17 -0
  15. data/docdiff.gemspec +13 -10
  16. data/lib/doc_diff.rb +63 -98
  17. data/lib/docdiff/charstring.rb +225 -241
  18. data/lib/docdiff/cli.rb +316 -0
  19. data/lib/docdiff/diff/contours.rb +1 -1
  20. data/lib/docdiff/diff/editscript.rb +1 -1
  21. data/lib/docdiff/diff/rcsdiff.rb +1 -1
  22. data/lib/docdiff/diff/shortestpath.rb +1 -1
  23. data/lib/docdiff/diff/speculative.rb +1 -1
  24. data/lib/docdiff/diff/subsequence.rb +1 -1
  25. data/lib/docdiff/diff/unidiff.rb +1 -1
  26. data/lib/docdiff/diff.rb +1 -1
  27. data/lib/docdiff/difference.rb +71 -70
  28. data/lib/docdiff/document.rb +129 -109
  29. data/lib/docdiff/encoding/en_ascii.rb +64 -58
  30. data/lib/docdiff/encoding/ja_eucjp.rb +250 -235
  31. data/lib/docdiff/encoding/ja_sjis.rb +240 -226
  32. data/lib/docdiff/encoding/ja_utf8.rb +6952 -6939
  33. data/lib/docdiff/version.rb +1 -1
  34. data/lib/docdiff/view.rb +523 -427
  35. data/lib/docdiff.rb +2 -2
  36. data/test/charstring_test.rb +475 -351
  37. data/test/cli_test.rb +314 -0
  38. data/test/diff_test.rb +15 -16
  39. data/test/difference_test.rb +40 -31
  40. data/test/docdiff_test.rb +162 -159
  41. data/test/document_test.rb +280 -175
  42. data/test/fixture/format_wdiff.conf +1 -0
  43. data/test/fixture/simple.conf +9 -0
  44. data/test/test_helper.rb +2 -1
  45. data/test/view_test.rb +636 -497
  46. metadata +27 -9
  47. data/devutil/testjis0208.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cde4401e24dbddfd093efe812847c7cc57f12cea257c113bc2625ac2c38361d5
4
- data.tar.gz: aa7fd969d604d090f16817dcdb09f2f4a1e5218c2063d3467e29929305afdd41
3
+ metadata.gz: 610b5b95840b0bc6c176dca519ba0b29f9da90a443f6e84026cded3619154d75
4
+ data.tar.gz: bd0ea4e230932dadc8bdf6ab4ecb112b56e1594111ebae3903b03c88bcd68394
5
5
  SHA512:
6
- metadata.gz: b0f085aa58f164c0b6a0d0cfaec0439df555d37fbe1c8dacd66962ab41084ec93cc6d0d13c3852ca9404d62c3941edc4477261b44f9402d0353b71cd3a3f257c
7
- data.tar.gz: b5b1bbb4a18524f5d9278f0afac27dc732dde0be686d4b526301219499fa3ef5a073b132a27a4e12a8bbc7bf847c8440c81179453243b1d30190d8901ea05770
6
+ metadata.gz: 6b281546af7612221702b0579ce26e99504ed76d5198c2894cff6c85371529b48bc3140acce1297f5191b0e3321f5c31a7aa3b222ed100941e1161856d08d521
7
+ data.tar.gz: aa76e99c2d89826abccf7dbbe64d3979d51389e87c79d491d309dc3589f096b0fdde16c84d0b840f6637dc21dac24bf52b3c9b6b68b6f774bf142db392506eb9
data/Gemfile CHANGED
@@ -1,16 +1,16 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  group :darwin do
4
- gem 'rb-fsevent'
5
- gem 'growl'
4
+ gem "rb-fsevent"
5
+ gem "growl"
6
6
  end
7
7
 
8
- gem 'guard'
9
- gem 'guard-test'
8
+ gem "guard"
9
+ gem "guard-test"
10
10
 
11
11
  group :test do
12
- gem 'simplecov', :require => false, :platforms => :ruby_19
13
- gem 'rcov', :require => false, :platforms => :ruby_18
12
+ gem "simplecov", require: false, platforms: :ruby_19
13
+ gem "rcov", require: false, platforms: :ruby_18
14
14
  end
15
15
 
16
16
  # Specify your gem's dependencies in docdiff.gemspec
data/Guardfile CHANGED
@@ -1,8 +1,8 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard 'test', :all_on_start => true do
5
- watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
6
- watch(%r{^test/.+_test\.rb$})
7
- watch('test/test_helper.rb') { "test" }
4
+ guard "test", all_on_start: true do
5
+ watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
6
+ watch(%r{^test/.+_test\.rb$})
7
+ watch("test/test_helper.rb") { "test" }
8
8
  end
data/Makefile CHANGED
@@ -14,12 +14,12 @@ DESTDIR =
14
14
  PREFIX = /usr/local
15
15
  datadir = $(DESTDIR)$(PREFIX)/share
16
16
 
17
- all: $(DOCS)
17
+ all: test docs dist gem
18
18
 
19
19
  test: $(TESTS)
20
20
  $(RUBY) -I./lib -e 'ARGV.map{|a| require_relative "#{a}"}' $^
21
21
 
22
- docs: $(DOCS)
22
+ docs: $(DOCS)
23
23
 
24
24
  %.html: %.md
25
25
  $(MD2HTML) --html-title="$(shell grep '^# .*' $< | head -n 1 | sed 's/^# //')" $< \
@@ -65,8 +65,9 @@ uninstall:
65
65
  -rm -fr $(DESTDIR)/etc/$(PRODUCT)
66
66
  -rm -fr $(datadir)/doc/$(PRODUCT)
67
67
 
68
- dist:
69
- git archive --prefix="$(PRODUCT)-$(VERSION)/" --format=tar HEAD --output="$(PRODUCT)-$(VERSION).tar.gz"
68
+ dist: $(PRODUCT)-$(VERSION).tar.gz
69
+ $(PRODUCT)-$(VERSION).tar.gz:
70
+ git archive --prefix="$(PRODUCT)-$(VERSION)/" --format=tar HEAD --output="$@"
70
71
 
71
72
  gem: $(PRODUCT)-$(VERSION).gem
72
73
  $(PRODUCT)-$(VERSION).gem: $(PRODUCT).gemspec
@@ -74,9 +75,7 @@ $(PRODUCT)-$(VERSION).gem: $(PRODUCT).gemspec
74
75
 
75
76
  clean:
76
77
  -rm -fr $(DOCS)
77
-
78
- distclean: clean
79
78
  -rm -fr $(PRODUCT)-$(VERSION).tar.gz
80
79
  -rm -fr $(PRODUCT)-$(VERSION).gem
81
80
 
82
- .PHONY: all test docs install uninstall dist gem clean distclean
81
+ .PHONY: all test docs install uninstall dist gem clean
data/README.md CHANGED
@@ -85,6 +85,7 @@ $
85
85
  * Runtime requirements:
86
86
  - [Ruby](https://www.ruby-lang.org/) (>= 3.0)
87
87
  * Development requirements:
88
+ - [Test::Unit](https://test-unit.github.io/)
88
89
  - Make ([GNU Make](https://www.gnu.org/software/make/))
89
90
  - [Git](https://git-scm.com/)
90
91
  - [md2html](https://github.com/mity/md4c) (for generating documents)
data/README_ja.md CHANGED
@@ -85,6 +85,7 @@ $
85
85
  * 実行時に必要なソフトウェア:
86
86
  - [Ruby](https://www.ruby-lang.org/) (>= 3.0)
87
87
  * 開発時に必要なソフトウェア:
88
+ - [Test::Unit](https://test-unit.github.io/)
88
89
  - Make ([GNU Make](https://www.gnu.org/software/make/))
89
90
  - [Git](https://git-scm.com/)
90
91
  - [md2html](https://github.com/mity/md4c)(ドキュメント生成用)
data/Rakefile CHANGED
@@ -1,12 +1,12 @@
1
- require 'rake/clean'
2
- require 'rake/testtask'
3
- require 'bundler/gem_tasks'
1
+ require "rake/clean"
2
+ require "rake/testtask"
3
+ require "bundler/gem_tasks"
4
4
 
5
- ENV['SOURCE_DATE_EPOCH'] ||= `git show --quiet --format=%ct HEAD`
5
+ ENV["SOURCE_DATE_EPOCH"] ||= `git show --quiet --format=%ct HEAD`
6
6
 
7
7
  Rake::TestTask.new do |t|
8
- t.test_files = FileList['test/*_test.rb']
8
+ t.test_files = FileList["test/*_test.rb"]
9
9
  t.verbose = true
10
10
  end
11
11
 
12
- task :default => :test
12
+ task default: :test
data/bin/docdiff CHANGED
@@ -2,213 +2,6 @@
2
2
  # DocDiff: word/character-oriented text comparison utility
3
3
  # Copyright (C) 2002-2011 Hisashi MORITA
4
4
  # Requirements: Ruby (>= 2.0)
5
- require 'docdiff'
6
- require 'optparse'
5
+ require "docdiff"
7
6
 
8
- # do_config_stuff
9
-
10
- default_config = {
11
- :resolution => "word",
12
- :encoding => "auto",
13
- :eol => "auto",
14
- :format => "html",
15
- :cache => true,
16
- :digest => false,
17
- :pager => nil,
18
- :verbose => false
19
- }
20
-
21
- clo = command_line_options = {}
22
-
23
- # if invoked as "worddiff" or "chardiff",
24
- # appropriate resolution is set respectively.
25
- case File.basename($0, ".*")
26
- when "worddiff" then; clo[:resolution] = "word"
27
- when "chardiff" then; clo[:resolution] = "char"
28
- end
29
-
30
- ARGV.options {|o|
31
- o.def_option('--resolution=RESOLUTION',
32
- resolutions = ['line', 'word', 'char'],
33
- 'specify resolution (granularity)',
34
- "#{resolutions.join('|')} (default: word)"
35
- ){|s| clo[:resolution] = (s || "word")}
36
- o.def_option('--line', 'same as --resolution=line'){clo[:resolution] = "line"}
37
- o.def_option('--word', 'same as --resolution=word'){clo[:resolution] = "word"}
38
- o.def_option('--char', 'same as --resolution=char'){clo[:resolution] = "char"}
39
-
40
- o.def_option('--encoding=ENCODING',
41
- encodings = ['ASCII', 'EUC-JP', 'Shift_JIS', 'CP932', 'UTF-8', 'auto'],
42
- "specify character encoding",
43
- "#{encodings.join('|')} (default: auto)",
44
- "(try ASCII for single byte encodings such as ISO-8859)"
45
- ){|s| clo[:encoding] = (s || "auto")}
46
- o.def_option('--ascii', 'same as --encoding=ASCII'){clo[:encoding] = "ASCII"}
47
- o.def_option('--iso8859', 'same as --encoding=ASCII'){clo[:encoding] = "ASCII"}
48
- o.def_option('--iso8859x', 'same as --encoding=ASCII (deprecated)'){clo[:encoding] = "ASCII"}
49
- o.def_option('--eucjp', 'same as --encoding=EUC-JP'){clo[:encoding] = "EUC-JP"}
50
- o.def_option('--sjis', 'same as --encoding=Shift_JIS'){clo[:encoding] = "Shift_JIS"}
51
- o.def_option('--cp932', 'same as --encoding=CP932'){clo[:encoding] = "CP932"}
52
- o.def_option('--utf8', 'same as --encoding=UTF-8'){clo[:encoding] = "UTF-8"}
53
-
54
- o.def_option('--eol=EOL',
55
- eols = ['CR','LF','CRLF','auto'],
56
- 'specify end-of-line character',
57
- "#{eols.join('|')} (default: auto)",
58
- ){|s| clo[:eol] = (s || "auto")}
59
- o.def_option('--cr', 'same as --eol=CR'){clo[:eol] = "CR"}
60
- o.def_option('--lf', 'same as --eol=LF'){clo[:eol] = "LF"}
61
- o.def_option('--crlf', 'same as --eol=CRLF'){clo[:eol] = "CRLF"}
62
-
63
- o.def_option('--format=FORMAT',
64
- formats = ['tty', 'manued', 'html', 'wdiff', 'stat', 'user'],
65
- 'specify output format',
66
- "#{formats.join('|')} (default: html) (stat is deprecated)",
67
- '(user tags can be defined in config file)'
68
- ){|s| clo[:format] = (s || "manued")}
69
- o.def_option('--tty', 'same as --format=tty'){clo[:format] = "tty"}
70
- o.def_option('--manued', 'same as --format=manued'){clo[:format] = "manued"}
71
- o.def_option('--html', 'same as --format=html'){clo[:format] = "html"}
72
- o.def_option('--wdiff', 'same as --format=wdiff'){clo[:format] = "wdiff"}
73
- o.def_option('--stat', 'same as --format=stat (not implemented) (deprecated)'){clo[:format] = "stat"}
74
-
75
- o.def_option('--label LABEL', '-L LABEL',
76
- 'use label instead of file name (not implemented; exists for compatibility with diff)'
77
- ){|s1, s2| clo[:label1], clo[:label2] = s1, s2}
78
-
79
- o.def_option('--digest', 'digest output, do not show all'){clo[:digest] = true}
80
- o.def_option('--summary', 'same as --digest'){clo[:digest] = true}
81
- o.def_option('--display=DISPLAY',
82
- display_types = ['inline', 'block', 'multi'],
83
- 'specify presentation type (effective only with digest; experimental feature)',
84
- "#{display_types.join('|')} (default: inline) (multi is deprecated)",
85
- ){|s| clo[:display] ||= s.downcase}
86
- o.def_option('--cache', 'use file cache (not implemented) (deprecated)'){clo[:cache] = true}
87
- o.def_option('--pager=PAGER', String,
88
- 'specify pager (if available, $DOCDIFF_PAGER is used by default)'
89
- ){|s| clo[:pager] = s}
90
- o.def_option('--no-pager', 'do not use pager'){clo[:pager] = false}
91
- o.def_option('--config-file=FILE', String,
92
- 'specify config file to read'){|s| clo[:config_file] = s}
93
- o.def_option('--no-config-file',
94
- 'do not read config files'){clo[:no_config_file] = true}
95
- o.def_option('--verbose', 'run verbosely (not well-supported) (deprecated)'){clo[:verbose] = true}
96
-
97
- o.def_option('--help', 'show this message'){puts o; exit(0)}
98
- o.def_option('--version', 'show version'){puts DocDiff::AppVersion; exit(0)}
99
- o.def_option('--license', 'show license (deprecated)'){puts DocDiff::License; exit(0)}
100
- o.def_option('--author', 'show author(s) (deprecated)'){puts DocDiff::Author; exit(0)}
101
-
102
- o.on_tail("When invoked as worddiff or chardiff, resolution will be set accordingly.",
103
- "Config files: /etc/docdiff/docdiff.conf, ~/.config/docdiff/docdiff.conf (or ~/etc/docdiff/docdiff.conf (deprecated))")
104
-
105
- o.parse!
106
- } or exit(1)
107
-
108
- docdiff = DocDiff.new()
109
- docdiff.config.update(default_config)
110
- unless clo[:no_config_file] == true # process_commandline_option
111
- message = docdiff.process_config_file(DocDiff::SystemConfigFileName)
112
- if clo[:verbose] == true || docdiff.config[:verbose] == true
113
- STDERR.print message
114
- end
115
- # message = docdiff.process_config_file(DocDiff::UserConfigFileName)
116
- case
117
- when [File.exist?(DocDiff::UserConfigFileName),
118
- File.exist?(DocDiff::AltUserConfigFileName),
119
- File.exist?(DocDiff::XDGUserConfigFileName)].count(true) >= 2
120
- raise <<~EOS
121
- #{DocDiff::UserConfigFileName}, #{DocDiff::AltUserConfigFileName}, and \
122
- #{DocDiff::XDGUserConfigFileName} cannot be used at the same time. \
123
- Keep one and remove or rename the others.
124
- EOS
125
- when File.exist?(DocDiff::UserConfigFileName)
126
- message = docdiff.process_config_file(DocDiff::UserConfigFileName)
127
- when File.exist?(DocDiff::AltUserConfigFileName)
128
- message = docdiff.process_config_file(DocDiff::AltUserConfigFileName)
129
- when File.exist?(DocDiff::XDGUserConfigFileName)
130
- message = docdiff.process_config_file(DocDiff::XDGUserConfigFileName)
131
- end
132
- if clo[:verbose] == true || docdiff.config[:verbose] == true
133
- STDERR.print message
134
- end
135
- end
136
- unless clo[:config_file].nil?
137
- if File.exist?(clo[:config_file])
138
- message = docdiff.process_config_file(clo[:config_file])
139
- else
140
- raise "#{clo[:config_file]} does not exist."
141
- end
142
- if clo[:verbose] == true || docdiff.config[:verbose] == true
143
- STDERR.print message
144
- end
145
- end
146
- docdiff.config.update(clo)
147
-
148
- docdiff.config[:pager] =
149
- if (pager = docdiff.config[:pager]).is_a?(String) && !pager.empty?
150
- pager
151
- elsif (pager = docdiff.config[:pager]) == false
152
- pager
153
- elsif (pager = ENV['DOCDIFF_PAGER']) && !pager.empty?
154
- pager
155
- end
156
-
157
- # config stuff done
158
-
159
- # process the documents
160
-
161
- file1_content = nil
162
- file2_content = nil
163
- raise "Try `#{File.basename($0)} --help' for more information." if ARGV[0].nil?
164
- raise "Specify at least 2 target files." unless ARGV[0] && ARGV[1]
165
- ARGV[0] = "/dev/stdin" if ARGV[0] == "-"
166
- ARGV[1] = "/dev/stdin" if ARGV[1] == "-"
167
- raise "No such file: #{ARGV[0]}." unless FileTest.exist?(ARGV[0])
168
- raise "No such file: #{ARGV[1]}." unless FileTest.exist?(ARGV[1])
169
- raise "#{ARGV[0]} is not readable." unless FileTest.readable?(ARGV[0])
170
- raise "#{ARGV[1]} is not readable." unless FileTest.readable?(ARGV[1])
171
- File.open(ARGV[0], "r"){|f| file1_content = f.read}
172
- File.open(ARGV[1], "r"){|f| file2_content = f.read}
173
-
174
- doc1 = nil
175
- doc2 = nil
176
-
177
- encoding1 = docdiff.config[:encoding]
178
- encoding2 = docdiff.config[:encoding]
179
- eol1 = docdiff.config[:eol]
180
- eol2 = docdiff.config[:eol]
181
-
182
- if docdiff.config[:encoding] == "auto"
183
- encoding1 = DocDiff::CharString.guess_encoding(file1_content)
184
- encoding2 = DocDiff::CharString.guess_encoding(file2_content)
185
- case
186
- when (encoding1 == "UNKNOWN" or encoding2 == "UNKNOWN")
187
- raise "Document encoding unknown (#{encoding1}, #{encoding2})."
188
- when encoding1 != encoding2
189
- raise "Document encoding mismatch (#{encoding1}, #{encoding2})."
190
- end
191
- end
192
-
193
- if docdiff.config[:eol] == "auto"
194
- eol1 = DocDiff::CharString.guess_eol(file1_content)
195
- eol2 = DocDiff::CharString.guess_eol(file2_content)
196
- case
197
- when (eol1.nil? or eol2.nil?)
198
- raise "Document eol is nil (#{eol1.inspect}, #{eol2.inspect}). The document might be empty."
199
- when (eol1 == 'UNKNOWN' or eol2 == 'UNKNOWN')
200
- raise "Document eol unknown (#{eol1.inspect}, #{eol2.inspect})."
201
- when (eol1 != eol2)
202
- raise "Document eol mismatch (#{eol1}, #{eol2})."
203
- end
204
- end
205
-
206
- doc1 = DocDiff::Document.new(file1_content, encoding1, eol1)
207
- doc2 = DocDiff::Document.new(file2_content, encoding2, eol2)
208
-
209
- output = docdiff.run(doc1, doc2,
210
- {:resolution => docdiff.config[:resolution],
211
- :format => docdiff.config[:format],
212
- :digest => docdiff.config[:digest],
213
- :display => docdiff.config[:display]})
214
- docdiff.print_or_write_to_pager(output, docdiff.config[:pager])
7
+ DocDiff::CLI.run
data/devutil/Rakefile CHANGED
@@ -1,9 +1,16 @@
1
- require 'rake/clean'
1
+ # frozen_string_literal: true
2
2
 
3
- file 'JIS0208.TXT' do |t|
4
- sh 'curl -O ftp://ftp.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/JIS0208.TXT'
3
+ require "rake/clean"
4
+
5
+ file "JIS0208.TXT" do
6
+ sh "curl -O ftp://ftp.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/JIS0208.TXT"
7
+ end
8
+
9
+ desc "Run unit test"
10
+ task :check => "jis0208_test.rb" do |t|
11
+ sh "ruby #{t.source}"
5
12
  end
6
13
 
7
- task :default => 'JIS0208.TXT'
14
+ task default: :check
8
15
 
9
- CLOBBER.include('JIS0208.TXT')
16
+ CLOBBER.include("JIS0208.TXT")
@@ -1,23 +1,46 @@
1
- #!/usr/bin/ruby
2
- # test character classes on ASCII characters.
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Categorize ASCII characters by character classes
3
5
  # 2003-03-10 Hisashi MORITA
4
6
 
5
- charclasses = ["[:cntrl:]",
6
- "[:space:]", "[:blank:]",
7
- "[:digit:]",
8
- "[:alpha:]", "[:alnum:]",
9
- "[:punct:]",
10
- "[:lower:]", "[:upper:]",
11
- "[:print:]", "[:graph:]",
12
- "[:xdigit:]"]
13
- chars = (0x00 .. 0xff).to_a
7
+ charclasses = [
8
+ "[:cntrl:]",
9
+ "[:space:]",
10
+ "[:blank:]",
11
+ "[:digit:]",
12
+ "[:alpha:]",
13
+ "[:alnum:]",
14
+ "[:punct:]",
15
+ "[:lower:]",
16
+ "[:upper:]",
17
+ "[:print:]",
18
+ "[:graph:]",
19
+ "[:xdigit:]",
20
+ ]
21
+
22
+ chars = (0x00..0xff).to_a
23
+
24
+ result =
25
+ charclasses.map do |charclass|
26
+ charclass_re = /[#{charclass}]/
27
+ member_chars =
28
+ chars.reduce([]) do |acc, char|
29
+ if charclass_re.match([char].pack("C*"))
30
+ acc << char
31
+ else
32
+ acc
33
+ end
34
+ end
35
+ member_chars_in_hex =
36
+ member_chars.map { |char| format("\\x%02x", char) }.join
37
+ member_chars_packed =
38
+ member_chars.map { |char| [char].pack("C*").inspect[1..-2] }.join
39
+
40
+ <<~EOS
41
+ #{charclass}\t#{member_chars_in_hex}
42
+ \t\t(#{member_chars_packed})
43
+ EOS
44
+ end
14
45
 
15
- charclasses.each{|charclass|
16
- member_chars = []
17
- chars.each{|char|
18
- if Regexp.new("[#{charclass}]") =~ char.to_a.pack("C*")
19
- member_chars.push char
20
- end
21
- }
22
- puts "#{charclass}\t#{member_chars.collect{|char|sprintf("\\x%02x", char)}.join}\n\t\t(#{member_chars.collect{|char|char.to_a.pack('C*').inspect[1..-2]}.join})"
23
- }
46
+ puts result
@@ -1,21 +1,42 @@
1
- #!/usr/bin/ruby
2
- # test character classes on ASCII characters.
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # List ASCII characters with matching character classes
3
5
  # 2003-03-10 Hisashi MORITA
4
6
 
5
- charclasses = ["[:cntrl:]",
6
- "[:space:]", "[:blank:]",
7
- "[:digit:]",
8
- "[:alpha:]", "[:alnum:]",
9
- "[:punct:]",
10
- "[:lower:]", "[:upper:]",
11
- "[:print:]", "[:graph:]",
12
- "[:xdigit:]"]
13
- (0x00 .. 0xff).to_a.each{|char|
14
- attribute = []
15
- charclasses.each{|charclass|
16
- if Regexp.new("[#{charclass}]") =~ char.to_a.pack("C*")
17
- attribute.push charclass
18
- end
19
- }
20
- puts "#{sprintf("\\x%02x", char)} (#{char.to_a.pack('C*').inspect})\t#{attribute.join(', ')}"
21
- }
7
+ charclasses = [
8
+ "[:cntrl:]",
9
+ "[:space:]",
10
+ "[:blank:]",
11
+ "[:digit:]",
12
+ "[:alpha:]",
13
+ "[:alnum:]",
14
+ "[:punct:]",
15
+ "[:lower:]",
16
+ "[:upper:]",
17
+ "[:print:]",
18
+ "[:graph:]",
19
+ "[:xdigit:]",
20
+ ]
21
+
22
+ chars = (0x00..0xff).to_a
23
+
24
+ result =
25
+ chars.map do |char|
26
+ char_packed = [char].pack("C*")
27
+ attribute =
28
+ charclasses.reduce([]) do |acc, charclass|
29
+ if /[#{charclass}]/.match(char_packed)
30
+ acc << charclass
31
+ else
32
+ acc
33
+ end
34
+ end
35
+ hex = format("\\x%02x", char)
36
+ packed_string = [char].pack("C*").inspect
37
+ attributes = attribute.join(", ")
38
+
39
+ "#{hex} (#{packed_string})\t#{attributes}"
40
+ end
41
+
42
+ puts result