module Metanorma::Standoc::Validate
Constants
- SOURCELOCALITY
Public Instance Methods
asset_style(root)
click to toggle source
# File lib/metanorma/standoc/validate_section.rb, line 38 def asset_style(root) asset_title_style(root) end
asset_title_style(root)
click to toggle source
# File lib/metanorma/standoc/validate_section.rb, line 29 def asset_title_style(root) root.xpath("//figure[image][not(name)]").each do |node| style_warning(node, "Figure should have title", nil) end root.xpath("//table[not(name)]").each do |node| style_warning(node, "Table should have title", nil) end end
concept_validate(doc, tag, refterm)
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 68 def concept_validate(doc, tag, refterm) found = false doc.xpath("//#{tag}/xref").each do |x| next if doc.at("//term[@id = '#{x['target']}']") next if doc.at("//definitions//dt[@id = '#{x['target']}']") ref = x&.at("../#{refterm}")&.text @log.add("Anchors", x, "#{tag.capitalize} #{ref} is pointing to "\ "#{x['target']}, which is not a term or symbol") found = true end found and @fatalerror << "#{tag.capitalize} not cross-referencing term or symbol" end
content_validate(doc)
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 43 def content_validate(doc) @fatalerror = [] xref_validate(doc) section_validate(doc) norm_ref_validate(doc) repeat_id_validate(doc.root) iev_validate(doc.root) concept_validate(doc, "concept", "refterm") concept_validate(doc, "related", "preferred//name") @fatalerror.empty? or clean_abort(@fatalerror.join("\n"), doc.to_xml) end
formattedstr_strip(doc)
click to toggle source
RelaxNG cannot cope well with wildcard attributes. So we strip any attributes from FormattedString instances (which can contain xs:any markup, and are signalled with @format) before validation.
# File lib/metanorma/standoc/validate.rb, line 126 def formattedstr_strip(doc) doc.xpath("//*[@format] | //stem | //bibdata//description | "\ "//formattedref | //bibdata//note | //bibdata/abstract | "\ "//bibitem/abstract | //bibitem/note | //misc-container") .each do |n| n.elements.each do |e| e.traverse do |e1| e1.element? and e1.each { |k, _v| e1.delete(k) } end end end doc end
hanging_para_style(root)
click to toggle source
# File lib/metanorma/standoc/validate_section.rb, line 42 def hanging_para_style(root) root.xpath("//clause | //annex | //foreword | //introduction | "\ "//acknowledgements").each do |c| next unless c.at("./clause") next if c.elements.reject do |n| %w(clause title).include? n.name end.empty? style_warning(c, "Hanging paragraph in clause") end end
iev_validate(xmldoc)
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 21 def iev_validate(xmldoc) @iev = init_iev or return xmldoc.xpath("//term").each do |t| t.xpath(".//termsource").each do |src| (/^IEC 60050-/.match(src&.at("./origin/@citeas")&.text) && loc = src.xpath(SOURCELOCALITY)&.text) or next iev_validate1(t, loc, xmldoc) end end end
iev_validate1(term, loc, xmldoc)
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 32 def iev_validate1(term, loc, xmldoc) iev = @iev.fetch(loc, xmldoc&.at("//language")&.text || "en") or return pref = term.xpath("./preferred//name").inject([]) do |m, x| m << x&.text&.downcase end pref.include?(iev.downcase) or @log.add("Bibliography", term, %(Term "#{pref[0]}" does not match ) + %(IEV #{loc} "#{iev}")) end
init_iev()
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 13 def init_iev return nil if @no_isobib return @iev if @iev @iev = Iev::Db.new(@iev_globalname, @iev_localname) unless @no_isobib @iev end
norm_ref_validate(doc)
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 55 def norm_ref_validate(doc) found = false doc.xpath("//references[@normative = 'true']/bibitem").each do |b| next unless docid = b.at("./docidentifier[@type = 'metanorma']") next unless /^\[\d+\]$/.match?(docid.text) @log.add("Bibliography", b, "Numeric reference in normative references") found = true end found and @fatalerror << "Numeric reference in normative references" end
repeat_id_validate(doc)
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 95 def repeat_id_validate(doc) ids = {} doc.xpath("//*[@id]").each do |x| ids = repeat_id_validate1(ids, x) end end
repeat_id_validate1(ids, elem)
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 84 def repeat_id_validate1(ids, elem) if ids[elem["id"]] @log.add("Anchors", elem, "Anchor #{elem['id']} has already been "\ "used at line #{ids[elem['id']]}") @fatalerror << "Multiple instances of same ID: #{elem['id']}" else ids[elem["id"]] = elem.line end ids end
schema_validate(doc, schema)
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 102 def schema_validate(doc, schema) Tempfile.open(["tmp", ".xml"], encoding: "UTF-8") do |f| schema_validate1(f, doc, schema) rescue Jing::Error => e clean_abort("Jing failed with error: #{e}", doc.to_xml) ensure f.close! end end
schema_validate1(file, doc, schema)
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 112 def schema_validate1(file, doc, schema) file.write(doc.to_xml) file.close errors = Jing.new(schema, encoding: "UTF-8").validate(file.path) warn "Syntax Valid!" if errors.none? errors.each do |e| @log.add("Metanorma XML Syntax", "XML Line #{'%06d' % e[:line]}:#{e[:column]}", e[:message]) end end
section_validate(doc)
click to toggle source
# File lib/metanorma/standoc/validate_section.rb, line 6 def section_validate(doc) sourcecode_style(doc.root) hanging_para_style(doc.root) asset_style(doc.root) end
sourcecode_style(root)
click to toggle source
# File lib/metanorma/standoc/validate_section.rb, line 12 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 @log.add("AsciiDoc Input", x, "mismatch of callouts and annotations") end end end
style_warning(node, msg, text = nil)
click to toggle source
# File lib/metanorma/standoc/validate_section.rb, line 23 def style_warning(node, msg, text = nil) w = msg w += ": #{text}" if text @log.add("Metanorma XML Style Warning", node, w) end
validate(doc)
click to toggle source
# File lib/metanorma/standoc/validate.rb, line 151 def validate(doc) content_validate(doc) schema_validate(formattedstr_strip(doc.dup), File.join(File.dirname(__FILE__), "isodoc.rng")) end
xref_validate(doc)
click to toggle source
manually check for xref/@target, xref/@to integrity
# File lib/metanorma/standoc/validate.rb, line 141 def xref_validate(doc) ids = doc.xpath("//*/@id").each_with_object({}) { |x, m| m[x.text] = 1 } doc.xpath("//xref/@target | //xref/@to").each do |x| next if ids[x.text] @log.add("Anchors", x.parent, "Crossreference target #{x.text} is undefined") end end