lib/asciidoctor/iso/validate_section.rb in asciidoctor-iso-0.7.0 vs lib/asciidoctor/iso/validate_section.rb in asciidoctor-iso-0.7.1

- old
+ new

@@ -6,10 +6,13 @@ def section_validate(doc) foreword_validate(doc.root) normref_validate(doc.root) symbols_validate(doc.root) sections_sequence_validate(doc.root) + section_style(doc.root) + sourcecode_style(doc.root) + asset_style(doc.root) end def foreword_validate(root) f = root.at("//foreword") || return s = f.at("./subsection") @@ -49,11 +52,11 @@ names end # spec of permissible section sequence # we skip normative references, it goes to end of list - SEQ = + SEQ = [ { msg: "Initial section must be (content) Foreword", val: [{ tag: "foreword", title: "Foreword" }], }, @@ -69,13 +72,13 @@ { msg: "Normative References must be followed by "\ "Terms and Definitions", val: [ { tag: "terms", title: "Terms and Definitions" }, - { + { tag: "terms", - title: "Terms, Definitions, Symbols and Abbreviated Terms" + title: "Terms, Definitions, Symbols and Abbreviated Terms", }, ], }, ].freeze @@ -101,11 +104,12 @@ unless n warn "ISO style: Document must contain at least one clause" return end n[:tag] == "clause" || - warn("ISO style: Document must contain clause after Terms and Definitions") + warn("ISO style: Document must contain clause after "\ + "Terms and Definitions") n == { tag: "clause", title: "Scope" } && warn("ISO style: Scope must occur before Terms and Definitions") n = names.shift || return while n[:tag] == "clause" n[:title] == "Scope" && @@ -129,9 +133,63 @@ n = names.shift n == { tag: "references", title: "Bibliography" } || warn("ISO style: Final section must be (references) Bibliography") names.empty? || warn("ISO style: There are sections after the final Bibliography") + end + + NORM_ISO_WARN = "non-ISO/IEC reference not expected as normative".freeze + SCOPE_WARN = "Scope contains subsections: should be succint".freeze + + def section_style(root) + foreword_style(root.at("//foreword")) + introduction_style(root.at("//introduction")) + scope_style(root.at("//clause[title = 'Scope']")) + scope = root.at("//clause[title = 'Scope']/subsection") + scope.nil? || style_warning(scope, SCOPE_WARN, nil) + end + + def sourcecode_style(root) + root.xpath("//sourcecode").each do |x| + callouts = x.elements.select { |e| e.name == "callout" } + annotations = x.elements.select { |e| e.name == "annotation" } + if callouts.size != annotations.size + warn "#{x['id']}: mismatch of callouts and annotations" + end + end + end + + ASSETS_TO_STYLE = + "//termsource | //formula | //termnote | //p | //li[not(p)] | "\ + "//dt | //dd[not(p)] | //td[not(p)] | //th[not(p)]".freeze + + NORM_BIBITEMS = + "//references[title = 'Normative References']/bibitem".freeze + + def asset_title_style(root) + root.xpath("//figure[image][not(title)]").each do |node| + style_warning(node, "Figure should have title", nil) + end + root.xpath("//table[not(title)]").each do |node| + style_warning(node, "Table should have title", nil) + end + end + + def norm_bibitem_style(root) + root.xpath(NORM_BIBITEMS).each do |b| + if b.at(Cleanup::ISO_PUBLISHER_XPATH).nil? + Utils::warning(b, NORM_ISO_WARN, b.text) + end + end + end + + def asset_style(root) + root.xpath("//example | //termexample").each { |e| example_style(e) } + root.xpath("//note").each { |e| note_style(e) } + root.xpath("//fn").each { |e| footnote_style(e) } + root.xpath(ASSETS_TO_STYLE).each { |e| style(e, extract_text(e)) } + asset_title_style(root) + norm_bibitem_style(root) end end end end