require_relative "xrefs" require_relative "reqt_label" module Metanorma class Requirements class Modspec < Default def requirement_render1(node) requirement_table_cleanup(super) end def recommendation_base(node, klass) out = node.document.create_element("table") out.default_namespace = node.namespace.href %w(id keep-with-next keep-lines-together unnumbered).each do |x| out[x] = node[x] if node[x] end out["class"] = klass out["type"] = recommend_class(node) recommendation_component_labels(node) out end def recommendation_component_labels(node) node.xpath(ns("./component[@class = 'part']")).each_with_index do |c, i| c["label"] = (i + "A".ord).chr.to_s end node.xpath(ns("./component[not(@class = 'part')]")).each do |c| c["label"] = recommend_component_label(c) end end def recommendation_header(recommend, out) h = out.add_child(""\ "").first recommendation_name(recommend, h.at(ns(".//th"))) out end def recommendation_name(node, out) b = out.add_child("

").first name = node.at(ns("./name")) and name.children.each do |n| b << n end title = node.at(ns("./title")) return unless title && node.ancestors("requirement, recommendation, permission").empty? b << l10n(": ") if name title.children.each { |n| b << n } end def recommendation_attributes(node, out) ins = out.add_child("").first recommend_title(node, ins) recommendation_attributes1(node).each do |i| ins.add_child("#{i[0]}#{i[1]}") end ins end def recommend_title(node, out) label = node.at(ns("./identifier")) or return b = out.add_child("

") p = b.at(ns(".//p")) p["class"] = "RecommendationLabel" p << label.children.to_xml end def recommendation_attributes1(node) ret = recommendation_attributes1_head(node, []) node.xpath(ns("./classification")).each do |c| line = recommendation_attr_keyvalue(c, "tag", "value") and ret << line end ret end def recommendation_attributes1_head(node, head) oblig = node["obligation"] and head << ["Obligation", oblig] subj = node.at(ns("./subject"))&.children and head << [rec_subj(node), subj] node.xpath(ns("./classification[tag = 'target']/value")).each do |v| xref = recommendation_id(node.document, v.text) and head << [ rec_target(node), xref ] end %w(general class).include?(node["type"]) and xref = recommendation_link(node.document, node.at(ns("./identifier"))&.text) and head << ["Conformance test", xref] recommendation_attributes1_dependencies(node, head) end def recommendation_attributes1_dependencies(node, head) node.xpath(ns("./inherit")).each do |i| head << ["Dependency", recommendation_id(node.document, i.children.to_xml)] end node.xpath(ns("./classification[tag = 'indirect-dependency']/value")) .each do |v| xref = recommendation_id(node.document, v.children.to_xml) and head << ["Indirect Dependency", xref] end head end def recommendation_steps(node) node.elements.each { |e| recommendation_steps(e) } return node unless node.at(ns("./component[@class = 'step']")) d = node.at(ns("./component[@class = 'step']")) d = d.replace("
  1. #{d.children.to_xml}
") .first node.xpath(ns("./component[@class = 'step']")).each do |f| f = f.replace("
  • #{f.children.to_xml}
  • ").first d << f end node end def recommendation_attributes1_component(node, out) node = recommendation_steps(node) out << "#{node['label']}#{node.children}" out end def recommendation_attr_keyvalue(node, key, value) tag = node.at(ns("./#{key}")) value = node.at(ns("./#{value}")) (tag && value && !%w(target indirect-dependency).include?(tag.text)) or return nil [tag.text.capitalize, value.children] end def reqt_component_type(node) klass = node.name klass == "component" and klass = node["class"] "requirement-#{klass}" end def preserve_in_nested_table?(node) %w(recommendation requirement permission table ol dl ul).include?(node.name) end def requirement_component_parse(node, out) return out if node["exclude"] == "true" node.elements.size == 1 && node.first_element_child.name == "dl" and return reqt_dl(node.first_element_child, out) node.name == "component" and return recommendation_attributes1_component(node, out) out.add_child("").first .at(ns(".//td")) << (preserve_in_nested_table?(node) ? node : node.children) out end def reqt_dl(node, out) node.xpath(ns("./dt")).each do |dt| dd = dt.next_element dd&.name == "dd" or next out.add_child("#{dt.children.to_xml}"\ "#{dd.children.to_xml}") end out end def requirement_table_cleanup(table) return table unless table["type"] == "recommendclass" table.xpath(ns("./tbody/tr/td/table")).each do |t| t.xpath(ns("./thead | ./tbody |./tfoot")).each do |x| x.replace(x.children) end (x = t.at(ns("./tr/th[@colspan = '2']"))) && (y = t.at(ns("./tr/td[@colspan = '2']"))) and requirement_table_cleanup1(x, y) t.parent.parent.replace(t.children) end table end # table nested in table: merge label and caption into a single row def requirement_table_cleanup1(outer, inner) outer.delete("colspan") outer.delete("scope") inner.delete("colspan") inner.delete("scope") outer.name = "td" p = outer.at(ns("./p[@class = 'RecommendationTitle']")) and p.delete("class") outer.parent << inner.dup inner.parent.remove end def rec_subj(node) case node["type"] when "class" then "Target type" else "Subject" end end def rec_target(node) case node["type"] when "class" then "Target type" when "conformanceclass" then "Requirements class" when "verification", "abstracttest" then "Requirement" else "Target" end end def recommend_class(node) case node["type"] when "verification", "abstracttest" then "recommendtest" when "class", "conformanceclass" then "recommendclass" else "recommend" end end def recommend_name_class(node) if %w(verification abstracttest).include?(node["type"]) "RecommendationTestTitle" else "RecommendationTitle" end end def recommend_component_label(node) case node["class"] when "test-purpose" then "Test purpose" when "test-method" then "Test method" else Metanorma::Utils.strict_capitalize_first(node["class"]) end end end end end