Class: Asciidoctor::ISO::Converter
- Inherits:
-
Standoc::Converter
- Object
- Standoc::Converter
- Asciidoctor::ISO::Converter
- Defined in:
- lib/asciidoctor/iso/converter.rb,
lib/asciidoctor/iso/base.rb,
lib/asciidoctor/iso/front.rb,
lib/asciidoctor/iso/cleanup.rb,
lib/asciidoctor/iso/section.rb,
lib/asciidoctor/iso/front_id.rb,
lib/asciidoctor/iso/validate.rb,
lib/asciidoctor/iso/validate_style.rb,
lib/asciidoctor/iso/validate_title.rb,
lib/asciidoctor/iso/validate_section.rb,
lib/asciidoctor/iso/validate_requirements.rb
Overview
A Converter implementation that generates ISO output, and a document schema encapsulation of the document for validation
Constant Summary collapse
- XML_ROOT_TAG =
"iso-standard".freeze
- XML_NAMESPACE =
"https://www.metanorma.org/ns/iso".freeze
- PRE_NORMREF_FOOTNOTES =
"//preface//fn | "\ "//clause[@type = 'scope']//fn".freeze
- NORMREF_FOOTNOTES =
"//references[@normative = 'true']//fn".freeze
- POST_NORMREF_FOOTNOTES =
"//sections//clause[not(@type = 'scope')]//fn | "\ "//annex//fn | "\ "//references[@normative = 'false']//fn".freeze
- TERM_CLAUSE =
"//sections//terms".freeze
- PUBLISHER =
"./contributor[role/@type = 'publisher']/organization".freeze
- OTHERIDS =
"@type = 'DOI' or @type = 'metanorma' or @type = 'ISSN' or "\ "@type = 'ISBN'".freeze
- STAGE_ABBRS =
{ "00": "PWI", "10": "NWIP", "20": "WD", "30": "CD", "40": "DIS", "50": "FDIS", "60": "IS", "90": "(Review)", "95": "(Withdrawal)", }.freeze
- STAGE_NAMES =
{ "00": "Preliminary work item", "10": "New work item proposal", "20": "Working draft", "30": "Committee draft", "40": "Draft", "50": "Final draft", "60": "International standard", "90": "Review", "95": "Withdrawal", }.freeze
- SI_UNIT =
leaving out as problematic: N J K C S T H h d B o E
"(m|cm|mm|km|μm|nm|g|kg|mgmol|cd|rad|sr|Hz|Hz|MHz|Pa|hPa|kJ|"\ "V|kV|W|MW|kW|F|μF|Ω|Wb|°C|lm|lx|Bq|Gy|Sv|kat|l|t|eV|u|Np|Bd|"\ "bit|kB|MB|Hart|nat|Sh|var)".freeze
- NONSTD_UNITS =
{ "sec": "s", "mins": "min", "hrs": "h", "hr": "h", "cc": "cm^3", "lit": "l", "amp": "A", "amps": "A", "rpm": "r/min" }.freeze
- ONE_SYMBOLS_WARNING =
"Only one Symbols and Abbreviated "\ "Terms section in the standard".freeze
- NON_DL_SYMBOLS_WARNING =
"Symbols and Abbreviated Terms can "\ "only contain a definition list".freeze
- SEQ =
spec of permissible section sequence we skip normative references, it goes to end of list
[ { msg: "Initial section must be (content) Foreword", val: ["./self::foreword"] }, { msg: "Prefatory material must be followed by (clause) Scope", val: ["./self::introduction", "./self::clause[@type = 'scope']" ] }, { msg: "Prefatory material must be followed by (clause) Scope", val: ["./self::clause[@type = 'scope']" ] }, { msg: "Normative References must be followed by "\ "Terms and Definitions", val: ["./self::terms | .//terms"] }, ].freeze
- SECTIONS_XPATH =
"//foreword | //introduction | //sections/terms | .//annex | "\ "//sections/definitions | //sections/clause | //references[not(parent::clause)] | "\ "//clause[descendant::references][not(parent::clause)]".freeze
- NORM_ISO_WARN =
"non-ISO/IEC reference not expected as normative".freeze
- SCOPE_WARN =
"Scope contains subclauses: should be succinct".freeze
- ASSETS_TO_STYLE =
"//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
- REQUIREMENT_RE_STR =
<<~REGEXP.freeze \\b ( shall | (is|are)_to | (is|are)_required_(not_)?to | (is|are)_required_that | has_to | only\\b[^.,]+\\b(is|are)_permitted | it_is_necessary | (is|are)_not_(allowed | permitted | acceptable | permissible) | (is|are)_not_to_be | [.,:;]_do_not ) \\b REGEXP
- REQUIREMENT_RE =
Regexp.new(REQUIREMENT_RE_STR.gsub(/\s/, "").gsub(/_/, "\\s"), Regexp::IGNORECASE)
- RECOMMENDATION_RE_STR =
<<~REGEXP.freeze \\b should | ought_(not_)?to | it_is_(not_)?recommended_that \\b REGEXP
- RECOMMENDATION_RE =
Regexp.new(RECOMMENDATION_RE_STR.gsub(/\s/, "").gsub(/_/, "\\s"), Regexp::IGNORECASE)
- PERMISSION_RE_STR =
<<~REGEXP.freeze \\b may | (is|are)_(permitted | allowed | permissible ) | it_is_not_required_that | no\\b[^.,]+\\b(is|are)_required \\b REGEXP
- PERMISSION_RE =
Regexp.new(PERMISSION_RE_STR.gsub(/\s/, "").gsub(/_/, "\\s"), Regexp::IGNORECASE)
- POSSIBILITY_RE_STR =
<<~REGEXP.freeze \\b can | cannot | be_able_to | there_is_a_possibility_of | it_is_possible_to | be_unable_to | there_is_no_possibility_of | it_is_not_possible_to \\b REGEXP
- POSSIBILITY_RE =
Regexp.new(POSSIBILITY_RE_STR.gsub(/\s/, "").gsub(/_/, "\\s"), Regexp::IGNORECASE)
Instance Method Summary collapse
- #add_amd_parts(dn, node) ⇒ Object
- #add_id_parts(dn, part, subpart) ⇒ Object
- #appendix_parse(attrs, xml, node) ⇒ Object
- #asset_style(root) ⇒ Object
- #bibdata_validate(doc) ⇒ Object
- #bibitem_cleanup(xmldoc) ⇒ Object
- #bibitem_validate(xmldoc) ⇒ Object
- #boilerplate_file(xmldoc) ⇒ Object
-
#cited_term_style(xmldoc) ⇒ Object
ISO/IEC DIR 2, 16.5.10.
- #clause_parse(attrs, xml, node) ⇒ Object
- #content_validate(doc) ⇒ Object
-
#definition_style(node) ⇒ Object
ISO/IEC DIR 2, 16.5.6.
- #disjunct_error(i, cond1, cond2, msg1, msg2) ⇒ Object
- #doc_converter(node) ⇒ Object
-
#docidentifier_cleanup(xmldoc) ⇒ Object
ISO as a prefix goes first.
- #doctype_validate(xmldoc) ⇒ Object
-
#example_style(node) ⇒ Object
ISO/IEC DIR 2, 16.5.7 ISO/IEC DIR 2, 25.5.
- #external_constraint(text) ⇒ Object
- #extract_text(node) ⇒ Object
- #figure_validate(xmldoc) ⇒ Object
- #footnote_cleanup(xmldoc) ⇒ Object
-
#footnote_style(node) ⇒ Object
ISO/IEC DIR 2, 26.5.
-
#foreword_style(node) ⇒ Object
ISO/IEC DIR 2, 12.2.
-
#foreword_validate(root) ⇒ Object
ISO/IEC DIR 2, 12.4.
- #format_ref(ref, type) ⇒ Object
- #get_id_prefix(xmldoc) ⇒ Object
- #get_stage(node) ⇒ Object
- #get_substage(node) ⇒ Object
- #get_typeabbr(node) ⇒ Object
- #html_converter(node) ⇒ Object
- #html_converter_alt(node) ⇒ Object
- #id_add_year(dn, node) ⇒ Object
- #id_langsuffix(dn, node) ⇒ Object
- #id_prefix(prefix, id) ⇒ Object
- #id_stage_abbr(stage, substage, node) ⇒ Object
- #id_stage_prefix(dn, node, force_year) ⇒ Object
- #image_name_prefix(xmldoc) ⇒ Object
- #image_name_suffix(xmldoc) ⇒ Object
-
#image_name_validate(xmldoc) ⇒ Object
DRG directives 3.2.
- #image_name_validate1(i, prefix) ⇒ Object
- #init(node) ⇒ Object
-
#introduction_style(node) ⇒ Object
ISO/IEC DIR 2, 13.2.
- #iso_id(node, xml) ⇒ Object
- #iso_id1(node) ⇒ Object
- #isosubgroup_validate(root) ⇒ Object
- #iteration_validate(xmldoc) ⇒ Object
-
#locality_erefs_validate(root) ⇒ Object
ISO/IEC DIR 2, 10.4.
- #metadata_author(node, xml) ⇒ Object
- #metadata_committee(node, xml) ⇒ Object
- #metadata_copyright(node, xml) ⇒ Object
- #metadata_doctype(node, xml) ⇒ Object
- #metadata_ext(node, xml) ⇒ Object
- #metadata_id(node, xml) ⇒ Object
- #metadata_publisher(node, xml) ⇒ Object
- #metadata_status(node, xml) ⇒ Object
-
#norm_bibitem_style(root) ⇒ Object
ISO/IEC DIR 2, 10.2.
-
#normref_validate(root) ⇒ Object
ISO/IEC DIR 2, 15.4.
-
#note_style(node) ⇒ Object
ISO/IEC DIR 2, 24.5.
- #ol_attrs(node) ⇒ Object
-
#onlychild_clause_validate(root) ⇒ Object
ISO/IEC DIR 2, 22.3.2.
- #org_abbrev ⇒ Object
- #other_footnote_renumber(xmldoc) ⇒ Object
- #outputs(node, ret) ⇒ Object
- #patent_notice_parse(xml, node) ⇒ Object
- #pdf_converter(node) ⇒ Object
- #permission_check(text) ⇒ Object
- #possibility(text) ⇒ Object
- #presentation_xml_converter(node) ⇒ Object
- #pub_class(bib) ⇒ Object
- #recommendation_check(text) ⇒ Object
- #requirement_check(text) ⇒ Object
- #scope_parse(attrs, xml, node) ⇒ Object
-
#scope_style(node) ⇒ Object
ISO/IEC DIR 2, 14.2.
- #script_validate(xmldoc) ⇒ Object
- #section_style(root) ⇒ Object
- #section_validate(doc) ⇒ Object
- #sections_cleanup(x) ⇒ Object
- #sections_presence_validate(root) ⇒ Object
- #sections_sequence_validate(root) ⇒ Object
- #sectiontype(node, level = true) ⇒ Object
-
#see_erefs_validate(root) ⇒ Object
ISO/IEC DIR 2, 15.5.3.
-
#see_xrefs_validate(root) ⇒ Object
ISO/IEC DIR 2, 15.5.3.
- #seqcheck(names, msg, accepted) ⇒ Object
- #sort_biblio(bib) ⇒ Object
-
#sort_biblio_key(bib) ⇒ Object
TODO sort by authors sort by: doc class (ISO, IEC, other standard (not DOI &c), other then standard class (docid class other than DOI &c) 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.
- #stage_abbr(stage, substage, doctype) ⇒ Object
- #stage_name(stage, substage, doctype, iteration = nil) ⇒ Object
- #stage_validate(xmldoc) ⇒ Object
- #structured_id(node, xml) ⇒ Object
- #sts_converter(node) ⇒ Object
- #style(n, t) ⇒ Object
-
#style_abbrev(n, t) ⇒ Object
ISO/IEC DIR 2, 8.4 ISO/IEC DIR 2, 9.3.
- #style_no_guidance(node, text, docpart) ⇒ Object
-
#style_non_std_units(n, t) ⇒ Object
ISO/IEC DIR 2, 9.3.
-
#style_number(n, t) ⇒ Object
ISO/IEC DIR 2, 9.1 ISO/IEC DIR 2, Table B.1.
-
#style_percent(n, t) ⇒ Object
ISO/IEC DIR 2, 9.2.1.
- #style_regex(re, warning, n, text) ⇒ Object
-
#style_two_regex_not_prev(n, text, re, re_prev, warning) ⇒ Object
style check with a regex on a token and a negative match on its preceding token.
-
#style_units(n, t) ⇒ Object
ISO/IEC DIR 2, 9.3.
- #style_warning(node, msg, text = nil) ⇒ Object
- #subclause_validate(root) ⇒ Object
-
#subfigure_validate(xmldoc) ⇒ Object
DRG directives 3.7; but anticipated by standoc.
- #substage_validate(xmldoc) ⇒ Object
- #symbols_validate(root) ⇒ Object
- #tech_report_style(root) ⇒ Object
-
#termdef_style(xmldoc) ⇒ Object
ISO/IEC DIR 2, 16.5.6.
- #termdef_warn(text, re, t, term, msg) ⇒ Object
- #title(node, xml) ⇒ Object
-
#title_all_siblings(xpath, label) ⇒ Object
ISO/IEC DIR 2, 22.2.
- #title_amd(node, t, lang, at) ⇒ Object
-
#title_first_level_validate(root) ⇒ Object
ISO/IEC DIR 2, 22.2.
- #title_full(node, t, lang, at) ⇒ Object
- #title_intro(node, t, lang, at) ⇒ Object
- #title_intro_validate(root) ⇒ Object
- #title_main(node, t, lang, at) ⇒ Object
- #title_main_validate(root) ⇒ Object
-
#title_names_type_validate(root) ⇒ Object
ISO/IEC DIR 2, 11.5.2.
- #title_part(node, t, lang, at) ⇒ Object
- #title_part_validate(root) ⇒ Object
-
#title_subpart_validate(root) ⇒ Object
ISO/IEC DIR 2, 11.4.
- #title_validate(root) ⇒ Object
- #unpub_footnotes(xmldoc) ⇒ Object
- #unpub_stage_prefix(dn, stage, typeabbr, node) ⇒ Object
- #unpublished_note(xmldoc) ⇒ Object
- #validate(doc) ⇒ Object
Instance Method Details
#add_amd_parts(dn, node) ⇒ Object
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/asciidoctor/iso/front_id.rb', line 95 def add_amd_parts(dn, node) a = node.attr("amendment-number") c = node.attr("corrigendum-number") case doctype(node) when "amendment" "#{dn}/Amd #{node.attr('amendment-number')}" when "technical-corrigendum" "#{dn}/Cor.#{node.attr('corrigendum-number')}" end end |
#add_id_parts(dn, part, subpart) ⇒ Object
129 130 131 132 133 |
# File 'lib/asciidoctor/iso/front_id.rb', line 129 def add_id_parts(dn, part, subpart) dn += "-#{part}" if part dn += "-#{subpart}" if subpart dn end |
#appendix_parse(attrs, xml, node) ⇒ Object
17 18 19 20 21 22 23 24 |
# File 'lib/asciidoctor/iso/section.rb', line 17 def appendix_parse(attrs, xml, node) attrs["inline-header".to_sym] = node.option? "inline-header" set_obligation(attrs, node) xml.appendix **attr_code(attrs) do |xml_section| xml_section.title { |name| name << node.title } xml_section << node.content end end |
#asset_style(root) ⇒ Object
190 191 192 193 194 195 196 197 198 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 190 def asset_style(root) root.xpath("//example | //termexample").each { |e| example_style(e) } root.xpath("//definition").each { |e| definition_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)) } norm_bibitem_style(root) super end |
#bibdata_validate(doc) ⇒ Object
226 227 228 229 230 231 232 |
# File 'lib/asciidoctor/iso/validate.rb', line 226 def bibdata_validate(doc) doctype_validate(doc) script_validate(doc) stage_validate(doc) substage_validate(doc) iteration_validate(doc) end |
#bibitem_cleanup(xmldoc) ⇒ Object
143 144 145 146 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 143 def bibitem_cleanup(xmldoc) super unpublished_note(xmldoc) end |
#bibitem_validate(xmldoc) ⇒ Object
249 250 251 252 253 254 255 256 |
# File 'lib/asciidoctor/iso/validate.rb', line 249 def bibitem_validate(xmldoc) xmldoc.xpath("//bibitem[date/on = '–']").each do |b| b.at("./note[@type = 'Unpublished-Status']") or @log.add("Style", b, "Reference #{b&.at("./@id")&.text} does not have an "\ "associated footnote indicating unpublished status") end end |
#boilerplate_file(xmldoc) ⇒ Object
122 123 124 125 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 122 def boilerplate_file(xmldoc) file = @lang == "fr" ? "boilerplate-fr.xml" : "boilerplate.xml" File.join(@libdir, file) end |
#cited_term_style(xmldoc) ⇒ Object
ISO/IEC DIR 2, 16.5.10
103 104 105 106 107 108 109 110 |
# File 'lib/asciidoctor/iso/validate.rb', line 103 def cited_term_style(xmldoc) xmldoc.xpath("//term//xref").each do |x| next unless xmldoc.at("//term[@id = '#{x['target']}']") x&.previous&.text == " (" and x&.previous&.previous&.name == "em" or style_warning(x, "term citation not preceded with italicised term", x.parent.text) end end |
#clause_parse(attrs, xml, node) ⇒ Object
7 8 9 10 |
# File 'lib/asciidoctor/iso/section.rb', line 7 def clause_parse(attrs, xml, node) node.option? "appendix" and return appendix_parse(attrs, xml, node) super end |
#content_validate(doc) ⇒ Object
234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/asciidoctor/iso/validate.rb', line 234 def content_validate(doc) super title_validate(doc.root) isosubgroup_validate(doc.root) onlychild_clause_validate(doc.root) termdef_style(doc.root) iev_validate(doc.root) see_xrefs_validate(doc.root) see_erefs_validate(doc.root) locality_erefs_validate(doc.root) bibdata_validate(doc.root) bibitem_validate(doc.root) figure_validate(doc.root) end |
#definition_style(node) ⇒ Object
ISO/IEC DIR 2, 16.5.6
37 38 39 40 41 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 37 def definition_style(node) return if @novalid r = requirement_check(extract_text(node)) style_warning(node, "Definition may contain requirement", r) if r end |
#disjunct_error(i, cond1, cond2, msg1, msg2) ⇒ Object
184 185 186 187 |
# File 'lib/asciidoctor/iso/validate.rb', line 184 def disjunct_error(i, cond1, cond2, msg1, msg2) cond1 && !cond2 and @log.add("Style", i, "image name #{i['src']} #{msg1}") !cond1 && cond2 and @log.add("Style", i, "image name #{i['src']} #{msg2}") end |
#doc_converter(node) ⇒ Object
24 25 26 |
# File 'lib/asciidoctor/iso/base.rb', line 24 def doc_converter(node) IsoDoc::Iso::WordConvert.new(doc_extract_attributes(node)) end |
#docidentifier_cleanup(xmldoc) ⇒ Object
ISO as a prefix goes first
52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 52 def docidentifier_cleanup(xmldoc) prefix = get_id_prefix(xmldoc) id = xmldoc.at("//bibdata/docidentifier[@type = 'ISO']") or return id.content = id_prefix(prefix, id) id = xmldoc.at("//bibdata/ext/structuredidentifier/project-number") and id.content = id_prefix(prefix, id) id = xmldoc.at("//bibdata/docidentifier[@type = 'iso-with-lang']") and id.content = id_prefix(prefix, id) id = xmldoc.at("//bibdata/docidentifier[@type = 'iso-reference']") and id.content = id_prefix(prefix, id) end |
#doctype_validate(xmldoc) ⇒ Object
112 113 114 115 116 117 118 119 |
# File 'lib/asciidoctor/iso/validate.rb', line 112 def doctype_validate(xmldoc) doctype = xmldoc&.at("//bibdata/ext/doctype")&.text %w(international-standard technical-specification technical-report publicly-available-specification international-workshop-agreement guide amendment technical-corrigendum).include? doctype or @log.add("Document Attributes", nil, "#{doctype} is not a recognised document type") end |
#example_style(node) ⇒ Object
ISO/IEC DIR 2, 16.5.7 ISO/IEC DIR 2, 25.5
45 46 47 48 49 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 45 def example_style(node) return if @novalid style_no_guidance(node, extract_text(node), "Example") style(node, extract_text(node)) end |
#external_constraint(text) ⇒ Object
88 89 90 91 92 93 |
# File 'lib/asciidoctor/iso/validate_requirements.rb', line 88 def external_constraint(text) text.split(/\.\s+/).each do |t| return t if /\b(must)\b/xi.match t end nil end |
#extract_text(node) ⇒ Object
8 9 10 11 12 13 14 15 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 8 def extract_text(node) return "" if node.nil? node1 = Nokogiri::XML.fragment(node.to_s) node1.xpath("//link | //locality | //localityStack").each(&:remove) ret = "" node1.traverse { |x| ret += x.text if x.text? } ret end |
#figure_validate(xmldoc) ⇒ Object
221 222 223 224 |
# File 'lib/asciidoctor/iso/validate.rb', line 221 def figure_validate(xmldoc) image_name_validate(xmldoc) subfigure_validate(xmldoc) end |
#footnote_cleanup(xmldoc) ⇒ Object
127 128 129 130 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 127 def footnote_cleanup(xmldoc) unpub_footnotes(xmldoc) super end |
#footnote_style(node) ⇒ Object
ISO/IEC DIR 2, 26.5
59 60 61 62 63 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 59 def footnote_style(node) return if @novalid style_no_guidance(node, extract_text(node), "Footnote") style(node, extract_text(node)) end |
#foreword_style(node) ⇒ Object
ISO/IEC DIR 2, 12.2
18 19 20 21 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 18 def foreword_style(node) return if @novalid style_no_guidance(node, extract_text(node), "Foreword") end |
#foreword_validate(root) ⇒ Object
ISO/IEC DIR 2, 12.4
21 22 23 24 25 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 21 def foreword_validate(root) f = root.at("//foreword") || return s = f.at("./clause") @log.add("Style", f, "foreword contains subclauses") unless s.nil? end |
#format_ref(ref, type) ⇒ Object
64 65 66 67 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 64 def format_ref(ref, type) ref = ref.sub(/ \(All Parts\)/i, "") super end |
#get_id_prefix(xmldoc) ⇒ Object
41 42 43 44 45 46 47 48 49 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 41 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 == "ISO" and prefix.unshift("ISO") or prefix << x1 end prefix end |
#get_stage(node) ⇒ Object
177 178 179 |
# File 'lib/asciidoctor/iso/front_id.rb', line 177 def get_stage(node) stage = node.attr("status") || node.attr("docstage") || "60" end |
#get_substage(node) ⇒ Object
181 182 183 184 |
# File 'lib/asciidoctor/iso/front_id.rb', line 181 def get_substage(node) stage = get_stage(node) node.attr("docsubstage") || ( stage == "60" ? "60" : "00" ) end |
#get_typeabbr(node) ⇒ Object
186 187 188 189 190 191 192 193 |
# File 'lib/asciidoctor/iso/front_id.rb', line 186 def get_typeabbr(node) case doctype(node) when "technical-report" then "TR " when "technical-specification" then "TS " else nil end end |
#html_converter(node) ⇒ Object
15 16 17 |
# File 'lib/asciidoctor/iso/base.rb', line 15 def html_converter(node) IsoDoc::Iso::HtmlConvert.new(html_extract_attributes(node)) end |
#html_converter_alt(node) ⇒ Object
19 20 21 22 |
# File 'lib/asciidoctor/iso/base.rb', line 19 def html_converter_alt(node) IsoDoc::Iso::HtmlConvert.new(html_extract_attributes(node). merge(alt: true)) end |
#id_add_year(dn, node) ⇒ Object
170 171 172 173 174 175 |
# File 'lib/asciidoctor/iso/front_id.rb', line 170 def id_add_year(dn, node) year = node.attr("copyright-year") @amd and year ||= node.attr("updated-date")&.sub(/-.*$/, "") dn += ":#{year}" if year dn end |
#id_langsuffix(dn, node) ⇒ Object
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/asciidoctor/iso/front_id.rb', line 106 def id_langsuffix(dn, node) lang = node.attr("language") || "en" suffix = case lang when "en" then "(E)" when "fr" then "(F)" else "(X)" end "#{dn}#{suffix}" end |
#id_prefix(prefix, id) ⇒ Object
36 37 38 39 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 36 def id_prefix(prefix, id) return id.text if @amd # we're just inheriting the prefixes from parent doc prefix.join("/") + ( id.text.match(%{^/}) ? "" : " " ) + id.text end |
#id_stage_abbr(stage, substage, node) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/asciidoctor/iso/front_id.rb', line 135 def id_stage_abbr(stage, substage, node) ret = IsoDoc::Iso::Metadata.new("en", "Latn", @i18n). status_abbrev(stage_abbr(stage, substage, doctype(node)), substage, node.attr("iteration"), node.attr("draft"), doctype(node)) if %w(amendment technical-corrigendum amendment technical-corrigendum).include?(doctype(node)) ret = ret + " " unless %w(40 50).include?(stage) end ret end |
#id_stage_prefix(dn, node, force_year) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/asciidoctor/iso/front_id.rb', line 147 def id_stage_prefix(dn, node, force_year) stage = get_stage(node) typeabbr = get_typeabbr(node) if stage && (stage.to_i < 60) dn = unpub_stage_prefix(dn, stage, typeabbr, node) elsif typeabbr && !@amd then dn = "/#{typeabbr}#{dn}" end (force_year || !(stage && (stage.to_i < 60))) and dn = id_add_year(dn, node) dn end |
#image_name_prefix(xmldoc) ⇒ Object
160 161 162 163 164 165 166 167 168 169 |
# File 'lib/asciidoctor/iso/validate.rb', line 160 def image_name_prefix(xmldoc) std = xmldoc&.at("//bibdata/ext/structuredidentifier/project-number") or return num = xmldoc&.at("//bibdata/docnumber")&.text or return ed = xmldoc&.at("//bibdata/edition")&.text || "1" prefix = num part = std["part"] and prefix += "-#{std['part']}" prefix += "_ed#{ed}" amd = std["amendment"] and prefix += "amd#{amd}" prefix end |
#image_name_suffix(xmldoc) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/asciidoctor/iso/validate.rb', line 171 def image_name_suffix(xmldoc) case xmldoc&.at("//bibdata/language")&.text when "fr" then "_f" when "de" then "_d" when "ru" then "_r" when "es" then "_s" when "ar" then "_a" when "en" then "_e" else "_e" end end |
#image_name_validate(xmldoc) ⇒ Object
DRG directives 3.2
209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/asciidoctor/iso/validate.rb', line 209 def image_name_validate(xmldoc) prefix = image_name_prefix(xmldoc) or return xmldoc.xpath("//image").each do |i| if /^ISO_\d+_/.match(File.basename(i["src"])) elsif /^(SL)?#{prefix}fig/.match(File.basename(i["src"])) image_name_validate1(i, prefix) else @log.add("Style", i, "image name #{i['src']} does not match DRG requirements: expect #{prefix}fig") end end end |
#image_name_validate1(i, prefix) ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/asciidoctor/iso/validate.rb', line 189 def image_name_validate1(i, prefix) m = %r[(SL)?#{prefix}fig(?<tab>Tab)?(?<annex>[A-Z])?(Text)?(?<num>\d+) (?<subfig>[a-z])?(?<key>_key\d+)?(?<lang>_[a-z])?$]x.match(File.basename(i["src"], ".*")) if m.nil? @log.add("Style", i, "image name #{i['src']} does not match DRG requirements") return end warn i['src'] disjunct_error(i, i.at("./ancestor::table"), !m[:tab].nil?, "is under a table but is not so labelled", "is labelled as under a table but is not") disjunct_error(i, i.at("./ancestor::annex"), !m[:annex].nil?, "is under an annex but is not so labelled", "is labelled as under an annex but is not") disjunct_error(i, i.xpath("./ancestor::figure").size > 1, !m[:subfig].nil?, "does not have a subfigure letter but is a subfigure", "has a subfigure letter but is not a subfigure") lang = image_name_suffix(i.document.root) (m[:lang] || "_e") == lang or @log.add("Style", i, "image name #{i['src']} expected to have suffix #{lang}") end |
#init(node) ⇒ Object
42 43 44 45 |
# File 'lib/asciidoctor/iso/base.rb', line 42 def init(node) super @amd = %w(amendment technical-corrigendum).include? doctype(node) end |
#introduction_style(node) ⇒ Object
ISO/IEC DIR 2, 13.2
30 31 32 33 34 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 30 def introduction_style(node) return if @novalid r = requirement_check(extract_text(node)) style_warning(node, "Introduction may contain requirement", r) if r end |
#iso_id(node, xml) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/asciidoctor/iso/front_id.rb', line 72 def iso_id(node, xml) return unless !@amd && node.attr("docnumber") || @amd && node.attr("updates") dn = iso_id1(node) dn1 = id_stage_prefix(dn, node, false) dn2 = id_stage_prefix(dn, node, true) xml.docidentifier dn1, **attr_code(type: "ISO") xml.docidentifier id_langsuffix(dn1, node), **attr_code(type: "iso-with-lang") xml.docidentifier id_langsuffix(dn2, node), **attr_code(type: "iso-reference") end |
#iso_id1(node) ⇒ Object
85 86 87 88 89 90 91 92 93 |
# File 'lib/asciidoctor/iso/front_id.rb', line 85 def iso_id1(node) if @amd dn = node.attr("updates") return add_amd_parts(dn, node) else part, subpart = node&.attr("partnumber")&.split(/-/) return add_id_parts(node.attr("docnumber"), part, subpart) end end |
#isosubgroup_validate(root) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/asciidoctor/iso/validate.rb', line 24 def isosubgroup_validate(root) root.xpath("//technical-committee/@type").each do |t| unless %w{TC PC JTC JPC}.include? t.text @log.add("Document Attributes", nil, "invalid technical committee type #{t}") end end root.xpath("//subcommittee/@type").each do |t| unless %w{SC JSC}.include? t.text @log.add("Document Attributes", nil, "invalid subcommittee type #{t}") end end end |
#iteration_validate(xmldoc) ⇒ Object
142 143 144 145 146 147 |
# File 'lib/asciidoctor/iso/validate.rb', line 142 def iteration_validate(xmldoc) iteration = xmldoc&.at("//bibdata/status/iteration")&.text or return /^\d+/.match(iteration) or @log.add("Document Attributes", nil, "#{iteration} is not a recognised iteration") end |
#locality_erefs_validate(root) ⇒ Object
ISO/IEC DIR 2, 10.4
73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/asciidoctor/iso/validate.rb', line 73 def locality_erefs_validate(root) root.xpath("//eref[descendant::locality]").each do |t| if /^(ISO|IEC)/.match t["citeas"] unless /:[ ]?(\d+{4}|–)$/.match t["citeas"] @log.add("Style", t, "undated reference #{t['citeas']} should not contain "\ "specific elements") end end end end |
#metadata_author(node, xml) ⇒ Object
31 32 33 34 35 36 37 38 39 |
# File 'lib/asciidoctor/iso/front.rb', line 31 def (node, xml) publishers = node.attr("publisher") || "ISO" csv_split(publishers).each do |p| xml.contributor do |c| c.role **{ type: "author" } c.organization { |a| organization(a, p, node, !node.attr("publisher")) } end end end |
#metadata_committee(node, xml) ⇒ Object
76 77 78 79 80 81 82 83 |
# File 'lib/asciidoctor/iso/front.rb', line 76 def (node, xml) xml.editorialgroup do |a| committee_component("technical-committee", node, a) committee_component("subcommittee", node, a) committee_component("workgroup", node, a) node.attr("secretariat") && a.secretariat(node.attr("secretariat")) end end |
#metadata_copyright(node, xml) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/asciidoctor/iso/front.rb', line 51 def (node, xml) publishers = node.attr("copyright-holder") || node.attr("publisher") || "ISO" csv_split(publishers).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, node, !(node.attr("copyright-holder") || node.attr("publisher"))) end end end end end |
#metadata_doctype(node, xml) ⇒ Object
21 22 23 24 |
# File 'lib/asciidoctor/iso/front.rb', line 21 def (node, xml) xml.doctype doctype(node) a = node.attr("horizontal") and xml.horizontal a end |
#metadata_ext(node, xml) ⇒ Object
12 13 14 15 16 17 18 19 |
# File 'lib/asciidoctor/iso/front.rb', line 12 def (node, xml) super structured_id(node, xml) xml.stagename stage_name(get_stage(node), get_substage(node), doctype(node), node.attr("iteration")) @amd && a = node.attr("updates-document-type") and xml.updates_document_type a end |
#metadata_id(node, xml) ⇒ Object
64 65 66 67 68 69 70 |
# File 'lib/asciidoctor/iso/front_id.rb', line 64 def (node, xml) iso_id(node, xml) node&.attr("tc-docnumber")&.split(/,\s*/)&.each do |n| xml.docidentifier(n, **attr_code(type: "iso-tc")) end xml.docnumber node&.attr("docnumber") end |
#metadata_publisher(node, xml) ⇒ Object
41 42 43 44 45 46 47 48 49 |
# File 'lib/asciidoctor/iso/front.rb', line 41 def (node, xml) publishers = node.attr("publisher") || "ISO" csv_split(publishers).each do |p| xml.contributor do |c| c.role **{ type: "publisher" } c.organization { |a| organization(a, p, node, !node.attr("publisher")) } end end end |
#metadata_status(node, xml) ⇒ Object
66 67 68 69 70 71 72 73 74 |
# File 'lib/asciidoctor/iso/front.rb', line 66 def (node, xml) stage = get_stage(node) substage = get_substage(node) xml.status do |s| s.stage stage, **attr_code(abbreviation: stage_abbr(stage, substage, doctype(node))) s.substage substage node.attr("iteration") && (s.iteration node.attr("iteration")) end end |
#norm_bibitem_style(root) ⇒ Object
ISO/IEC DIR 2, 10.2
182 183 184 185 186 187 188 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 182 def norm_bibitem_style(root) root.xpath(NORM_BIBITEMS).each do |b| if b.at(Standoc::Converter::ISO_PUBLISHER_XPATH).nil? @log.add("Style", b, "#{NORM_ISO_WARN}: #{b.text}") end end end |
#normref_validate(root) ⇒ Object
ISO/IEC DIR 2, 15.4
28 29 30 31 32 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 28 def normref_validate(root) f = root.at("//references[@normative = 'true']") || return f.at("./references | ./clause") && @log.add("Style", f, "normative references contains subclauses") end |
#note_style(node) ⇒ Object
ISO/IEC DIR 2, 24.5
52 53 54 55 56 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 52 def note_style(node) return if @novalid style_no_guidance(node, extract_text(node), "Note") style(node, extract_text(node)) end |
#ol_attrs(node) ⇒ Object
47 48 49 50 |
# File 'lib/asciidoctor/iso/base.rb', line 47 def ol_attrs(node) attr_code(keep_attrs(node). merge(id: ::Metanorma::Utils::anchor_or_uuid(node))) end |
#onlychild_clause_validate(root) ⇒ Object
ISO/IEC DIR 2, 22.3.2
14 15 16 17 18 19 20 21 22 |
# File 'lib/asciidoctor/iso/validate.rb', line 14 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 |
#org_abbrev ⇒ Object
26 27 28 29 |
# File 'lib/asciidoctor/iso/front.rb', line 26 def org_abbrev { "International Organization for Standardization" => "ISO", "International Electrotechnical Commission" => "IEC" } end |
#other_footnote_renumber(xmldoc) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 22 def other_footnote_renumber(xmldoc) seen = {} i = 0 xmldoc.xpath(PRE_NORMREF_FOOTNOTES).each do |fn| i, seen = other_footnote_renumber1(fn, i, seen) end xmldoc.xpath(NORMREF_FOOTNOTES).each do |fn| i, seen = other_footnote_renumber1(fn, i, seen) end xmldoc.xpath(POST_NORMREF_FOOTNOTES).each do |fn| i, seen = other_footnote_renumber1(fn, i, seen) end end |
#outputs(node, ret) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/asciidoctor/iso/base.rb', line 52 def outputs(node, ret) File.open(@filename + ".xml", "w:UTF-8") { |f| f.write(ret) } presentation_xml_converter(node).convert(@filename + ".xml") html_converter_alt(node).convert(@filename + ".presentation.xml", nil, false, "#{@filename}_alt.html") html_converter(node).convert(@filename + ".presentation.xml", nil, false, "#{@filename}.html") doc_converter(node).convert(@filename + ".presentation.xml", nil, false, "#{@filename}.doc") pdf_converter(node)&.convert(@filename + ".presentation.xml", nil, false, "#{@filename}.pdf") #sts_converter(node)&.convert(@filename + ".xml") end |
#patent_notice_parse(xml, node) ⇒ Object
26 27 28 29 30 31 |
# File 'lib/asciidoctor/iso/section.rb', line 26 def patent_notice_parse(xml, node) # xml.patent_notice do |xml_section| # xml_section << node.content # end xml << node.content end |
#pdf_converter(node) ⇒ Object
28 29 30 31 |
# File 'lib/asciidoctor/iso/base.rb', line 28 def pdf_converter(node) return nil if node.attr("no-pdf") IsoDoc::Iso::PdfConvert.new(doc_extract_attributes(node)) end |
#permission_check(text) ⇒ Object
63 64 65 66 67 68 |
# File 'lib/asciidoctor/iso/validate_requirements.rb', line 63 def (text) text.split(/\.\s+/).each do |t| return t if PERMISSION_RE.match t end nil end |
#possibility(text) ⇒ Object
83 84 85 86 |
# File 'lib/asciidoctor/iso/validate_requirements.rb', line 83 def possibility(text) text.split(/\.\s+/).each { |t| return t if POSSIBILITY_RE.match t } nil end |
#presentation_xml_converter(node) ⇒ Object
38 39 40 |
# File 'lib/asciidoctor/iso/base.rb', line 38 def presentation_xml_converter(node) IsoDoc::Iso::PresentationXMLConvert.new(html_extract_attributes(node)) end |
#pub_class(bib) ⇒ Object
74 75 76 77 78 79 80 81 82 83 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 74 def pub_class(bib) return 1 if bib.at("#{PUBLISHER}[abbreviation = 'ISO']") return 1 if bib.at("#{PUBLISHER}[name = 'International Organization "\ "for Standardization']") return 2 if bib.at("#{PUBLISHER}[abbreviation = 'IEC']") return 2 if bib.at("#{PUBLISHER}[name = 'International "\ "Electrotechnical Commission']") return 3 if bib.at("./docidentifier[@type][not(#{OTHERIDS})]") 4 end |
#recommendation_check(text) ⇒ Object
44 45 46 47 48 49 |
# File 'lib/asciidoctor/iso/validate_requirements.rb', line 44 def recommendation_check(text) text.split(/\.\s+/).each do |t| return t if RECOMMENDATION_RE.match t end nil end |
#requirement_check(text) ⇒ Object
26 27 28 29 30 31 |
# File 'lib/asciidoctor/iso/validate_requirements.rb', line 26 def requirement_check(text) text.split(/\.\s+/).each do |t| return t if REQUIREMENT_RE.match t end nil end |
#scope_parse(attrs, xml, node) ⇒ Object
12 13 14 15 |
# File 'lib/asciidoctor/iso/section.rb', line 12 def scope_parse(attrs, xml, node) attrs = attrs.merge(type: "scope") unless @amd clause_parse(attrs, xml, node) end |
#scope_style(node) ⇒ Object
ISO/IEC DIR 2, 14.2
24 25 26 27 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 24 def scope_style(node) return if @novalid style_no_guidance(node, extract_text(node), "Scope") end |
#script_validate(xmldoc) ⇒ Object
121 122 123 124 125 126 |
# File 'lib/asciidoctor/iso/validate.rb', line 121 def script_validate(xmldoc) script = xmldoc&.at("//bibdata/script")&.text script == "Latn" or @log.add("Document Attributes", nil, "#{script} is not a recognised script") end |
#section_style(root) ⇒ Object
156 157 158 159 160 161 162 163 164 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 156 def section_style(root) foreword_style(root.at("//foreword")) introduction_style(root.at("//introduction")) scope_style(root.at("//clause[@type = 'scope']")) scope = root.at("//clause[@type = 'scope']/clause") # ISO/IEC DIR 2, 14.4 scope.nil? || style_warning(scope, SCOPE_WARN, nil) tech_report_style(root) end |
#section_validate(doc) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 6 def section_validate(doc) doctype = doc&.at("//bibdata/ext/doctype")&.text unless %w(amendment technical-corrigendum).include? doctype foreword_validate(doc.root) normref_validate(doc.root) symbols_validate(doc.root) sections_presence_validate(doc.root) sections_sequence_validate(doc.root) end section_style(doc.root) subclause_validate(doc.root) super end |
#sections_cleanup(x) ⇒ Object
114 115 116 117 118 119 120 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 114 def sections_cleanup(x) super return unless @amd x.xpath("//*[@inline-header]").each do |h| h.delete('inline-header') end end |
#sections_presence_validate(root) ⇒ Object
62 63 64 65 66 67 68 69 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 62 def sections_presence_validate(root) root.at("//sections/clause[@type = 'scope']") or @log.add("Style", nil, "Scope clause missing") root.at("//references[@normative = 'true']") or @log.add("Style", nil, "Normative references missing") root.at("//terms") or @log.add("Style", nil, "Terms & definitions missing") end |
#sections_sequence_validate(root) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 99 def sections_sequence_validate(root) names = root.xpath(SECTIONS_XPATH) names = seqcheck(names, SEQ[0][:msg], SEQ[0][:val]) n = names[0] names = seqcheck(names, SEQ[1][:msg], SEQ[1][:val]) if n&.at("./self::introduction") names = seqcheck(names, SEQ[2][:msg], SEQ[2][:val]) end 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" @log.add("Style", nil, "Document must contain at least one clause") end 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 while n&.name == "clause" n&.at("./self::clause[@type = 'scope']") @log.add("Style", nil, "Scope must occur before Terms and Definitions") 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" n = names.shift if n.nil? @log.add("Style", nil, "Document must include (references) "\ "Normative References") end end n&.at("./self::references[@normative = 'true']") || @log.add("Style", nil, "Document must include (references) "\ "Normative References") n = names&.shift n&.at("./self::references[@normative = 'false']") || @log.add("Style", nil, "Final section must be (references) Bibliography") names.empty? || @log.add("Style", nil, "There are sections after the final Bibliography") end |
#sectiontype(node, level = true) ⇒ Object
33 34 35 36 |
# File 'lib/asciidoctor/iso/section.rb', line 33 def sectiontype(node, level = true) return nil if @amd super end |
#see_erefs_validate(root) ⇒ Object
ISO/IEC DIR 2, 15.5.3
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/asciidoctor/iso/validate.rb', line 55 def see_erefs_validate(root) root.xpath("//eref").each do |t| preceding = t.at("./preceding-sibling::text()[last()]") next unless !preceding.nil? && /\b(see|refer to)\s*$/mi.match(preceding) unless target = root.at("//*[@id = '#{t['bibitemid']}']") @log.add("Bibliography", t, "'#{t} is not pointing to a real reference") next end if target.at("./ancestor::references[@normative = 'true']") @log.add("Style", t, "'see #{t}' is pointing to a normative reference") end end end |
#see_xrefs_validate(root) ⇒ Object
ISO/IEC DIR 2, 15.5.3
40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/asciidoctor/iso/validate.rb', line 40 def see_xrefs_validate(root) root.xpath("//xref").each do |t| # does not deal with preceding text marked up preceding = t.at("./preceding-sibling::text()[last()]") next unless !preceding.nil? && /\b(see| refer to)\s*$/mi.match(preceding) (target = root.at("//*[@id = '#{t['target']}']")) || next if target&.at("./ancestor-or-self::*[@obligation = 'normative']") @log.add("Style", t, "'see #{t['target']}' is pointing to a normative section") end end end |
#seqcheck(names, msg, accepted) ⇒ Object
52 53 54 55 56 57 58 59 60 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 52 def seqcheck(names, msg, accepted) n = names.shift return [] if n.nil? test = accepted.map { |a| n.at(a) } if test.all? { |a| a.nil? } @log.add("Style", nil, msg) end names end |
#sort_biblio(bib) ⇒ Object
85 86 87 88 89 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 85 def sort_biblio(bib) bib.sort do |a, b| sort_biblio_key(a) <=> sort_biblio_key(b) end end |
#sort_biblio_key(bib) ⇒ Object
TODO sort by authors sort by: doc class (ISO, IEC, other standard (not DOI &c), other then standard class (docid class other than DOI &c) 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
99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 99 def sort_biblio_key(bib) pubclass = pub_class(bib) num = bib&.at("./docnumber")&.text id = bib&.at("./docidentifier[not(#{OTHERIDS})]") = bib&.at("./docidentifier[@type = 'metanorma']")&.text abbrid = unless /^\[\d+\]$/.match() /\d-(?<partid>\d+)/ =~ id&.text type = id['type'] if id title = bib&.at("./title[@type = 'main']")&.text || bib&.at("./title")&.text || bib&.at("./formattedref")&.text "#{pubclass} :: #{type} :: "\ "#{num.nil? ? abbrid : sprintf("%09d", num.to_i)} :: "\ "#{partid} :: #{id&.text} :: #{title}" end |
#stage_abbr(stage, substage, doctype) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/asciidoctor/iso/front_id.rb', line 36 def stage_abbr(stage, substage, doctype) return nil if stage.to_i > 60 ret = STAGE_ABBRS[stage.to_sym] ret = "PRF" if stage == "60" && substage == "00" if %w(amendment technical-corrigendum technical-report technical-specification).include?(doctype) ret = "NP" if stage == "10" ret = "AWI" if stage == "10" && substage == "99" ret = "D" if stage == "40" and doctype == "amendment" ret = "FD" if stage == "50" and %w(amendment technical-corrigendum).include?(doctype) ret = "D" if stage == "50" and %w(technical-report technical-specification).include?(doctype) end ret end |
#stage_name(stage, substage, doctype, iteration = nil) ⇒ Object
53 54 55 56 57 58 59 60 61 62 |
# File 'lib/asciidoctor/iso/front_id.rb', line 53 def stage_name(stage, substage, doctype, iteration = nil) return "Proof" if stage == "60" && substage == "00" ret = STAGE_NAMES[stage.to_sym] if iteration && %w(20 30).include?(stage) prefix = iteration.to_i.localize(@lang.to_sym). to_rbnf_s("SpelloutRules", "spellout-ordinal") ret = "#{prefix.capitalize} #{ret.downcase}" end ret end |
#stage_validate(xmldoc) ⇒ Object
128 129 130 131 132 133 |
# File 'lib/asciidoctor/iso/validate.rb', line 128 def stage_validate(xmldoc) stage = xmldoc&.at("//bibdata/status/stage")&.text %w(00 10 20 30 40 50 60 90 95).include? stage or @log.add("Document Attributes", nil, "#{stage} is not a recognised stage") end |
#structured_id(node, xml) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/asciidoctor/iso/front_id.rb', line 117 def structured_id(node, xml) return unless node.attr("docnumber") part, subpart = node&.attr("partnumber")&.split(/-/) xml.structuredidentifier do |i| i.project_number node.attr("docnumber"), **attr_code(part: part, subpart: subpart, amendment: node.attr("amendment-number"), corrigendum: node.attr("corrigendum-number"), origyr: node.attr("created-date")) end end |
#sts_converter(node) ⇒ Object
33 34 35 36 |
# File 'lib/asciidoctor/iso/base.rb', line 33 def sts_converter(node) return nil if node.attr("no-pdf") IsoDoc::Iso::StsConvert.new(html_extract_attributes(node)) end |
#style(n, t) ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 83 def style(n, t) return if @novalid style_number(n, t) style_percent(n, t) style_abbrev(n, t) style_units(n, t) end |
#style_abbrev(n, t) ⇒ Object
ISO/IEC DIR 2, 8.4 ISO/IEC DIR 2, 9.3
114 115 116 117 118 119 120 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 114 def style_abbrev(n, t) style_regex(/(^|\s)(?!e\.g\.|i\.e\.) (?<num>[a-z]{1,2}\.([a-z]{1,2}|\.))\b/ix, "no dots in abbreviations", n, t) style_regex(/\b(?<num>ppm)\b/i, "language-specific abbreviation", n, t) end |
#style_no_guidance(node, text, docpart) ⇒ Object
95 96 97 98 99 100 101 102 |
# File 'lib/asciidoctor/iso/validate_requirements.rb', line 95 def style_no_guidance(node, text, docpart) r = requirement_check(text) style_warning(node, "#{docpart} may contain requirement", r) if r r = (text) style_warning(node, "#{docpart} may contain permission", r) if r r = recommendation_check(text) style_warning(node, "#{docpart} may contain recommendation", r) if r end |
#style_non_std_units(n, t) ⇒ Object
ISO/IEC DIR 2, 9.3
142 143 144 145 146 147 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 142 def style_non_std_units(n, t) NONSTD_UNITS.each do |k, v| style_regex(/\b(?<num>[0-9][0-9,]*\s+#{k})\b/, "non-standard unit (should be #{v})", n, t) end end |
#style_number(n, t) ⇒ Object
ISO/IEC DIR 2, 9.1 ISO/IEC DIR 2, Table B.1
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 93 def style_number(n, t) style_two_regex_not_prev( n, t, /^(?<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 point", n, t) style_regex(/\b(?<num>billion[s]?)\b/i, "ambiguous number", n, t) end |
#style_percent(n, t) ⇒ Object
ISO/IEC DIR 2, 9.2.1
105 106 107 108 109 110 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 105 def style_percent(n, t) style_regex(/\b(?<num>[0-9.,]+%)/, "no space before percent sign", n, t) style_regex(/\b(?<num>[0-9.,]+ \u00b1 [0-9,.]+ %)/, "unbracketed tolerance before percent sign", n, t) end |
#style_regex(re, warning, n, text) ⇒ Object
65 66 67 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 65 def style_regex(re, warning, n, text) (m = re.match(text)) && style_warning(n, warning, m[:num]) end |
#style_two_regex_not_prev(n, text, re, re_prev, warning) ⇒ Object
style check with a regex on a token and a negative match on its preceding token
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 71 def style_two_regex_not_prev(n, text, re, re_prev, warning) return if text.nil? arr = Tokenizer::WhitespaceTokenizer.new.tokenize(text) arr.each_index do |i| m = re.match arr[i] m_prev = i.zero? ? nil : re_prev.match(arr[i - 1]) if !m.nil? && m_prev.nil? style_warning(n, warning, m[:num]) end end end |
#style_units(n, t) ⇒ Object
ISO/IEC DIR 2, 9.3
128 129 130 131 132 133 134 |
# File 'lib/asciidoctor/iso/validate_style.rb', line 128 def style_units(n, t) style_regex(/\b(?<num>[0-9][0-9,]*\s+[\u00b0\u2032\u2033])/, "space between number and degrees/minutes/seconds", n, t) style_regex(/\b(?<num>[0-9][0-9,]*#{SI_UNIT})\b/, "no space between number and SI unit", n, t) style_non_std_units(n, t) end |
#style_warning(node, msg, text = nil) ⇒ Object
146 147 148 149 150 151 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 146 def style_warning(node, msg, text = nil) return if @novalid w = msg w += ": #{text}" if text @log.add("Style", node, w) end |
#subclause_validate(root) ⇒ Object
200 201 202 203 204 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 200 def subclause_validate(root) 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 |
#subfigure_validate(xmldoc) ⇒ Object
DRG directives 3.7; but anticipated by standoc
150 151 152 153 154 155 156 157 158 |
# File 'lib/asciidoctor/iso/validate.rb', line 150 def subfigure_validate(xmldoc) xmldoc.xpath("//figure//figure").each do |f| { footnote: "fn", note: "note", key: "dl" }.each do |k, v| f.xpath(".//#{v}").each do |n| @log.add("Style", n, "#{k} is not permitted in a subfigure") end end end end |
#substage_validate(xmldoc) ⇒ Object
135 136 137 138 139 140 |
# File 'lib/asciidoctor/iso/validate.rb', line 135 def substage_validate(xmldoc) substage = xmldoc&.at("//bibdata/status/substage")&.text or return %w(00 20 60 90 92 93 98 99).include? substage or @log.add("Document Attributes", nil, "#{substage} is not a recognised substage") end |
#symbols_validate(root) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 40 def symbols_validate(root) f = root.xpath("//definitions") f.empty? && return (f.size == 1) || @log.add("Style", f.first, ONE_SYMBOLS_WARNING) f.first.elements.each do |e| unless e.name == "dl" @log.add("Style", f.first, NON_DL_SYMBOLS_WARNING) return end end end |
#tech_report_style(root) ⇒ Object
166 167 168 169 170 171 172 |
# File 'lib/asciidoctor/iso/validate_section.rb', line 166 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 end end |
#termdef_style(xmldoc) ⇒ Object
ISO/IEC DIR 2, 16.5.6
90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/asciidoctor/iso/validate.rb', line 90 def termdef_style(xmldoc) xmldoc.xpath("//term").each do |t| para = t.at("./definition") || return term = t.at("./preferred").text termdef_warn(para.text, /^(the|a)\b/i, t, term, "term definition starts with article") termdef_warn(para.text, /\.$/i, t, term, "term definition ends with period") end cited_term_style(xmldoc) end |
#termdef_warn(text, re, t, term, msg) ⇒ Object
85 86 87 |
# File 'lib/asciidoctor/iso/validate.rb', line 85 def termdef_warn(text, re, t, term, msg) re.match(text) && @log.add("Style", t, "#{term}: #{msg}") end |
#title(node, xml) ⇒ Object
125 126 127 128 129 130 131 132 133 134 |
# File 'lib/asciidoctor/iso/front.rb', line 125 def title(node, xml) ["en", "fr"].each do |lang| at = { language: lang, format: "text/plain" } title_full(node, xml, lang, at) title_intro(node, xml, lang, at) title_main(node, xml, lang, at) title_part(node, xml, lang, at) title_amd(node, xml, lang, at) if @amd end end |
#title_all_siblings(xpath, label) ⇒ Object
ISO/IEC DIR 2, 22.2
74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/asciidoctor/iso/validate_title.rb', line 74 def title_all_siblings(xpath, label) notitle = false withtitle = false xpath.each do |s| title_all_siblings(s.xpath("./clause | ./terms | ./references"), s&.at("./title")&.text || s["id"]) subtitle = s.at("./title") notitle = notitle || (!subtitle || subtitle.text.empty?) withtitle = withtitle || (subtitle && !subtitle.text.empty?) end notitle && withtitle && @log.add("Style", nil, "#{label}: all subclauses must have a title, or none") end |
#title_amd(node, t, lang, at) ⇒ Object
105 106 107 108 109 110 |
# File 'lib/asciidoctor/iso/front.rb', line 105 def title_amd(node, t, lang, at) return unless node.attr("title-amendment-#{lang}") t.title(**attr_code(at.merge(type: "title-amd"))) do |t1| t1 << Metanorma::Utils::asciidoc_sub(node.attr("title-amendment-#{lang}")) end end |
#title_first_level_validate(root) ⇒ Object
ISO/IEC DIR 2, 22.2
62 63 64 65 66 67 68 69 70 71 |
# File 'lib/asciidoctor/iso/validate_title.rb', line 62 def title_first_level_validate(root) root.xpath(SECTIONS_XPATH).each do |s| title = s&.at("./title")&.text || s.name s.xpath("./clause | ./terms | ./references").each do |ss| subtitle = ss.at("./title") !subtitle.nil? && !subtitle&.text&.empty? || @log.add("Style", ss, "#{title}: each first-level subclause must have a title") end end end |
#title_full(node, t, lang, at) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/asciidoctor/iso/front.rb', line 112 def title_full(node, t, lang, at) title = node.attr("title-main-#{lang}") intro = node.attr("title-intro-#{lang}") part = node.attr("title-part-#{lang}") amd = node.attr("title-amendment-#{lang}") title = "#{intro} -- #{title}" if intro title = "#{title} -- #{part}" if part title = "#{title} -- #{amd}" if amd && @amd t.title **attr_code(at.merge(type: "main")) do |t1| t1 << Metanorma::Utils::asciidoc_sub(title) end end |
#title_intro(node, t, lang, at) ⇒ Object
85 86 87 88 89 90 |
# File 'lib/asciidoctor/iso/front.rb', line 85 def title_intro(node, t, lang, at) return unless node.attr("title-intro-#{lang}") t.title(**attr_code(at.merge(type: "title-intro"))) do |t1| t1 << Metanorma::Utils::asciidoc_sub(node.attr("title-intro-#{lang}")) end end |
#title_intro_validate(root) ⇒ Object
6 7 8 9 10 11 12 13 14 15 |
# File 'lib/asciidoctor/iso/validate_title.rb', line 6 def title_intro_validate(root) title_intro_en = root.at("//title[@type='title-intro' and @language='en']") title_intro_fr = root.at("//title[@type='title-intro' and @language='fr']") if title_intro_en.nil? && !title_intro_fr.nil? @log.add("Style", title_intro_fr, "No English Title Intro!") end if !title_intro_en.nil? && title_intro_fr.nil? @log.add("Style", title_intro_en, "No French Title Intro!") end end |
#title_main(node, t, lang, at) ⇒ Object
92 93 94 95 96 |
# File 'lib/asciidoctor/iso/front.rb', line 92 def title_main(node, t, lang, at) t.title **attr_code(at.merge(type: "title-main")) do |t1| t1 << Metanorma::Utils::asciidoc_sub(node.attr("title-main-#{lang}")) end end |
#title_main_validate(root) ⇒ Object
17 18 19 20 21 22 23 24 25 26 |
# File 'lib/asciidoctor/iso/validate_title.rb', line 17 def title_main_validate(root) title_main_en = root.at("//title[@type='title-main' and @language='en']") title_main_fr = root.at("//title[@type='title-main' and @language='fr']") if title_main_en.nil? && !title_main_fr.nil? @log.add("Style", title_main_fr, "No English Title!") end if !title_main_en.nil? && title_main_fr.nil? @log.add("Style", title_main_en, "No French Title!") end end |
#title_names_type_validate(root) ⇒ Object
ISO/IEC DIR 2, 11.5.2
48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/asciidoctor/iso/validate_title.rb', line 48 def title_names_type_validate(root) doctypes = /International\sStandard | Technical\sSpecification | Publicly\sAvailable\sSpecification | Technical\sReport | Guide /xi title_main_en = root.at("//title[@type='title-main' and @language='en']") if !title_main_en.nil? && doctypes.match(title_main_en.text) @log.add("Style", title_main_en, "Main Title may name document type") end title_intro_en = root.at("//title[@type='title-intro' and @language='en']") if !title_intro_en.nil? && doctypes.match(title_intro_en.text) @log.add("Style", title_intro_en, "Title Intro may name document type") end end |
#title_part(node, t, lang, at) ⇒ Object
98 99 100 101 102 103 |
# File 'lib/asciidoctor/iso/front.rb', line 98 def title_part(node, t, lang, at) return unless node.attr("title-part-#{lang}") t.title(**attr_code(at.merge(type: "title-part"))) do |t1| t1 << Metanorma::Utils::asciidoc_sub(node.attr("title-part-#{lang}")) end end |
#title_part_validate(root) ⇒ Object
28 29 30 31 32 33 34 35 |
# File 'lib/asciidoctor/iso/validate_title.rb', line 28 def title_part_validate(root) title_part_en = root.at("//title[@type='title-part' and @language='en']") title_part_fr = root.at("//title[@type='title-part' and @language='fr']") (title_part_en.nil? && !title_part_fr.nil?) && @log.add("Style", title_part_fr, "No English Title Part!") (!title_part_en.nil? && title_part_fr.nil?) && @log.add("Style", title_part_en, "No French Title Part!") end |
#title_subpart_validate(root) ⇒ Object
ISO/IEC DIR 2, 11.4
38 39 40 41 42 43 44 45 |
# File 'lib/asciidoctor/iso/validate_title.rb', line 38 def title_subpart_validate(root) docid = root.at("//bibdata/docidentifier[@type = 'ISO']") subpart = /-\d+-\d+/.match docid iec = root.at("//bibdata/contributor[role/@type = 'publisher']/"\ "organization[abbreviation = 'IEC' or "\ "name = 'International Electrotechnical Commission']") @log.add("Style", docid, "Subpart defined on non-IEC document!") if subpart && !iec end |
#title_validate(root) ⇒ Object
88 89 90 91 92 93 94 95 96 |
# File 'lib/asciidoctor/iso/validate_title.rb', line 88 def title_validate(root) title_intro_validate(root) title_main_validate(root) title_part_validate(root) title_subpart_validate(root) title_names_type_validate(root) title_first_level_validate(root) title_all_siblings(root.xpath(SECTIONS_XPATH), "(top level)") end |
#unpub_footnotes(xmldoc) ⇒ Object
132 133 134 135 136 137 138 139 140 141 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 132 def unpub_footnotes(xmldoc) xmldoc.xpath("//bibitem/note[@type = 'Unpublished-Status']").each do |n| id = n.parent["id"] e = xmldoc.at("//eref[@bibitemid = '#{id}']") or next e.next = n.dup e.next.name = "fn" e.next.delete("format") e.next.delete("type") end end |
#unpub_stage_prefix(dn, stage, typeabbr, node) ⇒ Object
159 160 161 162 163 164 165 166 167 168 |
# File 'lib/asciidoctor/iso/front_id.rb', line 159 def unpub_stage_prefix(dn, stage, typeabbr, node) abbr = id_stage_abbr(stage, get_substage(node), node) %w(40 50).include?(stage) && i = node.attr("iteration") and itersuffix = ".#{i}" return dn if abbr.nil? || abbr.empty? # prefixes added in cleanup return "/#{abbr}#{typeabbr} #{dn}#{itersuffix}" unless @amd a = dn.split(%r{/}) a[-1] = "#{abbr}#{a[-1]}#{itersuffix}" a.join("/") end |
#unpublished_note(xmldoc) ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/asciidoctor/iso/cleanup.rb', line 148 def unpublished_note(xmldoc) xmldoc.xpath("//bibitem[not(note[@type = 'Unpublished-Status'])]").each do |b| next if pub_class(b) > 2 next unless s = b.at("./status/stage") and s.text.to_i < 60 id = b.at("docidentifier").text b.at("./language | ./script | ./abstract | ./status").previous = <<~NOTE <note type="Unpublished-Status"> <p>#{@i18n.under_preparation.sub(/%/, id)}</p></note> NOTE end end |
#validate(doc) ⇒ Object
258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/asciidoctor/iso/validate.rb', line 258 def validate(doc) content_validate(doc) doctype = doc&.at("//bibdata/ext/doctype")&.text schema = case doctype when "amendment", "technical-corrigendum" # @amd "isostandard-amd.rng" else "isostandard.rng" end schema_validate(formattedstr_strip(doc.dup), File.join(File.dirname(__FILE__), schema)) end |