obp-access 0.1.2 → 0.1.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: 2c24712820162a6dab6e7bca8d6df7f58635fcb07866b239e104092f94c8c813
4
- data.tar.gz: c724572b57754c8f1d4804c038b6a8664c34bf8bd6e2b9228c440b192be05368
3
+ metadata.gz: 3b3fda155513c49b50f81b401262456e78f63e55fb0ced23f8a54bf4577ee0af
4
+ data.tar.gz: 75070c8db35ae812f69f19bb55e536c9c9b3da5ec29a5846bd9d9cd53e6d5f2a
5
5
  SHA512:
6
- metadata.gz: 9216dfe8b1881f9cdf299b472c8de1ae061ddeb8b7ffcb9f5c8bf793c44342e6f768e8d99497644eee8ca61f8f610b0a4dd961dda23294859710ae80d7dda2cf
7
- data.tar.gz: ffdb6ac594b50d198b2d5d55e45fbf14dde2f148c17829b0cb6ea9a30134ee584a6b81597ffd589d8fad37ce348a5efc62ba82d47a9c8c544ebb01fad83e2451
6
+ metadata.gz: fcf54d0abc492eae8542e14e3313199be54bce5eb45fd454996a3c69dc8d5c7641a8a4bd58bbde701320c142d051ab186441b4ce47d39f47dba1774d6b329562
7
+ data.tar.gz: c19c3f486740f899e6e0ecad8479f78f34a7c9cf3cad8638c2eb5344408a2047e3f6f8e7222e31ea57ac7e1c79047709466c23795872c6bf238e8b076a31e77f
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-05-12 09:41:56 UTC using RuboCop version 1.86.1.
3
+ # on 2026-06-15 08:31:30 UTC using RuboCop version 1.86.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -11,23 +11,9 @@ Gemspec/RequiredRubyVersion:
11
11
  Exclude:
12
12
  - 'obp-access.gemspec'
13
13
 
14
- # Offense count: 1
15
- # This cop supports safe autocorrection (--autocorrect).
16
- # Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
17
- # URISchemes: http, https
18
- Layout/LineLength:
19
- Max: 124
20
-
21
14
  # Offense count: 3
22
15
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
23
16
  Metrics/AbcSize:
24
17
  Exclude:
25
18
  - 'lib/obp/access/elements/bibliography/bib_ref.rb'
26
19
  - 'lib/obp/access/elements/root.rb'
27
-
28
- # Offense count: 1
29
- # This cop supports safe autocorrection (--autocorrect).
30
- # Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
31
- # URISchemes: http, https
32
- Layout/LineLength:
33
- Max: 124
data/README.adoc CHANGED
@@ -82,7 +82,7 @@ $ obp-access fetch -l fr,de -o output/ iso:std:iso:5598:ed-3:v1:en
82
82
  The output is NISO STS XML with TBX-Basic terminology markup:
83
83
 
84
84
  * Terms use `<tbx:termEntry>` with `<tbx:langSet>` per language
85
- * Grammar is encoded via `<tbx:gram>` (gender: m/f/n) and `<tbx:partOfSpeech>`
85
+ * Grammar is encoded via `<tbx:grammaticalGender>` (values: masculine/feminine/neuter) and `<tbx:partOfSpeech>`
86
86
  * Domains are extracted as `<tbx:subjectField>`
87
87
  * Deprecated terms use `<tbx:normativeAuthorization value="deprecatedTerm"/>`
88
88
 
@@ -8,7 +8,7 @@ module Obp
8
8
  end
9
9
 
10
10
  def match_node?
11
- super && node.css("img").any?
11
+ super && node.css("img").one?
12
12
  end
13
13
 
14
14
  private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Obp
2
4
  class Access
3
5
  class Renderer
@@ -16,29 +18,30 @@ module Obp
16
18
  def content
17
19
  Nokogiri::XML::Builder.new do |xml|
18
20
  xml.public_send(:"fig-group") do
19
- render_caption(xml, node)
21
+ render_caption_from(xml, node)
20
22
  node.css("img").each { |img| render_figure(xml, img) }
21
23
  end
22
24
  end
23
25
  end
24
26
 
25
- def render_caption(xml, children)
26
- xml.label children.at(".sts-caption-label").content
27
- xml.caption do
28
- xml.title children.at(".sts-caption-title").content
29
- end
30
- end
31
-
32
27
  def render_figure(xml, img)
33
28
  xml.fig do
34
- div = img.previous
35
- xml.label div.at(".sts-caption-label").content
36
- xml.caption do
37
- xml.title div.at(".sts-caption-title").content
38
- end
29
+ # OBP HTML often places no caption between grouped imgs; guard accordingly.
30
+ render_caption_from(xml, img.previous_element) if img.previous_element
39
31
  xml.graphic("xlink:href": local_image_path(img))
40
32
  end
41
33
  end
34
+
35
+ def render_caption_from(xml, source)
36
+ label = source&.at(".sts-caption-label")
37
+ title = source&.at(".sts-caption-title")
38
+ xml.label label.content if label
39
+ return unless title
40
+
41
+ xml.caption do
42
+ xml.title title.content
43
+ end
44
+ end
42
45
  end
43
46
  end
44
47
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Obp
2
4
  class Access
3
5
  class Renderer
@@ -15,10 +17,6 @@ module Obp
15
17
  def path_suffix
16
18
  "/tbx:termEntry/tbx:langSet"
17
19
  end
18
-
19
- def bold_term?(node)
20
- node.inner_html.start_with?("<b>") || node.inner_html.include?("<b>")
21
- end
22
20
  end
23
21
  end
24
22
  end
@@ -1,9 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Obp
2
4
  class Access
3
5
  class Renderer
4
6
  class Elements
5
7
  class Terminology
6
8
  class Tig < Base
9
+ NORMATIVE_AUTHORIZATION = "preferredTerm"
10
+
7
11
  def self.classes
8
12
  %w[sts-tbx-term]
9
13
  end
@@ -11,15 +15,16 @@ module Obp
11
15
  private
12
16
 
13
17
  def id
14
- node.parent.at_css("div.sts-tbx-label").text.strip
18
+ node.parent.at_css("div.sts-tbx-label")&.text&.strip || ""
15
19
  end
16
20
 
17
21
  def index
18
- node.path.match(/\[(\d+)\](?=\z)/)[1].to_i - 1
22
+ match = node.path.match(/\[(\d+)\](?=\z)/)
23
+ match ? match[1].to_i - 1 : 0
19
24
  end
20
25
 
21
26
  def normative_authorization
22
- bold_term?(node) ? "admittedTerm" : "preferredTerm"
27
+ self.class::NORMATIVE_AUTHORIZATION
23
28
  end
24
29
 
25
30
  def content
@@ -46,7 +51,7 @@ module Obp
46
51
  return unless genders.any?
47
52
 
48
53
  genders.each do |gender|
49
- xml.public_send(:"tbx:gram", value: gender, type: "gender")
54
+ xml.public_send(:"tbx:grammaticalGender", value: gender)
50
55
  end
51
56
  end
52
57
  end
@@ -1,18 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Obp
2
4
  class Access
3
5
  class Renderer
4
6
  class Elements
5
7
  class Terminology
6
8
  class TigAdmitted < Tig
9
+ NORMATIVE_AUTHORIZATION = "admittedTerm"
10
+
7
11
  def self.classes
8
12
  %w[sts-tbx-term admittedTerm]
9
13
  end
10
-
11
- private
12
-
13
- def normative_authorization
14
- "admittedTerm"
15
- end
16
14
  end
17
15
  end
18
16
  end
@@ -1,27 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Obp
2
4
  class Access
3
5
  class Renderer
4
6
  class Elements
5
7
  class Terminology
6
8
  class TigDeprecated < Tig
9
+ NORMATIVE_AUTHORIZATION = "deprecatedTerm"
10
+
7
11
  def self.classes
8
12
  %w[sts-tbx-term deprecatedTerm]
9
13
  end
10
14
 
11
15
  private
12
16
 
13
- def normative_authorization
14
- "deprecatedTerm"
15
- end
16
-
17
- def content
18
- Nokogiri::XML::Builder.new do |xml|
19
- xml.public_send(:"tbx:tig", id: "term_#{id}-#{index}") do
20
- render_tig_content(xml)
21
- end
22
- end
23
- end
24
-
25
17
  def parsed_html
26
18
  strip_deprecation_label(node.inner_html)
27
19
  end
@@ -1,18 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Obp
2
4
  class Access
3
5
  class Renderer
4
6
  class Elements
5
7
  class Terminology
6
8
  class TigPreferred < Tig
