lib/asciidoctor/iso/validate_section.rb in metanorma-iso-1.8.0 vs lib/asciidoctor/iso/validate_section.rb in metanorma-iso-1.8.1

- old
+ new

@@ -48,14 +48,15 @@ end end end def seqcheck(names, msg, accepted) - n = names.shift + n = names.shift return [] if n.nil? + test = accepted.map { |a| n.at(a) } - if test.all? { |a| a.nil? } + if test.all?(&:nil?) @log.add("Style", nil, msg) end names end @@ -72,41 +73,42 @@ # we skip normative references, it goes to end of list SEQ = [ { msg: "Initial section must be (content) Foreword", - val: ["./self::foreword"] + val: ["./self::foreword"], }, { msg: "Prefatory material must be followed by (clause) Scope", - val: ["./self::introduction", "./self::clause[@type = 'scope']" ] + val: ["./self::introduction", "./self::clause[@type = 'scope']"], }, { msg: "Prefatory material must be followed by (clause) Scope", - val: ["./self::clause[@type = 'scope']" ] + val: ["./self::clause[@type = 'scope']"], }, { msg: "Normative References must be followed by "\ "Terms and Definitions", - val: ["./self::terms | .//terms"] + val: ["./self::terms | .//terms"], }, - ].freeze + ].freeze SECTIONS_XPATH = "//foreword | //introduction | //sections/terms | .//annex | "\ - "//sections/definitions | //sections/clause | //references[not(parent::clause)] | "\ + "//sections/definitions | //sections/clause | "\ + "//references[not(parent::clause)] | "\ "//clause[descendant::references][not(parent::clause)]".freeze def sections_sequence_validate(root) names = root.xpath(SECTIONS_XPATH) - names = seqcheck(names, SEQ[0][:msg], SEQ[0][:val]) + names = seqcheck(names, SEQ[0][:msg], SEQ[0][:val]) n = names[0] - names = seqcheck(names, SEQ[1][:msg], SEQ[1][:val]) + names = seqcheck(names, SEQ[1][:msg], SEQ[1][:val]) if n&.at("./self::introduction") - names = seqcheck(names, SEQ[2][:msg], SEQ[2][:val]) + names = seqcheck(names, SEQ[2][:msg], SEQ[2][:val]) end - names = seqcheck(names, SEQ[3][:msg], SEQ[3][:val]) + names = seqcheck(names, SEQ[3][:msg], SEQ[3][:val]) n = names.shift if n&.at("./self::definitions") n = names.shift end if n.nil? || n.name != "clause" @@ -115,15 +117,15 @@ n&.at("./self::clause") || @log.add("Style", nil, "Document must contain clause after "\ "Terms and Definitions") n&.at("./self::clause[@type = 'scope']") && @log.add("Style", nil, "Scope must occur before Terms and Definitions") - n = names.shift + n = names.shift while n&.name == "clause" n&.at("./self::clause[@type = 'scope']") @log.add("Style", nil, "Scope must occur before Terms and Definitions") - n = names.shift + n = names.shift end unless %w(annex references).include? n&.name @log.add("Style", nil, "Only annexes and references can follow clauses") end while n&.name == "annex" @@ -143,10 +145,11 @@ @log.add("Style", nil, "There are sections after the final Bibliography") end def style_warning(node, msg, text = nil) return if @novalid + w = msg w += ": #{text}" if text @log.add("Style", node, w) end @@ -163,19 +166,22 @@ tech_report_style(root) end def tech_report_style(root) root.at("//bibdata/ext/doctype")&.text == "technical-report" or return - root.xpath("//sections/clause[not(@type = 'scope')] | //annex").each do |s| - r = requirement_check(extract_text(s)) - style_warning(s, "Technical Report clause may contain requirement", r) if r + root.xpath("//sections/clause[not(@type = 'scope')] | //annex") + .each do |s| + r = requirement_check(extract_text(s)) and + style_warning(s, + "Technical Report clause may contain requirement", r) end end ASSETS_TO_STYLE = - "//termsource | //formula | //termnote | //p[not(ancestor::boilerplate)] | "\ - "//li[not(p)] | //dt | //dd[not(p)] | //td[not(p)] | //th[not(p)]".freeze + "//termsource | //formula | //termnote | "\ + "//p[not(ancestor::boilerplate)] | //li[not(p)] | //dt | "\ + "//dd[not(p)] | //td[not(p)] | //th[not(p)]".freeze NORM_BIBITEMS = "//references[@normative = 'true']/bibitem".freeze # ISO/IEC DIR 2, 10.2 @@ -196,11 +202,24 @@ norm_bibitem_style(root) super end def subclause_validate(root) - root.xpath("//clause/clause/clause/clause/clause/clause/clause/clause").each do |c| + root.xpath("//clause/clause/clause/clause/clause/clause/clause/clause") + .each do |c| style_warning(c, "Exceeds the maximum clause depth of 7", nil) + end + end + + # ISO/IEC DIR 2, 22.3.2 + def onlychild_clause_validate(root) + root.xpath(Standoc::Utils::SUBCLAUSE_XPATH).each do |c| + next unless c.xpath("../clause").size == 1 + + title = c.at("./title") + location = c["id"] || "#{c.text[0..60]}..." + location += ":#{title.text}" if c["id"] && !title.nil? + @log.add("Style", nil, "#{location}: subclause is only child") end end end end end