Class: Metanorma::Requirements::Default

Inherits:
Object
  • Object
show all
Defined in:
lib/metanorma/default/utils.rb,
lib/metanorma/default/xrefs.rb,
lib/metanorma/default/isodoc.rb,
lib/metanorma/default/cleanup.rb,
lib/metanorma/default/default.rb

Direct Known Subclasses

Modspec

Constant Summary collapse

REQS =
%w(recommendation requirement permission).freeze

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Default

Returns a new instance of Default.



10
11
12
13
14
15
# File 'lib/metanorma/default/default.rb', line 10

def initialize(options)
  @c = HTMLEntities.new
  @parent = options[:parent]
  @i18n = @parent.i18n
  @labels = @parent.labels
end

Instance Method Details

#attr_code(attributes) ⇒ Object



10
11
12
# File 'lib/metanorma/default/utils.rb', line 10

def attr_code(attributes)
  Metanorma::Utils.attr_code(attributes)
end

#csv_split(text, delim = ";") ⇒ Object



14
15
16
# File 'lib/metanorma/default/utils.rb', line 14

def csv_split(text, delim = ";")
  Metanorma::Utils.csv_split(text, delim)
end

#descr_classif_extract(desc, ins) ⇒ Object



127
128
129
130
131
132
133
134
135
# File 'lib/metanorma/default/isodoc.rb', line 127

def descr_classif_extract(desc, ins)
  dlist = desc.xpath(ns("./classification"))
  dlist.each do |x|
    x.at(ns("./tag")).name = "dt"
    x.at(ns("./value")).name = "dd"
    ins << x.children
    x.remove
  end
end

#descr_classif_render(reqt) ⇒ Object



121
122
123
124
125
# File 'lib/metanorma/default/isodoc.rb', line 121

def descr_classif_render(reqt)
  reqt.at(ns("./classification")) or return
  ins = reqt.at(ns("./classification")).before("<dl/>").previous
  descr_classif_extract(reqt, ins)
end

#dl_to_attrs(elem, dlist, name) ⇒ Object



86
87
88
# File 'lib/metanorma/default/cleanup.rb', line 86

def dl_to_attrs(elem, dlist, name)
  Metanorma::Utils::dl_to_attrs(elem, dlist, name)
end

#dl_to_elems(ins, elem, dlist, name) ⇒ Object



90
91
92
# File 'lib/metanorma/default/cleanup.rb', line 90

def dl_to_elems(ins, elem, dlist, name)
  Metanorma::Utils::dl_to_elems(ins, elem, dlist, name)
end

#l10n(text) ⇒ Object



4
5
6
# File 'lib/metanorma/default/isodoc.rb', line 4

def l10n(text)
  @i18n.l10n(text)
end

#noko(&block) ⇒ Object



6
7
8
# File 'lib/metanorma/default/utils.rb', line 6

def noko(&block)
  Metanorma::Utils.noko(&block)
end

#ns(xpath) ⇒ Object



22
23
24
# File 'lib/metanorma/default/utils.rb', line 22

def ns(xpath)
  Metanorma::Utils.ns(xpath)
end

#permission_parts(_block, _block_id, _label, _klass) ⇒ Object



4
5
6
# File 'lib/metanorma/default/xrefs.rb', line 4

def permission_parts(_block, _block_id, _label, _klass)
  []
end

#postprocess_anchor_struct(_block, anchor) ⇒ Object



30
31
32
# File 'lib/metanorma/default/xrefs.rb', line 30

def postprocess_anchor_struct(_block, anchor)
  anchor
end

#recommendation_attr_keyvalue(node, key, value) ⇒ Object



88
89
90
91
92
93
# File 'lib/metanorma/default/isodoc.rb', line 88

def recommendation_attr_keyvalue(node, key, value)
  tag = node.at(ns("./#{key}")) or return nil
  value = node.at(ns("./#{value}")) or return nil
  l10n("#{Metanorma::Utils.strict_capitalize_first tag.text}: " \
       "#{to_xml(value.children)}")
end

#recommendation_attr_parse(node, label) ⇒ Object



