Module: Metanorma::Collection::Config::Converters

Included in:
Config, Manifest
Defined in:
lib/metanorma/collection/config/converters.rb

Constant Summary collapse

V1_BIBDATA_KEYS =

Keys present only in 1.x YAML format — unambiguously absent in 2.x

%w[docid link biblionote].freeze

Instance Method Summary collapse

Instance Method Details

#add_raw_xml_element(doc, raw) ⇒ Object

Add a single-element XML string as a child of the wrapper’s current context, preserving inline namespace declarations.

The custom-method ‘doc.add_element(parent, str)` path under lutaml-model 0.8 routes through Moxml fragment parsing, whose graft (`CustomMethodWrapper#add_fragment_children_to_parent`) discards xmlns declarations on grafted DataModel children. The `create_and_add_element` + `raw_content` path goes through the XML adapter’s raw-content handler, which uses Nokogiri’s native fragment parser and keeps xmlns intact. Tag the new element with MetanormaCollectionNamespace so it inherits cleanly from the metanorma-collection root rather than emitting ‘xmlns=“”`.



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/metanorma/collection/config/converters.rb', line 100

def add_raw_xml_element(doc, raw)
  parsed = Nokogiri::XML.fragment(raw)
  src = parsed.elements.first or return
  el = doc.create_and_add_element(src.name)
  el.namespace_class = MetanormaCollectionNamespace
  src.attribute_nodes.each do |a|
    doc.add_attribute(el, a.name, a.value)
  end
  el.raw_content = src.children.map(&:to_xml).join
  el
end

#bibdata_from_xml(model, node) ⇒ Object



68
69
70
71
72
# File 'lib/metanorma/collection/config/converters.rb', line 68

def bibdata_from_xml(model, node)
  node or return
  force_primary_docidentifier_xml(node.adapter_node.native)
  model.bibdata = Relaton::Cli.parse_xml(node.adapter_node.native)
end

#bibdata_from_yaml(model, value) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/metanorma/collection/config/converters.rb', line 12

def bibdata_from_yaml(model, value)
  (value and !value.empty?) or return
  if value.is_a?(String)
    value = YAML.safe_load_file(value,
                                permitted_classes: [Date,
                                                    Symbol])
  end
  force_primary_docidentifier_yaml(value)
  model.bibdata = if bibdata_yaml_v1_format?(value)
                    # 1.x YAML format (docid:/link:/biblionote: present) —
                    # bridge via HashParserV1 for backward compatibility
                    h = Relaton::Bib::HashParserV1.hash_to_bib(value)
                    Relaton::Bib::ItemData.new(**h)
                  else
                    # 2.x YAML format (docidentifier:/uri:/note: keys) —
                    # parse directly with lutaml-model
                    Relaton::Bib::Item.from_yaml(value.to_yaml)
                  end
end

#bibdata_to_xml(model, _parent, doc) ⇒ Object



80
81
82
83
# File 'lib/metanorma/collection/config/converters.rb', line 80

def bibdata_to_xml(model, _parent, doc)
  b = model.bibdata or return
  add_raw_xml_element(doc, b.to_xml(bibdata: true, date_format: :full))
end

#bibdata_to_yaml(model, doc) ⇒ Object



61
62
63
64
65
66
# File 'lib/metanorma/collection/config/converters.rb', line 61

def bibdata_to_yaml(model, doc)
  return unless model.bibdata

  doc["bibdata"] = YAML.safe_load(model.bibdata.to_yaml,
                                  permitted_classes: [Date, Symbol])
end

#bibdata_yaml_v1_format?(obj) ⇒ Boolean

Recursively detect 1.x-format YAML by presence of renamed keys. Checks the entire nested structure so relation:/contributor: entries are also detected.

Returns:

  • (Boolean)


35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/metanorma/collection/config/converters.rb', line 35

def bibdata_yaml_v1_format?(obj)
  case obj
  when Hash
    return true if (obj.keys.map(&:to_s) & V1_BIBDATA_KEYS).any?

    obj.values.any? { |v| bibdata_yaml_v1_format?(v) }
  when Array
    obj.any? { |v| bibdata_yaml_v1_format?(v) }
  else
    false
  end
end

#force_primary_docidentifier_xml(node) ⇒ Object



74
75
76
77
78
# File 'lib/metanorma/collection/config/converters.rb', line 74

def force_primary_docidentifier_xml(node)
  node.at("//docidentifier[@primary = 'true']") and return node
  d = node.at("//docidentifier") or return node
  d["primary"] = "true"
end

#force_primary_docidentifier_yaml(value) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/metanorma/collection/config/converters.rb', line 48

def force_primary_docidentifier_yaml(value)
  case value["docid"]
  when Array
    value["docid"].empty? ||
      value["docid"].none? do |x|
        x["primary"] == "true"
      end or
      value["docid"].first["primary"] = "true"
  when Hash
    value["docid"]["primary"] ||= "true"
  end
end

#nop_to_xml(model, parent, doc) ⇒ Object



86
# File 'lib/metanorma/collection/config/converters.rb', line 86

def nop_to_xml(model, parent, doc); end

#nop_to_yaml(model, doc) ⇒ Object



85
# File 'lib/metanorma/collection/config/converters.rb', line 85

def nop_to_yaml(model, doc); end