metanorma-plugin-glossarist 0.3.0 → 0.3.2

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.
@@ -1,150 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "liquid"
4
+ require_relative "../../concept_filter"
5
+ require_relative "../../concept_serializer"
4
6
 
5
7
  module Metanorma
6
8
  module Plugin
7
9
  module Glossarist
8
10
  module Liquid
9
- module CustomBlocks
10
- class WithGlossaristContext < ::Liquid::Block
11
- def initialize(tag_name, markup, tokens) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
12
- super
13
-
14
- @contexts = []
15
- @filters = {}
16
-
17
- contexts, filters = markup.strip.split(";", 2)
18
-
19
- if filters && !filters.empty?
20
- filters = filters.strip.gsub(/^['"]|['"]$/, "").split(";")
21
- filters.each do |filter|
22
- property, value = filter.split("=")
23
- @filters[property] = value
24
- end
25
- end
26
-
27
- contexts.split(",").each do |context|
28
- context_name, file_path = context.split("=").map(&:strip)
29
-
30
- @contexts << {
31
- name: context_name,
32
- file_path: file_path,
33
- }
34
- end
35
- end
36
-
37
- def load_collection(folder_path)
38
- @@collections ||= {}
39
-
40
- return @@collections[folder_path] if @@collections[folder_path]
11
+ module CollectionCache
12
+ @cache = {}
41
13
 
14
+ def self.fetch(folder_path)
15
+ @cache[folder_path] ||= begin
42
16
  collection = ::Glossarist::ManagedConceptCollection.new
43
17
  collection.load_from_files(folder_path)
44
- @@collections[folder_path] = collection
45
- end
46
-
47
- def filter_collection(collection, filters)
48
- return collection unless filters
49
-
50
- concept_filters = filters.dup
51
- lang_filter = concept_filters.delete("lang")
52
- group_filter = concept_filters.delete("group")
53
- sort_filter = concept_filters.delete("sort_by")
54
-
55
- collection = apply_lang_filter(collection, lang_filter)
56
- collection = apply_group_filter(collection, group_filter)
57
- collection = apply_field_filter(collection, concept_filters)
58
- apply_sort_filter(collection, sort_filter)
59
- end
60
-
61
- def apply_field_filter(collection, field_filter) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
62
- return collection if field_filter.nil? || field_filter.empty?
63
-
64
- collection.select do |obj| # rubocop:disable Metrics/BlockLength
65
- fields = field_filter.keys.first.split(".")
66
- value = field_filter.values.first
67
- start_with = false
68
-
69
- # check if the last field is a start_with condition
70
- if fields.last.start_with?("start_with(") &&
71
- fields.last.include?(")")
72
- start_with = true
73
- # Extract content between first '(' and last ')'
74
- f = fields.last
75
- value = f[(f.index("(") + 1)...f.rindex(")")]
76
- fields = fields[0..-2]
77
- end
78
-
79
- fields.each do |field|
80
- # contain index (i.e. field['abc'] or field[1])
81
- if field.include?("[")
82
- field, index = field[0..-2].split("[")
83
-
84
- index = if index.include?("'") || index.include?("\"")
85
- index.gsub(/['"]/, "")
86
- else
87
- index.to_i
88
- end
89
-
90
- obj = obj.send(field.to_sym)[index]
91
- else
92
- obj = obj.send(field.to_sym)
93
- end
94
- end
95
-
96
- # check if the object matches the value
97
- if start_with
98
- obj.start_with?(value)
99
- else
100
- obj == value
101
- end
102
- end
103
- end
104
-
105
- def apply_lang_filter(collection, lang_filter)
106
- return collection unless lang_filter
107
-
108
- collection.select do |concept|
109
- concept.data.localizations.key?(lang_filter)
110
- end
111
- end
112
-
113
- def apply_group_filter(collection, group_filter)
114
- return collection unless group_filter
115
-
116
- collection.select do |concept|
117
- concept.data.groups&.include?(group_filter)
118
- end
119
- end
120
-
121
- def apply_sort_filter(collection, sort_filter)
122
- return collection unless sort_filter
123
-
124
- sort_filter = case sort_filter
125
- when "term"
126
- "default_designation"
127
- else
128
- sort_filter
129
- end
130
-
131
- collection.sort_by do |concept|
132
- concept.send(sort_filter.to_sym).downcase
133
- end
134
- end
135
-
136
- def render(context)
137
- @contexts.each do |local_context|
138
- context_file = local_context[:file_path].strip
139
- collection = load_collection(context_file)
140
-
141
- filtered_collection = filter_collection(collection, @filters)
142
-
143
- context[local_context[:name]] = filtered_collection
144
- .map(&:to_liquid)
145
- end
146
-
147
- super
18
+ collection
148
19
  end
149
20
  end
150
21
  end
@@ -152,3 +23,54 @@ module Metanorma
152
23
  end
153
24
  end
154
25
  end
26
+
27
+ Liquid::Template.register_tag("with_glossarist_context",
28
+ Class.new(Liquid::Block) do
29
+ def initialize(tag_name, markup, tokens)
30
+ super
31
+ @contexts = []
32
+ @raw_filters = {}
33
+
34
+ contexts_part, filters_part = markup.strip.split(
35
+ ";", 2
36
+ )
37
+
38
+ parse_filters(filters_part.strip) if filters_part && !filters_part.strip.empty?
39
+
40
+ contexts_part.split(",").each do |context|
41
+ context_name, file_path = context.split("=").map(&:strip)
42
+ @contexts << { name: context_name,
43
+ file_path: file_path }
44
+ end
45
+ end
46
+
47
+ def render(context)
48
+ @contexts.each do |local_context|
49
+ collection = load_collection(local_context[:file_path].strip)
50
+ filtered = Metanorma::Plugin::Glossarist::ConceptFilter.new(@raw_filters).apply(collection)
51
+ context[local_context[:name]] = filtered.map do |c|
52
+ Metanorma::Plugin::Glossarist::ConceptSerializer.new(c).to_h
53
+ end
54
+ end
55
+
56
+ super
57
+ end
58
+
59
+ private
60
+
61
+ def parse_filters(filters_str)
62
+ stripped = filters_str.gsub(/\A['"]|['"]\z/,
63
+ "")
64
+ stripped.split(";").each do |filter|
65
+ property, value = filter.split("=", 2)
66
+ if property
67
+ @raw_filters[property.strip] =
68
+ value&.strip
69
+ end
70
+ end
71
+ end
72
+
73
+ def load_collection(folder_path)
74
+ Metanorma::Plugin::Glossarist::Liquid::CollectionCache.fetch(folder_path)
75
+ end
76
+ end)
@@ -1,50 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "liquid"
4
+
3
5
  module Metanorma
4
6
  module Plugin
5
7
  module Glossarist
6
8
  module Liquid
7
9
  module CustomFilters
8
10
  module Filters
9
- REF_REGEX = /{{([^,]{1,500}),([^\}]{1,500})}}(.*?)$/s.freeze
10
-
11
11
  def values(list)
12
12
  list.values
13
13
  end
14
14
 
15
15
  def sanitize_references(str)
16
- return str unless str.match?(REF_REGEX)
17
-
18
- matched_str = str.match(REF_REGEX)
19
- urn = Metanorma::Utils.to_ncname(matched_str[1]).gsub(":", "_")
20
-
21
- "{{#{urn},#{matched_str[2]}}}#{matched_str[3]}"
22
- end
23
-
24
- def terminological_data(term)
25
- result = []
26
-
27
- result << "&lt;#{term['usage_info']}&gt;" if term["usage_info"]
28
- result << extract_grammar_info(term)
29
- result << term["geographical_area"]&.upcase
30
-
31
- result.unshift(",") if result.compact.size.positive?
32
-
33
- result.compact.join(" ")
34
- end
35
-
36
- def extract_grammar_info(term)
37
- return unless term["grammar_info"]
38
-
39
- grammar_info = []
40
-
41
- term["grammar_info"].each do |info|
42
- grammar_info << info["gender"]&.join(", ")
43
- grammar_info << info["number"]&.join(", ")
44
- grammar_info << extract_parts_of_speech(info)
45
- end
46
-
47
- grammar_info.join(" ")
16
+ Sanitize.references(str)
48
17
  end
49
18
  end
50
19
  end
@@ -52,3 +21,5 @@ module Metanorma
52
21
  end
53
22
  end
54
23
  end
24
+
25
+ Liquid::Template.register_filter(Metanorma::Plugin::Glossarist::Liquid::CustomFilters::Filters)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Metanorma
2
4
  module Plugin
3
5
  module Glossarist
@@ -14,7 +16,8 @@ module Metanorma
14
16
  full_path = full_path(template_path)
15
17
 
16
18
  unless File.exist?(full_path)
17
- raise FileSystemError, "No such template '#{template_path}'"
19
+ raise FileSystemError,
20
+ "No such template '#{template_path}'"
18
21
  end
19
22
 
20
23
  File.read(full_path)
@@ -52,8 +55,8 @@ module Metanorma
52
55
 
53
56
  if result_path.nil?
54
57
  raise ::Liquid::FileSystemError,
55
- "No documents in template path: " \
56
- " #{File.expand_path(template_path)}"
58
+ "No documents in template path: " \
59
+ "#{File.expand_path(template_path)}"
57
60
  end
58
61
 
59
62
  unless roots.any? do |root|
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Plugin
5
+ module Glossarist
6
+ module Sanitize
7
+ REF_REGEX = /{{([^,{}]+),([^}]+?)}}(.*)$/s
8
+ XREF_REGEX = /<<((?>[^,>\n]+))(?:,[^>\n]*)?>>/
9
+
10
+ def self.references(str)
11
+ return str unless str&.match?(REF_REGEX)
12
+
13
+ match = str.match(REF_REGEX)
14
+ urn = Metanorma::Utils.to_ncname(match[1]).gsub(":", "_")
15
+ "{{#{urn},#{match[2]}}}#{match[3]}"
16
+ end
17
+
18
+ def self.extract_xrefs(text)
19
+ return [] unless text
20
+
21
+ text.scan(XREF_REGEX).map(&:first).uniq
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Metanorma
2
4
  module Plugin
3
5
  module Glossarist
4
- VERSION = "0.3.0".freeze
6
+ VERSION = "0.3.2"
5
7
  end
6
8
  end
7
9
  end
@@ -1,13 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "metanorma/plugin/glossarist/version"
4
+ require "metanorma-utils"
5
+ require "metanorma/plugin/glossarist/sanitize"
6
+ require "metanorma/plugin/glossarist/concept_serializer"
7
+ require "metanorma/plugin/glossarist/concept_renderer"
8
+ require "metanorma/plugin/glossarist/bibliography_renderer"
9
+ require "metanorma/plugin/glossarist/concept_filter"
2
10
  require "metanorma/plugin/glossarist/document"
3
11
  require "metanorma/plugin/glossarist/dataset_preprocessor"
4
- require "metanorma-utils"
5
-
6
- module Metanorma
7
- module Plugin
8
- module Glossarist
9
- class Error < StandardError; end
10
- # Your code goes here...
11
- end
12
- end
13
- end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "lib/metanorma/plugin/glossarist/version"
2
4
 
3
5
  Gem::Specification.new do |spec|
@@ -12,9 +14,6 @@ Gem::Specification.new do |spec|
12
14
  spec.homepage = "https://github.com/metanorma/metanorma-plugin-glossarist"
13
15
  spec.license = "BSD-2-Clause"
14
16
 
15
- # Specify which files should be added to the gem when it is released.
16
- # The `git ls-files -z` loads the files in the RubyGem that have been added
17
- # into git.
18
17
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
19
18
  `git ls-files -z`.split("\x0").reject do |f|
20
19
  f.match(%r{^(test|spec|features)/})
@@ -24,10 +23,11 @@ Gem::Specification.new do |spec|
24
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
24
  spec.require_paths = ["lib"]
26
25
 
27
- spec.required_ruby_version = ">= 3.1.0" # rubocop:disable Gemspec/RequiredRubyVersion
26
+ spec.required_ruby_version = ">= 3.1.0"
28
27
 
29
28
  spec.add_dependency "asciidoctor"
30
- spec.add_dependency "glossarist", "~> 2.4.0"
29
+ spec.add_dependency "glossarist", "~> 2.6.0"
31
30
  spec.add_dependency "liquid"
32
- spec.add_dependency "metanorma-utils", "~> 2.0"
31
+ spec.add_dependency "metanorma-utils"
32
+ spec.metadata["rubygems_mfa_required"] = "true"
33
33
  end
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.0
4
+ version: 0.3.2
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-04-09 00:00:00.000000000 Z
11
+ date: 2026-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.4.0
33
+ version: 2.6.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.4.0
40
+ version: 2.6.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: liquid
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: metanorma-utils
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '2.0'
61
+ version: '0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '2.0'
68
+ version: '0'
69
69
  description: Metanorma plugin for glossarist
70
70
  email:
71
71
  - open.source@ribose.com
@@ -79,6 +79,7 @@ files:
79
79
  - ".hound.yml"
80
80
  - ".rspec"
81
81
  - ".rubocop.yml"
82
+ - ".rubocop_todo.yml"
82
83
  - CODE_OF_CONDUCT.md
83
84
  - Gemfile
84
85
  - LICENSE.txt
@@ -87,17 +88,23 @@ files:
87
88
  - bin/console
88
89
  - bin/setup
89
90
  - lib/metanorma-plugin-glossarist.rb
91
+ - lib/metanorma/plugin/glossarist/bibliography_renderer.rb
92
+ - lib/metanorma/plugin/glossarist/concept_filter.rb
93
+ - lib/metanorma/plugin/glossarist/concept_renderer.rb
94
+ - lib/metanorma/plugin/glossarist/concept_serializer.rb
90
95
  - lib/metanorma/plugin/glossarist/dataset_preprocessor.rb
91
96
  - lib/metanorma/plugin/glossarist/document.rb
92
97
  - lib/metanorma/plugin/glossarist/liquid/custom_blocks/with_glossarist_context.rb
93
98
  - lib/metanorma/plugin/glossarist/liquid/custom_filters/filters.rb
94
99
  - lib/metanorma/plugin/glossarist/liquid/multiply_local_file_system.rb
100
+ - lib/metanorma/plugin/glossarist/sanitize.rb
95
101
  - lib/metanorma/plugin/glossarist/version.rb
96
102
  - metanorma-plugin-glossarist.gemspec
97
103
  homepage: https://github.com/metanorma/metanorma-plugin-glossarist
98
104
  licenses:
99
105
  - BSD-2-Clause
100
- metadata: {}
106
+ metadata:
107
+ rubygems_mfa_required: 'true'
101
108
  post_install_message:
102
109
  rdoc_options: []
103
110
  require_paths: