class Asciidoctor::BSI::Converter
Constants
- BSI_PUBLISHER_XPATH
- NORM_BSI_WARN
- PARENT_PARA
- PERMISSION_RE_STR
- POSSIBILITY_RE_STR
- RECOMMENDATION_RE_STR
- REQUIREMENT_RE_STR
Rules for Structure 7.1
- XML_NAMESPACE
- XML_ROOT_TAG
Public Instance Methods
Rules for Structure 24.8
# File lib/asciidoctor/bsi/validate_requirement.rb, line 70 def admonition_style(node, text) r = requirement_check(text) and style_warning(node, "admonition may contain requirement", r) r = permission_check(text) and style_warning(node, "admonition may contain permission", r) r = recommendation_check(text) and style_warning(node, "admonition may contain recommendation", r) r = possibility_check(text) and style_warning(node, "admonition may contain possibility", r) end
Rules for Structure 20.2
# File lib/asciidoctor/bsi/validate.rb, line 95 def annex_normative_validate(root) @doctype == "guide" and root.xpath("//annex[@obligation = 'normative']") .each do |s| style_warning(s, "Guide contains normative annex", s&.at("./title")&.text) end end
Rules for Structure 20.4
# File lib/asciidoctor/bsi/validate.rb, line 104 def annex_ordering_validate(root) ids = citation_order(root.xpath("//annex")) cite_order = ids.keys.sort_by { |a| ids[a] || 999999 } annex_order = root.xpath("//annex").map { |x| x["id"] } cite_order.each_with_index do |a, i| next if annex_order[i] == a || ids[a].nil? annex = root.at("//annex[@id = '#{a}']") title = annex&.at("./title")&.text || "Annex #{a}" style_warning(annex, "#{title} should be annex ##{i + 1}", nil) end end
# File lib/asciidoctor/bsi/validate.rb, line 89 def annex_validate(root) annex_normative_validate(root) annex_ordering_validate(root) end
# File lib/asciidoctor/bsi/validate_requirement.rb, line 62 def asset_style(root) root.xpath("//admonition[not(@type = 'commentary')]").each do |e| admonition_style(e, extract_text(e)) end super end
Rules for Structure 7.1
# File lib/asciidoctor/bsi/validate_requirement.rb, line 16 def avoid_must(root) root.xpath("//sections/clause[not(@type = 'scope')] | //annex") .each do |s| r = avoid_must_check(extract_text(s)) style_warning(s, "text contains ambiguous 'must'", r) if r end end
# File lib/asciidoctor/bsi/validate_requirement.rb, line 24 def avoid_must_check(text) text.split(/\.\s+/).each do |t| return t if /\b(must|will)\b/xi.match? t end nil end
# File lib/asciidoctor/bsi/cleanup.rb, line 64 def bibdata_cleanup(xmldoc) super xmldoc.xpath("//bibdata/relation[@type = 'bsi-related']").each do |r| r["type"] = "related" end end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 4 def biblio_cleanup(xmldoc) biblio_metanorma_ids_informative(xmldoc) super end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 98 def biblio_key_title(bib) bib&.at("./title[@type = 'main']")&.text || bib&.at("./title")&.text || bib&.at("./formattedref")&.text end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 17 def biblio_metanorma_ids1(bib, idx) bib.at("./docidentifier[@type][not(@type = 'DOI' or "\ "@type = 'ISSN' or @type = 'ISBN')]") and return bib&.at("./docidentifier[@type = 'metanorma']")&.remove bib.at("./docidentifier").previous = "<docidentifier type='metanorma'>[#{idx}]</docidentifier>" end
Rules for Structure 21.4
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 26 def biblio_metanorma_ids_informative(xmldoc) xmldoc.xpath("//references[@normative = 'false']/bibitem") .each_with_index do |b, i| biblio_metanorma_ids1(b, i) end end
Rules for Structure 15.4
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 10 def biblio_metanorma_ids_normative(xmldoc) xmldoc.xpath("//references[@normative = 'true']/bibitem") .each_with_index do |b, i| biblio_metanorma_ids1(b, i) end end
Rules for Structure 21.5
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 152 def biblio_preface(ref) ref.at("./title").next = "<p>#{@i18n.biblio_pref}</p>" end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 103 def biblio_renumber(xmldoc) ["true", "false"].each do |norm| i = 0 xmldoc.xpath("//bibliography//references | //clause//references | "\ "//annex//references").each do |r| next if r["normative"] != norm r.xpath("./bibitem").each do |b| next unless docid = b.at("./docidentifier[@type = 'metanorma']") next unless /^\[\d+\]$/.match?(docid.text) i += 1 docid.children = "[#{norm == 'true' ? 'N' : ''}#{i}]" end end end end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 33 def biblio_reorder(xmldoc) xmldoc.xpath("//references[@normative = 'false']").each do |r| biblio_reorder1(r) end xmldoc.xpath("//references[@normative = 'true']").each do |r| biblio_reorder1(r) end end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 144 def boilerplate_cleanup(xmldoc) super f = xmldoc.at("//bibliography//references[@normative = 'false']"\ "[not(references)]") f and biblio_preface(f) end
# File lib/asciidoctor/bsi/converter.rb, line 15 def boilerplate_file(_x_orig) File.join(@libdir, "bsi_intro_en.xml") end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 46 def citation_order(bib) return {} if bib.empty? ids = bib.each_with_object({}) { |b, m| m[b["id"]] = nil } bib.first.document.xpath(".//xref").each_with_index do |b, i| next unless ids.has_key?(b["target"]) ids[b["target"]] ||= i + 1 end ids end
# File lib/asciidoctor/bsi/cleanup.rb, line 6 def cleanup(xmldoc) super ol_cleanup(xmldoc) commentary_cleanup(xmldoc) xmldoc end
# File lib/asciidoctor/bsi/converter.rb, line 39 def commentary(node) noko do |xml| xml.admonition **commentary_attrs(node) do |a| node.title.nil? or a.name { |name| name << node.title } wrap_in_para(node, a) end end.join("\n") end
# File lib/asciidoctor/bsi/converter.rb, line 29 def commentary_attrs(node) b = node.attr("beforeclauses") == "true" ? "true" : nil attr_code(keep_attrs(node).merge( id: Metanorma::Utils::anchor_or_uuid(node), type: "commentary", target: node.attr("target"), beforeclauses: b, )) end
# File lib/asciidoctor/bsi/cleanup.rb, line 31 def commentary_cleanup(xmldoc) @isodoc ||= isodoc(@lang, @script) xmldoc.xpath("//admonition[@type = 'commentary'][not(@target)]") .each do |a| a["target"] = @isodoc.get_clause_id(a) end end
# File lib/asciidoctor/bsi/validate.rb, line 167 def content_validate(doc) super symbol_style(doc) table_validate(doc) listcount_validate(doc) list_punctuation(doc) end
BS as a prefix goes first
# File lib/asciidoctor/bsi/cleanup.rb, line 50 def docidentifier_cleanup(xmldoc) prefix = get_id_prefix(xmldoc) id = xmldoc.at("//bibdata/docidentifier[@type = 'BS']") or return id.content = id_prefix(prefix, id) id = xmldoc.at("//bibdata/ext/structuredidentifier/project-number") and id.content = id_prefix(prefix, id) end
BSI
0:2016 9.4.1
# File lib/asciidoctor/bsi/validate.rb, line 8 def doctype_validate(xmldoc) doctype = xmldoc&.at("//bibdata/ext/doctype")&.text %w(specification management-systems-standard code-of-practice guide method-of-test method-of-specifying vocabulary classification).include? doctype or @log.add("Document Attributes", nil, "#{doctype} is not a recognised document type") end
Rules for Structure 25.5
# File lib/asciidoctor/bsi/validate_requirement.rb, line 54 def example_style(node) return if @novalid r = requirement_check(extract_text(node)) and style_warning(node, "Example may contain requirement", r) style(node, extract_text(node)) end
# File lib/asciidoctor/bsi/validate_requirement.rb, line 4 def external_constraint(text); end
# File lib/asciidoctor/bsi/cleanup.rb, line 39 def get_id_prefix(xmldoc) prefix = [] xmldoc.xpath("//bibdata/contributor[role/@type = 'publisher']"\ "/organization").each do |x| x1 = x.at("abbreviation")&.text || x.at("name")&.text x1 == "BSI" and prefix.unshift("BS") or prefix << x1 end prefix end
# File lib/asciidoctor/bsi/front.rb, line 64 def get_typeabbr(node, amd = false) case doctype(node) when "publicly-available-specification" then "PAS " when "british-standard" then "BS " when "draft-for-development" then "DD " when "privately-subscribed-standard" then "PSS " when "flex-standard" then "Flex " else super end end
# File lib/asciidoctor/bsi/converter.rb, line 48 def html_converter(node) if node.nil? IsoDoc::BSI::HtmlConvert.new({}) else IsoDoc::BSI::HtmlConvert.new(html_extract_attributes(node)) end end
# File lib/asciidoctor/bsi/cleanup.rb, line 58 def id_prefix(prefix, id) return id.text if prefix == ["BS"] && %r{^[^/]}.match?(id.text) super end
# File lib/asciidoctor/bsi/front.rb, line 76 def id_stage_abbr(stage, substage, node, bare = false) ret = super if %w(publicly-available-specification).include?(doctype(node)) && !%w(D FD).include?(ret) ret = "#{ret} " end ret end
# File lib/asciidoctor/bsi/front.rb, line 85 def id_stage_prefix(docnum, node, force_year) stage = get_stage(node) typeabbr = get_typeabbr(node) typeabbr.nil? || typeabbr.empty? and typeabbr = "BS " docnum = if stage && (stage.to_i < 60) unpub_stage_prefix(docnum, stage, typeabbr, node) else "#{typeabbr}#{docnum}" end (force_year || !(stage && (stage.to_i < 60))) and docnum = id_add_year(docnum, node) docnum end
if this is a standard document, we ignore citation order (Rules for Structure 21.4). That is done by zeroing id_to_num
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 61 def id_to_num(bib, ids) return "000000000" if bib["id"].nil? sprintf("%09d", ids[bib["id"]] || 0) end
# File lib/asciidoctor/bsi/validate.rb, line 23 def image_name_validate(xmldoc); end
Rules for Structure 7.2, 7.3, 24.5
# File lib/asciidoctor/bsi/validate_requirement.rb, line 35 def informative_text_style(root) root.xpath("//note | //admonition[@type = 'commentary'] | "\ "//annex[@obligation = 'informative']").each do |s| if r = requirement_check(extract_text(s)) style_warning(s, "#{@type} clause may contain requirement", r) end if r = recommendation_check(extract_text(s)) %w(code-of-practice guide).include?(@doctype) and style_warning(s, "#{@type} clause may contain recommendation", r) end end end
# File lib/asciidoctor/bsi/front.rb, line 47 def iso_id(node, xml) return unless node.attr("docnumber") part = node&.attr("partnumber") dn = add_id_parts(node.attr("docnumber"), part, nil) dn = id_stage_prefix(dn, node, false) xml.docidentifier dn, **attr_code(type: "BS") end
# File lib/asciidoctor/bsi/validate_list.rb, line 60 def list_full_sentence(elem) text = elem.text.strip text.match?(/^[^A-Za-z]*[A-Z]/) or style_warning(elem, "List entry after full stop must start with "\ "uppercase letter", text) punct = text.sub(/^.*?(\S)\s*$/, "\\1") punct == "." or style_warning(elem, "List entry after full stop must "\ "end with full stop", text) end
Rules for Structure 23.5
# File lib/asciidoctor/bsi/validate_list.rb, line 19 def list_punctuation(doc) return if @novalid ((doc.xpath("//ol") - doc.xpath("//ul//ol | //ol//ol")) + (doc.xpath("//ul") - doc.xpath("//ul//ul | //ol//ul"))).each do |list| prec = list.previous_element prec&.name == "p" or style_warning(list, "All lists must be preceded by "\ "introductory phrase", nil) list_punctuation1(list, prec&.text) end end
# File lib/asciidoctor/bsi/validate_list.rb, line 32 def list_punctuation1(list, prectext) entries = list.xpath(".//li") case prectext&.sub(/^.*?(\S)\s*$/, "\\1") when ":" list.xpath(".//li").each_with_index do |li, i| list_semicolon_phrase(li, i == entries.size - 1) end when "." then entries.each { |li| list_full_sentence(li) } else style_warning(list, "All lists must be preceded by "\ "colon or full stop", prectext) end end
# File lib/asciidoctor/bsi/validate_list.rb, line 45 def list_semicolon_phrase(elem, last) text = elem.text.strip text.match?(/^[^A-Za-z]*[a-z]/) or style_warning(elem, "List entry after colon must start with "\ "lowercase letter", text) punct = text.sub(/^.*?(\S)\s*$/, "\\1") if last punct == "." or style_warning(elem, "Final list entry after colon "\ "must end with full stop", text) else punct == ";" or style_warning(elem, "List entry after colon must "\ "end with semicolon", text) end end
Rules for Structure 23.3
# File lib/asciidoctor/bsi/validate_list.rb, line 5 def listcount_validate(doc) return if @novalid doc.xpath("//clause[not(.//clause)] | //annex").each do |c| next if c.xpath(".//ol").empty? ols = c.xpath(".//ol") - c.xpath(".//ul//ol | .//ol//ol") ols.size > 3 and style_warning(c, "More than 3 ordered lists in a numbered clause", nil) end end
# File lib/asciidoctor/bsi/front.rb, line 32 def metadata_copyright(node, xml) pub = node.attr("copyright-holder") || node.attr("publisher") || "BSI" csv_split(pub)&.each do |p| xml.copyright do |c| c.from (node.attr("copyright-year") || Date.today.year) c.owner do |owner| owner.organization do |o| organization(o, p, true, node, !node.attr("copyright-holder") || node.attr("publisher")) end end end end end
# File lib/asciidoctor/bsi/front.rb, line 56 def metadata_doctype(node, xml) xml.doctype doctype(node) end
# File lib/asciidoctor/bsi/front.rb, line 20 def metadata_publisher(node, xml) publishers = node.attr("publisher") || "BSI" csv_split(publishers)&.each do |p| xml.contributor do |c| c.role **{ type: "publisher" } c.organization do |a| organization(a, p, true, node, !node.attr("publisher")) end end end end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 138 def new_ref(title, norm) id = "_#{UUIDTools::UUID.random_create}" "<references id='#{id}' normative='#{norm}' unnumbered='true'>"\ "<title>#{title}</title></references>" end
Rules for Structure 10.2
# File lib/asciidoctor/bsi/validate.rb, line 127 def norm_bibitem_style(root) root.xpath(NORM_BIBITEMS).each do |b| b.at(BSI_PUBLISHER_XPATH).nil? and @log.add("Style", b, "#{NORM_BSI_WARN}: #{b.text}") status = b&.at("./status/stage")&.text /^9.$/.match?(status) and @log.add("Style", b, "Do not cite withdrawn standards as normative: #{b.text}") /^[0-5].$/.match?(status) and @log.add("Style", b, "Do not cite unpublished standards "\ "as normative: #{b.text}") end end
Rules for Structure 7.2
# File lib/asciidoctor/bsi/validate_requirement.rb, line 82 def normative_text_style(root) root.xpath("//sections/* | //annex[@obligation = 'normative']") .each do |s1| s = s1.dup s.xpath(".//note | .//admonition | .//example").each(&:remove) %w(code-of-practice guide).include?(@doctype) and r = requirement_check(extract_text(s)) and style_warning(s, "#{@type} clause may contain requirement", r) %w(specification method-of-specifying test-method) .include?(@doctype) and spec_normative_text_style(s) end end
Rules for Structure 15.4
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 122 def normref_cleanup(xmldoc) biblio_metanorma_ids_normative(xmldoc) xmldoc.xpath("//references[@normative = 'true']//references") .each do |ref| ref["unnumbered"] = true end super end
Generalise to all biblio: Standards Publications and Other Publications
# File lib/asciidoctor/bsi/validate.rb, line 211 def normref_validate(xmldoc) xmldoc.xpath("//references").each do |r| t = r.at("./title") case t.text.strip.downcase when "standards publications" r.xpath("./bibitem").each { |b| normref_validate1(b, true) } when "other publications" r.xpath("./bibitem").each { |b| normref_validate1(b, false) } end end end
# File lib/asciidoctor/bsi/validate.rb, line 223 def normref_validate1(bib, std_pub) numbered = bib.at("./docidentifier[@type = 'metanorma']") numbered && std_pub and style_warning(bib, "Non-Standard reference included under "\ "Standards Publications", nil) !numbered && !std_pub and style_warning(bib, "Standard reference included under "\ "Other Publications", nil) end
TODO: we will not implement sections for now (Rules for Structure 6.4)
TODO: we will not implement access date for now (Rules for Structure 10.3)
# File lib/asciidoctor/bsi/converter.rb, line 23 def note(node) return commentary(node) if node.attr("type") == "commentary" super end
requirement language taken care of in informative_text_style
# File lib/asciidoctor/bsi/validate_requirement.rb, line 49 def note_style(node) style(node, extract_text(node)) end
# File lib/asciidoctor/bsi/cleanup.rb, line 13 def ol_cleanup(doc) doc.xpath("//clause[not(.//clause)] | //annex | //preface/*") .each do |c| (c.xpath(".//ol") - c.xpath(".//ul//ol | .//ol//ol")) .each_with_index do |l, i| ol_cleanup1(l, i) end end end
# File lib/asciidoctor/bsi/cleanup.rb, line 23 def ol_cleanup1(list, idx) styles = %w(alphabet arabic roman) list["type"] = styles[idx % styles.size] (list.xpath(".//ol") - list.xpath(".//ol//ol")).each do |l| ol_cleanup1(l, idx + 1) end end
Rules for Structure 9.1
# File lib/asciidoctor/bsi/validate.rb, line 71 def ordinal_check(node) node.xpath(".//sup").each do |s| next unless %w(st nd rd th).include? s.text style_warning(s, "text contains ordinal superscript", s.text) end end
# File lib/asciidoctor/bsi/front.rb, line 4 def org_abbrev super.merge("The British Standards Institution" => "BSI") end
# File lib/asciidoctor/bsi/converter.rb, line 56 def pdf_converter(node) return if node.attr("no-pdf") if node.nil? IsoDoc::BSI::PdfConvert.new({}) else IsoDoc::BSI::PdfConvert.new(doc_extract_attributes(node)) end end
# File lib/asciidoctor/bsi/converter.rb, line 66 def presentation_xml_converter(node) if node.nil? IsoDoc::BSI::PresentationXMLConvert.new({}) else IsoDoc::BSI::PresentationXMLConvert.new(doc_extract_attributes(node)) end end
# File lib/asciidoctor/bsi/front.rb, line 60 def relaton_relations super + %w(obsoletes adopted-from bsi-related) end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 131 def section_names_refs_cleanup(xml) replace_title(xml, "//bibliography/references[@normative = 'true']", @i18n&.normref, true) replace_title(xml, "//bibliography/references[@normative = 'false']", @i18n&.bibliography, true) end
# File lib/asciidoctor/bsi/validate.rb, line 79 def section_style(root) super @doctype = root.at("//bibdata/ext/doctype")&.text @type = @doctype.gsub(/-/, " ").split.map(&:capitalize).join(" ") informative_text_style(root) normative_text_style(root) avoid_must(root) annex_validate(root) end
# File lib/asciidoctor/bsi/validate_requirement.rb, line 106 def see_xrefs_validate(root) root.xpath("//xref").each do |t| (target = root.at("//*[@id = '#{t['target']}']")) || next if target.at("./ancestor-or-self::annex") xrefs_annex_validate(t, target) else preceding = t.at("./preceding-sibling::text()[last()]") next unless !preceding.nil? && /\b(see| refer to)\s*$/mi.match(preceding) if target&.at("./ancestor-or-self::*[@obligation = 'normative']") @log.add("Style", t, "'see #{t['target']}' is pointing "\ "to a normative section") end end end end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 42 def sort_biblio(bib) sort_norm_appearance(bib) end
Rules for Structure 15.4 Normative references ordering sort by: alphanumeric prefix, then docnumber if present, numeric sort
else alphanumeric metanorma id (abbreviation)
then doc part number if present, numeric sort then doc id (not DOI &c) then title
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 86 def sort_biblio_key(bib) num = bib&.at("./docnumber")&.text id = bib&.at("./docidentifier[not(#{OTHERIDS})]") metaid = bib&.at("./docidentifier[@type = 'metanorma']")&.text abbrid = metaid unless /^\[\d+\]$/.match?(metaid) /\d-(?<partid>\d+)/ =~ id&.text type = id["type"] if id "#{type} :: "\ "#{num.nil? ? abbrid : sprintf('%09d', num.to_i)} :: "\ "#{partid} :: #{id&.text} :: #{biblio_key_title(bib)}" end
# File lib/asciidoctor/bsi/cleanup_ref.rb, line 67 def sort_norm_appearance(bib) ids = citation_order(bib) bib.each do |b| ids[b["id"]] = 0 unless b.at("./docidentifier[@type = 'metanorma']") end bib.sort do |a, b| "#{id_to_num(a, ids)} :: #{sort_biblio_key(a)}" <=> "#{id_to_num(b, ids)} :: #{sort_biblio_key(b)}" end end
Rules for Structure 7.3, 7.4, 7.5
# File lib/asciidoctor/bsi/validate_requirement.rb, line 96 def spec_normative_text_style(node) r = recommendation_check(extract_text(node)) r and style_warning(node, "#{@type} clause may contain recommendation", r) r = permission_check(extract_text(node)) r and style_warning(node, "#{@type} clause may contain permission", r) r = possibility_check(extract_text(node)) r and style_warning(node, "#{@type} clause may contain possibility", r) end
# File lib/asciidoctor/bsi/converter.rb, line 74 def sts_converter(node) return if node.attr("no-pdf") if node.nil? IsoDoc::BSI::StsConvert.new({}) else IsoDoc::BSI::StsConvert.new(html_extract_attributes(node)) end end
# File lib/asciidoctor/bsi/validate.rb, line 25 def style(node, text) super style_plusminus(node, text) style_subscript(node) end
protest decimal comma not decimal point TODO we will not yet override decimal comma warning if this is a National Annex to Eurocode (Rules for Structure Annex B)
# File lib/asciidoctor/bsi/validate.rb, line 57 def style_number(node, text) style_two_regex_not_prev( node, text, /^(?<num>-?[0-9]{4,}[,0-9]*)$/, %r{\b(ISO|IEC|IEEE/|(in|January|February|March|April|May|June|August|September|October|November|December)\b)$}, "number not broken up in threes" ) style_regex(/\b(?<num>[0-9]+,[0-9]+)/i, "possible decimal comma", node, text) style_regex(/\b(?<num>billions?)\b/i, "ambiguous number", node, text) ordinal_check(node) end
Rules for Structure 27.5
# File lib/asciidoctor/bsi/validate.rb, line 32 def style_plusminus(node, text) style_regex(/\s*(?<num>\S+\u00b1\s*\S+)/, "no space before plus-minus sign", node, text) style_regex(/\s*(?<num>\S+\s*\u00b1\s+\S+)/, "space after plus-minus sign", node, text) end
Rules for Structure 27.6
# File lib/asciidoctor/bsi/validate.rb, line 40 def style_subscript(node) node.xpath(".//sub[.//sub]").each do |r| style_warning(node, "Nested subscript", r) end node.xpath(".//m:msub[.//m:msub]", "m" => MATHML_NS).each do |r| style_warning(node, "Nested subscript", r) end node.xpath(".//sup[.//sup]").each do |r| style_warning(node, "Nested superscript", r) end node.xpath(".//m:msup[.//m:msup]", "m" => MATHML_NS).each do |r| style_warning(node, "Nested superscript", r) end end
Rules for Structure 22.3.2
# File lib/asciidoctor/bsi/validate.rb, line 193 def subclause_validate(root) return if @novalid root.xpath("//clause/clause/clause/clause/clause/clause") .each do |c| style_warning(c, "Exceeds the maximum clause depth of 5", nil) end end
Rules for Structure 17.5
# File lib/asciidoctor/bsi/validate.rb, line 176 def symbol_style(xmldoc) return if @novalid xmldoc.xpath("//definitions//dd").each do |para| term = para&.at("./preceding::dt[1]")&.text&.strip || "[symbol]" termdef_warn(para.text, /^(the|a)\b/i, para, term, "symbol definition starts with article") termdef_warn(para.text, /\.$/i, para, term, "symbol definition ends with period") termdef_warn(para.text, /^[A-Z]/, para, term, "symbol definition starts with upper case character") termdef_warn(para.text, /\b#{term.downcase}\b/i, para, term, "symbol definition may be circular") end end
# File lib/asciidoctor/bsi/cleanup.rb, line 71 def table_footnote_renumber1(fnote, idx, seen) content = footnote_content(fnote) if seen[content] then outnum = seen[content] else idx += 1 outnum = idx seen[content] = outnum end fnote["reference"] = (outnum - 1 + "A".ord).chr fnote["table"] = true [idx, seen] end
Rules for Structure 29.6
# File lib/asciidoctor/bsi/validate.rb, line 203 def table_validate(xmldoc) xmldoc.xpath("//td[not(./*) and normalize-space(.)=''] | "\ "//th[not(./*) and normalize-space(.)='']").each do |td| style_warning(td, "Empty table cell", nil) end end
Rules for Structure 7.2
# File lib/asciidoctor/bsi/validate_requirement.rb, line 32 def tech_report_style(root); end
Rules for Structure 16.5.5
# File lib/asciidoctor/bsi/validate.rb, line 155 def termdef_style(xmldoc) super xmldoc.xpath("//term").each do |t| para = t.at("./definition") || return term = t.at("./preferred").text.strip termdef_warn(para.text, /^[A-Z]/, t, term, "term definition starts with upper case character") termdef_warn(para.text, /\b#{term.downcase}\b/i, t, term, "term definition may be circular") end end
Rules for Structure 11.5.2
# File lib/asciidoctor/bsi/validate.rb, line 142 def title_names_type_validate(root) super doctypes = /British\sStandard/xi title_main_en = title_lang_part(root, "main", "en") !title_main_en.nil? && doctypes.match(title_main_en.text) and @log.add("Style", title_main_en, "Main Title may name document type") title_intro_en = title_lang_part(root, "intro", "en") !title_intro_en.nil? && doctypes.match(title_intro_en.text) and @log.add("Style", title_intro_en, "Title Intro may name document type") end
# File lib/asciidoctor/bsi/front.rb, line 98 def unpub_stage_prefix(docnum, stage, typeabbr, node) typeabbr = "" if typeabbr == "BS " super end
# File lib/asciidoctor/bsi/validate.rb, line 17 def validate(doc) content_validate(doc) schema_validate(formattedstr_strip(doc.dup), File.join(File.dirname(__FILE__), "bsi.rng")) end
Rules for Structure 20.5
# File lib/asciidoctor/bsi/validate_requirement.rb, line 129 def xrefs_annex_validate(xref, target) normative = !target&.at("./ancestor-or-self::*"\ "[@obligation='normative']").nil? clause = xref.at(PARENT_PARA) or return prec = (clause&.children & xref&.xpath("./preceding::text()")) &.text&.split(/\.\s*(?=[A-Z])/m)[-1]&.strip foll = (clause.children & xref.xpath("./following::text()")) &.text&.split(/\.\s*(?=[A-Z])/m)[0]&.strip text = "#{prec} XREF #{foll}".strip if %w(specification method-of-specifying).include?(@doctype) && normative requirement_re.match?(text) or style_warning(xref, "#{@type} must cite normative "\ "annex as requirement", text) elsif @doctype == "code-of-practice" && normative recommendation_re.match?(text) or style_warning(xref, "#{@type} must cite normative "\ "annex as recommendation", text) elsif %w(specification method-of-specifying).include?(@doctype) && !normative (recommendation_re.match?(text) || (!requirement_re.match?(text) && !permission_re.match?(text) && !possibility_re.match?(text))) or style_warning(xref, "#{@type} must cite informative annex as "\ "recommendation or statement", text) elsif %w(code-of-practice guide).include?(@doctype) && !normative (!recommendation_re.match?(text) && !requirement_re.match?(text) && !permission_re.match?(text) && !possibility_re.match?(text)) or style_warning(xref, "#{@type} must cite informative annex as "\ "statement", text) end end