class Metanorma::Plugin::Datastruct::BaseStructuredTextPreprocessor
Base class for processing structured data blocks(yaml, json)
Constants
- BLOCK_END_REGEXP
- BLOCK_START_REGEXP
Public Instance Methods
process(document, reader)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 29 def process(document, reader) input_lines = reader.readlines.to_enum Asciidoctor::Reader.new(processed_lines(document, input_lines)) end
Protected Instance Methods
content_from_file(_document, _file_path)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 36 def content_from_file(_document, _file_path) raise ArgumentError, "Implement `content_from_file` in your class" end
Private Instance Methods
collect_internal_block_lines(document, input_lines, end_mark)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 72 def collect_internal_block_lines(document, input_lines, end_mark) current_block = [] nested_marks = [] while (block_line = input_lines.next) != end_mark if nested_match = block_line .match(/^\[#{config[:block_name]},(.+?),(.+?)\]/) current_block .push(*nested_context_tag(document, nested_match[1], nested_match[2]).split("\n")) next nested_marks.push(input_lines.next) end if nested_marks.include?(block_line) current_block.push("{% endwith_#{data_file_type}_nested_context %}") next nested_marks.delete(block_line) end current_block.push(block_line) end current_block end
data_file_type()
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 94 def data_file_type @config[:block_name].split("2").first end
nested_context_tag(document, file_path, context_name)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 98 def nested_context_tag(document, file_path, context_name) absolute_file_path = relative_file_path(document, file_path) <<~TEMPLATE {% capture nested_file_path %} #{absolute_file_path} {% endcapture %} {% with_#{data_file_type}_nested_context nested_file_path, #{context_name} %} TEMPLATE end
notify_render_errors(document, errors)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 166 def notify_render_errors(document, errors) errors.each do |error_obj| document .logger .warn("Liquid render error: #{error_obj.message}") end end
parse_context_block(context_lines:, context_items:, context_name:, document:)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 140 def parse_context_block(context_lines:, context_items:, context_name:, document:) render_result, errors = render_liquid_string( template_string: context_lines.join("\n"), context_items: context_items, context_name: context_name, document: document ) notify_render_errors(document, errors) render_result.split("\n") end
parse_template(document, current_block, block_match)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 108 def parse_template(document, current_block, block_match) transformed_liquid_lines = current_block .map(&method(:transform_line_liquid)) context_items = content_from_file(document, block_match[1]) parse_context_block(document: document, context_lines: transformed_liquid_lines, context_items: context_items, context_name: block_match[2].strip) rescue StandardError => e document.logger .warn("Failed to parse #{config[:block_name]} \ block: #{e.message}") [] end
process_text_blocks(document, input_lines)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 59 def process_text_blocks(document, input_lines) line = input_lines.next block_match = line.match(/^\[#{config[:block_name]},(.+?),(.+?)\]/) return [line] if block_match.nil? end_mark = input_lines.next parse_template(document, collect_internal_block_lines(document, input_lines, end_mark), block_match) end
processed_lines(document, input_lines)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 42 def processed_lines(document, input_lines) result = [] loop do result.push(*process_text_blocks(document, input_lines)) end result end
relative_file_path(document, file_path)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 50 def relative_file_path(document, file_path) docfile_directory = File.dirname( document.attributes["docfile"] || "." ) document .path_resolver .system_path(file_path, docfile_directory) end
render_liquid_string(template_string:, context_items:, context_name:, document:)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 154 def render_liquid_string(template_string:, context_items:, context_name:, document:) liquid_template = Liquid::Template.parse(template_string) # Allow includes for the template liquid_template.registers[:file_system] = ::Liquid::LocalFileSystem.new(relative_file_path(document, "")) rendered_string = liquid_template .render(context_name => context_items, strict_variables: true, error_mode: :warn) [rendered_string, liquid_template.errors] end
transform_line_liquid(line)
click to toggle source
# File lib/metanorma/plugin/datastruct/base_structured_text_preprocessor.rb, line 123 def transform_line_liquid(line) if line.match?(BLOCK_START_REGEXP) line.gsub!(BLOCK_START_REGEXP, '{% keyiterator \1, \2 %}') end if line.strip.match?(BLOCK_END_REGEXP) line.gsub!(BLOCK_END_REGEXP, "{% endkeyiterator %}") end line .gsub(/(?<!{){(?!%)([^{}]+)(?<!%)}(?!})/, '{{\1}}') .gsub(/[a-z\.]+\#/, "index") .gsub(/{{(.+)\s+\+\s+(\d+)\s*?}}/, '{{ \1 | plus: \2 }}') .gsub(/{{(.+)\s+\-\s+(\d+)\s*?}}/, '{{ \1 | minus: \2 }}') .gsub(/{{(.+)\.values(.*?)}}/, '{% assign custom_value = \1 | values %}{{custom_value\2}}') end