84
85
86
# File 'lib/metanorma/default/isodoc.rb', line 84

def recommendation_attr_parse(node, label)
  l10n("#{label}: #{to_xml(node.children)}")
end

#recommendation_attributes(node, out) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/metanorma/default/isodoc.rb', line 95

def recommendation_attributes(node, out)
  ret = recommendation_attributes1(node, [])
    .map { |a| "<em>#{a}</em>" }
  ret.empty? or
    out << "<p>#{ret.join("<br/>\n")}</p>"
  out
end

#recommendation_attributes1(node, out) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/metanorma/default/isodoc.rb', line 69

def recommendation_attributes1(node, out)
  oblig = node["obligation"] and
    out << l10n("#{@labels['default']['obligation']}: #{oblig}")
  node.xpath(ns("./subject")).each do |subj|
    out << l10n("#{@labels['default']['subject']}: #{subj.text}")
  end
  node.xpath(ns("./inherit")).each do |i|
    out << recommendation_attr_parse(i, @labels["default"]["inherits"])
  end
  node.xpath(ns("./classification")).each do |c|
    out << recommendation_attr_keyvalue(c, "tag", "value")
  end
  out
end

#recommendation_base(node, klass) ⇒ Object



52
53
54
55
56
57
58
59
60
# File 'lib/metanorma/default/isodoc.rb', line 52

def recommendation_base(node, klass)
  out = node.document.create_element(klass)
  node.attributes.each do |k, v|
    out[k] = v
  end
  n = node.at(ns("./fmt-name")) and out << n
  n = node.at(ns("./fmt-xref-label")) and out << n
  out
end

#recommendation_header(_node, out) ⇒ Object



48
49
50
# File 'lib/metanorma/default/isodoc.rb', line 48

def recommendation_header(_node, out)
  out
end

#recommendation_label(elem, type, xrefs) ⇒ Object



8
9
10
11
12
13
14
15
16
17
# File 'lib/metanorma/default/isodoc.rb', line 8

def recommendation_label(elem, type, xrefs)
  label, title = recommendation_labels(elem)
  type = "<span class='fmt-element-name'>#{type}</span>"
  num = xrefs.anchor(elem["id"], :label, false)
  num &&= "<semx element='autonum' source='#{elem['id']}'>#{num}</semx>"
  ret = "#{type} #{num}".strip
  label || title and
    ret += recommendation_label_add(elem, label, title)
  ret
end

#recommendation_label_add(elem, label, title) ⇒ Object



19
20
21
22
23
24
25
26
27
# File 'lib/metanorma/default/isodoc.rb', line 19

def recommendation_label_add(elem, label, title)
  r = recommendation_label_caption_delim
  label and
    r += "<semx element='identifier' source='#{elem['id']}'>#{label}</semx>"
  label && title and r += ". "
  title and
    r += "<semx element='title' source='#{elem['id']}'>#{title}</semx>"
  r
end

#recommendation_label_caption_delimObject



29
30
31
# File 'lib/metanorma/default/isodoc.rb', line 29

def recommendation_label_caption_delim
  "<span class='fmt-caption-delim'>:<br/></span>"
end

#recommendation_labels(node) ⇒ Object



62
63
64
65
66
67
# File 'lib/metanorma/default/isodoc.rb', line 62

def recommendation_labels(node)
  [node.at(ns("./identifier")), node.at(ns("./title"))]
    .map do |n|
    to_xml(n&.children)
  end
end

#req_class_pathsObject



8
9
10
11
12
13
14
15
16
17
# File 'lib/metanorma/default/xrefs.rb', line 8

def req_class_paths
  [
    { klass: "permission", label: @labels["default"]["permission"],
      xpath: "permission" },
    { klass: "requirement", label: @labels["default"]["requirement"],
      xpath: "requirement" },
    { klass: "recommendation", label: @labels["default"]["recommendation"],
      xpath: "recommendation" },
  ]
end

#req_classif_parse(classif) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/metanorma/default/default.rb', line 39

def req_classif_parse(classif)
  ret = []
  @c.decode(classif).split(/;\s*/).each do |c|
    c1 = c.split(/:\s*/)
    next unless c1.size == 2

    c1[1].split(/,\s*/).each { |v| ret << [c1[0], v] }
  end
  ret
end

#req_nested_class_pathsObject



19
20
21
22
23
24
25
26
27
28
# File 'lib/metanorma/default/xrefs.rb', line 19

def req_nested_class_paths
  [
    { klass: "permission", label: @labels["default"]["permission"],
      xpath: "permission" },
    { klass: "requirement", label: @labels["default"]["requirement"],
      xpath: "requirement" },
    { klass: "recommendation", label: @labels["default"]["recommendation"],
      xpath: "recommendation" },
  ]
end

#reqt_attrs(node, attrs) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/metanorma/default/default.rb', line 59

def reqt_attrs(node, attrs)
  attr_code(attrs.merge(
              id: Metanorma::Utils.anchor_or_uuid(node),
              unnumbered: node.option?("unnumbered") ? "true" : nil,
              number: node.attr("number"),
              subsequence: node.attr("subsequence"),
              obligation: node.attr("obligation"),
              filename: node.attr("filename"),
              type: node.attr("type"),
              class: node.attr("class"),
            ))
end

#reqt_component_type(node) ⇒ Object



103
104
105
106
107
# File 'lib/metanorma/default/isodoc.rb', line 103

def reqt_component_type(node)
  klass = node.name
  klass == "component" and klass = node["class"]
  "requirement-#{klass}"
end

#reqt_dl_to_classif(ins, reqt, dlist) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/metanorma/default/cleanup.rb', line 118

def reqt_dl_to_classif(ins, reqt, dlist)
  if a = reqt.at("./classification[last()]") then ins = a end
  dlist.xpath("./dt[text()='classification']").each do |e|
    val = e.at("./following::dd").text.strip
    req_classif_parse(val).each do |r|
      ins.next = "<classification><tag>#{r[0]}</tag>" \
                 "<value>#{r[1]}</value></classification>"
      ins = ins.next
    end
  end
  ins
end

#reqt_dl_to_classif1(ins, reqt, dlist) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
# File 'lib/metanorma/default/cleanup.rb', line 131

def reqt_dl_to_classif1(ins, reqt, dlist)
  if a = reqt.at("./classification[last()]") then ins = a end
  dlist.xpath("./dt").each do |e|
    next if (requirement_metadata1_attrs + requirement_metadata1_tags +
              + %w(classification))
      .include?(e.text)

    ins = reqt_dl_to_classif2(e, ins)
  end
  ins
end

#reqt_dl_to_classif2(term, ins) ⇒ Object



143
144
145
146
147
148
# File 'lib/metanorma/default/cleanup.rb', line 143

def reqt_dl_to_classif2(term, ins)
  val = unwrap_para(term.at("./following::dd"))
  ins.next = "<classification><tag>#{term.text}</tag>" \
             "<value>#{val}</value></classification>"
  ins.next
end

#reqt_metadata_node?(node) ⇒ Boolean

Returns:

  • (Boolean)


33
34
35
36
# File 'lib/metanorma/default/isodoc.rb', line 33

def (node)
  %w(identifier title subject classification tag value
     inherit name fmt-name fmt-xref-label fmt-title).include? node.name
end

#reqt_subpart?(name) ⇒ Boolean

Returns:

  • (Boolean)


17
18
19
20
# File 'lib/metanorma/default/default.rb', line 17

def reqt_subpart?(name)
  %w[specification measurement-target verification import identifier title
     description component subject inherit classification].include? name
end

#reqt_subpart_attrs(node, name, attrs) ⇒ Object



22
23
24
25
26
27
28
# File 'lib/metanorma/default/default.rb', line 22

def reqt_subpart_attrs(node, name, attrs)
  klass = node.attr("class") || "component"
  attr_code(attrs
    .merge(exclude: node.option?("exclude"),
           type: node.attr("type"),
           class: name == "component" ? klass : nil))
end

#requirement(node, obligation, attrs) ⇒ Object



90
91
92
93
94
95
96
97
# File 'lib/metanorma/default/default.rb', line 90

