engtagger 0.4.3 → 0.4.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 688eb41815586b529212a5451966f0cb2a1f4027c8aeb1c949fb437f1c8e5b4a
4
- data.tar.gz: 1c7eea0dccc4c52133506220861c3ccce512d84f75df10060419dce5d24dfb8f
3
+ metadata.gz: 9c5c2c223bf80febf6a9130399b5d2a54dbdb043b0c9964289d98863d38572ce
4
+ data.tar.gz: 02ddd1ddee60893ffbd9ae686b382238ef99f6487b7eca38448cae39ec8f5c15
5
5
  SHA512:
6
- metadata.gz: 3e5d673b7dd49cbe468c915e247f7d7e6b13002dc1b67e4e98c4e2d9066165f6cc6e0426d1393ff2711a4fb9df1294e44e9dbfc4c89e2b685b32a49482cd68c6
7
- data.tar.gz: 609562c6c5cc2ea37762ff27e16a8689d569389eb9bf31af413d702e421a78d47acc8bdf993a1acffdce19631c565ca3452f371936f005e395db7f930933695e
6
+ metadata.gz: 91f5bfaee891d1c455e1a361ccd556714708d60a7c66e3ae0a24780cf2ce66c2fc975433da5b053453444701299b523254ba47bf89e62786368e6ae95300cc42
7
+ data.tar.gz: 8af44f088a545afe81b23009d77cd119949b27e027fdcee13344f68667768f2fd12a5eb89de189ae46ed5cc6f15a30acdcf2e07964b0efad0bc89664f79f1db0
data/.gitattributes ADDED
@@ -0,0 +1,4 @@
1
+ # Packaging reads the working tree (gemspec uses `git ls-files`), so a
2
+ # checkout that rewrites line endings would ship a corrupted model or lexicon.
3
+ *.etm.gz binary
4
+ *.hash binary
data/.gitignore CHANGED
@@ -16,3 +16,6 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  /.idea
19
+ experiments/
20
+
21
+ .DS_Store
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@ AllCops:
3
3
  SuggestExtensions: false
4
4
  TargetRubyVersion: 2.6
5
5
 
6
- Documentation:
6
+ Style/Documentation:
7
7
  Enabled: false
8
8
 
9
9
  Naming/AccessorMethodName:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.4 (2026-08-14)
4
+
5
+ This is the final planned release of the 0.4 line. Version 2.0 replaces the
6
+ HMM engine with an averaged perceptron and does not ship the Penn
7
+ Treebank-derived probability tables, so its tagging output differs. Pin
8
+ `gem "engtagger", "~> 0.4"` to stay on this line; it will receive critical
9
+ fixes only.
10
+
11
+ - Fix the test suite silently rewriting the bundled lexicon files
12
+ (`lib/engtagger/*.hash`) on every run: a path-join bug in the test setup made
13
+ the existence check always fail, so `install` ran before each test. This was
14
+ also the enabler of the 0600-permission contamination behind #20. Tests are
15
+ ~6x faster as a result.
16
+ - `get_sentences` now applies its intended punctuation cleanup. Four of its
17
+ five reattachment rules had discarded their results since the original port
18
+ (only the leading-backquote rule was ever applied), and their regexes were
19
+ corrupted by string escaping (`\W` matched a literal "W"). Sentences returned
20
+ by this method now read naturally (`"Lisa Raines, a lawyer,"`,`"$3"`).
21
+ Known limitation carried over from the tokenizer: contractions other than
22
+ possessives remain space-separated (`"I 'm"`, `"is n't"`).
23
+ - Fix the public `WORD` constant, whose regex was corrupted by the same
24
+ escaping problem and matched only `<w>`-style tags.
25
+ - Tag regexes produced by `EngTagger.get_ext` (NUM, NN, SEN, etc.) now end with
26
+ a real `\s*`, so they consume trailing whitespace including newlines instead
27
+ of spaces only.
28
+ - `assign_tag` no longer raises `NoMethodError` for words absent from the
29
+ lexicon; it returns `""` so callers fall back to `"nn"` as designed.
30
+ - `EngTagger::VERSION` is now defined at runtime (`engtagger/version` was not
31
+ required by the library itself).
32
+ - Read and write the Marshal lexicon files in binary mode to avoid corruption
33
+ on Windows.
34
+ - Remove the stray shebang and executable bit from `lib/engtagger.rb`, and the
35
+ obsolete `require "rubygems"`.
36
+ - Clarify licensing: the LICENSE file had a stray MIT license appended after
37
+ the GPLv2 text. The library is licensed as GPL-2.0-or-later; the MIT tail has
38
+ been removed and the gemspec now declares the SPDX identifier.
39
+ - Gemspec: use the https homepage URL, add `metadata` URIs, and drop the
40
+ obsolete `test_files`.
41
+ - Fix a dead test (`text_get_ext` typo) that had never run and would have
42
+ failed if enabled.
43
+ - Note in the README that 0.4.x carries Penn Treebank-derived probability
44
+ tables; 2.x is trained on openly licensed data instead.
45
+
3
46
  ## 0.4.3
