metanorma-plugin-glossarist 0.3.10 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e98a4e95056510d3c6071f7c46e4bd378b2898e7fa75b44e14d5ca423efc4ca
4
- data.tar.gz: ebbf812935c1fb98b523675892813de831c1ec87d152d0de78d1fd9103d6342d
3
+ metadata.gz: b7f273c4d3190131198e62d21b17f06ba86cba920e649b148f6eb5b739382b5b
4
+ data.tar.gz: 9d6341ea4819346714bc9bd8432f4a43f308a6b66fbb16e1783a9c19a3280fbe
5
5
  SHA512:
6
- metadata.gz: 99d6b54e76a006d51f7f657e5d408139e0dbcb1af14545f17d8f08f157d7c197c52a88934c84238560d5860dc0131fe78b4b4933c155934aea11410239a8cf6e
7
- data.tar.gz: 34f5d1c25bb615c2a2a3efdac7710b9dd8e06d0c98c4f63bc4f8846475a952715fdf2269ca4dbc970a9bd5e0bdc17327f9f8204ef2c3a5ba42ed30a75d299747
6
+ metadata.gz: 4432be1f049b3c52f6ae6473189adac86b65f9d14c2b20929b0974016398bc7e8032a4e82649c4dcbbbb9e16b88e943d999f14441c1fbca2a0e4b34e4ceb32c5
7
+ data.tar.gz: 10a9aa8898e1e7d0cef5af135a515c0b3c53c1edbe97844adb9446c253293d24d6540be35460edc46f64167b06b86fc75a85e876f7dfa424b31ff559ce046a33
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-06-13 04:20:36 UTC using RuboCop version 1.86.1.
3
+ # on 2026-07-05 06:01:54 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,106 +11,41 @@ Gemspec/RequiredRubyVersion:
11
11
  Exclude:
12
12
  - 'metanorma-plugin-glossarist.gemspec'
13
13
 
14
- # Offense count: 2
15
- # This cop supports safe autocorrection (--autocorrect).
16
- # Configuration parameters: EnforcedStyle, IndentationWidth.
17
- # SupportedStyles: with_first_argument, with_fixed_indentation
18
- Layout/ArgumentAlignment:
19
- Exclude:
20
- - 'lib/metanorma/plugin/glossarist/concept_path_resolver.rb'
21
- - 'spec/metanorma/plugin/glossarist/section_spec.rb'
22
-
23
- # Offense count: 1
24
- # This cop supports safe autocorrection (--autocorrect).
25
- # Configuration parameters: EnforcedStyleAlignWith.
26
- # SupportedStylesAlignWith: either, start_of_block, start_of_line
27
- Layout/BlockAlignment:
28
- Exclude:
29
- - 'spec/metanorma/plugin/glossarist/section_spec.rb'
30
-
31
- # Offense count: 1
32
- # This cop supports safe autocorrection (--autocorrect).
33
- Layout/BlockEndNewline:
34
- Exclude:
35
- - 'spec/metanorma/plugin/glossarist/section_spec.rb'
36
-
37
- # Offense count: 2
38
- # This cop supports safe autocorrection (--autocorrect).
39
- # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
40
- # SupportedHashRocketStyles: key, separator, table
41
- # SupportedColonStyles: key, separator, table
42
- # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
43
- Layout/HashAlignment:
44
- Exclude:
45
- - 'spec/metanorma/plugin/glossarist/section_spec.rb'
46
-
47
- # Offense count: 2
48
- # This cop supports safe autocorrection (--autocorrect).
49
- # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
50
- # SupportedStylesAlignWith: start_of_line, relative_to_receiver
51
- Layout/IndentationWidth:
52
- Exclude:
53
- - 'spec/metanorma/plugin/glossarist/section_spec.rb'
54
-
55
- # Offense count: 32
14
+ # Offense count: 37
56
15
  # This cop supports safe autocorrection (--autocorrect).
57
16
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
58
17
  # URISchemes: http, https
59
18
  Layout/LineLength:
60
- Exclude:
61
- - 'lib/metanorma-plugin-glossarist.rb'
62
- - 'lib/metanorma/plugin/glossarist/concept_path_resolver.rb'
63
- - 'lib/metanorma/plugin/glossarist/dataset_preprocessor.rb'
64
- - 'lib/metanorma/plugin/glossarist/liquid.rb'
65
- - 'lib/metanorma/plugin/glossarist/liquid/custom_blocks/with_glossarist_context.rb'
66
- - 'lib/metanorma/plugin/glossarist/liquid/drop_bracket_access.rb'
67
- - 'lib/metanorma/plugin/glossarist/liquid/drops/managed_concept_data_drop.rb'
68
- - 'lib/metanorma/plugin/glossarist/section_filter.rb'
69
- - 'spec/metanorma/plugin/glossarist/bibliography_renderer_spec.rb'
70
- - 'spec/metanorma/plugin/glossarist/bibliography_scope_spec.rb'
71
- - 'spec/metanorma/plugin/glossarist/concept_filter_spec.rb'
72
- - 'spec/metanorma/plugin/glossarist/concept_path_resolver_spec.rb'
73
- - 'spec/metanorma/plugin/glossarist/liquid/drops/localization_collection_drop_spec.rb'
74
- - 'spec/metanorma/plugin/glossarist/liquid/with_glossarist_context_spec.rb'
75
-
76
- # Offense count: 1
77
- # This cop supports safe autocorrection (--autocorrect).
78
- Layout/MultilineBlockLayout:
79
- Exclude:
80
- - 'spec/metanorma/plugin/glossarist/section_spec.rb'
19
+ Enabled: false
81
20
 
82
21
  # Offense count: 2
83
- # This cop supports safe autocorrection (--autocorrect).
84
- # Configuration parameters: AllowInHeredoc.
85
- Layout/TrailingWhitespace:
22
+ # Configuration parameters: AllowedMethods.
23
+ # AllowedMethods: enums
24
+ Lint/ConstantDefinitionInBlock:
86
25
  Exclude:
87
- - 'lib/metanorma/plugin/glossarist/concept_path_resolver.rb'
88
- - 'spec/metanorma/plugin/glossarist/section_spec.rb'
26
+ - 'lib/metanorma/plugin/glossarist/field_filter.rb'
27
+ - 'spec/metanorma/plugin/glossarist/field_filter_spec.rb'
89
28
 
90
29
  # Offense count: 1
91
- # This cop supports safe autocorrection (--autocorrect).
92
- # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
93
- # NotImplementedExceptions: NotImplementedError
94
- Lint/UnusedMethodArgument:
30
+ Lint/StructNewOverride:
95
31
  Exclude:
96
- - 'lib/metanorma/plugin/glossarist/dataset_preprocessor.rb'
32
+ - 'spec/metanorma/plugin/glossarist/field_filter_spec.rb'
97
33
 
98
34
  # Offense count: 1
99
35
  Lint/UselessConstantScoping:
100
36
  Exclude:
101
37
  - 'lib/metanorma/plugin/glossarist/dataset_preprocessor.rb'
102
38
 
103
- # Offense count: 11
39
+ # Offense count: 10
104
40
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
105
41
  Metrics/AbcSize:
106
42
  Exclude:
107
43
  - 'lib/metanorma/plugin/glossarist/bibliography_renderer.rb'
108
44
  - 'lib/metanorma/plugin/glossarist/concept_filter.rb'
109
45
  - 'lib/metanorma/plugin/glossarist/dataset_preprocessor.rb'
110
- - 'lib/metanorma/plugin/glossarist/liquid/custom_blocks/with_glossarist_context.rb'
111
46
  - 'lib/metanorma/plugin/glossarist/template_renderer.rb'
112
47
 
113
- # Offense count: 6
48
+ # Offense count: 5
114
49
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
115
50
  Metrics/CyclomaticComplexity:
116
51
  Exclude:
@@ -119,12 +54,12 @@ Metrics/CyclomaticComplexity:
119
54
  - 'lib/metanorma/plugin/glossarist/concept_path_resolver.rb'
120
55
  - 'lib/metanorma/plugin/glossarist/dataset_preprocessor.rb'
121
56
 
122
- # Offense count: 14
57
+ # Offense count: 15
123
58
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
124
59
  Metrics/MethodLength:
125
- Max: 24
60
+ Max: 17
126
61
 
127
- # Offense count: 5
62
+ # Offense count: 4
128
63
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
129
64
  Metrics/PerceivedComplexity:
130
65
  Exclude:
@@ -132,7 +67,7 @@ Metrics/PerceivedComplexity:
132
67
  - 'lib/metanorma/plugin/glossarist/concept_filter.rb'
133
68
  - 'lib/metanorma/plugin/glossarist/dataset_preprocessor.rb'
134
69
 
135
- # Offense count: 19
70
+ # Offense count: 25
136
71
  # Configuration parameters: Prefixes, AllowedPatterns.
137
72
  # Prefixes: when, with, without
138
73
  RSpec/ContextWording:
@@ -145,23 +80,28 @@ RSpec/DescribeClass:
145
80
  Exclude:
146
81
  - 'spec/metanorma/plugin/glossarist/bibliography_scope_spec.rb'
147
82
 
148
- # Offense count: 27
83
+ # Offense count: 45
149
84
  # Configuration parameters: CountAsOne.
150
85
  RSpec/ExampleLength:
151
86
  Max: 35
152
87
 
153
- # Offense count: 31
88
+ # Offense count: 1
89
+ RSpec/LeakyConstantDeclaration:
90
+ Exclude:
91
+ - 'spec/metanorma/plugin/glossarist/field_filter_spec.rb'
92
+
93
+ # Offense count: 66
154
94
  RSpec/MultipleExpectations:
155
95
  Max: 4
156
96
 
157
- # Offense count: 33
97
+ # Offense count: 38
158
98
  # Configuration parameters: EnforcedStyle, IgnoreSharedExamples.
159
99
  # SupportedStyles: always, named_only
160
100
  RSpec/NamedSubject:
161
101
  Exclude:
162
102
  - 'spec/metanorma/plugin/glossarist/dataset_preprocessor_spec.rb'
163
103
 
164
- # Offense count: 30
104
+ # Offense count: 34
165
105
  # Configuration parameters: AllowedGroups.
166
106
  RSpec/NestedGroups:
167
107
  Max: 6
@@ -171,45 +111,21 @@ RSpec/RepeatedExample:
171
111
  Exclude:
172
112
  - 'spec/metanorma/plugin/glossarist/concept_path_resolver_spec.rb'
173
113
 
174
- # Offense count: 3
114
+ # Offense count: 5
175
115
  # Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
176
116
  # SupportedInflectors: default, active_support
177
117
  RSpec/SpecFilePathFormat:
178
118
  Exclude:
119
+ - 'spec/metanorma/plugin/glossarist/liquid/custom_filters_spec.rb'
120
+ - 'spec/metanorma/plugin/glossarist/liquid/drop_bracket_access_spec.rb'
179
121
  - 'spec/metanorma/plugin/glossarist/liquid/drops/localization_collection_drop_spec.rb'
180
122
  - 'spec/metanorma/plugin/glossarist/liquid/drops/managed_concept_data_drop_spec.rb'
181
123
  - 'spec/metanorma/plugin/glossarist/liquid/drops/managed_concept_drop_spec.rb'
182
124
 
183
125
  # Offense count: 1
184
- # This cop supports safe autocorrection (--autocorrect).
185
- # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
186
- # SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
187
- # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
188
- # FunctionalMethods: let, let!, subject, watch
189
- # AllowedMethods: lambda, proc, it
190
- Style/BlockDelimiters:
191
- Exclude:
192
- - 'spec/metanorma/plugin/glossarist/section_spec.rb'
193
-
194
- # Offense count: 1
195
- # This cop supports safe autocorrection (--autocorrect).
196
- # Configuration parameters: EnforcedStyle, AllowComments.
197
- # SupportedStyles: empty, nil, both
198
- Style/EmptyElse:
199
- Exclude:
200
- - 'lib/metanorma/plugin/glossarist/concept_path_resolver.rb'
201
-
202
- # Offense count: 1
203
- # This cop supports safe autocorrection (--autocorrect).
204
- Style/MultilineIfModifier:
205
- Exclude:
206
- - 'lib/metanorma/plugin/glossarist/concept_path_resolver.rb'
207
-
208
- # Offense count: 2
209
126
  # Configuration parameters: Max.
210
127
  Style/SafeNavigationChainLength:
211
128
  Exclude:
212
- - 'lib/metanorma/plugin/glossarist/dataset_registry.rb'
213
129
  - 'lib/metanorma/plugin/glossarist/template_renderer.rb'
214
130
 
215
131
  # Offense count: 1
data/Gemfile CHANGED
@@ -12,8 +12,11 @@ gem "rubocop-rspec"
12
12
 
13
13
  gemspec
14
14
 
15
- group :test do
16
- gem "metanorma"
17
- gem "metanorma-plugin-lutaml"
18
- gem "metanorma-standoc"
19
- end
15
+ # metanorma / metanorma-standoc / metanorma-plugin-lutaml are needed by
16
+ # spec_helper.rb at test time, but live in the default group (not :test)
17
+ # so the release workflow's `bundle install --without development test`
18
+ # still installs them. Bundler otherwise fails `bundle exec rake release`
19
+ # with GemNotFound when the resolver walks the Gemfile.
20
+ gem "metanorma"
21
+ gem "metanorma-plugin-lutaml"
22
+ gem "metanorma-standoc"
@@ -111,7 +111,7 @@ module Metanorma
111
111
  l10n.examples&.each { |e| parts << e.content.to_s }
112
112
  return [] if parts.empty?
113
113
 
114
- Sanitize.extract_xrefs(parts.join(" "))
114
+ MentionExtractor.new(parts.join(" ")).bibliography_ids
115
115
  end
116
116
  end
117
117
  end
@@ -20,6 +20,7 @@ module Metanorma
20
20
  def initialize(filters)
21
21
  @filters = filters || {}
22
22
  @resolver = ConceptPathResolver.new
23
+ @field_filters = build_field_filters
23
24
  end
24
25
 
25
26
  # Applies all configured filters in canonical order.
@@ -38,15 +39,18 @@ module Metanorma
38
39
  register)
39
40
  end
40
41
  result = filter_by_tag(result) if @filters.key?("tag")
41
- result = filter_by_field(result) if field_filters?
42
+ result = filter_by_field(result) unless @field_filters.empty?
42
43
  result = sort(result) if @filters.key?("sort_by")
43
44
  result
44
45
  end
45
46
 
46
47
  private
47
48
 
48
- def field_filters?
49
- (@filters.keys - COLLECTION_FILTERS).any?
49
+ def build_field_filters
50
+ field_keys = @filters.keys - COLLECTION_FILTERS
51
+ field_keys.map do |key|
52
+ FieldFilter.from_options_entry(key, @filters[key])
53
+ end
50
54
  end
51
55
 
52
56
  def filter_by_lang(collection)
@@ -103,33 +107,10 @@ module Metanorma
103
107
  end
104
108
 
105
109
  def filter_by_field(collection)
106
- path, value, start_with = field_filter_spec
107
- start_with_match_value = extract_start_with_value(path, value)
108
- path, match_value = if start_with_match_value
109
- [start_with_match_value[:path],
110
- start_with_match_value[:value]]
111
- else
112
- [path, value]
113
- end
114
-
115
110
  collection.select do |concept|
116
- actual = @resolver.resolve(concept, path)
117
- start_with ? actual&.start_with?(match_value) : actual == value
111
+ @field_filters.all? { |filter| filter.match?(@resolver, concept) }
118
112
  end
119
113
  end
120
-
121
- def field_filter_spec
122
- path = (@filters.keys - COLLECTION_FILTERS).first
123
- start_with = path.include?(".start_with(")
124
- [path, @filters[path], start_with]
125
- end
126
-
127
- def extract_start_with_value(path, _value)
128
- match = path.match(/^([^.]+(?:\.[^.]+)*)\.start_with\(([^)]+)\)$/)
129
- return nil unless match
130
-
131
- { path: match[1], value: match[2] }
132
- end
133
114
  end
134
115
  end
135
116
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "asciidoctor"
4
3
  require "asciidoctor/reader"
5
- require "glossarist"
6
4
 
7
5
  module Metanorma
8
6
  module Plugin
@@ -108,14 +106,13 @@ module Metanorma
108
106
  if (match = current_line.match(BIB_ANCHOR_REGEX))
109
107
  @existing_bib_anchors << match[1]
110
108
  end
111
- liquid_doc.add_content(current_line)
109
+ liquid_doc.add_raw(current_line)
112
110
  end
113
111
 
114
112
  def process_dataset_tag(document, input_lines, liquid_doc, match)
115
113
  @seen_glossarist = true
116
114
  @registry.register(document, match[1])
117
- liquid_doc.add_content(prepare_document(document, input_lines).to_s,
118
- render: false)
115
+ liquid_doc.add_raw(prepare_document(document, input_lines).to_s)
119
116
  end
120
117
 
121
118
  def process_glossarist_block(document, liquid_doc, input_lines, match)
@@ -129,9 +126,11 @@ module Metanorma
129
126
  {% endwith_glossarist_context %}
130
127
  SECTION
131
128
 
132
- options = { render: true }
133
- options[:template] = template if template
134
- liquid_doc.add_content(section, options)
129
+ if template
130
+ liquid_doc.add_rendered(section, template: template)
131
+ else
132
+ liquid_doc.add_rendered(section)
133
+ end
135
134
  end
136
135
 
137
136
  def prepare_glossarist_block_params(document, match)
@@ -175,7 +174,7 @@ module Metanorma
175
174
  depth: @title_depth,
176
175
  anchor_prefix: options["anchor-prefix"],
177
176
  non_verbal: non_verbal_for(context_name))
178
- liquid_doc.add_content("\n#{rendered}")
177
+ liquid_doc.add_raw("\n#{rendered}")
179
178
  end
180
179
 
181
180
  RENDER_OPTIONS = %w[anchor-prefix].freeze
@@ -198,7 +197,7 @@ module Metanorma
198
197
  depth: @title_depth,
199
198
  anchor_prefix: options["anchor-prefix"],
200
199
  non_verbal: non_verbal_for(context_name))
201
- liquid_doc.add_content("\n#{rendered}")
200
+ liquid_doc.add_raw("\n#{rendered}")
202
201
  end
203
202
 
204
203
  def process_import_sections_tag(_document, liquid_doc, match)
@@ -215,7 +214,7 @@ module Metanorma
215
214
  return unless dataset
216
215
 
217
216
  parts = render_sections(dataset, register, sections, context_name, options)
218
- liquid_doc.add_content("\n#{parts.join("\n\n")}")
217
+ liquid_doc.add_raw("\n#{parts.join("\n\n")}")
219
218
  end
220
219
 
221
220
  def render_sections(dataset, register, sections, context_name, options)
@@ -266,7 +265,7 @@ module Metanorma
266
265
  existing_anchors: @existing_bib_anchors,
267
266
  bibliography: @registry.bibliography_for(dataset_name),
268
267
  )
269
- liquid_doc.add_content(renderer.render_all(concepts))
268
+ liquid_doc.add_raw(renderer.render_all(concepts))
270
269
  end
271
270
 
272
271
  def process_bibliography_entry(document, liquid_doc, match)
@@ -280,7 +279,7 @@ module Metanorma
280
279
  bibliography: @registry.bibliography_for(dataset_name),
281
280
  )
282
281
  entry = renderer.render_entry(concept)
283
- liquid_doc.add_content(entry) if entry
282
+ liquid_doc.add_raw(entry) if entry
284
283
  end
285
284
 
286
285
  # Renders all dataset-level entities of a non-verbal kind
@@ -295,7 +294,7 @@ module Metanorma
295
294
 
296
295
  renderer = NonVerbalRenderer.new(collections: { kind => collection })
297
296
  rendered = renderer.render_kind(kind)
298
- liquid_doc.add_content("\n#{rendered}") unless rendered.empty?
297
+ liquid_doc.add_raw("\n#{rendered}") unless rendered.empty?
299
298
  end
300
299
 
301
300
  def relative_file_path(document, file_path)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "glossarist"
4
-
5
3
  module Metanorma
6
4
  module Plugin
7
5
  module Glossarist
@@ -10,19 +10,18 @@ module Metanorma
10
10
  @content = []
11
11
  end
12
12
 
13
- def add_content(content, options = {})
14
- @content << if options[:render]
15
- LiquidRendering.render(
16
- content,
17
- include_paths: [file_system,
18
- TEMPLATES_DIR,
19
- options[:template]].compact,
20
- patterns: LiquidRendering::DOCUMENT_PATTERNS,
21
- registry: registry,
22
- )
23
- else
24
- content
25
- end
13
+ def add_raw(content)
14
+ @content << content
15
+ end
16
+
17
+ def add_rendered(content, template: nil)
18
+ include_paths = [file_system, TEMPLATES_DIR, template].compact
19
+ @content << LiquidRendering.render(
20
+ content,
21
+ include_paths: include_paths,
22
+ patterns: LiquidRendering::DOCUMENT_PATTERNS,
23
+ registry: registry,
24
+ )
26
25
  end
27
26
 
28
27
  def to_s
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Plugin
5
+ module Glossarist
6
+ # A single field-based filter specification: a path through the concept
7
+ # graph, a matcher kind, and the comparison value.
8
+ #
9
+ # FieldFilter is the structured representation behind ConceptFilter's
10
+ # field-filter DSL. ConceptFilter parses the legacy pseudo-syntax
11
+ # (e.g. +key.start_with(pattern)=ignored+) into FieldFilter instances;
12
+ # future syntaxes (regex, contains) only need a new matcher symbol.
13
+ FieldFilter = Struct.new(:path, :matcher, :value, keyword_init: true) do
14
+ START_WITH_SUFFIX = /\.start_with\(([^)]+)\)\z/
15
+
16
+ # Parses a single filter hash entry (path-key, optional value) into
17
+ # a FieldFilter. Two shapes are recognized:
18
+ #
19
+ # - "data.path" => "value" → matcher :eq, value "value"
20
+ # - "data.path.start_with(pattern)" => _ → matcher :start_with,
21
+ # value "pattern" (the hash value is ignored)
22
+ #
23
+ # @param path [String] raw filter key
24
+ # @param raw_value [String, nil] raw filter value
25
+ # @return [FieldFilter]
26
+ def self.from_options_entry(path, raw_value)
27
+ if (match = path.match(START_WITH_SUFFIX))
28
+ FieldFilter.new(
29
+ path: match.pre_match,
30
+ matcher: :start_with,
31
+ value: match[1],
32
+ )
33
+ else
34
+ FieldFilter.new(path: path, matcher: :eq, value: raw_value)
35
+ end
36
+ end
37
+
38
+ # Applies the filter to a single concept via the given path resolver.
39
+ # @param resolver [ConceptPathResolver]
40
+ # @param concept [ManagedConcept]
41
+ def match?(resolver, concept)
42
+ actual = resolver.resolve(concept, path)
43
+ case matcher
44
+ when :start_with then actual&.start_with?(value.to_s)
45
+ else actual == value
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -31,7 +31,7 @@ module Metanorma
31
31
 
32
32
  @contexts.each do |local_context|
33
33
  path = local_context[:file_path].strip
34
- collection = registry ? registry.concepts_at(path) : load_collection(path)
34
+ collection = concepts_for(registry, path)
35
35
  filtered = ConceptFilter.new(@raw_filters).apply(collection)
36
36
  context[local_context[:name]] = filtered.map do |c|
37
37
  ManagedConceptDrop.new(c)
@@ -51,10 +51,14 @@ module Metanorma
51
51
  end
52
52
  end
53
53
 
54
- def load_collection(folder_path)
55
- collection = ::Glossarist::ManagedConceptCollection.new
56
- collection.load_from_files(folder_path)
57
- collection
54
+ def concepts_for(registry, path)
55
+ return registry.concepts_at(path) if registry
56
+
57
+ fallback_store(path).concepts
58
+ end
59
+
60
+ def fallback_store(path)
61
+ ::Glossarist::GlossaryStore.new.load_directory(path)
58
62
  end
59
63
  end
60
64
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "liquid"
4
-
5
3
  module Metanorma
6
4
  module Plugin
7
5
  module Glossarist
@@ -16,7 +14,10 @@ module Metanorma
16
14
  Liquid::LocalFileSystem.new(include_paths, patterns)
17
15
  template.registers[:dataset_registry] = registry if registry
18
16
  rendered = template.render(assigns)
19
- raise template.errors.first.cause if template.errors.any?
17
+ if template.errors.any?
18
+ error = template.errors.first
19
+ raise error.cause || error
20
+ end
20
21
 
21
22
  rendered
22
23
  end
@@ -29,9 +29,14 @@ domain:[{{ l10n.data.domain }}]
29
29
  {% for note in l10n.data.notes.definitions -%}
30
30
  [NOTE]
31
31
  ====
32
- {{ note.content | sanitize_references }}
33
- ====
32
+ {{ note.content | sanitize_references }}{% for example in note.examples %}
34
33
 
34
+ [example]
35
+ ====
36
+ {{ example.content | sanitize_references }}
37
+ ====
38
+ {% endfor %}
39
+ ====
35
40
  {% endfor %}
36
41
  {% if l10n.data.annotations -%}
37
42
  {% for annotation in l10n.data.annotations.definitions -%}
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Plugin
5
+ module Glossarist
6
+ # Extracts bibliography-citable mention IDs from concept text using
7
+ # +Glossarist::ReferenceExtractor+ as the single canonical parser.
8
+ #
9
+ # Bibliography relevance = +BibliographicReference+ (from +<<anchor>>+
10
+ # xrefs) and +ConceptReference+ instances whose +#cite?+ is true (from
11
+ # +{{cite:id}}+ mentions). Other mention kinds (fig/table/formula/urn)
12
+ # reference assets or concepts, not bibliography entries.
13
+ class MentionExtractor
14
+ def initialize(text)
15
+ @text = text
16
+ end
17
+
18
+ def bibliography_ids
19
+ refs = ::Glossarist::ReferenceExtractor.new
20
+ .extract_from_text(@text.to_s)
21
+ refs.filter_map { |ref| bibliography_id(ref) }.uniq
22
+ end
23
+
24
+ private
25
+
26
+ def bibliography_id(ref)
27
+ case ref
28
+ when ::Glossarist::BibliographicReference
29
+ ref.anchor
30
+ when ::Glossarist::ConceptReference
31
+ ref.concept_id if ref.cite?
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -5,7 +5,6 @@ module Metanorma
5
5
  module Glossarist
6
6
  module Sanitize
7
7
  REF_REGEX = /{{(urn:[^,{}]+),([^}]+?)}}(.*)$/m
8
- XREF_REGEX = /<<((?>[^,>\n]+))(?:,[^>\n]*)?>>/
9
8
 
10
9
  def self.references(str)
11
10
  return str unless str&.match?(REF_REGEX)
@@ -16,12 +15,6 @@ module Metanorma
16
15
  "{{#{urn},#{m[2]}}}#{m[3]}"
17
16
  end
18
17
  end
19
-
20
- def self.extract_xrefs(text)
21
- return [] unless text
22
-
23
- text.scan(XREF_REGEX).map(&:first).uniq
24
- end
25
18
  end
26
19
  end
27
20
  end
@@ -9,7 +9,6 @@ module Metanorma
9
9
  def initialize(file_system:, lang: "eng")
10
10
  @file_system = file_system
11
11
  @lang = lang
12
- @template_cache = {}
13
12
  end
14
13
 
15
14
  def render_concepts(concepts, depth:, anchor_prefix: nil,
@@ -30,8 +29,7 @@ module Metanorma
30
29
  "depth_marker" => "=" * (depth + 1),
31
30
  "anchor" => build_anchor(concept.data.id.to_s, anchor_prefix),
32
31
  }
33
- template_content = cached_template(concept)
34
- rendered = render_template(template_content, context)
32
+ rendered = render_template(File.read(DEFAULT_TEMPLATE), context)
35
33
  if non_verbal
36
34
  rendered += "\n\n#{non_verbal.render_concept_refs(concept)}"
37
35
  end
@@ -40,14 +38,6 @@ module Metanorma
40
38
 
41
39
  private
42
40
 
43
- def cached_template(concept)
44
- version = concept.schema_version
45
- @template_cache[version] ||= begin
46
- path = File.join(TEMPLATES_DIR, "_concept_#{version}.liquid")
47
- File.exist?(path) ? File.read(path) : File.read(DEFAULT_TEMPLATE)
48
- end
49
- end
50
-
51
41
  def render_tree_node((concept, children), depth, anchor_prefix,
52
42
  non_verbal)
53
43
  result = render_concept(concept, depth: depth,
@@ -3,7 +3,7 @@
3
3
  module Metanorma
4
4
  module Plugin
5
5
  module Glossarist
6
- VERSION = "0.3.10"
6
+ VERSION = "0.4.0"
7
7
  end
8
8
  end
9
9
  end
@@ -19,8 +19,11 @@ module Metanorma
19
19
  "metanorma/plugin/glossarist/dataset_preprocessor"
20
20
  autoload :DatasetRegistry, "metanorma/plugin/glossarist/dataset_registry"
21
21
  autoload :Document, "metanorma/plugin/glossarist/document"
22
+ autoload :FieldFilter, "metanorma/plugin/glossarist/field_filter"
22
23
  autoload :Liquid, "metanorma/plugin/glossarist/liquid"
23
24
  autoload :LiquidRendering, "metanorma/plugin/glossarist/liquid_rendering"
25
+ autoload :MentionExtractor,
26
+ "metanorma/plugin/glossarist/mention_extractor"
24
27
  autoload :NonVerbalFormatters,
25
28
  "metanorma/plugin/glossarist/non_verbal_formatters"
26
29
  autoload :NonVerbalRenderer,
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.required_ruby_version = ">= 3.1.0"
27
27
 
28
28
  spec.add_dependency "asciidoctor"
29
- spec.add_dependency "glossarist", "~> 2.8", ">= 2.8.16"
29
+ spec.add_dependency "glossarist", "~> 2.8", ">= 2.9.0"
30
30
  spec.add_dependency "liquid"
31
31
  spec.add_dependency "metanorma-utils"
32
32
  spec.metadata["rubygems_mfa_required"] = "true"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-plugin-glossarist
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.10
4
+ version: 0.4.0
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-06-20 00:00:00.000000000 Z
11
+ date: 2026-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: '2.8'
34
34
  - - ">="
35
35
  - !ruby/object:Gem::Version
36
- version: 2.8.16
36
+ version: 2.9.0
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '2.8'
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 2.8.16
46
+ version: 2.9.0
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: liquid
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +100,7 @@ files:
100
100
  - lib/metanorma/plugin/glossarist/dataset_preprocessor.rb
101
101
  - lib/metanorma/plugin/glossarist/dataset_registry.rb
102
102
  - lib/metanorma/plugin/glossarist/document.rb
103
+ - lib/metanorma/plugin/glossarist/field_filter.rb
103
104
  - lib/metanorma/plugin/glossarist/liquid.rb
104
105
  - lib/metanorma/plugin/glossarist/liquid/custom_blocks/with_glossarist_context.rb
105
106
  - lib/metanorma/plugin/glossarist/liquid/custom_filters.rb
@@ -111,6 +112,7 @@ files:
111
112
  - lib/metanorma/plugin/glossarist/liquid/multiply_local_file_system.rb
112
113
  - lib/metanorma/plugin/glossarist/liquid_rendering.rb
113
114
  - lib/metanorma/plugin/glossarist/liquid_templates/_concept.liquid
115
+ - lib/metanorma/plugin/glossarist/mention_extractor.rb
114
116
  - lib/metanorma/plugin/glossarist/non_verbal_formatters.rb
115
117
  - lib/metanorma/plugin/glossarist/non_verbal_formatters/base.rb
116
118
  - lib/metanorma/plugin/glossarist/non_verbal_formatters/figure.rb