metanorma-plugin-datastruct 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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