metanorma-iso 2.4.3 → 2.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/isodoc/iso/iso.amendment.xsl +621 -229
- data/lib/isodoc/iso/iso.international-standard.xsl +621 -229
- data/lib/isodoc/iso/presentation_terms.rb +102 -0
- data/lib/isodoc/iso/presentation_xml_convert.rb +1 -83
- data/lib/metanorma/iso/base.rb +1 -0
- data/lib/metanorma/iso/isodoc.rng +5 -1
- data/lib/metanorma/iso/validate.rb +2 -0
- data/lib/metanorma/iso/validate_image.rb +6 -5
- data/lib/metanorma/iso/validate_list.rb +6 -6
- data/lib/metanorma/iso/validate_requirements.rb +24 -0
- data/lib/metanorma/iso/validate_style.rb +49 -8
- data/lib/metanorma/iso/version.rb +1 -1
- metadata +3 -2
| @@ -0,0 +1,102 @@ | |
| 1 | 
            +
            require_relative "init"
         | 
| 2 | 
            +
            require "isodoc"
         | 
| 3 | 
            +
            require_relative "index"
         | 
| 4 | 
            +
            require_relative "presentation_xref"
         | 
| 5 | 
            +
            require_relative "presentation_bibdata"
         | 
| 6 | 
            +
            require_relative "../../relaton/render/general"
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            module IsoDoc
         | 
| 9 | 
            +
              module Iso
         | 
| 10 | 
            +
                class PresentationXMLConvert < IsoDoc::PresentationXMLConvert
         | 
| 11 | 
            +
                  def concept(docxml)
         | 
| 12 | 
            +
                    concept_term(docxml)
         | 
| 13 | 
            +
                    docxml.xpath(ns("//concept")).each do |node|
         | 
| 14 | 
            +
                      concept_render(node, ital: "false", ref: "false",
         | 
| 15 | 
            +
                                           linkref: "true", linkmention: "false")
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  def concept_term(docxml)
         | 
| 20 | 
            +
                    docxml.xpath(ns("//term")).each do |f|
         | 
| 21 | 
            +
                      m = {}
         | 
| 22 | 
            +
                      (f.xpath(ns(".//concept")) - f.xpath(ns(".//term//concept")))
         | 
| 23 | 
            +
                        .each { |c| concept_term1(c, m) }
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  def concept_term1(node, seen)
         | 
| 28 | 
            +
                    term = to_xml(node.at(ns("./refterm")))
         | 
| 29 | 
            +
                    if term && seen[term]
         | 
| 30 | 
            +
                      concept_render(node, ital: "false", ref: "false",
         | 
| 31 | 
            +
                                           linkref: "true", linkmention: "false")
         | 
| 32 | 
            +
                    else concept_render(node, ital: "true", ref: "true",
         | 
| 33 | 
            +
                                              linkref: "true", linkmention: "false")
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                    seen[term] = true if term
         | 
| 36 | 
            +
                    seen
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  def concept1_ref_content(ref)
         | 
| 40 | 
            +
                    prev = "("
         | 
| 41 | 
            +
                    foll = ")"
         | 
| 42 | 
            +
                    if ref.name == "termref"
         | 
| 43 | 
            +
                      prev, foll = @i18n.term_defined_in.split("%")
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                    ref.previous = prev
         | 
| 46 | 
            +
                    ref.next = foll
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  def concept1(node)
         | 
| 50 | 
            +
                    node.replace(node&.at(ns("./renderterm"))&.children ||
         | 
| 51 | 
            +
                                 node&.at(ns("./refterm"))&.children ||
         | 
| 52 | 
            +
                                 node.children)
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  def termdefinition1(elem)
         | 
| 56 | 
            +
                    prefix_domain_to_definition(elem)
         | 
| 57 | 
            +
                    super
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  def prefix_domain_to_definition(elem)
         | 
| 61 | 
            +
                    ((d = elem.at(ns("./domain"))) &&
         | 
| 62 | 
            +
                      (v = elem.at(ns("./definition/verbal-definition"))) &&
         | 
| 63 | 
            +
                      v.elements.first.name == "p") or return
         | 