4
47
 
5
48
  - Fix gem packaging that produced files with owner-only (0600) permissions,
data/Gemfile CHANGED
@@ -5,5 +5,6 @@ source "https://rubygems.org"
5
5
  gemspec
6
6
 
7
7
  gem "rake"
8
+ gem "rubocop", require: false
8
9
  gem "sin_lru_redux"
9
10
  gem "test-unit"
data/LICENSE CHANGED
@@ -338,25 +338,3 @@ proprietary programs. If your program is a subroutine library, you may
338
338
  consider it more useful to permit linking proprietary applications with the
339
339
  library. If this is what you want to do, use the GNU Library General
340
340
  Public License instead of this License.
341
- Copyright (c) 2012 Yoichiro Hasebe
342
-
343
- MIT License
344
-
345
- Permission is hereby granted, free of charge, to any person obtaining
346
- a copy of this software and associated documentation files (the
347
- "Software"), to deal in the Software without restriction, including
348
- without limitation the rights to use, copy, modify, merge, publish,
349
- distribute, sublicense, and/or sell copies of the Software, and to
350
- permit persons to whom the Software is furnished to do so, subject to
351
- the following conditions:
352
-
353
- The above copyright notice and this permission notice shall be
354
- included in all copies or substantial portions of the Software.
355
-
356
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
357
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
358
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
359
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
360
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
361
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
362
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -174,4 +174,8 @@ Aaron Coburn, the author of the original Perl version.
174
174
 
175
175
  ## License
176
176
 
177
- This library is distributed under the GPL. Please see the LICENSE file.
177
+ This library is distributed under the GPL (GPL-2.0-or-later). Please see the LICENSE file.
178
+
179
+ The 0.4 line ships probability tables derived from the Penn Treebank. Version
180
+ 2.0 drops them in favour of a model trained on openly licensed corpora; if the
181
+ provenance of the bundled data matters for your use, prefer 2.x.
data/engtagger.gemspec CHANGED
@@ -7,16 +7,29 @@ Gem::Specification.new do |gem|
7
7
  gem.email = ["yohasebe@gmail.com"]
8
8
  gem.summary = "A probability based, corpus-trained English POS tagger"
9
9
  gem.description = "A Ruby port of Perl Lingua::EN::Tagger, a probability based, corpus-trained tagger that assigns POS tags to English text based on a lookup dictionary and a set of probability values."
10
- gem.homepage = "http://github.com/yohasebe/engtagger"
11
- gem.license = "GPL"
10
+ gem.homepage = "https://github.com/yohasebe/engtagger"
11
+ gem.license = "GPL-2.0-or-later"
12
12
  gem.required_ruby_version = Gem::Requirement.new(">= 2.6")
13
13
  gem.files = Dir.chdir(File.expand_path(__dir__)) do
14
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
14
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|tools|docs)/}) }
15
15
  end
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
17
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
17
  gem.name = "engtagger"
18
+ gem.metadata = {
19
+ "source_code_uri" => "https://github.com/yohasebe/engtagger",
20
+ "changelog_uri" => "https://github.com/yohasebe/engtagger/blob/master/CHANGELOG.md",
21
+ "bug_tracker_uri" => "https://github.com/yohasebe/engtagger/issues"
22
+ }
19
23
  gem.require_paths = ["lib"]
20
24
  gem.version = EngTagger::VERSION
21
25
  gem.add_dependency "sin_lru_redux"
26
+ gem.post_install_message = <<~MESSAGE
27
+ EngTagger 0.4.4 is the final planned release of the 0.4 line.
28
+
29
+ Version 2.0 replaces the HMM engine with an averaged perceptron trained on
30
+ openly licensed data. It is considerably more accurate, and its tagging
31
+ output differs, so treat it as a rewrite rather than an upgrade.
32
+
33
+ To stay on this line, pin it: gem "engtagger", "~> 0.4"
34
+ MESSAGE
22
35
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class EngTagger
4
- VERSION = "0.4.3"
4
+ VERSION = "0.4.4"
5
5
  end