9
+ NORMATIVE_AUTHORIZATION = "preferredTerm"
10
+
7
11
  def self.classes
8
12
  %w[sts-tbx-term preferredTerm]
9
13
  end
10
-
11
- private
12
-
13
- def normative_authorization
14
- "preferredTerm"
15
- end
16
14
  end
17
15
  end
18
16
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Obp
2
4
  class Access
3
5
  class GrammarParser
@@ -9,18 +11,22 @@ module Obp
9
11
  "verb" => "verb",
10
12
  }.freeze
11
13
 
12
- GENDER_VALUES = %w[m f n].freeze
14
+ GENDER_MAP = {
15
+ "m" => "masculine",
16
+ "f" => "feminine",
17
+ "n" => "neuter",
18
+ }.freeze
13
19
 
14
20
  BOLD_PATTERNS = [
15
21
  [->(t) { POS_MAP.key?(t) }, :handle_pos_marker],
16
- [->(t) { GENDER_VALUES.include?(t) }, :handle_gender_marker],
22
+ [->(t) { GENDER_MAP.key?(t) }, :handle_gender_marker],
17
23
  [->(t) { t.match?(/\A[mfn],\z/) }, :handle_gender_with_comma],
18
24
  [->(t) { t.match?(/\A[mfn][,\s]+[mfn]([,\s]+[mfn])*\z/) }, :handle_multi_gender],
19
25
  [->(t) { t == "," }, :handle_comma],
20
- [->(t) { t == "〈" }, :handle_enter_bracket],
21
- [->(t) { t == "〉" }, :handle_exit_bracket],
22
- [->(t) { t.match?(/\A[mfn]\s+/) }, :handle_gender_qualifier],
23
- [->(t) { t.match?(/,.+[mfn]\z/) }, :handle_term_with_gender],
26
+ [->(t) { t == "〈" }, :handle_enter_bracket],
27
+ [->(t) { t == "〉" }, :handle_exit_bracket],
28
+ [->(t) { t.match?(/\A[mfn]\s+/) }, :handle_gender_qualifier],
29
+ [->(t) { t.match?(/,.+[mfn]\z/) }, :handle_term_with_gender],
24
30
  ].freeze
25
31
 
26
32
  def self.parse(inner_html)
@@ -60,15 +66,15 @@ module Obp
60
66
  end
61
67
 
62
68
  def handle_gender_marker(text, state)
63
- state[:genders] << text.strip
69
+ add_gender(state, text.strip)
64
70
  end
65
71
 
66
72
  def handle_gender_with_comma(text, state)
67
- state[:genders] << text.strip[0]
73
+ add_gender(state, text.strip[0])
68
74
  end
69
75
 
70
76
  def handle_multi_gender(text, state)
71
- text.strip.scan(/[mfn]/).each { |g| state[:genders] << g }
77
+ text.strip.scan(/[mfn]/).each { |code| add_gender(state, code) }
72
78
  end
73
79
 
74
80
  def handle_enter_bracket(_text, state)
@@ -80,14 +86,14 @@ module Obp
80
86
  end
81
87
 
82
88
  def handle_gender_qualifier(text, state)
83
- state[:genders] << text.strip[0]
89
+ add_gender(state, text.strip[0])
84
90
  end
85
91
 
86
92
  def handle_term_with_gender(text, state)
87
93
  stripped = text.strip
88
94
  if stripped =~ /\A(.+),\s*([mfn])\z/
89
- state[:term_parts] << $1.strip
90
- state[:genders] << $2
95
+ state[:term_parts] << Regexp.last_match(1).strip
96
+ add_gender(state, Regexp.last_match(2))
91
97
  else
92
98
  state[:term_parts] << stripped
93
99
  end
@@ -105,6 +111,10 @@ module Obp
105
111
 
106
112
  def handle_skip(_text, _state); end
107
113
 
114
+ def add_gender(state, code)
115
+ state[:genders] << GENDER_MAP.fetch(code)
116
+ end
117
+
108
118
  def parse_segments(html)
109
119
  segments = []
110
120
  remaining = html.dup
@@ -1,5 +1,5 @@
1
1
  module Obp
2
2
  class Access
3
- VERSION = "0.1.2".freeze
3
+ VERSION = "0.1.4".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: obp-access
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-12 00:00:00.000000000 Z
11
+ date: 2026-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri