metanorma-plugin-datastruct 0.2.3 → 0.3.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: fe622d105e9790da8f5d61265addc954c5718827464c6b7069bfcf4f28b854e2
4
- data.tar.gz: aa6fd9ec16c14b9d558631ce6dd3f87a4a5547d7cd917a8651489018ca7b9bdc
3
+ metadata.gz: fc634fc7a6b9a9f552e22cc95a4ca8175398003670fb00a8e6570f12adf735ac
4
+ data.tar.gz: 5a39bb7f4053fcfba93e50a0f78eca3d127c0a088f48c1f8db4c4606fc8fc3af
5
5
  SHA512:
6
- metadata.gz: 57afedfbda26e055e3b09cc7ea5fd84978c95862039ce7894438ad6acead8dff3551fc9c7980fa006ad98eadfc6d3ed5d1c76dbe465c89df487aaa69be44c642
7
- data.tar.gz: 23171c33074450db80cd6c6ab310cfdab19153428bf147beb9a7478edc3d7a61c55a89e29274debece82663ffc9d98d9d886a3193cce259b37e78a1bc40fe046
6
+ metadata.gz: e09440e5e49f8293720973e657b93dd46bf51c0a5952364aa45b8638dc7605ce27ec146bc0057fa677f4e6ae4b26f08576b3c729956473ffbf099e882bf2a4c9
7
+ data.tar.gz: a7da83aabbfaa3907355af04304551eb7eb829d304ddca8ef0e06072801f082e842565c79b2fce6ddd483503cac17fcacfc88dfb454699f376662b9db97ebd84
data/.gitignore CHANGED
@@ -9,4 +9,8 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
- Gemfile.lock
12
+ Gemfile.lock
13
+
14
+ .byebug_history
15
+ *.err
16
+ .rubocop*
data/Gemfile CHANGED
@@ -1,5 +1,9 @@
1
+ Encoding.default_external = Encoding::UTF_8
2
+ Encoding.default_internal = Encoding::UTF_8
3
+
1
4
  source "https://rubygems.org"
5
+ git_source(:github) { |repo| "https://github.com/#{repo}" }
2
6
 
3
- # Specify your gem's dependencies in metanorma-plugin-datastruct.gemspec
4
7
  gemspec
5
- gem "debug"
8
+
9
+ eval_gemfile("Gemfile.devel") rescue nil
@@ -8,6 +8,7 @@ require "liquid/custom_blocks/with_yaml_nested_context"
8
8
  require "liquid/custom_blocks/with_json_nested_context"
9
9
  require "liquid/custom_filters/values"
10
10
  require "liquid/custom_filters/replace_regex"
11
+ require "metanorma/plugin/datastruct/source_extractor"
11
12
 
12
13
  Liquid::Template.register_tag("keyiterator", Liquid::CustomBlocks::KeyIterator)
13
14
  Liquid::Template
@@ -18,6 +19,14 @@ Liquid::Template
18
19
  Liquid::CustomBlocks::WithJsonNestedContext)
19
20
  Liquid::Template.register_filter(Liquid::CustomFilters)
20
21
 
22
+ module Asciidoctor
23
+ class PreprocessorNoIfdefsReader < PreprocessorReader
24
+ def preprocess_conditional_directive(_keyword, _target, _delimiter, _text)
25
+ false # decline to resolve idefs
26
+ end
27
+ end
28
+ end
29
+
21
30
  module Metanorma
22
31
  module Plugin
23
32
  module Datastruct
@@ -28,8 +37,15 @@ module Metanorma
28
37
  BLOCK_END_REGEXP = /\A\{[A-Z]+\}\z/.freeze
29
38
 
30
39
  def process(document, reader)
31
- input_lines = reader.readlines.to_enum
32
- Asciidoctor::Reader.new(processed_lines(document, input_lines))
40
+ r = ::Asciidoctor::PreprocessorNoIfdefsReader
41
+ .new document, reader.lines
42
+ input_lines = r.readlines
43
+ Metanorma::Plugin::Datastruct::SourceExtractor.extract(
44
+ document,
45
+ input_lines,
46
+ )
47
+ Asciidoctor::PreprocessorNoIfdefsReader
48
+ .new(document, processed_lines(document, input_lines.to_enum))
33
49
  end
34
50
 
35
51
  protected
@@ -38,6 +54,10 @@ module Metanorma
38
54
  raise ArgumentError, "Implement `content_from_file` in your class"
39
55
  end
40
56
 
57
+ def content_from_anchor(_document, _file_path)
58
+ raise ArgumentError, "Implement `content_from_anchor` in your class"
59
+ end
60
+
41
61
  private
42
62
 
43
63
  def processed_lines(document, input_lines)
@@ -50,7 +70,7 @@ module Metanorma
50
70
 
51
71
  def relative_file_path(document, file_path)
52
72
  docfile_directory = File.dirname(
53
- document.attributes["docfile"] || "."
73
+ document.attributes["docfile"] || ".",
54
74
  )
55
75
  document
56
76
  .path_resolver
@@ -109,7 +129,13 @@ module Metanorma
109
129
  def parse_template(document, current_block, block_match)
110
130
  transformed_liquid_lines = current_block
111
131
  .map(&method(:transform_line_liquid))
112
- context_items = content_from_file(document, block_match[1])
132
+
133
+ context_items = if block_match[1].start_with?("#")
134
+ content_from_anchor(document, block_match[1][1..-1])
135
+ else
136
+ content_from_file(document, block_match[1])
137
+ end
138
+
113
139
  parse_context_block(document: document,
114
140
  context_lines: transformed_liquid_lines,
115
141
  context_items: context_items,
@@ -133,7 +159,7 @@ module Metanorma
133
159
  .gsub(/(?<!{){(?!%)([^{}]+)(?<!%)}(?!})/, '{{\1}}')
134
160
  .gsub(/[a-z\.]+\#/, "index")
135
161
  .gsub(/{{(.+)\s+\+\s+(\d+)\s*?}}/, '{{ \1 | plus: \2 }}')
136
- .gsub(/{{(.+)\s+\-\s+(\d+)\s*?}}/, '{{ \1 | minus: \2 }}')
162
+ .gsub(/{{(.+)\s+-\s+(\d+)\s*?}}/, '{{ \1 | minus: \2 }}')
137
163
  .gsub(/{{(.+)\.values(.*?)}}/,
138
164
  '{% assign custom_value = \1 | values %}{{custom_value\2}}')
139
165
  end
@@ -146,7 +172,7 @@ module Metanorma
146
172
  template_string: context_lines.join("\n"),
147
173
  context_items: context_items,
148
174
  context_name: context_name,
149
- document: document
175
+ document: document,
150
176
  )
151
177
  notify_render_errors(document, errors)
152
178
  render_result.split("\n")
@@ -156,7 +182,8 @@ module Metanorma
156
182
  context_name:, document:)
157
183
  liquid_template = Liquid::Template.parse(template_string)
158
184
  # Allow includes for the template
159
- liquid_template.registers[:file_system] = ::Liquid::LocalFileSystem.new(relative_file_path(document, ""))
185
+ liquid_template.registers[:file_system] =
186
+ ::Liquid::LocalFileSystem.new(relative_file_path(document, ""))
160
187
  rendered_string = liquid_template
161
188
  .render(context_name => context_items,
162
189
  strict_variables: true,
@@ -41,6 +41,10 @@ module Metanorma
41
41
  JSON.parse(File.read(relative_file_path(document, file_path),
42
42
  encoding: "UTF-8"))
43
43
  end
44
+
45
+ def content_from_anchor(document, anchor)
46
+ JSON.parse(document.attributes["source_blocks"][anchor])
47
+ end
44
48
  end
45
49
  end
46
50
  end
@@ -0,0 +1,100 @@
1
+ module Metanorma
2
+ module Plugin
3
+ module Datastruct
4
+ class SourceExtractor
5
+ # example:
6
+ # - [[abc]]
7
+ ANCHOR_REGEX_1 = /^\[\[(?<id>[^\]]*)\]\]\s*$/.freeze
8
+
9
+ # examples:
10
+ # - [#abc]
11
+ # - [source#abc,ruby]
12
+ ANCHOR_REGEX_2 = /^\[[^#,]*#(?<id>[^,\]]*)[,\]]/.freeze
13
+
14
+ # examples:
15
+ # - [id=abc]
16
+ # - [source,id="abc"]
17
+ ANCHOR_REGEX_3 = /^\[(?:.+,)?id=['"]?(?<id>[^,\]'"]*)['"]?[,\]]/.freeze
18
+
19
+ def initialize(document, input_lines)
20
+ @document = document
21
+ @input_lines = input_lines
22
+
23
+ @document.attributes["source_blocks"] ||= {}
24
+ end
25
+
26
+ def self.extract(document, input_lines)
27
+ new(document, input_lines).extract
28
+ end
29
+
30
+ def extract
31
+ lines = @input_lines.to_enum
32
+
33
+ loop do
34
+ line = lines.next
35
+
36
+ if /^embed::|^include::/.match?(line.strip)
37
+ file_lines = read(filename(@document, line)) or next
38
+ SourceExtractor.extract(@document, file_lines)
39
+ elsif m = match_anchor(line)
40
+ @document.attributes["source_blocks"][m[:id]] = read_section lines
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def match_anchor(line)
48
+ line.match(ANCHOR_REGEX_1) ||
49
+ line.match(ANCHOR_REGEX_2) ||
50
+ line.match(ANCHOR_REGEX_3)
51
+ end
52
+
53
+ def readlines_safe(file)
54
+ return [] if file.eof?
55
+
56
+ file.readlines
57
+ end
58
+
59
+ def read(inc_path)
60
+ inc_path or return nil
61
+ ::File.open inc_path, "r" do |fd|
62
+ readlines_safe(fd).map(&:chomp)
63
+ end
64
+ end
65
+
66
+ def filename(document, line)
67
+ m = /(^include::|^embed::)([^\[]+)\[/.match(line)
68
+ return nil unless m
69
+
70
+ file_path = relative_file_path(document, m[2])
71
+
72
+ File.exist?(file_path) ? file_path : nil
73
+ end
74
+
75
+ def relative_file_path(document, file_path)
76
+ docfile_directory = File.dirname(
77
+ document.attributes["docfile"] || ".",
78
+ )
79
+ document
80
+ .path_resolver
81
+ .system_path(file_path, docfile_directory)
82
+ end
83
+
84
+ def read_section(lines)
85
+ m = lines.next.match(/^--+/)
86
+ return "" unless m
87
+
88
+ end_mark = m[0]
89
+ current_section = []
90
+
91
+ while (line = lines.next) != end_mark
92
+ current_section << line
93
+ end
94
+
95
+ current_section.join("\n")
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -1,7 +1,7 @@
1
1
  module Metanorma
2
2
  module Plugin
3
3
  module Datastruct
4
- VERSION = "0.2.3".freeze
4
+ VERSION = "0.3.0".freeze
5
5
  end
6
6
  end
7
7
  end
@@ -43,7 +43,16 @@ module Metanorma
43
43
  File.read(relative_file_path(document, file_path), encoding: "UTF-8"),
44
44
  permitted_classes: [Date, Time],
45
45
  permitted_symbols: [],
46
- aliases: true
46
+ aliases: true,
47
+ )
48
+ end
49
+
50
+ def content_from_anchor(document, anchor)
51
+ YAML.safe_load(
52
+ document.attributes["source_blocks"][anchor],
53
+ permitted_classes: [Date, Time],
54
+ permitted_symbols: [],
55
+ aliases: true,
47
56
  )
48
57
  end
49
58
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-plugin-datastruct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.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: 2023-04-09 00:00:00.000000000 Z
11
+ date: 2024-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -234,6 +234,7 @@ files:
234
234
  - lib/metanorma-plugin-datastruct.rb
235
235
  - lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb
236
236
  - lib/metanorma/plugin/datastruct/json2_text_preprocessor.rb
237
+ - lib/metanorma/plugin/datastruct/source_extractor.rb
237
238
  - lib/metanorma/plugin/datastruct/version.rb
238
239
  - lib/metanorma/plugin/datastruct/yaml2_text_preprocessor.rb
239
240
  - metanorma-plugin-datastruct.gemspec