lib/metanorma/modspec/reqt_label.rb in mn-requirements-0.0.2 vs lib/metanorma/modspec/reqt_label.rb in mn-requirements-0.1.0

- old
+ new

@@ -1,45 +1,64 @@ module Metanorma class Requirements class Modspec < Default def recommendation_label(elem, type, xrefs) + @xrefs ||= xrefs.dup + init_lookups(elem.document) + label = elem.at(ns("./identifier"))&.text if inject_crossreference_reqt?(elem, label) - number = xrefs.anchor(reqtlabels(elem.document, label), :xref, false) - number.nil? ? type : number + recommendation_label_xref(elem, label, xrefs) else type = recommendation_class_label(elem) super end end - def reqtlabels(doc, label) - @reqtlabels ||= doc - .xpath(ns("//requirement | //recommendation | //permission")) + def recommendation_label_xref(elem, label, xrefs) + id = @reqtlabels[label] + number = xrefs.anchor(id, :xref, false) + number.nil? and return type + elem.ancestors("requirement, recommendation, permission").empty? and + return number + "<xref target='#{id}'>#{number}</xref>" + end + + def init_lookups(doc) + return if @init_lookups + + @init_lookups = true + @reqtlabels = reqtlabels(doc) + @reqt_ids = reqt_ids(doc) + @reqt_links_class = reqt_links_class(doc) + @reqt_links_test = reqt_links_test(doc) + end + + def reqtlabels(doc) + doc.xpath(ns("//requirement | //recommendation | //permission")) .each_with_object({}) do |r, m| - l = r.at(ns("./label"))&.text and m[l] = r["id"] + l = r.at(ns("./identifier"))&.text and m[l] = r["id"] end - @reqtlabels[label] end - # embedded reqts xref to top level reqts via label lookup + # embedded reqts xref to reqts via label lookup def inject_crossreference_reqt?(node, label) - !node.ancestors("requirement, recommendation, permission").empty? && - reqtlabels(node.document, label) + !node.ancestors("requirement, recommendation, permission").empty? and + @reqtlabels[label] end def recommendation_class_label(node) case node["type"] - when "verification" then @labels["#{node.name}test"] - when "class" then @labels["#{node.name}class"] - when "abstracttest" then @labels["abstracttest"] - when "conformanceclass" then @labels["conformanceclass"] + when "verification" then @labels["modspec"]["#{node.name}test"] + when "class" then @labels["modspec"]["#{node.name}class"] + when "abstracttest" then @labels["modspec"]["abstracttest"] + when "conformanceclass" then @labels["modspec"]["conformanceclass"] else case node.name - when "recommendation" then @labels["recommendation"] - when "requirement" then @labels["requirement"] - when "permission" then @labels["permission"] + when "recommendation" then @labels["default"]["recommendation"] + when "requirement" then @labels["default"]["requirement"] + when "permission" then @labels["default"]["permission"] end end end def reqt_ids(docxml) @@ -48,31 +67,52 @@ id = r.at(ns("./identifier")) or next m[id.text] = r["id"] end end - def reqt_links(docxml) + def reqt_links_test(docxml) docxml.xpath(ns("//requirement | //recommendation | //permission")) .each_with_object({}) do |r, m| next unless %w(conformanceclass verification).include?(r["type"]) subj = r.at(ns("./classification[tag = 'target']/value")) - id = r.at(ns("./identifier")) - next unless subj && id + id = r.at(ns("./identifier")) or next + lbl = @xrefs.anchor(@reqt_ids[id.text.strip], :xref, false) + next unless subj && lbl - m[subj.text] = { lbl: id.text, id: r["id"] } + m[subj.text] = { lbl: lbl, id: r["id"] } end end - def recommendation_link(docxml, ident) - @reqt_links ||= reqt_links(docxml) - test = @reqt_links[ident&.strip] or return nil + def recommendation_link_test(ident) + test = @reqt_links_test[ident&.strip] or return nil "<xref target='#{test[:id]}'>#{test[:lbl]}</xref>" end - def recommendation_id(docxml, ident) - @reqt_ids ||= reqt_ids(docxml) + def reqt_links_class(docxml) + docxml.xpath(ns("//requirement | //recommendation | //permission")) + .each_with_object({}) do |r, m| + next unless %w(class conformanceclass).include?(r["type"]) + + id = r.at(ns("./identifier")) or next + r.xpath(ns("./requirement | ./recommendation | ./permission")) + .each do |r1| + id1 = r1.at(ns("./identifier")) or next + lbl = @xrefs.anchor(@reqt_ids[id.text.strip], :xref, false) + next unless lbl + + m[id1.text] = { lbl: lbl, id: r["id"] } + end + end + end + + def recommendation_link_class(ident) + test = @reqt_links_class[ident&.strip] or return nil + "<xref target='#{test[:id]}'>#{test[:lbl]}</xref>" + end + + def recommendation_id(ident) test = @reqt_ids[ident&.strip] or return ident&.strip "<xref target='#{test}'>#{ident.strip}</xref>" end end end