data/lib/engtagger.rb CHANGED
@@ -1,10 +1,8 @@
1
- #!/usr/bin/env ruby
2
-
3
1
  # frozen_string_literal: true
4
2
 
5
- require "rubygems"
6
3
  require "lru_redux"
7
- require_relative "./engtagger/porter"
4
+ require_relative "engtagger/version"
5
+ require_relative "engtagger/porter"
8
6
 
9
7
  module BoundedSpaceMemoizable
10
8
  def memoize(method, max_cache_size = 100_000)
@@ -52,7 +50,7 @@ class EngTagger
52
50
  def self.get_ext(tag = nil)
53
51
  return nil unless tag
54
52
 
55
- Regexp.new("<#{tag}>[^<]+</#{tag}>\s*")
53
+ Regexp.new("<#{tag}>[^<]+</#{tag}>\\s*")
56
54
  end
57
55
 
58
56
  # Regexps to match XML-style part-of-speech tags
@@ -66,7 +64,7 @@ class EngTagger
66
64
  PAREN = get_ext("[lr]rb")
67
65
  QUOT = get_ext("ppr")
68
66
  SEN = get_ext("pp")
69
- WORD = get_ext("\w+")
67
+ WORD = get_ext("\\w+")
70
68
  VB = get_ext("vb")
71
69
  VBG = get_ext("vbg")
72
70
  VBD = get_ext("vbd")
@@ -97,7 +95,7 @@ class EngTagger
97
95
  TAGS[tag] || tag
98
96
  end
99
97
 
100
- # The folloging is to make a hash to convert a pos tag to its definition
98
+ # The following is to make a hash to convert a pos tag to its definition
101
99
  # used by the explain_tag method
102
100
  tags = [
103
101
  "CC", "Conjunction, coordinating",
@@ -157,7 +155,7 @@ class EngTagger
157
155
  # => (Boolean) Stem single words using Porter module
158
156
  # * :weight_noun_phrases
159
157
  # => (Boolean) When returning occurrence counts for a noun phrase, multiply
160
- # the valuethe number of words in the NP.
158
+ # the value by the number of words in the NP.
161
159
  # * :longest_noun_phrase
162
160
  # => (Integer) Will ignore noun phrases longer than this threshold. This
163
161
  # affects only the get_words() and get_nouns() methods.
@@ -200,7 +198,7 @@ class EngTagger
200
198
  @conf[:word_path] = DEFAULT_WORDPATH
201
199
  @conf[:tag_path] = DEFAULT_TAGPATH
202
200
  @conf[:debug] = false
203
- # assuming that we start analyzing from the beginninga new sentence...
201
+ # assuming that we start analyzing from the beginning of a new sentence...
204
202
  @conf[:current_tag] = "pp"
205
203
  @conf.merge!(params) if params
206
204
  if !File.exist?(@conf[:word_path]) || !File.exist?(@conf[:tag_path])
@@ -208,10 +206,10 @@ class EngTagger
208
206
  @@hmm = {}
209
207
  @@lexicon = {}
210
208
  else
211
- lexf = File.open(@conf[:word_path], "r")
209
+ lexf = File.open(@conf[:word_path], "rb")
212
210
  @@lexicon = Marshal.load(lexf)
213
211
  lexf.close
214
- hmmf = File.open(@conf[:tag_path], "r")
212
+ hmmf = File.open(@conf[:tag_path], "rb")
215
213
  @@hmm = Marshal.load(hmmf)
216
214
  hmmf.close
217
215
  end
@@ -304,12 +302,16 @@ class EngTagger
304
302
  tagged.split(%r{</pp>}).each do |line|
305
303
  sentences << strip_tags(line)
306
304
  end
307
- sentences = sentences.map do |sentence|
308
- sentence.gsub(Regexp.new(" ('s?) ")) { $1 + " " }
309
- sentence.gsub(Regexp.new(" (\W+) ")) { $1 + " " }
310
- sentence.gsub(Regexp.new(" (`+) ")) { " " + $1 }
311
- sentence.gsub(Regexp.new(" (\W+)$")) { $1 }
312
- sentence.gsub(Regexp.new("^(`+) ")) { $1 }
305
+ sentences.map do |sentence|
306
+ # Reattach punctuation to the neighboring word: opening quotes/brackets
307
+ # and currency signs join the following word, everything else (commas,
308
+ # closing marks, possessives) joins the preceding word. (These gsub
309
+ # results used to be discarded, so none of this cleanup was applied.)
310
+ sentence.gsub(/ ('s?) /) { "#{$1} " }
311
+ .gsub(/ ([`(\[{$]+) /) { " #{$1}" }
312
+ .gsub(/ ([^\w\s`(\[{$]+) /) { "#{$1} " }
313
+ .gsub(/ ([^\w\s]+)\z/) { $1 }
314
+ .gsub(/\A([`(\[{$]+) /) { $1 }
313
315
  end
314
316
  end
315
317
 
@@ -360,7 +362,7 @@ class EngTagger
360
362
  build_matches_hash(build_trimmed(tagged, tags))
361
363
  end
362
364
 
363
- # Returns all types of verbs and does not descriminate between the
365
+ # Returns all types of verbs and does not discriminate between the
364
366
  # various kinds. Combines all other verb methods listed in this
365
367
  # class.
366
368
  #
@@ -588,10 +590,10 @@ class EngTagger
588
590
  load_tags(@conf[:tag_lex])
589
591
  load_words(@conf[:word_lex])
590
592
  load_words(@conf[:unknown_lex])
591
- File.open(@conf[:word_path], "w") do |f|
593
+ File.open(@conf[:word_path], "wb") do |f|
592
594
  Marshal.dump(@@lexicon, f)
593
595
  end
594
- File.open(@conf[:tag_path], "w") do |f|
596
+ File.open(@conf[:tag_path], "wb") do |f|
595
597
  Marshal.dump(@@hmm, f)
596
598
  end
597
599
  end
@@ -635,7 +637,7 @@ class EngTagger
635
637
  @conf[:stem] ? word.stem : word
636
638
  end
637
639
 
638
- # This method will reset the preceeding tag to a sentence ender (PP).
640
+ # This method will reset the preceding tag to a sentence ender (PP).
639
641
  # This prepares the first word of a new sentence to be tagged correctly.
640
642
  def reset
641
643
  @conf[:current_tag] = "pp"
@@ -705,7 +707,7 @@ class EngTagger
705
707
  end
706
708
  words = []
707
709
  tokenized.each_with_index do |_, i|
708
- if tokenized[i + 1] && tokenized [i + 1] =~ /[A-Z\W]/ && tokenized[i] =~ /\A(.+)\.\z/
710
+ if tokenized[i + 1] && tokenized[i + 1] =~ /[A-Z\W]/ && tokenized[i] =~ /\A(.+)\.\z/
709
711
  w = $1
710
712
  # Don't separate the period off words that
711
713
  # meet any of the following conditions:
@@ -772,13 +774,13 @@ class EngTagger
772
774
  return "sym"
773
775
  end
774
776
  best_so_far = 0
775
- w = @@lexicon[word]
777
+ w = @@lexicon[word] || {}
776
778
  t = @@hmm
777
779
 
778
780
  # TAG THE TEXT: What follows is a modified version of the Viterbi algorithm
779
781
  # which is used in most POS taggers
780
782
  best_tag = ""
781
- t[prev_tag].each_key do |tag|
783
+ (t[prev_tag] || {}).each_key do |tag|
782
784
  # With @config[:relax] set, this method
783
785
  # will also include any `open classes' of POS tags
784
786
  pw = 0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: engtagger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoichiro Hasebe
@@ -32,6 +32,7 @@ executables: []
32
32
  extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
+ - ".gitattributes"
35
36
  - ".gitignore"
36
37
  - ".rubocop.yml"
37
38
  - ".solargraph.yml"
@@ -50,10 +51,21 @@ files:
50
51
  - lib/engtagger/unknown.yml
51
52
  - lib/engtagger/version.rb
52
53
  - lib/engtagger/words.yml
53
- homepage: http://github.com/yohasebe/engtagger
54
+ homepage: https://github.com/yohasebe/engtagger
54
55
  licenses:
55
- - GPL
56
- metadata: {}
56
+ - GPL-2.0-or-later
57
+ metadata:
58
+ source_code_uri: https://github.com/yohasebe/engtagger
59
+ changelog_uri: https://github.com/yohasebe/engtagger/blob/master/CHANGELOG.md
60
+ bug_tracker_uri: https://github.com/yohasebe/engtagger/issues
61
+ post_install_message: |
62
+ EngTagger 0.4.4 is the final planned release of the 0.4 line.
63
+
64
+ Version 2.0 replaces the HMM engine with an averaged perceptron trained on
65
+ openly licensed data. It is considerably more accurate, and its tagging
66
+ output differs, so treat it as a rewrite rather than an upgrade.
67
+
68
+ To stay on this line, pin it: gem "engtagger", "~> 0.4"
57
69
  rdoc_options: []
58
70
  require_paths:
59
71
  - lib