def requirement(node, obligation, attrs)
  noko do |xml|
    xml.send obligation, **reqt_attrs(node, attrs) do |ex|
      requirement_elems(node, ex)
      wrap_in_para(node, ex)
    end
  end
end

#requirement_classification(classif, out) ⇒ Object



50
51
52
53
54
55
56
57
# File 'lib/metanorma/default/default.rb', line 50

def requirement_classification(classif, out)
  req_classif_parse(classif).each do |r|
    out.classification do |c|
      c.tag { |t| t << r[0] }
      c.value { |v| v << r[1] }
    end
  end
end

#requirement_component_parse(node, out) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/metanorma/default/isodoc.rb', line 109

def requirement_component_parse(node, out)
  node["exclude"] == "true" and return out
  ret = node.dup
  if reqt_subpart?(node.name)
    ret["type"] = reqt_component_type(node)
    ret.name = "div"
  end
  descr_classif_render(ret)
  out << ret
  out
end

#requirement_description_cleanup1(reqt) ⇒ Object



58
59
60
61
62
63
64
65
66
67
# File 'lib/metanorma/default/cleanup.rb', line 58

def requirement_description_cleanup1(reqt)
  while d = reqt.at("./description[following-sibling::*[1]" \
                    "[self::description]]")
    n = d.next.remove
    d << n.children
  end
  reqt.xpath("./description[normalize-space(.)='']").each do |r|
    r.replace("\n")
  end
end

#requirement_description_wrap(reqt, text) ⇒ Object



48
49
50
51
52
53
54
55
56
# File 'lib/metanorma/default/cleanup.rb', line 48

def requirement_description_wrap(reqt, text)
  return if (text.element? && (reqt_subpart?(text.name) ||
          REQS.include?(text.name))) ||
    (text.text.strip.empty? && !text.at(".//xref | .//eref | .//link"))

  t = Nokogiri::XML::Element.new("description", reqt.document)
  text.before(t)
  t.children = text.remove
end

#requirement_descriptions_cleanup(reqt) ⇒ Object



38
39
40
41
42
43
44
# File 'lib/metanorma/default/cleanup.rb', line 38

def requirement_descriptions_cleanup(reqt)
  reqt.xpath(".//p[not(./*)][normalize-space(.)='']").each(&:remove)
  reqt.children.each do |e|
    requirement_description_wrap(reqt, e)
  end
  requirement_description_cleanup1(reqt)
end

#requirement_elems(node, out) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/metanorma/default/default.rb', line 72

def requirement_elems(node, out)
  node.title and out.title { |t| t << node.title }
  a = node.attr("identifier") and out.identifier do |l|
    l << out.text(a)
  end
  a = node.attr("subject") and csv_split(a)&.each do |subj|
    out.subject { |s| s << out.text(subj) }
  end
  a = @c.decode(node.attr("inherit")) and
    csv_split(a)&.each do |i|
      out.inherit do |inh|
        inh << @c.encode(i, :hexadecimal)
      end
    end
  classif = node.attr("classification") and
    requirement_classification(classif, out)
end

#requirement_identifier_cleanup(reqt) ⇒ Object



6
7
8
9
10
# File 'lib/metanorma/default/cleanup.rb', line 6

def requirement_identifier_cleanup(reqt)
  reqt.xpath("./identifier[link] | ./inherit[link]").each do |i|
    i.children = i.at("./link/@target").text
  end
end

#requirement_inherit_cleanup(reqt) ⇒ Object



12
13
14
15
# File 'lib/metanorma/default/cleanup.rb', line 12

def requirement_inherit_cleanup(reqt)
  ins = requirement_inherit_insert(reqt)
  reqt.xpath("./*//inherit").each { |i| ins.previous = i }
end

#requirement_inherit_insert(reqt) ⇒ Object



17
18
19
20
21
22
23
24
# File 'lib/metanorma/default/cleanup.rb', line 17

def requirement_inherit_insert(reqt)
  ins = reqt.at("./classification") || reqt.at(
    "./description | ./measurementtarget | ./specification | " \
    "./verification | ./import | ./description | ./component | " \
    "./requirement | ./recommendation | ./permission",
  ) and return ins
  requirement_inherit_insert1(reqt)
end

#requirement_inherit_insert1(reqt) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/metanorma/default/cleanup.rb', line 26

def requirement_inherit_insert1(reqt)
  if t = reqt.at("./title")
    t.next = " "
    t.next
  else
    if reqt.children.empty? then reqt.add_child(" ")
    else reqt.children.first.previous = " "
    end
    reqt.children.first
  end
end

#requirement_metadata1(reqt, dlist, ins) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
# File 'lib/metanorma/default/cleanup.rb', line 94

def requirement_metadata1(reqt, dlist, ins)
  ins = requirement_metadata1_set_insert(reqt, ins)
  requirement_metadata1_attrs.each do |a|
    dl_to_attrs(reqt, dlist, a)
  end
  requirement_metadata1_tags.each do |a|
    ins = dl_to_elems(ins, reqt, dlist, a)
  end
  ins = reqt_dl_to_classif(ins, reqt, dlist)
  reqt_dl_to_classif1(ins, reqt, dlist)
end

#requirement_metadata1_attrsObject



74
75
76
# File 'lib/metanorma/default/cleanup.rb', line 74

def requirement_metadata1_attrs
  %w(obligation model type class)
end

#requirement_metadata1_set_insert(reqt, ins) ⇒ Object



106
107
108
109
110
# File 'lib/metanorma/default/cleanup.rb', line 106

def requirement_metadata1_set_insert(reqt, ins)
  ins and return ins
  reqt.children.first.previous = " "
  reqt.children.first
end

#requirement_metadata1_tagsObject



78
79
80
# File 'lib/metanorma/default/cleanup.rb', line 78

def requirement_metadata1_tags
  %w(identifier subject inherit)
end

#requirement_metadata_cleanup(reqt) ⇒ Object



69
70
71
72
# File 'lib/metanorma/default/cleanup.rb', line 69

def (reqt)
  dl = reqt.at("./dl[@metadata = 'true']")&.remove or return
  requirement_metadata1(reqt, dl, reqt.at("./title"))
end

#requirement_metadata_component_tagsObject



82
83
84
# File 'lib/metanorma/default/cleanup.rb', line 82

def 
  []
end

#requirement_render1(node) ⇒ Object



38
39
40
41
42
43
44
45
46
# File 'lib/metanorma/default/isodoc.rb', line 38

def requirement_render1(node)
  out = recommendation_base(node, node.name)
  ins = recommendation_header(node, out)
  ins = recommendation_attributes(node, ins)
  node.elements.reject do |n|
    (n)
  end.each { |n| ins = requirement_component_parse(n, ins) }
  out
end

#requirement_subpart(node, attrs) ⇒ Object



30
31
32
33
34
35
36
37
# File 'lib/metanorma/default/default.rb', line 30

def requirement_subpart(node, attrs)
  name = node.role || node.attr("style")
  noko do |xml|
    xml.send name, **reqt_subpart_attrs(node, name, attrs) do |o|
      o << node.content
    end
  end
end

#requirement_type_cleanup(reqt) ⇒ Object



4
# File 'lib/metanorma/default/cleanup.rb', line 4

def requirement_type_cleanup(reqt); end

#to_xml(node) ⇒ Object



26
27
28
29
# File 'lib/metanorma/default/utils.rb', line 26

def to_xml(node)
  node&.to_xml(encoding: "UTF-8", indent: 0,
             save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
end

#unwrap_para(ddef) ⇒ Object



112
113
114
115
116
# File 'lib/metanorma/default/cleanup.rb', line 112

def unwrap_para(ddef)
  e = ddef.elements and e.size == 1 && e.first.name == "p" and
    ddef = e.first
  to_xml(ddef.children)
end

#validate(_reqt, _log) ⇒ Object



99
100
101
# File 'lib/metanorma/default/default.rb', line 99

def validate(_reqt, _log)
  []
end

#wrap_in_para(node, out) ⇒ Object



18
19
20
# File 'lib/metanorma/default/utils.rb', line 18

def wrap_in_para(node, out)
  Metanorma::Utils.wrap_in_para(node, out)
end