class Metanorma::Plugin::Lutaml::LutamlPreprocessor

Class for processing Lutaml files

Constants

REMARKS_ATTRIBUTE

Public Instance Methods

process(document, reader) click to toggle source
# File lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb, line 18
def process(document, reader)
  input_lines = reader.readlines.to_enum
  express_indexes = Utils.parse_document_express_indexes(
    document,
    input_lines
  )
  result_content = processed_lines(document, input_lines, express_indexes)
  result_reader = Asciidoctor::PreprocessorReader.new(document, result_content)
  result_reader
end

Protected Instance Methods

content_from_files(document, file_paths) click to toggle source
# File lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb, line 31
def content_from_files(document, file_paths)
  file_list = file_paths.map do |file_path|
    File.new(Utils.relative_file_path(document, file_path), encoding: "UTF-8")
  end
  ::Lutaml::Parser.parse(file_list)
end

Private Instance Methods

collect_internal_block_lines(_document, input_lines, end_mark) click to toggle source
# File lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb, line 67
def collect_internal_block_lines(_document, input_lines, end_mark)
  current_block = []
  while (block_line = input_lines.next) != end_mark
    current_block.push(block_line)
  end
  current_block
end
contexts_items(block_match, document, express_indexes) click to toggle source
# File lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb, line 75
def contexts_items(block_match, document, express_indexes)
  contexts_names = block_match[1].split(";").map(&:strip)
  file_paths = []
  result = contexts_names.each_with_object([]) do |path, res|
    if express_indexes[path]
      res.push(express_indexes[path])
    else
      file_paths.push(path)
    end
  end
  if !file_paths.empty?
    from_files = content_from_files(document, file_paths)
    # TODO: decide how to handle expressir multiply file parse as one object and lutaml
    if from_files.is_a?(Array)
      result.push(*from_files.map(&:to_liquid))
    else
      from_files = from_files.to_liquid
      from_files["schemas"] = from_files["schemas"].map do |n|
        n.merge("relative_path_prefix" => Utils.relative_file_path(document, File.dirname(n["file"])))
      end
      result.push(from_files)
    end
  end
  result
end
decorate_context_items(context_items, options) click to toggle source
# File lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb, line 129
def decorate_context_items(context_items, options)
  return context_items if !context_items.is_a?(Hash)

  context_items
    .map do |(key, val)|
      if val.is_a?(Hash)
        [key, decorate_context_items(val, options)]
      elsif key == REMARKS_ATTRIBUTE
        [key,
         val&.map do |remark|
           Metanorma::Plugin::Lutaml::ExpressRemarksDecorator
             .call(remark, options)
         end]
      elsif val.is_a?(Array)
        [key, val.map { |n| decorate_context_items(n, options) }]
      else
        [key, val]
      end
    end
    .to_h
end
parse_context_block(context_lines:, context_items:, context_name:, document:) click to toggle source
# File lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb, line 151
def parse_context_block(context_lines:,
                        context_items:,
                        context_name:,
                        document:)
  render_result, errors = Utils.render_liquid_string(
    template_string: context_lines.join("\n"),
    context_items: context_items,
    context_name: context_name,
    document: document
  )
  Utils.notify_render_errors(document, errors)
  render_result.split("\n")
end
parse_options(options_string) click to toggle source
# File lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb, line 121
def parse_options(options_string)
  options_string
    .to_s
    .scan(/(.+?)=(\s?[^\s]+)/)
    .map { |elem| elem.map(&:strip) }
    .to_h
end
parse_template(document, current_block, block_match, express_indexes) click to toggle source
# File lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb, line 101
def parse_template(document, current_block, block_match, express_indexes)
  options = parse_options(block_match[3])
  contexts_items(block_match, document, express_indexes)
    .map do |items|
      if items["schemas"]
        items["schemas"] = items["schemas"].map do |j|
          opts = options.merge("relative_path_prefix" => j["relative_path_prefix"])
          decorate_context_items(j, opts)
        end
      end
      parse_context_block(document: document,
                          context_lines: current_block,
                          context_items: items,
                          context_name: block_match[2].strip)
    end.flatten
  rescue StandardError => e
    document.logger.warn("Failed to parse lutaml block: #{e.message}")
    []
end
process_text_blocks(document, input_lines, express_indexes) click to toggle source
# File lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb, line 53
def process_text_blocks(document, input_lines, express_indexes)
  line = input_lines.next
  block_match = line.match(/^\[lutaml_express,([^,]+)?,?([^,]+)?,?([^,]+)?\]/)
  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,
                 express_indexes)
end
processed_lines(document, input_lines, express_indexes) click to toggle source
# File lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb, line 40
def processed_lines(document, input_lines, express_indexes)
  result = []
  loop do
    result
      .push(*process_text_blocks(
        document,
        input_lines,
        express_indexes
      ))
  end
  result
end