| 64 | 
            +
                    v.elements.first.children.first.previous =
         | 
| 65 | 
            +
                      "<#{to_xml(d.remove.children)}> "
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  def insertall_after_here(node, insert, name)
         | 
| 69 | 
            +
                    node.children.each do |n|
         | 
| 70 | 
            +
                      n.name == name or next
         | 
| 71 | 
            +
                      insert.next = n.remove
         | 
| 72 | 
            +
                      insert = n
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
                    insert
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  def termexamples_before_termnotes(node)
         | 
| 78 | 
            +
                    insert = node.at(ns("./definition")) or return
         | 
| 79 | 
            +
                    insert = insertall_after_here(node, insert, "termexample")
         | 
| 80 | 
            +
                    insertall_after_here(node, insert, "termnote")
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  def terms(docxml)
         | 
| 84 | 
            +
                    docxml.xpath(ns("//term[termnote][termexample]")).each do |node|
         | 
| 85 | 
            +
                      termexamples_before_termnotes(node)
         | 
| 86 | 
            +
                    end
         | 
| 87 | 
            +
                    super
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  def related1(node)
         | 
| 91 | 
            +
                    node.remove
         | 
| 92 | 
            +
                  end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                  def termsource_status(status)
         | 
| 95 | 
            +
                    case status
         | 
| 96 | 
            +
                    when "modified", "adapted"
         | 
| 97 | 
            +
                      @i18n.modified
         | 
| 98 | 
            +
                    end
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
              end
         | 
| 102 | 
            +
            end
         | 
| @@ -3,6 +3,7 @@ require "isodoc" | |
| 3 3 | 
             
            require_relative "index"
         | 
| 4 4 | 
             
            require_relative "presentation_xref"
         | 
| 5 5 | 
             
            require_relative "presentation_bibdata"
         | 
| 6 | 
            +
            require_relative "presentation_terms"
         | 
| 6 7 | 
             
            require_relative "../../relaton/render/general"
         | 
| 7 8 |  | 
| 8 9 | 
             
            module IsoDoc
         | 
| @@ -86,50 +87,6 @@ module IsoDoc | |
| 86 87 | 
             
                    end
         | 
| 87 88 | 
             
                  end
         | 
| 88 89 |  | 
| 89 | 
            -
                  def concept(docxml)
         | 
| 90 | 
            -
                    concept_term(docxml)
         | 
| 91 | 
            -
                    docxml.xpath(ns("//concept")).each do |node|
         | 
| 92 | 
            -
                      concept_render(node, ital: "false", ref: "false",
         | 
| 93 | 
            -
                                           linkref: "true", linkmention: "false")
         | 
| 94 | 
            -
                    end
         | 
| 95 | 
            -
                  end
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                  def concept_term(docxml)
         | 
| 98 | 
            -
                    docxml.xpath(ns("//term")).each do |f|
         | 
| 99 | 
            -
                      m = {}
         | 
| 100 | 
            -
                      (f.xpath(ns(".//concept")) - f.xpath(ns(".//term//concept")))
         | 
| 101 | 
            -
                        .each { |c| concept_term1(c, m) }
         | 
| 102 | 
            -
                    end
         | 
| 103 | 
            -
                  end
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                  def concept_term1(node, seen)
         | 
| 106 | 
            -
                    term = to_xml(node.at(ns("./refterm")))
         | 
| 107 | 
            -
                    if term && seen[term]
         | 
| 108 | 
            -
                      concept_render(node, ital: "false", ref: "false",
         | 
| 109 | 
            -
                                           linkref: "true", linkmention: "false")
         | 
| 110 | 
            -
                    else concept_render(node, ital: "true", ref: "true",
         | 
| 111 | 
            -
                                              linkref: "true", linkmention: "false")
         | 
| 112 | 
            -
                    end
         | 
| 113 | 
            -
                    seen[term] = true if term
         | 
| 114 | 
            -
                    seen
         | 
| 115 | 
            -
                  end
         | 
| 116 | 
            -
             | 
| 117 | 
            -
                  def concept1_ref_content(ref)
         | 
| 118 | 
            -
                    prev = "("
         | 
| 119 | 
            -
                    foll = ")"
         | 
| 120 | 
            -
                    if ref.name == "termref"
         | 
| 121 | 
            -
                      prev, foll = @i18n.term_defined_in.split("%")
         | 
| 122 | 
            -
                    end
         | 
| 123 | 
            -
                    ref.previous = prev
         | 
| 124 | 
            -
                    ref.next = foll
         | 
| 125 | 
            -
                  end
         | 
| 126 | 
            -
             | 
| 127 | 
            -
                  def concept1(node)
         | 
| 128 | 
            -
                    node.replace(node&.at(ns("./renderterm"))&.children ||
         | 
| 129 | 
            -
                                 node&.at(ns("./refterm"))&.children ||
         | 
| 130 | 
            -
                                 node.children)
         | 
| 131 | 
            -
                  end
         | 
| 132 | 
            -
             | 
| 133 90 | 
             
                  # we're assuming terms and clauses in the right place for display,
         | 
| 134 91 | 
             
                  # to cope with multiple terms sections
         | 
| 135 92 | 
             
                  def display_order(docxml)
         | 
| @@ -145,41 +102,6 @@ module IsoDoc | |
| 145 102 | 
             
                    display_order_xpath(docxml, "//indexsect", i)
         | 
| 146 103 | 
             
                  end
         | 
| 147 104 |  | 
| 148 | 
            -
                  def termdefinition1(elem)
         | 
| 149 | 
            -
                    prefix_domain_to_definition(elem)
         | 
| 150 | 
            -
                    super
         | 
| 151 | 
            -
                  end
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                  def prefix_domain_to_definition(elem)
         | 
| 154 | 
            -
                    ((d = elem.at(ns("./domain"))) &&
         | 
| 155 | 
            -
                      (v = elem.at(ns("./definition/verbal-definition"))) &&
         | 
| 156 | 
            -
                      v.elements.first.name == "p") or return
         | 
| 157 | 
            -
                    v.elements.first.children.first.previous =
         | 
| 158 | 
            -
                      "<#{to_xml(d.remove.children)}> "
         | 
| 159 | 
            -
                  end
         | 
| 160 | 
            -
             | 
| 161 | 
            -
                  def insertall_after_here(node, insert, name)
         | 
| 162 | 
            -
                    node.children.each do |n|
         | 
| 163 | 
            -
                      n.name == name or next
         | 
| 164 | 
            -
                      insert.next = n.remove
         | 
| 165 | 
            -
                      insert = n
         | 
| 166 | 
            -
                    end
         | 
| 167 | 
            -
                    insert
         | 
| 168 | 
            -
                  end
         | 
| 169 | 
            -
             | 
| 170 | 
            -
                  def termexamples_before_termnotes(node)
         | 
| 171 | 
            -
                    insert = node.at(ns("./definition")) or return
         | 
| 172 | 
            -
                    insert = insertall_after_here(node, insert, "termexample")
         | 
| 173 | 
            -
                    insertall_after_here(node, insert, "termnote")
         | 
| 174 | 
            -
                  end
         | 
| 175 | 
            -
             | 
| 176 | 
            -
                  def terms(docxml)
         | 
| 177 | 
            -
                    docxml.xpath(ns("//term[termnote][termexample]")).each do |node|
         | 
| 178 | 
            -
                      termexamples_before_termnotes(node)
         | 
| 179 | 
            -
                    end
         | 
| 180 | 
            -
                    super
         | 
| 181 | 
            -
                  end
         | 
| 182 | 
            -
             | 
| 183 105 | 
             
                  def admonition1(elem)
         | 
| 184 106 | 
             
                    super
         | 
| 185 107 | 
             
                    n = elem.at(ns("./name")) or return
         | 
| @@ -212,10 +134,6 @@ module IsoDoc | |
| 212 134 | 
             
                    type
         | 
| 213 135 | 
             
                  end
         | 
| 214 136 |  | 
| 215 | 
            -
                  def related1(node)
         | 
| 216 | 
            -
                    node.remove
         | 
| 217 | 
            -
                  end
         | 
| 218 | 
            -
             | 
| 219 137 | 
             
                  def note1(elem)
         | 
| 220 138 | 
             
                    elem["type"] == "units" and return
         | 
| 221 139 | 
             
                    super
         | 
    
        data/lib/metanorma/iso/base.rb
    CHANGED
    
    
| @@ -17,7 +17,7 @@ | |
| 17 17 | 
             
              these elements; we just want one namespace for any child grammars
         | 
| 18 18 | 
             
              of this.
         | 
| 19 19 | 
             
            -->
         | 
| 20 | 
            -
            <!-- VERSION v1.2. | 
| 20 | 
            +
            <!-- VERSION v1.2.2 -->
         | 
| 21 21 | 
             
            <grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
         | 
| 22 22 | 
             
              <include href="reqt.rng"/>
         | 
| 23 23 | 
             
              <include href="basicdoc.rng">
         | 
| @@ -211,6 +211,9 @@ | |
| 211 211 | 
             
                      <data type="boolean"/>
         | 
| 212 212 | 
             
                    </attribute>
         | 
| 213 213 | 
             
                  </optional>
         | 
| 214 | 
            +
                  <optional>
         | 
| 215 | 
            +
                    <attribute name="style"/>
         | 
| 216 | 
            +
                  </optional>
         | 
| 214 217 | 
             
                  <ref name="CitationType"/>
         | 
| 215 218 | 
             
                  <oneOrMore>
         | 
| 216 219 | 
             
                    <ref name="PureTextElement"/>
         | 
| @@ -2136,6 +2139,7 @@ | |
| 2136 2139 | 
             
                <choice>
         | 
| 2137 2140 | 
             
                  <value>identical</value>
         | 
| 2138 2141 | 
             
                  <value>modified</value>
         | 
| 2142 | 
            +
                  <value>adapted</value>
         | 
| 2139 2143 | 
             
                  <value>restyled</value>
         | 
| 2140 2144 | 
             
                  <value>context-added</value>
         | 
| 2141 2145 | 
             
                  <value>generalisation</value>
         | 
| @@ -30,6 +30,7 @@ module Metanorma | |
| 30 30 | 
             
                  # ISO/IEC DIR 2, 15.5.3, 20.2
         | 
| 31 31 | 
             
                  # does not deal with preceding text marked up
         | 
| 32 32 | 
             
                  def see_xrefs_validate(root)
         | 
| 33 | 
            +
                    @lang == "en" or return
         | 
| 33 34 | 
             
                    root.xpath("//xref").each do |t|
         | 
| 34 35 | 
             
                      preceding = t.at("./preceding-sibling::text()[last()]")
         | 
| 35 36 | 
             
                      next unless !preceding.nil? &&
         | 
| @@ -45,6 +46,7 @@ module Metanorma | |
| 45 46 |  | 
| 46 47 | 
             
                  # ISO/IEC DIR 2, 15.5.3
         | 
| 47 48 | 
             
                  def see_erefs_validate(root)
         | 
| 49 | 
            +
                    @lang == "en" or return
         | 
| 48 50 | 
             
                    root.xpath("//eref").each do |t|
         | 
| 49 51 | 
             
                      prec = t.at("./preceding-sibling::text()[last()]")
         | 
| 50 52 | 
             
                      next unless !prec.nil? && /\b(see|refer to)\s*\Z/mi.match(prec)
         | 
| @@ -3,8 +3,9 @@ module Metanorma | |
| 3 3 | 
             
                class Converter < Standoc::Converter
         | 
| 4 4 | 
             
                  # DRG directives 3.7; but anticipated by standoc
         | 
| 5 5 | 
             
                  def subfigure_validate(xmldoc)
         | 
| 6 | 
            +
                    elems = { footnote: "fn", note: "note", key: "dl" }
         | 
| 6 7 | 
             
                    xmldoc.xpath("//figure//figure").each do |f|
         | 
| 7 | 
            -
                       | 
| 8 | 
            +
                      elems.each do |k, v|
         | 
| 8 9 | 
             
                        f.xpath(".//#{v}").each do |n|
         | 
| 9 10 | 
             
                          @log.add("Style", n, "#{k} is not permitted in a subfigure")
         | 
| 10 11 | 
             
                        end
         | 
| @@ -13,10 +14,10 @@ module Metanorma | |
| 13 14 | 
             
                  end
         | 
| 14 15 |  | 
| 15 16 | 
             
                  def image_name_prefix(xmldoc)
         | 
| 16 | 
            -
                    std = xmldoc | 
| 17 | 
            +
                    std = xmldoc.at("//bibdata/ext/structuredidentifier/project-number") or
         | 
| 17 18 | 
             
                      return
         | 
| 18 | 
            -
                    num = xmldoc | 
| 19 | 
            -
                    ed = xmldoc | 
| 19 | 
            +
                    num = xmldoc.at("//bibdata/docnumber")&.text or return
         | 
| 20 | 
            +
                    ed = xmldoc.at("//bibdata/edition")&.text || "1"
         | 
| 20 21 | 
             
                    prefix = num
         | 
| 21 22 | 
             
                    std["part"] and prefix += "-#{std['part']}"
         | 
| 22 23 | 
             
                    prefix += "_ed#{ed}"
         | 
| @@ -25,7 +26,7 @@ module Metanorma | |
| 25 26 | 
             
                  end
         | 
| 26 27 |  | 
| 27 28 | 
             
                  def image_name_suffix(xmldoc)
         | 
| 28 | 
            -
                    case xmldoc | 
| 29 | 
            +
                    case xmldoc.at("//bibdata/language")&.text
         | 
| 29 30 | 
             
                    when "fr" then "_f"
         | 
| 30 31 | 
             
                    when "de" then "_d"
         | 
| 31 32 | 
             
                    when "ru" then "_r"
         | 
| @@ -60,7 +60,7 @@ module Metanorma | |
| 60 60 | 
             
                    case prectext.strip[-1]
         | 
| 61 61 | 
             
                    when ":", "" then list_after_colon_punctuation(list, entries)
         | 
| 62 62 | 
             
                    when "." then entries.each { |li| list_full_sentence(li) }
         | 
| 63 | 
            -
                    else style_warning(list, "All lists must be preceded by "\
         | 
| 63 | 
            +
                    else style_warning(list, "All lists must be preceded by " \
         | 
| 64 64 | 
             
                                             "colon or full stop", prectext)
         | 
| 65 65 | 
             
                    end
         | 
| 66 66 | 
             
                  end
         | 
| @@ -80,7 +80,7 @@ module Metanorma | |
| 80 80 | 
             
                  def list_semicolon_phrase(elem, last)
         | 
| 81 81 | 
             
                    text = elem.text.strip
         | 
| 82 82 | 
             
                    starts_lowercase?(text) or
         | 
| 83 | 
            -
                      style_warning(elem, "List entry of broken up sentence must start "\
         | 
| 83 | 
            +
                      style_warning(elem, "List entry of broken up sentence must start " \
         | 
| 84 84 | 
             
                                          "with lowercase letter", text)
         | 
| 85 85 | 
             
                    list_semicolon_phrase_punct(elem, text, last)
         | 
| 86 86 | 
             
                  end
         | 
| @@ -89,11 +89,11 @@ module Metanorma | |
| 89 89 | 
             
                    punct = text.strip.sub(/^.*?(\S)$/m, "\\1")
         | 
| 90 90 | 
             
                    if last
         | 
| 91 91 | 
             
                      punct == "." or
         | 
| 92 | 
            -
                        style_warning(elem, "Final list entry of broken up "\
         | 
| 92 | 
            +
                        style_warning(elem, "Final list entry of broken up " \
         | 
| 93 93 | 
             
                                            "sentence must end with full stop", text)
         | 
| 94 94 | 
             
                    else
         | 
| 95 95 | 
             
                      punct == ";" or
         | 
| 96 | 
            -
                        style_warning(elem, "List entry of broken up sentence must "\
         | 
| 96 | 
            +
                        style_warning(elem, "List entry of broken up sentence must " \
         | 
| 97 97 | 
             
                                            "end with semicolon", text)
         | 
| 98 98 | 
             
                    end
         | 
| 99 99 | 
             
                  end
         | 
| @@ -102,11 +102,11 @@ module Metanorma | |
| 102 102 | 
             
                    %w(Cyrl Latn Grek).include?(@script) or return
         | 
| 103 103 | 
             
                    text = elem.text.strip
         | 
| 104 104 | 
             
                    starts_uppercase?(text) or
         | 
| 105 | 
            -
                      style_warning(elem, "List entry of separate sentences must start "\
         | 
| 105 | 
            +
                      style_warning(elem, "List entry of separate sentences must start " \
         | 
| 106 106 | 
             
                                          "with uppercase letter", text)
         | 
| 107 107 | 
             
                    punct = text.strip.sub(/^.*?(\S)$/m, "\\1")
         | 
| 108 108 | 
             
                    punct == "." or
         | 
| 109 | 
            -
                      style_warning(elem, "List entry of separate sentences must "\
         | 
| 109 | 
            +
                      style_warning(elem, "List entry of separate sentences must " \
         | 
| 110 110 | 
             
                                          "end with full stop", text)
         | 
| 111 111 | 
             
                  end
         | 
| 112 112 |  | 
| @@ -24,6 +24,7 @@ module Metanorma | |
| 24 24 | 
             
                  end
         | 
| 25 25 |  | 
| 26 26 | 
             
                  def requirement_check(text)
         | 
| 27 | 
            +
                    @lang == "en" or return
         | 
| 27 28 | 
             
                    text.split(/\.\s+/).each do |t|
         | 
| 28 29 | 
             
                      return t if requirement_re.match t
         | 
| 29 30 | 
             
                    end
         | 
| @@ -44,6 +45,7 @@ module Metanorma | |
| 44 45 | 
             
                  end
         | 
| 45 46 |  | 
| 46 47 | 
             
                  def recommendation_check(text)
         | 
| 48 | 
            +
                    @lang == "en" or return
         | 
| 47 49 | 
             
                    text.split(/\.\s+/).each do |t|
         | 
| 48 50 | 
             
                      return t if recommendation_re.match t
         | 
| 49 51 | 
             
                    end
         | 
| @@ -60,6 +62,7 @@ module Metanorma | |
| 60 62 | 
             
                  REGEXP
         | 
| 61 63 |  | 
| 62 64 | 
             
                  def permission_re
         | 
| 65 | 
            +
                    @lang == "en" or return
         | 
| 63 66 | 
             
                    Regexp.new(self.class::PERMISSION_RE_STR.gsub(/\s/, "")
         | 
| 64 67 | 
             
                      .gsub(/_/, "\\s"), Regexp::IGNORECASE)
         | 
| 65 68 | 
             
                  end
         | 
| @@ -82,6 +85,7 @@ module Metanorma | |
| 82 85 | 
             
                  REGEXP
         | 
| 83 86 |  | 
| 84 87 | 
             
                  def possibility_re
         | 
| 88 | 
            +
                    @lang == "en" or return
         | 
| 85 89 | 
             
                    Regexp.new(self.class::POSSIBILITY_RE_STR.gsub(/\s/, "")
         | 
| 86 90 | 
             
                      .gsub(/_/, "\\s"), Regexp::IGNORECASE)
         | 
| 87 91 | 
             
                  end
         | 
| @@ -98,6 +102,26 @@ module Metanorma | |
| 98 102 | 
             
                    nil
         | 
| 99 103 | 
             
                  end
         | 
| 100 104 |  | 
| 105 | 
            +
                  AMBIG_WORDS_RE_STR = <<~REGEXP.freeze
         | 
| 106 | 
            +
                    \\b
         | 
| 107 | 
            +
                        need_to | needs_to | might | could
         | 
| 108 | 
            +
                    \\b
         | 
| 109 | 
            +
                  REGEXP
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  def ambig_words_re
         | 
| 112 | 
            +
                    @lang == "en" or return
         | 
| 113 | 
            +
                    Regexp.new(self.class::AMBIG_WORDS_RE_STR.gsub(/\s/, "")
         | 
| 114 | 
            +
                      .gsub(/_/, "\\s"), Regexp::IGNORECASE)
         | 
| 115 | 
            +
                  end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                  def ambig_words_check(text)
         | 
| 118 | 
            +
                    @lang == "en" or return
         | 
| 119 | 
            +
                    text.split(/\.\s+/).each do |t|
         | 
| 120 | 
            +
                      return t if ambig_words_re.match t
         | 
| 121 | 
            +
                    end
         | 
| 122 | 
            +
                    nil
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
             | 
| 101 125 | 
             
                  def style_no_guidance(node, text, docpart)
         | 
| 102 126 | 
             
                    @lang == "en" or return
         | 
| 103 127 | 
             
                    r = requirement_check(text)
         | 
| @@ -90,32 +90,63 @@ module Metanorma | |
| 90 90 | 
             
                  end
         | 
| 91 91 |  | 
| 92 92 | 
             
                  def style(node, text)
         | 
| 93 | 
            -
                     | 
| 94 | 
            -
             | 
| 93 | 
            +
                    @novalid and return
         | 
| 95 94 | 
             
                    style_number(node, text)
         | 
| 96 95 | 
             
                    style_percent(node, text)
         | 
| 97 96 | 
             
                    style_abbrev(node, text)
         | 
| 98 97 | 
             
                    style_units(node, text)
         | 
| 99 98 | 
             
                    style_punct(node, text)
         | 
| 99 | 
            +
                    style_subscript(node)
         | 
| 100 | 
            +
                    style_ambig_words(node, text)
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  # https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-s-quantity
         | 
| 104 | 
            +
                  def style_subscript(node)
         | 
| 105 | 
            +
                    warning = "may contain nested subscripts (max 3 levels allowed)"
         | 
| 106 | 
            +
                    node.xpath(".//sub[.//sub]").each do |x|
         | 
| 107 | 
            +
                      style_warning(node, warning, x.to_xml)
         | 
| 108 | 
            +
                    end
         | 
| 109 | 
            +
                    node.xpath(".//m:msub[.//m:msub]", "m" => MATHML_NS).each do |x|
         | 
| 110 | 
            +
                      style_warning(node, warning, x.to_xml)
         | 
| 111 | 
            +
                    end
         | 
| 112 | 
            +
                  end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                  # https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-s-need
         | 
| 115 | 
            +
                  # https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-s-might
         | 
| 116 | 
            +
                  def style_ambig_words(node, text)
         | 
| 117 | 
            +
                    r = ambig_words_check(text) and
         | 
| 118 | 
            +
                      style_warning(node, "may contain ambiguous provision", r)
         | 
| 100 119 | 
             
                  end
         | 
| 101 120 |  | 
| 102 121 | 
             
                  # ISO/IEC DIR 2, 9.1
         | 
| 103 122 | 
             
                  # ISO/IEC DIR 2, Table B.1
         | 
| 104 123 | 
             
                  # https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-n-numbers
         | 
| 105 124 | 
             
                  def style_number(node, text)
         | 
| 106 | 
            -
                     | 
| 107 | 
            -
                      node, text, /^(?<num>-?[0-9]{4,}[,0-9]*)\Z/,
         | 
| 108 | 
            -
                      %r{\b(ISO|IEC|IEEE/|(in|January|February|March|April|May|June|August|September|October|November|December)\b)\Z},
         | 
| 109 | 
            -
                      "number not broken up in threes"
         | 
| 110 | 
            -
                    )
         | 
| 125 | 
            +
                    style_number_grouping(node, text)
         | 
| 111 126 | 
             
                    style_regex(/\b(?<num>[0-9]+\.[0-9]+)/i,
         | 
| 112 127 | 
             
                                "possible decimal point", node, text)
         | 
| 113 128 | 
             
                    @lang == "en" and style_regex(/\b(?<num>billions?)\b/i,
         | 
| 114 129 | 
             
                                                  "ambiguous number", node, text)
         | 
| 115 | 
            -
                    style_regex(/( | 
| 130 | 
            +
                    style_regex(/(?:^|\s)(?<num>-[0-9][0-9,.]*)/i,
         | 
| 116 131 | 
             
                                "hyphen instead of minus sign U+2212", node, text)
         | 
| 117 132 | 
             
                  end
         | 
| 118 133 |  | 
| 134 | 
            +
                  def style_number_grouping(node, text)
         | 
| 135 | 
            +
                    if @validate_years
         | 
| 136 | 
            +
                      style_two_regex_not_prev(
         | 
| 137 | 
            +
                        node, text, /^(?<num>-?[0-9]{4,}[,0-9]*)\Z/,
         | 
| 138 | 
            +
                        %r{\b(ISO|IEC|IEEE|(in|January|February|March|April|May|June|August|September|October|November|December)\b)\Z},
         | 
| 139 | 
            +
                        "number not broken up in threes"
         | 
| 140 | 
            +
                      )
         | 
| 141 | 
            +
                    else
         | 
| 142 | 
            +
                      style_two_regex_not_prev(
         | 
| 143 | 
            +
                        node, text, /^(?<num>-?(?:[0-9]{5,}[,0-9]*|[03-9]\d\d\d|1[0-8]\d\d|2[1-9]\d\d|20[5-9]\d))\Z/,
         | 
| 144 | 
            +
                        %r{\b(ISO|IEC|IEEE|\b)\Z},
         | 
| 145 | 
            +
                        "number not broken up in threes"
         | 
| 146 | 
            +
                      )
         | 
| 147 | 
            +
                    end
         | 
| 148 | 
            +
                  end
         | 
| 149 | 
            +
             | 
| 119 150 | 
             
                  # ISO/IEC DIR 2, 9.2.1
         | 
| 120 151 | 
             
                  def style_percent(node, text)
         | 
| 121 152 | 
             
                    style_regex(/\b(?<num>[0-9.,]+%)/,
         | 
| @@ -169,6 +200,16 @@ module Metanorma | |
| 169 200 | 
             
                                                  "Use 'either x or y, or both'", node, text)
         | 
| 170 201 | 
             
                    style_regex(/\s(?<num>&)\s/i,
         | 
| 171 202 | 
             
                                "Avoid ampersand in ordinary text'", node, text)
         | 
| 203 | 
            +
                    eref_style_punct(node)
         | 
| 204 | 
            +
                  end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                  # https://www.iso.org/ISO-house-style.html#iso-hs-s-text-r-r-ref_unnumbered
         | 
| 207 | 
            +
                  def eref_style_punct(node)
         | 
| 208 | 
            +
                    node.xpath(".//eref[@type='footnote']").each do |e|
         | 
| 209 | 
            +
                      /^\p{P}/.match?(e.next&.text) or next
         | 
| 210 | 
            +
                      style_warning(node, "superscript cross-reference followed by punctuation",
         | 
| 211 | 
            +
                                    node.to_xml)
         | 
| 212 | 
            +
                    end
         | 
| 172 213 | 
             
                  end
         | 
| 173 214 |  | 
| 174 215 | 
             
                  def style_warning(node, msg, text = nil)
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: metanorma-iso
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.4. | 
| 4 | 
            +
              version: 2.4.4
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Ribose Inc.
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2023- | 
| 11 | 
            +
            date: 2023-05-22 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: metanorma-standoc
         | 
| @@ -352,6 +352,7 @@ files: | |
| 352 352 | 
             
            - lib/isodoc/iso/metadata.rb
         | 
| 353 353 | 
             
            - lib/isodoc/iso/pdf_convert.rb
         | 
| 354 354 | 
             
            - lib/isodoc/iso/presentation_bibdata.rb
         | 
| 355 | 
            +
            - lib/isodoc/iso/presentation_terms.rb
         | 
| 355 356 | 
             
            - lib/isodoc/iso/presentation_xml_convert.rb
         | 
| 356 357 | 
             
            - lib/isodoc/iso/presentation_xref.rb
         | 
| 357 358 | 
             
            - lib/isodoc/iso/sections.rb
         |