Class: Metanorma::ISO::Converter
- Inherits:
-
Standoc::Converter
- Object
- Standoc::Converter
- Metanorma::ISO::Converter
- Defined in:
- lib/metanorma/iso/converter.rb,
lib/metanorma/iso/base.rb,
lib/metanorma/iso/front.rb,
lib/metanorma/iso/cleanup.rb,
lib/metanorma/iso/section.rb,
lib/metanorma/iso/front_id.rb,
lib/metanorma/iso/validate.rb,
lib/metanorma/iso/validate_list.rb,
lib/metanorma/iso/cleanup_biblio.rb,
lib/metanorma/iso/validate_image.rb,
lib/metanorma/iso/validate_style.rb,
lib/metanorma/iso/validate_title.rb,
lib/metanorma/iso/validate_section.rb,
lib/metanorma/iso/front_contributor.rb,
lib/metanorma/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
- DOCUMENT_SCHEMES =
[1951, 1972, 1979, 1987, 1989, 2012, 2013, 2024].freeze
- STAGE_ERROR =
[Pubid::Core::Errors::HarmonizedStageCodeInvalidError, Pubid::Core::Errors::TypeStageParseError, Pubid::Core::Errors::StageInvalidError].freeze
- PRE_NORMREF_FOOTNOTES =
"//preface//fn | " \ "//clause[@type = 'scope']//fn".freeze
- NORMREF_FOOTNOTES =
"//references[@normative = 'true']//fn | " \ "//clause[.//references[@normative = 'true']]//fn".freeze
- POST_NORMREF_FOOTNOTES =
"//sections//clause[not(@type = 'scope')]//fn | " \ "//annex//fn | //references[@normative = 'false']//fn | " \ "//clause[.//references[@normative = 'false']]//fn".freeze
- NORM_REF =
"//bibliography/references[@normative = 'true'][not(@hidden)] | " \ "//bibliography/clause[.//references[@normative = 'true']] | "\ "//sections//references[@normative = 'true'][not(@hidden)]" .freeze
- TERM_CLAUSE =
"//sections//terms[not(preceding-sibling::clause)] | " \ "//sections//clause[descendant::terms][not(descendant::definitions)][@type = 'terms'] | " \ "//sections/clause[not(@type = 'terms')][not(descendant::definitions)]//terms".freeze
- DEFAULT_EDGROUP_TYPE =
{ "technical-committee": "TC", subcommittee: "SC", workgroup: "WG" }.freeze
- DOCTYPE2HASHID =
{ directive: :dir, "technical-report": :tr, "guide": :guide, "technical-specification": :ts, "publicly-available-specification": :pas, "committee-document": :tc, "recommendation": :r }.freeze
- PUBLISHER =
"./contributor[role/@type = 'publisher']/organization".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
- ASSETS_TO_STYLE =
"//termsource | //formula | //termnote | " \ "//p[not(ancestor::boilerplate)] | //li[not(p)] | //dt | " \ "//dd[not(p)] | //td[not(p)] | //th[not(p)]".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
- NORM_BIBITEMS =
"//references[@normative = 'true']/bibitem".freeze
- ISO_PUBLISHER_XPATH =
<<~XPATH.freeze ./contributor[role/@type = 'publisher']/organization[abbreviation = 'ISO' or abbreviation = 'IEC' or name = 'International Organization for Standardization' or name = 'International Electrotechnical Commission'] XPATH
- COMMITTEE_ABBREVS =
{ "technical-committee" => "TC", "subcommittee" => "SC", "workgroup" => "WG" }.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
- RECOMMENDATION_RE_STR =
<<~REGEXP.freeze \\b should | ought_(not_)?to | it_is_(not_)?recommended_that \\b REGEXP
- 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
- 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
- AMBIG_WORDS_RE_STR =
<<~REGEXP.freeze \\b need_to | needs_to | might | could \\b REGEXP
Instance Method Summary collapse
- #admonition_name(node) ⇒ Object
- #ambig_words_check(text) ⇒ Object
- #ambig_words_re ⇒ Object
- #appendix_parse(attrs, xml, node) ⇒ Object
- #approval_groups_rename(xmldoc) ⇒ Object
- #asset_style(root) ⇒ Object
- #base_pubid ⇒ Object
- #bibdata_cleanup(xmldoc) ⇒ Object
- #bibdata_validate(doc) ⇒ Object
- #bibitem_cleanup(xmldoc) ⇒ Object
- #bibitem_validate(xmldoc) ⇒ Object
- #boilerplate_file(_xmldoc) ⇒ Object
- #cen?(str) ⇒ Boolean
- #cen_id_out(xml, params) ⇒ Object
- #clause_parse(attrs, xml, node) ⇒ Object
- #committee_abbrev(type, number, level) ⇒ Object
- #committee_contributors(node, xml, approval, agency) ⇒ Object
- #committee_contributors_approval(node, xml, agency) ⇒ Object
- #compact_blank(hash) ⇒ Object
- #content_validate(doc) ⇒ Object
- #contrib_committee_build(xml, agency, committee) ⇒ Object
-
#default_publisher ⇒ Object
def home_agency “ISO” end.
-
#definition_style(node) ⇒ Object
ISO/IEC DIR 2, 16.5.6.
- #disjunct_error(img, cond1, cond2, msg1, msg2) ⇒ Object
- #doc_converter(node) ⇒ Object
- #doc_extract_attributes(node) ⇒ Object
-
#docidentifier_cleanup(xmldoc) ⇒ Object
ISO as a prefix goes first.
- #doctype_validate(_xmldoc) ⇒ Object
- #document_scheme(node) ⇒ Object
- #editorial_group_types(xmldoc) ⇒ Object
- #editorial_groups_agency(xmldoc) ⇒ Object
- #eref_style_punct(node) ⇒ Object
-
#example_style(node) ⇒ Object
ISO/IEC DIR 2, 16.5.7 ISO/IEC DIR 2, 25.5.
- #external_constraint(text) ⇒ Object
- #extract_org_attrs_complex(node, opts, source, suffix) ⇒ Object
- #extract_publishers(xmldoc) ⇒ 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, amd: false) ⇒ Object
document’s type, eg.
- #html_converter(node) ⇒ Object
- #html_converter_alt(node) ⇒ Object
- #id_add_year(docnum, node) ⇒ Object
- #id_prefix(prefix, id) ⇒ Object
- #image_name_parse(img, prefix) ⇒ 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
- #insert_unpub_note(biblio, msg) ⇒ Object
-
#introduction_style(node) ⇒ Object
ISO/IEC DIR 2, 13.2.
- #iso_id(node, xml) ⇒ Object
- #iso_id_default(params) ⇒ Object
- #iso_id_out(xml, params, with_prf) ⇒ Object
- #iso_id_out_common(xml, params, with_prf) ⇒ Object
- #iso_id_out_non_amd(xml, params, with_prf) ⇒ Object
- #iso_id_params(node) ⇒ Object
- #iso_id_params_add(node) ⇒ Object
-
#iso_id_params_core(node) ⇒ Object
unpublished is for internal use.
- #iso_id_params_resolve(params, params2, node, orig_id) ⇒ Object
- #iso_id_pub(node) ⇒ Object
- #iso_id_reference(params) ⇒ Object
- #iso_id_stage(node) ⇒ Object
- #iso_id_stage_populate(ret, node, stage) ⇒ Object
- #iso_id_undated(params) ⇒ Object
- #iso_id_with_lang(params) ⇒ Object
- #iso_id_year(node) ⇒ Object
- #iso_xref_validate(doc) ⇒ Object
- #isosubgroup_validate(root) ⇒ Object
- #iteration_validate(xmldoc) ⇒ Object
- #li_depth_validate(doc) ⇒ Object
-
#list_after_colon_punctuation(list, entries) ⇒ Object
if first list entry starts lowercase, treat as sentence broken up.
- #list_full_sentence(elem) ⇒ Object
- #list_punctuation(doc) ⇒ Object
- #list_punctuation1(list, prectext) ⇒ Object
- #list_semicolon_phrase(elem, last) ⇒ Object
- #list_semicolon_phrase_punct(elem, text, last) ⇒ Object
- #list_validate(doc) ⇒ Object
- #listcount_validate(doc) ⇒ Object
-
#locality_erefs_validate(root) ⇒ Object
ISO/IEC DIR 2, 10.4.
- #metadata_approval_agency(xml, list) ⇒ Object
- #metadata_approval_committee(node, xml) ⇒ Object
- #metadata_approval_committee_types(node) ⇒ Object
- #metadata_author(node, xml) ⇒ Object
- #metadata_committee(node, xml) ⇒ Object
- #metadata_editorial_committee(node, xml) ⇒ Object
- #metadata_ext(node, xml) ⇒ Object
- #metadata_id(node, xml) ⇒ Object
- #metadata_publisher(node, xml) ⇒ Object
- #metadata_stage(node, xml) ⇒ Object
- #metadata_stagename(id) ⇒ Object
- #metadata_status(node, xml) ⇒ Object
- #metadata_subdoctype(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
- #ol_cleanup(doc) ⇒ Object
- #ol_count_validate(doc) ⇒ Object
-
#onlychild_clause_validate(root) ⇒ Object
ISO/IEC DIR 2, 22.3.2.
- #org_abbrev ⇒ Object
- #org_attrs_parse(node, opts) ⇒ Object
- #org_organization(node, xml, org) ⇒ Object
- #orig_id_parse(orig) ⇒ Object
- #other_footnote_renumber(xmldoc) ⇒ Object
- #outputs(node, ret) ⇒ Object
- #patent_notice_parse(xml, node) ⇒ Object
- #pdf_converter(node) ⇒ Object
- #permission_check(text) ⇒ Object
- #permission_re ⇒ Object
- #possibility_check(text) ⇒ Object
- #possibility_re ⇒ Object
- #presentation_xml_converter(node) ⇒ Object
- #pub_class(bib) ⇒ Object
- #pubid_select(params) ⇒ Object
- #recommendation_check(text) ⇒ Object
- #recommendation_re ⇒ Object
- #relaton_relation_descriptions ⇒ Object
- #relaton_relations ⇒ Object
- #replacement_standard(biblio) ⇒ Object
- #report_illegal_stage(stage, substage) ⇒ Object
- #requirement_check(text) ⇒ Object
- #requirement_re ⇒ Object
- #requirements_processor ⇒ Object
- #scope_parse(attrs, xml, node) ⇒ Object
-
#scope_style(node) ⇒ Object
ISO/IEC DIR 2, 14.2.
- #section_names_terms_cleanup(xml) ⇒ Object
- #section_style(root) ⇒ Object
- #section_validate(doc) ⇒ Object
- #sections_cleanup(xml) ⇒ Object
- #sections_presence_validate(root) ⇒ Object
- #sections_sequence_validate(root) ⇒ Object
- #sections_sequence_validate_body(names, elem) ⇒ Object
- #sections_sequence_validate_body_vocab(names, elem) ⇒ Object
- #sections_sequence_validate_end(names, elem) ⇒ Object
- #sections_sequence_validate_start(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, 20.2 does not deal with preceding text marked up.
- #seqcheck(names, msg, accepted) ⇒ Object
- #skip_list_punctuation(list) ⇒ Object
- #sort_biblio(bib) ⇒ Object
-
#sort_biblio_key(bib) ⇒ Object
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.
-
#starts_lowercase?(text) ⇒ Boolean
allow that all-caps word (acronym) is agnostic as to lowercase.
- #starts_uppercase?(text) ⇒ Boolean
- #structured_id(node, xml) ⇒ Object
- #sts_converter(node) ⇒ Object
- #style(node, text) ⇒ Object
-
#style_abbrev(node, text) ⇒ Object
ISO/IEC DIR 2, 8.4 ISO/IEC DIR 2, 9.3.
- #style_ambig_words(node, text) ⇒ Object
- #style_no_guidance(node, text, docpart) ⇒ Object
-
#style_non_std_units(node, text) ⇒ Object
ISO/IEC DIR 2, 9.3.
-
#style_number(node, text) ⇒ Object
ISO/IEC DIR 2, 9.1 ISO/IEC DIR 2, Table B.1 www.iso.org/ISO-house-style.html#iso-hs-s-text-r-n-numbers.
- #style_number_grouping(node, text) ⇒ Object
-
#style_percent(node, text) ⇒ Object
ISO/IEC DIR 2, 9.2.1.
- #style_punct(node, text) ⇒ Object
- #style_regex(regex, warning, node, text) ⇒ Object
- #style_subscript(node) ⇒ Object
-
#style_two_regex_not_prev(n, text, regex, re_prev, warning) ⇒ Object
style check with a regex on a token and a negative match on its preceding token.
-
#style_units(node, text) ⇒ 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.
- #symbols_validate(root) ⇒ Object
- #tc_number(ret, node) ⇒ Object
- #tech_report_style(root) ⇒ Object
-
#term_contains_subclauses(node) ⇒ Object
in ISO, term has subterm, unless there is no definition to the term (subclauses start immediately), or it is labelled as “grouping”.
- #term_def_subclause_parse(attrs, xml, node) ⇒ Object
- #term_defs_boilerplate_cont(src, term, isodoc) ⇒ Object
- #term_xrefs_validate(xmldoc) ⇒ Object
- #term_xrefs_validate1(xref, termids) ⇒ Object
- #termdef_boilerplate_insert(xmldoc, isodoc, once = false) ⇒ Object
- #termdef_boilerplate_insert_locationx(xmldoc) ⇒ Object
-
#termdef_style(xmldoc) ⇒ Object
ISO/IEC DIR 2, 16.5.6.
- #termdef_warn(text, regex, elem, term, msg) ⇒ Object
- #terms_terms_cleanup(xmldoc) ⇒ Object
- #title(node, xml) ⇒ Object
-
#title_all_siblings(xpath, label) ⇒ Object
ISO/IEC DIR 2, 22.2.
- #title_amd(node, xml, lang, at) ⇒ Object
-
#title_first_level_validate(root) ⇒ Object
ISO/IEC DIR 2, 22.2.
- #title_full(node, xml, lang, at) ⇒ Object
- #title_intro(node, xml, lang, at) ⇒ Object
- #title_intro_validate(root) ⇒ Object
- #title_lang_part(doc, part, lang) ⇒ Object
- #title_main(node, xml, lang, at) ⇒ Object
- #title_main_validate(root) ⇒ Object
-
#title_names_type_validate(root) ⇒ Object
ISO/IEC DIR 2, 11.5.2.
- #title_no_full_stop_validate(root) ⇒ Object
- #title_part(node, xml, lang, at) ⇒ Object
- #title_part_validate(root) ⇒ Object
-
#title_subpart_validate(root) ⇒ Object
ISO/IEC DIR 2, 11.4.
- #title_validate(root) ⇒ Object
- #toc_default ⇒ Object
- #unpub_footnotes(xmldoc) ⇒ Object
- #unpublished_note(xmldoc) ⇒ Object
- #validate(doc) ⇒ Object
- #vocab_terms_titles_validate(root) ⇒ Object
- #withdrawn_note(xmldoc) ⇒ Object
- #withdrawn_ref?(biblio) ⇒ Boolean
-
#xrefs_mandate_validate(xmldoc) ⇒ Object
require that all assets of a particular type be cross-referenced within the document.
- #xrefs_mandate_validate1(xmldoc, xpath, name) ⇒ Object
Instance Method Details
#admonition_name(node) ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/metanorma/iso/base.rb', line 74 def admonition_name(node) name = super a = node.attr("type") and ["editorial"].each do |t| name = t if a.casecmp(t).zero? end name end |
#ambig_words_check(text) ⇒ Object
117 118 119 120 121 122 123 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 117 def ambig_words_check(text) @lang == "en" or return text.split(/\.\s+/).each do |t| return t if ambig_words_re.match t end nil end |
#ambig_words_re ⇒ Object
111 112 113 114 115 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 111 def ambig_words_re @lang == "en" or return Regexp.new(self.class::AMBIG_WORDS_RE_STR.gsub(/\s/, "") .gsub("_", "\\s"), Regexp::IGNORECASE) end |
#appendix_parse(attrs, xml, node) ⇒ Object
17 18 19 20 21 22 23 24 |
# File 'lib/metanorma/iso/section.rb', line 17 def appendix_parse(attrs, xml, node) attrs[:"inline-header"] = 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 |
#approval_groups_rename(xmldoc) ⇒ Object
105 106 107 108 109 |
# File 'lib/metanorma/iso/cleanup.rb', line 105 def approval_groups_rename(xmldoc) %w(technical-committee subcommittee workgroup).each do |v| xmldoc.xpath("//bibdata//approval-#{v}").each { |a| a.name = v } end end |
#asset_style(root) ⇒ Object
224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/metanorma/iso/validate_style.rb', line 224 def asset_style(root) root.xpath("//example | //termexample").each { |e| example_style(e) } root.xpath("//definition/verbal-definition").each do |e| definition_style(e) end 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 |
#base_pubid ⇒ Object
66 67 68 |
# File 'lib/metanorma/iso/front_id.rb', line 66 def base_pubid Pubid::Iso::Identifier end |
#bibdata_cleanup(xmldoc) ⇒ Object
98 99 100 101 102 103 |
# File 'lib/metanorma/iso/cleanup.rb', line 98 def bibdata_cleanup(xmldoc) super approval_groups_rename(xmldoc) editorial_groups_agency(xmldoc) editorial_group_types(xmldoc) end |
#bibdata_validate(doc) ⇒ Object
155 156 157 158 |
# File 'lib/metanorma/iso/validate.rb', line 155 def bibdata_validate(doc) doctype_validate(doc) iteration_validate(doc) end |
#bibitem_cleanup(xmldoc) ⇒ Object
73 74 75 76 77 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 73 def bibitem_cleanup(xmldoc) super unpublished_note(xmldoc) withdrawn_note(xmldoc) end |
#bibitem_validate(xmldoc) ⇒ Object
186 187 188 189 190 191 192 193 |
# File 'lib/metanorma/iso/validate.rb', line 186 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
55 56 57 58 59 60 61 62 |
# File 'lib/metanorma/iso/cleanup.rb', line 55 def boilerplate_file(_xmldoc) file = case @lang when "fr" then "boilerplate-fr.adoc" when "ru" then "boilerplate-ru.adoc" else "boilerplate.adoc" end File.join(@libdir, file) end |
#cen?(str) ⇒ Boolean
51 52 53 |
# File 'lib/metanorma/iso/front_id.rb', line 51 def cen?(str) /^C?EN/.match?(str) end |
#cen_id_out(xml, params) ⇒ Object
163 164 165 166 |
# File 'lib/metanorma/iso/front_id.rb', line 163 def cen_id_out(xml, params) xml.docidentifier iso_id_default(params).to_s, **attr_code(type: "CEN", primary: "true") end |
#clause_parse(attrs, xml, node) ⇒ Object
7 8 9 10 |
# File 'lib/metanorma/iso/section.rb', line 7 def clause_parse(attrs, xml, node) node.option? "appendix" and return appendix_parse(attrs, xml, node) super end |
#committee_abbrev(type, number, level) ⇒ Object
70 71 72 73 74 |
# File 'lib/metanorma/iso/front_contributor.rb', line 70 def committee_abbrev(type, number, level) type ||= COMMITTEE_ABBREVS[level.sub(/^approval-/, "")] type == "Other" and type = "" "#{type} #{number}".strip end |
#committee_contributors(node, xml, approval, agency) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/metanorma/iso/front_contributor.rb', line 30 def committee_contributors(node, xml, approval, agency) (approval ? node : nil).each do |v| node.attr("#{v}-number") or next node.attr(v) or node.set_attr(v, "") o = { source: [v], role: approval ? "authorizer" : "author", default_org: false, committee: true, agency:, desc: v.sub(/^approval-/, "").tr("-", " ").capitalize } org_contributor(node, xml, o) end approval or committee_contributors_approval(node, xml, agency) end |
#committee_contributors_approval(node, xml, agency) ⇒ Object
42 43 44 45 46 |
# File 'lib/metanorma/iso/front_contributor.rb', line 42 def committee_contributors_approval(node, xml, agency) o = { name: agency, role: "authorizer", default_org: false, desc: "Agency", committee: false } org_contributor(node, xml, o) end |
#compact_blank(hash) ⇒ Object
77 78 79 |
# File 'lib/metanorma/iso/front_id.rb', line 77 def compact_blank(hash) hash.compact.reject { |_, v| v.is_a?(String) && v.empty? } end |
#content_validate(doc) ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/metanorma/iso/validate.rb', line 160 def content_validate(doc) super root = doc.root title_validate(root) isosubgroup_validate(root) termdef_style(root) iso_xref_validate(root) bibdata_validate(root) bibitem_validate(root) figure_validate(root) list_validate(doc) end |
#contrib_committee_build(xml, agency, committee) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/metanorma/iso/front_contributor.rb', line 54 def contrib_committee_build(xml, agency, committee) name = org_abbrev.invert[agency] and agency = name xml.name agency xml.subdivision do |s| s.organization do |o| o.name committee[:name] committee[:abbr] and o.abbreviation committee[:abbr] committee[:ident] and o.identifier committee[:ident] end end end |
#default_publisher ⇒ Object
def home_agency “ISO” end
8 9 10 |
# File 'lib/metanorma/iso/front_contributor.rb', line 8 def default_publisher "ISO" end |
#definition_style(node) ⇒ Object
ISO/IEC DIR 2, 16.5.6
38 39 40 41 42 |
# File 'lib/metanorma/iso/validate_style.rb', line 38 def definition_style(node) @novalid and return r = requirement_check(extract_text(node)) style_warning(node, "Definition may contain requirement", r) if r end |
#disjunct_error(img, cond1, cond2, msg1, msg2) ⇒ Object
41 42 43 44 45 46 |
# File 'lib/metanorma/iso/validate_image.rb', line 41 def disjunct_error(img, cond1, cond2, msg1, msg2) cond1 && !cond2 and @log.add("Style", img, "image name #{img['src']} #{msg1}") !cond1 && cond2 and @log.add("Style", img, "image name #{img['src']} #{msg2}") end |
#doc_converter(node) ⇒ Object
29 30 31 |
# File 'lib/metanorma/iso/base.rb', line 29 def doc_converter(node) IsoDoc::Iso::WordConvert.new(doc_extract_attributes(node)) end |
#doc_extract_attributes(node) ⇒ Object
33 34 35 36 |
# File 'lib/metanorma/iso/base.rb', line 33 def doc_extract_attributes(node) super.merge(isowordtemplate: node.attr("iso-word-template"), isowordbgstripcolor: node.attr("iso-word-bg-strip-color")) end |
#docidentifier_cleanup(xmldoc) ⇒ Object
ISO as a prefix goes first
19 20 21 22 23 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 19 def docidentifier_cleanup(xmldoc) prefix = get_id_prefix(xmldoc) id = xmldoc.at("//bibdata/ext/structuredidentifier/project-number") and id.content = id_prefix(prefix, id) end |
#doctype_validate(_xmldoc) ⇒ Object
139 140 141 142 143 144 145 146 |
# File 'lib/metanorma/iso/validate.rb', line 139 def doctype_validate(_xmldoc) %w(international-standard technical-specification technical-report publicly-available-specification international-workshop-agreement guide amendment technical-corrigendum committee-document recommendation) .include? @doctype or @log.add("Document Attributes", nil, "#{@doctype} is not a recognised document type") end |
#document_scheme(node) ⇒ Object
84 85 86 87 88 89 90 91 92 |
# File 'lib/metanorma/iso/base.rb', line 84 def document_scheme(node) r = node.attr("document-scheme") and return r r = node.attr("copyright-year")&.to_i or return "2024" DOCUMENT_SCHEMES.each_index do |i| i.zero? and next r < DOCUMENT_SCHEMES[i] and return DOCUMENT_SCHEMES[i - 1].to_s end "2024" end |
#editorial_group_types(xmldoc) ⇒ Object
133 134 135 136 137 138 139 140 |
# File 'lib/metanorma/iso/cleanup.rb', line 133 def editorial_group_types(xmldoc) %w(technical-committee subcommittee workgroup).each do |v| xmldoc.xpath("//bibdata//#{v} | //bibdata//approval-#{v}").each do |g| g["type"] and next g["type"] = DEFAULT_EDGROUP_TYPE[v.to_sym] end end end |
#editorial_groups_agency(xmldoc) ⇒ Object
111 112 113 114 115 116 117 118 119 120 |
# File 'lib/metanorma/iso/cleanup.rb', line 111 def editorial_groups_agency(xmldoc) pubs = extract_publishers(xmldoc) xmldoc.xpath("//bibdata/ext/editorialgroup").each do |e| pubs.reverse_each do |p| if e.children.empty? then e << "<agency>#{p}</agency>" else e.children.first.previous = "<agency>#{p}</agency>" end end end end |
#eref_style_punct(node) ⇒ Object
203 204 205 206 207 208 209 |
# File 'lib/metanorma/iso/validate_style.rb', line 203 def eref_style_punct(node) node.xpath(".//eref[@type='footnote']").each do |e| /^\p{P}/.match?(e.next&.text) or next style_warning(node, "superscript cross-reference followed by punctuation", node.to_xml) end end |
#example_style(node) ⇒ Object
ISO/IEC DIR 2, 16.5.7 ISO/IEC DIR 2, 25.5
46 47 48 49 50 |
# File 'lib/metanorma/iso/validate_style.rb', line 46 def example_style(node) @novalid and return style_no_guidance(node, extract_text(node), "Example") style(node, extract_text(node)) end |
#external_constraint(text) ⇒ Object
98 99 100 101 102 103 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 98 def external_constraint(text) text.split(/\.\s+/).each do |t| return t if /\b(must)\b/xi.match? t end nil end |
#extract_org_attrs_complex(node, opts, source, suffix) ⇒ Object
48 49 50 51 52 |
# File 'lib/metanorma/iso/front_contributor.rb', line 48 def extract_org_attrs_complex(node, opts, source, suffix) n = node.attr("#{source}-number#{suffix}") t = committee_abbrev(node.attr("#{source}-type#{suffix}"), n, source) super.merge(ident: t).compact end |
#extract_publishers(xmldoc) ⇒ Object
122 123 124 125 126 127 128 |
# File 'lib/metanorma/iso/cleanup.rb', line 122 def extract_publishers(xmldoc) xmldoc.xpath("//bibdata/contributor[role/@type = 'publisher']/" \ "organization").each_with_object([]) do |p, m| x = p.at("./abbreviation") || p.at("./name") or next m << x.children.to_xml end end |
#extract_text(node) ⇒ Object
8 9 10 11 12 13 14 15 16 |
# File 'lib/metanorma/iso/validate_style.rb', line 8 def extract_text(node) node.nil? and return "" node1 = Nokogiri::XML.fragment(node.to_s) node1.xpath(".//link | .//locality | .//localityStack | .//stem") .each(&:remove) ret = "" node1.traverse { |x| ret += x.text if x.text? } HTMLEntities.new.decode(ret) end |
#figure_validate(xmldoc) ⇒ Object
92 93 94 95 |
# File 'lib/metanorma/iso/validate_image.rb', line 92 def figure_validate(xmldoc) image_name_validate(xmldoc) subfigure_validate(xmldoc) end |
#footnote_cleanup(xmldoc) ⇒ Object
64 65 66 67 |
# File 'lib/metanorma/iso/cleanup.rb', line 64 def footnote_cleanup(xmldoc) unpub_footnotes(xmldoc) super end |
#footnote_style(node) ⇒ Object
ISO/IEC DIR 2, 26.5
60 61 62 63 64 |
# File 'lib/metanorma/iso/validate_style.rb', line 60 def footnote_style(node) @novalid and return style_no_guidance(node, extract_text(node), "Footnote") style(node, extract_text(node)) end |
#foreword_style(node) ⇒ Object
ISO/IEC DIR 2, 12.2
19 20 21 22 |
# File 'lib/metanorma/iso/validate_style.rb', line 19 def foreword_style(node) @novalid and return style_no_guidance(node, extract_text(node), "Foreword") end |
#foreword_validate(root) ⇒ Object
ISO/IEC DIR 2, 12.4
22 23 24 25 26 |
# File 'lib/metanorma/iso/validate_section.rb', line 22 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
25 26 27 28 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 25 def format_ref(ref, type) ref = ref.sub(/ \(All Parts\)/i, "") super end |
#get_id_prefix(xmldoc) ⇒ Object
10 11 12 13 14 15 16 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 10 def get_id_prefix(xmldoc) xmldoc.xpath("//bibdata/contributor[role/@type = 'publisher']" \ "/organization").each_with_object([]) do |x, prefix| x1 = x.at("abbreviation")&.text || x.at("name")&.text prefix << x1 end end |
#get_stage(node) ⇒ Object
236 237 238 239 240 241 |
# File 'lib/metanorma/iso/front_id.rb', line 236 def get_stage(node) a = node.attr("status") a = node.attr("docstage") if a.nil? || a.empty? a = "60" if a.nil? || a.empty? a end |
#get_substage(node) ⇒ Object
243 244 245 246 247 248 |
# File 'lib/metanorma/iso/front_id.rb', line 243 def get_substage(node) stage = get_stage(node) ret = node.attr("docsubstage") ret = (stage == "60" ? "60" : "00") if ret.nil? || ret.empty? ret end |
#get_typeabbr(node, amd: false) ⇒ Object
document’s type, eg. :tr, :ts, :amd, :cor, Type.new(:tr)
28 29 30 31 32 |
# File 'lib/metanorma/iso/front_id.rb', line 28 def get_typeabbr(node, amd: false) node.attr("amendment-number") and return :amd node.attr("corrigendum-number") and return :cor DOCTYPE2HASHID[doctype(node).to_sym] end |
#html_converter(node) ⇒ Object
20 21 22 |
# File 'lib/metanorma/iso/base.rb', line 20 def html_converter(node) IsoDoc::Iso::HtmlConvert.new(html_extract_attributes(node)) end |
#html_converter_alt(node) ⇒ Object
24 25 26 27 |
# File 'lib/metanorma/iso/base.rb', line 24 def html_converter_alt(node) IsoDoc::Iso::HtmlConvert.new(html_extract_attributes(node) .merge(alt: true)) end |
#id_add_year(docnum, node) ⇒ Object
229 230 231 232 233 234 |
# File 'lib/metanorma/iso/front_id.rb', line 229 def id_add_year(docnum, node) year = node.attr("copyright-year") @amd and year ||= node.attr("updated-date")&.sub(/-.*$/, "") docnum += ":#{year}" if year docnum end |
#id_prefix(prefix, id) ⇒ Object
4 5 6 7 8 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 4 def id_prefix(prefix, id) # we're just inheriting the prefixes from parent doc @amd and return id.text prefix.join("/") + (id.text.match?(%{^/}) ? "" : " ") + id.text end |
#image_name_parse(img, prefix) ⇒ Object
48 49 50 51 52 53 54 55 56 |
# File 'lib/metanorma/iso/validate_image.rb', line 48 def image_name_parse(img, 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(img["src"], ".*")) m.nil? and @log.add("Style", img, "image name #{img['src']} does not match DRG requirements") m end |
#image_name_prefix(xmldoc) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/metanorma/iso/validate_image.rb', line 16 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 std["part"] and prefix += "-#{std['part']}" prefix += "_ed#{ed}" amd = std["amendment"] and prefix += "amd#{amd}" prefix end |
#image_name_suffix(xmldoc) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/metanorma/iso/validate_image.rb', line 28 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
77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/metanorma/iso/validate_image.rb', line 77 def image_name_validate(xmldoc) prefix = image_name_prefix(xmldoc) or return xmldoc.xpath("//image").each do |i| next if i["src"].start_with?("data:") case File.basename(i["src"]) when /^ISO_\d+_/ when /^(SL)?#{prefix}fig/ then 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
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/metanorma/iso/validate_image.rb', line 58 def image_name_validate1(i, prefix) m = image_name_parse(i, prefix) or return 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
56 57 58 59 60 61 |
# File 'lib/metanorma/iso/base.rb', line 56 def init(node) super @amd = %w(amendment technical-corrigendum).include? doctype(node) @vocab = node.attr("docsubtype") == "vocabulary" @validate_years = node.attr("validate-years") end |
#insert_unpub_note(biblio, msg) ⇒ Object
114 115 116 117 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 114 def insert_unpub_note(biblio, msg) biblio.at("./language | ./script | ./abstract | ./status") .previous = %(<note type="Unpublished-Status"><p>#{msg}</p></note>) end |
#introduction_style(node) ⇒ Object
ISO/IEC DIR 2, 13.2
31 32 33 34 35 |
# File 'lib/metanorma/iso/validate_style.rb', line 31 def introduction_style(node) @novalid and return r = requirement_check(extract_text(node)) style_warning(node, "Introduction may contain requirement", r) if r end |
#iso_id(node, xml) ⇒ Object
34 35 36 37 38 39 |
# File 'lib/metanorma/iso/front_id.rb', line 34 def iso_id(node, xml) (!@amd && node.attr("docnumber") || node.attr("adopted-from")) || (@amd && node.attr("updates")) or return params = iso_id_params(node) iso_id_out(xml, params, true) end |
#iso_id_default(params) ⇒ Object
185 186 187 188 189 190 191 192 |
# File 'lib/metanorma/iso/front_id.rb', line 185 def iso_id_default(params) params_nolang = params.dup.tap { |hs| hs.delete(:language) } params1 = if params[:unpublished] params_nolang.dup.tap { |hs| hs.delete(:year) } else params_nolang end params1.delete(:unpublished) pubid_select(params1).create(**params1) end |
#iso_id_out(xml, params, with_prf) ⇒ Object
154 155 156 157 158 159 160 161 |
# File 'lib/metanorma/iso/front_id.rb', line 154 def iso_id_out(xml, params, with_prf) cen?(params[:publisher]) and return cen_id_out(xml, params) iso_id_out_common(xml, params, with_prf) @amd and return iso_id_out_non_amd(xml, params, with_prf) rescue StandardError, *STAGE_ERROR => e clean_abort("Document identifier: #{e}", xml) end |
#iso_id_out_common(xml, params, with_prf) ⇒ Object
168 169 170 171 172 173 174 175 |
# File 'lib/metanorma/iso/front_id.rb', line 168 def iso_id_out_common(xml, params, with_prf) xml.docidentifier iso_id_default(params).to_s(with_prf:), **attr_code(type: "ISO", primary: "true") xml.docidentifier iso_id_reference(params) .to_s(format: :ref_num_short, with_prf:), **attr_code(type: "iso-reference") xml.docidentifier iso_id_reference(params).urn, **attr_code(type: "URN") end |
#iso_id_out_non_amd(xml, params, with_prf) ⇒ Object
177 178 179 180 181 182 183 |
# File 'lib/metanorma/iso/front_id.rb', line 177 def iso_id_out_non_amd(xml, params, with_prf) xml.docidentifier iso_id_undated(params).to_s(with_prf:), **attr_code(type: "iso-undated") xml.docidentifier iso_id_with_lang(params) .to_s(format: :ref_num_long, with_prf:), **attr_code(type: "iso-with-lang") end |
#iso_id_params(node) ⇒ Object
41 42 43 44 45 46 47 48 49 |
# File 'lib/metanorma/iso/front_id.rb', line 41 def iso_id_params(node) params = iso_id_params_core(node) params2 = iso_id_params_add(node) num = node.attr("docnumber") orig = node.attr("updates") || node.attr("adopted-from") /[[:alpha:]]/.match?(num) and orig ||= num orig and orig_id = orig_id_parse(orig) iso_id_params_resolve(params, params2, node, orig_id) end |
#iso_id_params_add(node) ⇒ Object
100 101 102 103 104 105 106 107 108 109 |
# File 'lib/metanorma/iso/front_id.rb', line 100 def iso_id_params_add(node) stage = iso_id_stage(node) ret = { number: node.attr("amendment-number") || node.attr("corrigendum-number"), year: iso_id_year(node), iteration: node.attr("iteration") } iso_id_stage_populate(ret, node, stage) tc_number(ret, node) compact_blank(ret) end |
#iso_id_params_core(node) ⇒ Object
unpublished is for internal use
82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/metanorma/iso/front_id.rb', line 82 def iso_id_params_core(node) pub = iso_id_pub(node) ret = { number: node.attr("docnumber"), part: node.attr("partnumber"), language: node.attr("language") || "en", type: get_typeabbr(node), publisher: pub[0], unpublished: /^[0-5]/.match?(get_stage(node)), copublisher: pub[1..] } ret[:copublisher].empty? and ret.delete(:copublisher) compact_blank(ret) end |
#iso_id_params_resolve(params, params2, node, orig_id) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/metanorma/iso/front_id.rb', line 140 def iso_id_params_resolve(params, params2, node, orig_id) if orig_id && (node.attr("amendment-number") || node.attr("corrigendum-number")) %i(unpublished part).each { |x| params.delete(x) } params2[:base] = orig_id elsif orig_id && ![Pubid::Iso::Identifier, Pubid::Iec::Identifier].include?(pubid_select(params)) params2[:adopted] = orig_id end params.merge!(params2) params end |
#iso_id_pub(node) ⇒ Object
95 96 97 98 |
# File 'lib/metanorma/iso/front_id.rb', line 95 def iso_id_pub(node) (node.attr("publisher") || default_publisher).split(/[;,]/) .map(&:strip).map { |x| org_abbrev[x] || x } end |
#iso_id_reference(params) ⇒ Object
211 212 213 214 |
# File 'lib/metanorma/iso/front_id.rb', line 211 def iso_id_reference(params) params1 = params.dup.tap { |hs| hs.delete(:unpublished) } pubid_select(params1).create(**params1) end |
#iso_id_stage(node) ⇒ Object
130 131 132 |
# File 'lib/metanorma/iso/front_id.rb', line 130 def iso_id_stage(node) "#{get_stage(node)}.#{get_substage(node)}" end |
#iso_id_stage_populate(ret, node, stage) ⇒ Object
122 123 124 125 126 127 128 |
# File 'lib/metanorma/iso/front_id.rb', line 122 def iso_id_stage_populate(ret, node, stage) if stage && !cen?(node.attr("publisher")) ret[:stage] = stage ret[:stage] == "60.00" and ret[:stage] = :PRF end ret end |
#iso_id_undated(params) ⇒ Object
194 195 196 197 198 199 200 201 |
# File 'lib/metanorma/iso/front_id.rb', line 194 def iso_id_undated(params) params_nolang = params.dup.tap { |hs| hs.delete(:language) } params2 = params_nolang.dup.tap do |hs| hs.delete(:year) hs.delete(:unpublished) end pubid_select(params2).create(**params2) end |
#iso_id_with_lang(params) ⇒ Object
203 204 205 206 207 208 209 |
# File 'lib/metanorma/iso/front_id.rb', line 203 def iso_id_with_lang(params) params1 = if params[:unpublished] params.dup.tap { |hs| hs.delete(:year) } else params end params1.delete(:unpublished) pubid_select(params1).create(**params1) end |
#iso_id_year(node) ⇒ Object
134 135 136 137 138 |
# File 'lib/metanorma/iso/front_id.rb', line 134 def iso_id_year(node) (node.attr("copyright-year") || node.attr("updated-date") || node.attr("published-date")) &.sub(/-.*$/, "") || Date.today.year end |
#iso_xref_validate(doc) ⇒ Object
178 179 180 181 182 183 184 |
# File 'lib/metanorma/iso/validate.rb', line 178 def iso_xref_validate(doc) see_xrefs_validate(doc) term_xrefs_validate(doc) xrefs_mandate_validate(doc) see_erefs_validate(doc) locality_erefs_validate(doc) end |
#isosubgroup_validate(root) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/metanorma/iso/validate.rb', line 15 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
148 149 150 151 152 153 |
# File 'lib/metanorma/iso/validate.rb', line 148 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 |
#li_depth_validate(doc) ⇒ Object
24 25 26 27 28 29 |
# File 'lib/metanorma/iso/validate_list.rb', line 24 def li_depth_validate(doc) doc.xpath("//li//li//li//li").each do |l| l.at(".//li") and style_warning(l, "List more than four levels deep", nil) end end |
#list_after_colon_punctuation(list, entries) ⇒ Object
if first list entry starts lowercase, treat as sentence broken up
69 70 71 72 73 74 75 76 77 78 |
# File 'lib/metanorma/iso/validate_list.rb', line 69 def list_after_colon_punctuation(list, entries) lower = starts_lowercase?(list.at(".//li").text) entries.each_with_index do |li, i| if lower list_semicolon_phrase(li, i == entries.size - 1) else list_full_sentence(li) end end end |
#list_full_sentence(elem) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/metanorma/iso/validate_list.rb', line 101 def list_full_sentence(elem) %w(Cyrl Latn Grek).include?(@script) or return text = elem.text.strip starts_uppercase?(text) or style_warning(elem, "List entry of separate sentences must start " \ "with uppercase letter", text) punct = text.strip.sub(/^.*?(\S)$/m, "\\1") punct == "." or style_warning(elem, "List entry of separate sentences must " \ "end with full stop", text) end |
#list_punctuation(doc) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/metanorma/iso/validate_list.rb', line 32 def list_punctuation(doc) return if @novalid ((doc.xpath("//ol") - doc.xpath("//ul//ol | //ol//ol")) + (doc.xpath("//ul") - doc.xpath("//ul//ul | //ol//ul"))).each do |list| next if skip_list_punctuation(list) prec = list.at("./preceding::text()[normalize-space(.) != ''][1]") list_punctuation1(list, prec&.text) end end |
#list_punctuation1(list, prectext) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/metanorma/iso/validate_list.rb', line 56 def list_punctuation1(list, prectext) prectext ||= "" entries = list.xpath(".//li") %w(Cyrl Latn Grek).include?(@script) or return case prectext.strip[-1] when ":", "" then list_after_colon_punctuation(list, entries) when "." then entries.each { |li| list_full_sentence(li) } else style_warning(list, "All lists must be preceded by " \ "colon or full stop", prectext) end end |
#list_semicolon_phrase(elem, last) ⇒ Object
80 81 82 83 84 85 86 |
# File 'lib/metanorma/iso/validate_list.rb', line 80 def list_semicolon_phrase(elem, last) text = elem.text.strip starts_lowercase?(text) or style_warning(elem, "List entry of broken up sentence must start " \ "with lowercase letter", text) list_semicolon_phrase_punct(elem, text, last) end |
#list_semicolon_phrase_punct(elem, text, last) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/metanorma/iso/validate_list.rb', line 88 def list_semicolon_phrase_punct(elem, text, last) punct = text.strip.sub(/^.*?(\S)$/m, "\\1") if last punct == "." or style_warning(elem, "Final list entry of broken up " \ "sentence must end with full stop", text) else punct == ";" or style_warning(elem, "List entry of broken up sentence must " \ "end with semicolon", text) end end |
#list_validate(doc) ⇒ Object
173 174 175 176 |
# File 'lib/metanorma/iso/validate.rb', line 173 def list_validate(doc) listcount_validate(doc) list_punctuation(doc) end |
#listcount_validate(doc) ⇒ Object
5 6 7 8 9 10 |
# File 'lib/metanorma/iso/validate_list.rb', line 5 def listcount_validate(doc) return if @novalid ol_count_validate(doc) li_depth_validate(doc) end |
#locality_erefs_validate(root) ⇒ Object
ISO/IEC DIR 2, 10.4
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/metanorma/iso/validate.rb', line 65 def locality_erefs_validate(root) root.xpath("//eref[descendant::locality]").each do |t| if /^(ISO|IEC)/.match?(t["citeas"]) && !/: ?(\d+{4}|–)$/.match?(t["citeas"]) @log.add("Style", t, "undated reference #{t['citeas']} should not contain " \ "specific elements") end end end |
#metadata_approval_agency(xml, list) ⇒ Object
123 124 125 126 127 128 |
# File 'lib/metanorma/iso/front_contributor.rb', line 123 def (xml, list) list = [default_publisher] if list.nil? || list.empty? list.each do |v| xml.agency v end end |
#metadata_approval_committee(node, xml) ⇒ Object
104 105 106 107 108 109 110 111 112 113 |
# File 'lib/metanorma/iso/front_contributor.rb', line 104 def (node, xml) types = (node) xml.approvalgroup do |a| (a, node.attr("approval-agency") &.split(%r{[/,;]})) types.each do |v| node.attr("#{v}-number") and committee_component(v, node, a) end end end |
#metadata_approval_committee_types(node) ⇒ Object
115 116 117 118 119 120 121 |
# File 'lib/metanorma/iso/front_contributor.rb', line 115 def (node) types = %w(technical-committee subcommittee workgroup) !node.nil? && node.attr("approval-technical-committee-number") and types = %w(approval-technical-committee approval-subcommittee approval-workgroup) types end |
#metadata_author(node, xml) ⇒ Object
17 18 19 20 21 22 |
# File 'lib/metanorma/iso/front_contributor.rb', line 17 def (node, xml) org_contributor(node, xml, { source: ["publisher", "pub"], role: "author", default: default_publisher }) committee_contributors(node, xml, false, default_publisher) end |
#metadata_committee(node, xml) ⇒ Object
90 91 92 93 |
# File 'lib/metanorma/iso/front_contributor.rb', line 90 def (node, xml) (node, xml) (node, xml) end |
#metadata_editorial_committee(node, xml) ⇒ Object
95 96 97 98 99 100 101 102 |
# File 'lib/metanorma/iso/front_contributor.rb', line 95 def (node, xml) xml.editorialgroup do |a| %w(technical-committee subcommittee workgroup).each do |v| node.attr("#{v}-number") and committee_component(v, node, a) end node.attr("secretariat") and a.secretariat(node.attr("secretariat")) end end |
#metadata_ext(node, xml) ⇒ Object
13 14 15 16 17 18 19 20 |
# File 'lib/metanorma/iso/front.rb', line 13 def (node, xml) super structured_id(node, xml) (node, xml) @amd && a = node.attr("updates-document-type") and xml.updates_document_type a a = node.attr("fast-track") and xml.send "fast-track", a != "false" end |
#metadata_id(node, xml) ⇒ Object
10 11 12 13 14 15 16 17 18 |
# File 'lib/metanorma/iso/front_id.rb', line 10 def (node, xml) if id = node.attr("docidentifier") xml.docidentifier id, **attr_code(type: "ISO", primary: "true") else iso_id(node, xml) end node.attr("tc-docnumber")&.split(/,\s*/)&.each do |n| xml.docidentifier(n, **attr_code(type: "iso-tc")) end end |
#metadata_publisher(node, xml) ⇒ Object
83 84 85 86 87 88 |
# File 'lib/metanorma/iso/front_contributor.rb', line 83 def (node, xml) super # approvals committee_contributors(node, xml, true, node.attr("approval-agency") || default_publisher) end |
#metadata_stage(node, xml) ⇒ Object
26 27 28 29 30 31 32 33 34 35 |
# File 'lib/metanorma/iso/front.rb', line 26 def (node, xml) id = iso_id_default(iso_id_params(node)) id.stage or return if abbr = id.typed_stage_abbrev abbr = abbr.to_s.upcase.strip end xml.stagename (id)&.strip, **attr_code(abbreviation: abbr) rescue *STAGE_ERROR end |
#metadata_stagename(id) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/metanorma/iso/front.rb', line 37 def (id) if @amd id.amendments&.first&.stage&.name || id.corrigendums&.first&.stage&.name else begin id.typed_stage_name rescue StandardError id.stage&.name end end end |
#metadata_status(node, xml) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/metanorma/iso/front.rb', line 55 def (node, xml) stage = get_stage(node) substage = get_substage(node) abbrev = iso_id_default(iso_id_params(node)).stage&.abbr&.upcase xml.status do |s| s.stage stage, **attr_code(abbreviation: abbrev) s.substage substage i = node.attr("iteration") and s.iteration i end rescue *STAGE_ERROR report_illegal_stage(stage, substage) end |
#metadata_subdoctype(node, xml) ⇒ Object
50 51 52 53 |
# File 'lib/metanorma/iso/front.rb', line 50 def (node, xml) super a = node.attr("horizontal") and xml.horizontal a end |
#norm_bibitem_style(root) ⇒ Object
ISO/IEC DIR 2, 10.2
201 202 203 204 205 206 207 |
# File 'lib/metanorma/iso/validate_section.rb', line 201 def norm_bibitem_style(root) root.xpath(NORM_BIBITEMS).each do |b| if b.at(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
29 30 31 32 33 |
# File 'lib/metanorma/iso/validate_section.rb', line 29 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
53 54 55 56 57 |
# File 'lib/metanorma/iso/validate_style.rb', line 53 def note_style(node) @novalid and return style_no_guidance(node, extract_text(node), "Note") style(node, extract_text(node)) end |
#ol_attrs(node) ⇒ Object
67 68 69 70 71 72 |
# File 'lib/metanorma/iso/base.rb', line 67 def ol_attrs(node) attr_code(keep_attrs(node) .merge(id: ::Metanorma::Utils::anchor_or_uuid(node), "explicit-type": olist_style(node.attributes[1]), start: node.attr("start"))) end |
#ol_cleanup(doc) ⇒ Object
35 36 37 38 39 40 41 42 |
# File 'lib/metanorma/iso/cleanup.rb', line 35 def ol_cleanup(doc) doc.xpath("//ol[@explicit-type]").each do |x| x["type"] = x["explicit-type"] x.delete("explicit-type") @log.add("Style", x, "Style override set for ordered list") end end |
#ol_count_validate(doc) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/metanorma/iso/validate_list.rb', line 12 def ol_count_validate(doc) doc.xpath("//clause | //annex").each do |c| next if c.xpath(".//ol").empty? ols = c.xpath(".//ol") - c.xpath(".//ul//ol | .//ol//ol | .//clause//ol") ols.size > 1 and style_warning(c, "More than 1 ordered list in a numbered clause", nil) end end |
#onlychild_clause_validate(root) ⇒ Object
ISO/IEC DIR 2, 22.3.2
217 218 219 220 221 222 223 224 225 226 |
# File 'lib/metanorma/iso/validate_section.rb', line 217 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
12 13 14 15 |
# File 'lib/metanorma/iso/front_contributor.rb', line 12 def org_abbrev { "International Organization for Standardization" => "ISO", "International Electrotechnical Commission" => "IEC" } end |
#org_attrs_parse(node, opts) ⇒ Object
76 77 78 79 80 81 |
# File 'lib/metanorma/iso/front_contributor.rb', line 76 def org_attrs_parse(node, opts) super&.map do |x| x.merge(agency: opts[:agency], abbr: opts[:abbr], committee: opts[:committee], default_org: opts[:default_org]) end end |
#org_organization(node, xml, org) ⇒ Object
24 25 26 27 28 |
# File 'lib/metanorma/iso/front_contributor.rb', line 24 def org_organization(node, xml, org) org[:committee] and contrib_committee_build(xml, org[:agency], org) or super end |
#orig_id_parse(orig) ⇒ Object
55 56 57 58 59 60 61 62 63 64 |
# File 'lib/metanorma/iso/front_id.rb', line 55 def orig_id_parse(orig) cen?(orig) and return Pubid::Cen::Identifier::Base.parse(orig) ret = case orig when /^ISO/ then Pubid::Iso::Identifier::Base.parse(orig) when /^IEC/ then Pubid::Iec::Identifier.parse(orig) else base_pubid::Base.parse(orig) end ret.edition ||= 1 ret end |
#other_footnote_renumber(xmldoc) ⇒ Object
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/metanorma/iso/cleanup.rb', line 24 def other_footnote_renumber(xmldoc) seen = {} i = 0 [PRE_NORMREF_FOOTNOTES, NORMREF_FOOTNOTES, POST_NORMREF_FOOTNOTES].each do |xpath| xmldoc.xpath(xpath).each do |fn| i, seen = other_footnote_renumber1(fn, i, seen) end end end |
#outputs(node, ret) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/metanorma/iso/base.rb', line 94 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/metanorma/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
38 39 40 41 42 |
# File 'lib/metanorma/iso/base.rb', line 38 def pdf_converter(node) return nil if node.attr("no-pdf") IsoDoc::Iso::PdfConvert.new(pdf_extract_attributes(node)) end |
#permission_check(text) ⇒ Object
70 71 72 73 74 75 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 70 def (text) text.split(/\.\s+/).each do |t| return t if .match t end nil end |
#permission_re ⇒ Object
64 65 66 67 68 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 64 def @lang == "en" or return Regexp.new(self.class::PERMISSION_RE_STR.gsub(/\s/, "") .gsub("_", "\\s"), Regexp::IGNORECASE) end |
#possibility_check(text) ⇒ Object
93 94 95 96 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 93 def possibility_check(text) text.split(/\.\s+/).each { |t| return t if possibility_re.match t } nil end |
#possibility_re ⇒ Object
87 88 89 90 91 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 87 def possibility_re @lang == "en" or return Regexp.new(self.class::POSSIBILITY_RE_STR.gsub(/\s/, "") .gsub("_", "\\s"), Regexp::IGNORECASE) end |
#presentation_xml_converter(node) ⇒ Object
50 51 52 53 54 |
# File 'lib/metanorma/iso/base.rb', line 50 def presentation_xml_converter(node) IsoDoc::Iso::PresentationXMLConvert .new(html_extract_attributes(node) .merge(output_formats: ::Metanorma::Iso::Processor.new.output_formats)) end |
#pub_class(bib) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 32 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(#{skip_docid} or @type = 'metanorma')]") || bib.at("./docidentifier[not(@type)]") 4 end |
#pubid_select(params) ⇒ Object
70 71 72 73 74 75 |
# File 'lib/metanorma/iso/front_id.rb', line 70 def pubid_select(params) if cen?(Array(params[:publisher])&.first || "") Pubid::Cen::Identifier else base_pubid end end |
#recommendation_check(text) ⇒ Object
47 48 49 50 51 52 53 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 47 def recommendation_check(text) @lang == "en" or return text.split(/\.\s+/).each do |t| return t if recommendation_re.match t end nil end |
#recommendation_re ⇒ Object
42 43 44 45 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 42 def recommendation_re Regexp.new(self.class::RECOMMENDATION_RE_STR.gsub(/\s/, "") .gsub("_", "\\s"), Regexp::IGNORECASE) end |
#relaton_relation_descriptions ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/metanorma/iso/front.rb', line 134 def relaton_relation_descriptions super.merge( "amends" => "updates", "revises" => "updates", "replaces" => "obsoletes", "supersedes" => "obsoletes", "corrects" => "updates", "informatively-cited-in" => "isCitedIn", "informatively-cites" => "cites", "normatively-cited in" => "isCitedIn", "normatively-cites" => "cites", "identical-adopted-from" => "adoptedFrom", "modified-adopted-from" => "adoptedFrom", "related-directive" => "related", "related-mandate" => "related" ) end |
#relaton_relations ⇒ Object
129 130 131 132 |
# File 'lib/metanorma/iso/front.rb', line 129 def relaton_relations super + %w(obsoletes successor-of manifestation-of related annotation-of) end |
#replacement_standard(biblio) ⇒ Object
107 108 109 110 111 112 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 107 def replacement_standard(biblio) r = biblio.at("./relation[@type = 'updates']/bibitem") or return nil id = r.at("./formattedref | ./docidentifier[@primary = 'true'] | " \ "./docidentifier | ./formattedref") or return nil id.text end |
#report_illegal_stage(stage, substage) ⇒ Object
68 69 70 71 |
# File 'lib/metanorma/iso/front.rb', line 68 def report_illegal_stage(stage, substage) err = "Illegal document stage: #{stage}.#{substage}" @log.add("Document Attributes", nil, err) end |
#requirement_check(text) ⇒ Object
26 27 28 29 30 31 32 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 26 def requirement_check(text) @lang == "en" or return text.split(/\.\s+/).each do |t| return t if requirement_re.match t end nil end |
#requirement_re ⇒ Object
21 22 23 24 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 21 def requirement_re Regexp.new(self.class::REQUIREMENT_RE_STR.gsub(/\s/, "") .gsub("_", "\\s"), Regexp::IGNORECASE) end |
#requirements_processor ⇒ Object
16 17 18 |
# File 'lib/metanorma/iso/base.rb', line 16 def requirements_processor ::Metanorma::Requirements::Iso end |
#scope_parse(attrs, xml, node) ⇒ Object
12 13 14 15 |
# File 'lib/metanorma/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
25 26 27 28 |
# File 'lib/metanorma/iso/validate_style.rb', line 25 def scope_style(node) @novalid and return style_no_guidance(node, extract_text(node), "Scope") end |
#section_names_terms_cleanup(xml) ⇒ Object
88 89 90 91 |
# File 'lib/metanorma/iso/cleanup.rb', line 88 def section_names_terms_cleanup(xml) @vocab and return super end |
#section_style(root) ⇒ Object
173 174 175 176 177 178 179 180 181 |
# File 'lib/metanorma/iso/validate_section.rb', line 173 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 19 |
# File 'lib/metanorma/iso/validate_section.rb', line 6 def section_validate(doc) 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) onlychild_clause_validate(doc.root) @vocab and vocab_terms_titles_validate(doc.root) super end |
#sections_cleanup(xml) ⇒ Object
49 50 51 52 53 |
# File 'lib/metanorma/iso/cleanup.rb', line 49 def sections_cleanup(xml) super @amd or return xml.xpath("//*[@inline-header]").each { |h| h.delete("inline-header") } end |
#sections_presence_validate(root) ⇒ Object
65 66 67 68 69 70 71 72 |
# File 'lib/metanorma/iso/validate_section.rb', line 65 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
94 95 96 97 98 99 100 101 102 |
# File 'lib/metanorma/iso/validate_section.rb', line 94 def sections_sequence_validate(root) names, n = sections_sequence_validate_start(root) if @vocab names, n = sections_sequence_validate_body_vocab(names, n) else names, n = sections_sequence_validate_body(names, n) end sections_sequence_validate_end(names, n) end |
#sections_sequence_validate_body(names, elem) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/metanorma/iso/validate_section.rb', line 117 def sections_sequence_validate_body(names, elem) if elem.nil? || elem.name != "clause" @log.add("Style", elem, "Document must contain at least one clause") end elem&.at("./self::clause") || @log.add("Style", elem, "Document must contain clause after " \ "Terms and Definitions") elem&.at("./self::clause[@type = 'scope']") && @log.add("Style", elem, "Scope must occur before Terms and Definitions") elem = names.shift while elem&.name == "clause" elem&.at("./self::clause[@type = 'scope']") @log.add("Style", elem, "Scope must occur before Terms and Definitions") elem = names.shift end %w(annex references).include? elem&.name or @log.add("Style", elem, "Only annexes and references can follow clauses") [names, elem] end |
#sections_sequence_validate_body_vocab(names, elem) ⇒ Object
140 141 142 143 144 145 146 147 148 |
# File 'lib/metanorma/iso/validate_section.rb', line 140 def sections_sequence_validate_body_vocab(names, elem) while elem && %w(clause terms).include?(elem.name) elem = names.shift end %w(annex references).include? elem&.name or @log.add("Style", elem, "Only annexes and references can follow terms and clauses") [names, elem] end |
#sections_sequence_validate_end(names, elem) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/metanorma/iso/validate_section.rb', line 150 def sections_sequence_validate_end(names, elem) while elem&.name == "annex" elem = names.shift if elem.nil? @log.add("Style", nil, "Document must include (references) " \ "Normative References") end end elem&.at("./self::references[@normative = 'true']") || @log.add("Style", nil, "Document must include (references) " \ "Normative References") elem = names&.shift elem&.at("./self::references[@normative = 'false']") || @log.add("Style", elem, "Final section must be (references) Bibliography") names.empty? || @log.add("Style", elem, "There are sections after the final Bibliography") end |
#sections_sequence_validate_start(root) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/metanorma/iso/validate_section.rb', line 104 def sections_sequence_validate_start(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]) n&.at("./self::introduction") and names = seqcheck(names, SEQ[2][:msg], SEQ[2][:val]) names = seqcheck(names, SEQ[3][:msg], SEQ[3][:val]) n = names.shift n = names.shift if n&.at("./self::definitions") [names, n] end |
#sectiontype(node, level = true) ⇒ Object
33 34 35 36 37 38 39 40 |
# File 'lib/metanorma/iso/section.rb', line 33 def sectiontype(node, level = true) return nil if @amd ret = sectiontype_streamline(sectiontype1(node)) return ret if ret == "terms and definitions" && @vocab super end |
#see_erefs_validate(root) ⇒ Object
ISO/IEC DIR 2, 15.5.3
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/metanorma/iso/validate.rb', line 48 def see_erefs_validate(root) @lang == "en" or return root.xpath("//eref").each do |t| prec = t.at("./preceding-sibling::text()[last()]") !prec.nil? && /\b(see|refer to)\p{Zs}*\Z/mi.match(prec) or next unless target = root.at("//*[@id = '#{t['bibitemid']}']") @log.add("Bibliography", t, "'#{t} is not pointing to a real reference") next end target.at("./ancestor::references[@normative = 'true']") and @log.add("Style", t, "'see #{t}' is pointing to a normative reference") end end |
#see_xrefs_validate(root) ⇒ Object
ISO/IEC DIR 2, 15.5.3, 20.2 does not deal with preceding text marked up
32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/metanorma/iso/validate.rb', line 32 def see_xrefs_validate(root) @lang == "en" or return root.xpath("//xref").each do |t| preceding = t.at("./preceding-sibling::text()[last()]") next unless !preceding.nil? && /\b(see| refer to)\p{Zs}*\Z/mi.match(preceding) (target = root.at("//*[@id = '#{t['target']}']")) || next target.at("./ancestor-or-self::*[@obligation = 'normative']") && !target.at("./ancestor::sections") and @log.add("Style", t, "'see #{t['target']}' is pointing to a normative section") end end |
#seqcheck(names, msg, accepted) ⇒ Object
54 55 56 57 58 59 60 61 62 63 |
# File 'lib/metanorma/iso/validate_section.rb', line 54 def seqcheck(names, msg, accepted) n = names.shift return [] if n.nil? test = accepted.map { |a| n.at(a) } if test.all?(&:nil?) @log.add("Style", nil, msg) end names end |
#skip_list_punctuation(list) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/metanorma/iso/validate_list.rb', line 44 def skip_list_punctuation(list) return true if list.at("./ancestor::table") return true if list.at("./following-sibling::term") # terms boilerplate list.xpath(".//li").each do |entry| l = entry.dup l.xpath(".//ol | .//ul").each(&:remove) l.text.split.size > 2 and return false end true end |
#sort_biblio(bib) ⇒ Object
46 47 48 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 46 def sort_biblio(bib) bib.sort { |a, b| sort_biblio_key(a) <=> sort_biblio_key(b) } end |
#sort_biblio_key(bib) ⇒ Object
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
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 57 def sort_biblio_key(bib) pubclass = pub_class(bib) num = bib.at("./docnumber")&.text id = bib.at("./docidentifier[@primary]") || bib.at("./docidentifier[not(#{skip_docid} or @type = 'metanorma')]") = 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)} :: " \ "#{sprintf('%09d', partid.to_i)} :: #{id&.text} :: #{title}" end |
#starts_lowercase?(text) ⇒ Boolean
allow that all-caps word (acronym) is agnostic as to lowercase
114 115 116 117 |
# File 'lib/metanorma/iso/validate_list.rb', line 114 def starts_lowercase?(text) text.match?(/^[^[[:upper:]][[:lower:]]]*[[:lower:]]/) || text.match?(/^[^[[:upper:]][[:lower:]]]*[[:upper:]][[:upper:]]+[^[[:alpha:]]]/) end |
#starts_uppercase?(text) ⇒ Boolean
119 120 121 |
# File 'lib/metanorma/iso/validate_list.rb', line 119 def starts_uppercase?(text) text.match?(/^[^[[:upper:]][[:lower:]]]*[[:upper:]]/) end |
#structured_id(node, xml) ⇒ Object
216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/metanorma/iso/front_id.rb', line 216 def structured_id(node, xml) node.attr("docnumber") or return part, subpart = node&.attr("partnumber")&.split("-") xml.structuredidentifier do |i| i.project_number(node.attr("docnumber"), **attr_code( part:, subpart:, amendment: node.attr("amendment-number"), corrigendum: node.attr("corrigendum-number"), origyr: node.attr("created-date") )) end end |
#sts_converter(node) ⇒ Object
44 45 46 47 48 |
# File 'lib/metanorma/iso/base.rb', line 44 def sts_converter(node) return nil if node.attr("no-pdf") IsoDoc::Iso::StsConvert.new(html_extract_attributes(node)) end |
#style(node, text) ⇒ Object
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/metanorma/iso/validate_style.rb', line 85 def style(node, text) @novalid and return @novalid_number or style_number(node, text) style_percent(node, text) style_abbrev(node, text) style_units(node, text) style_punct(node, text) style_subscript(node) style_ambig_words(node, text) end |
#style_abbrev(node, text) ⇒ Object
ISO/IEC DIR 2, 8.4 ISO/IEC DIR 2, 9.3
156 157 158 159 160 161 162 |
# File 'lib/metanorma/iso/validate_style.rb', line 156 def style_abbrev(node, text) style_regex(/(?:\A|\p{Zs})(?!e\.g\.|i\.e\.) (?<num>[a-z]{1,2}\.(?:[a-z]{1,2}|\.))\b/ix, "no dots in abbreviations", node, text) style_regex(/\b(?<num>ppm)\b/i, "language-specific abbreviation", node, text) end |
#style_ambig_words(node, text) ⇒ Object
109 110 111 112 113 114 |
# File 'lib/metanorma/iso/validate_style.rb', line 109 def style_ambig_words(node, text) r = ambig_words_check(text) and style_warning(node, "may contain ambiguous provision", r) @lang == "en" and style_regex(/\b(?<num>billions?)\b/i, "ambiguous number", node, text) end |
#style_no_guidance(node, text, docpart) ⇒ Object
125 126 127 128 129 130 131 132 133 |
# File 'lib/metanorma/iso/validate_requirements.rb', line 125 def style_no_guidance(node, text, docpart) @lang == "en" or return 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(node, text) ⇒ Object
ISO/IEC DIR 2, 9.3
185 186 187 188 189 190 |
# File 'lib/metanorma/iso/validate_style.rb', line 185 def style_non_std_units(node, text) NONSTD_UNITS.each do |k, v| style_regex(/\b(?<num>[0-9][0-9,]*\p{Zs}+#{k})\b/, "non-standard unit (should be #{v})", node, text) end end |
#style_number(node, text) ⇒ Object
ISO/IEC DIR 2, 9.1 ISO/IEC DIR 2, Table B.1 www.iso.org/ISO-house-style.html#iso-hs-s-text-r-n-numbers
119 120 121 122 123 124 125 126 127 128 |
# File 'lib/metanorma/iso/validate_style.rb', line 119 def style_number(node, text) style_number_grouping(node, text) style_regex(/(?:^|\p{Zs})(?<num>[0-9]+\.[0-9]+)(?!\.[0-9])/i, "possible decimal point: mark up numbers with stem:[]", node, text) @lang == "en" and style_regex(/\b(?<num>billions?)\b/i, "ambiguous number", node, text) style_regex(/(?:^|\p{Zs})(?<num>-[0-9][0-9,.]*)/i, "hyphen instead of minus sign U+2212", node, text) @novalid_number = true end |
#style_number_grouping(node, text) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/metanorma/iso/validate_style.rb', line 130 def style_number_grouping(node, text) if @validate_years style_two_regex_not_prev( node, text, /^(?<num>-?[0-9]{4,}[,0-9]*)\Z/, %r{\b(ISO|IEC|IEEE|(in|January|February|March|April|May|June|August|September|October|November|December)\b)\Z}, "number not broken up in threes: mark up numbers with stem:[]" ) else style_two_regex_not_prev( 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/, %r{\b(ISO|IEC|IEEE|\b)\Z}, "number not broken up in threes: mark up numbers with stem:[]" ) end end |
#style_percent(node, text) ⇒ Object
ISO/IEC DIR 2, 9.2.1
147 148 149 150 151 152 |
# File 'lib/metanorma/iso/validate_style.rb', line 147 def style_percent(node, text) style_regex(/\b(?<num>[0-9.,]+%)/, "no space before percent sign", node, text) style_regex(/\b(?<num>[0-9.,]+ \u00b1 [0-9,.]+ %)/, "unbracketed tolerance before percent sign", node, text) end |
#style_punct(node, text) ⇒ Object
194 195 196 197 198 199 200 |
# File 'lib/metanorma/iso/validate_style.rb', line 194 def style_punct(node, text) @lang == "en" and style_regex(/\b(?<num>and\/?or)\b/i, "Use 'either x or y, or both'", node, text) style_regex(/\p{Zs}(?<num>&)\p{Zs}/i, "Avoid ampersand in ordinary text'", node, text) eref_style_punct(node) end |
#style_regex(regex, warning, node, text) ⇒ Object
66 67 68 |
# File 'lib/metanorma/iso/validate_style.rb', line 66 def style_regex(regex, warning, node, text) (m = regex.match(text)) && style_warning(node, warning, m[:num]) end |
#style_subscript(node) ⇒ Object
97 98 99 100 101 102 103 104 105 |
# File 'lib/metanorma/iso/validate_style.rb', line 97 def style_subscript(node) warning = "may contain nested subscripts (max 3 levels allowed)" node.xpath(".//sub[.//sub]").each do |x| style_warning(node, warning, x.to_xml) end node.xpath(".//m:msub[.//m:msub]", "m" => MATHML_NS).each do |x| style_warning(node, warning, x.to_xml) end end |
#style_two_regex_not_prev(n, text, regex, re_prev, warning) ⇒ Object
style check with a regex on a token and a negative match on its preceding token
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/metanorma/iso/validate_style.rb', line 72 def style_two_regex_not_prev(n, text, regex, re_prev, warning) return if text.nil? arr = Tokenizer::WhitespaceTokenizer.new.tokenize(text) arr.each_index do |i| m = regex.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(node, text) ⇒ Object
ISO/IEC DIR 2, 9.3
170 171 172 173 174 175 176 177 |
# File 'lib/metanorma/iso/validate_style.rb', line 170 def style_units(node, text) style_regex(/\b(?<num>[0-9][0-9,]*\p{Zs}+[\u00b0\u2032\u2033])/, "space between number and degrees/minutes/seconds", node, text) style_regex(/\b(?<num>[0-9][0-9,]*#{SI_UNIT})\b/o, "no space between number and SI unit", node, text) style_non_std_units(node, text) end |
#style_warning(node, msg, text = nil) ⇒ Object
211 212 213 214 215 216 217 |
# File 'lib/metanorma/iso/validate_style.rb', line 211 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
209 210 211 212 213 214 |
# File 'lib/metanorma/iso/validate_section.rb', line 209 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
5 6 7 8 9 10 11 12 13 14 |
# File 'lib/metanorma/iso/validate_image.rb', line 5 def subfigure_validate(xmldoc) elems = { footnote: "fn", note: "note", key: "dl" } xmldoc.xpath("//figure//figure").each do |f| elems.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 |
#symbols_validate(root) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/metanorma/iso/validate_section.rb', line 40 def symbols_validate(root) f = root.xpath("//definitions") f.empty? && return (f.size == 1 || @vocab) or @log.add("Style", f.first, ONE_SYMBOLS_WARNING) f.first.elements.reject { |e| %w(title dl).include? e.name }.empty? or @log.add("Style", f.first, NON_DL_SYMBOLS_WARNING) @vocab and f.each do |f1| f1.at("./ancestor::annex") or @log.add("Style", f1, "In vocabulary documents, Symbols and " \ "Abbreviated Terms are only permitted in annexes") end end |
#tc_number(ret, node) ⇒ Object
111 112 113 114 115 116 117 118 119 120 |
# File 'lib/metanorma/iso/front_id.rb', line 111 def tc_number(ret, node) doctype(node) == "committee-document" or return ret { sc: "subcommittee", tc: "technical-committee", wg: "workgroup" }.each do |k, v| n = node.attr("#{v}-number") and ret.merge!({ "#{k}type": node.attr("#{v}-type") || k.to_s.upcase, "#{k}number": n }) end ret end |
#tech_report_style(root) ⇒ Object
183 184 185 186 187 188 189 190 191 |
# File 'lib/metanorma/iso/validate_section.rb', line 183 def tech_report_style(root) @doctype == "technical-report" or return root.xpath("//sections/clause[not(@type = 'scope')] | //annex") .each do |s| r = requirement_check(extract_text(s)) and style_warning(s, "Technical Report clause may contain requirement", r) end end |
#term_contains_subclauses(node) ⇒ Object
in ISO, term has subterm, unless there is no definition to the term (subclauses start immediately), or it is labelled as “grouping”
51 52 53 54 55 |
# File 'lib/metanorma/iso/section.rb', line 51 def term_contains_subclauses(node) !node.sections? and return false node.level != node.blocks[0].level || node.role == "grouping" end |
#term_def_subclause_parse(attrs, xml, node) ⇒ Object
42 43 44 45 46 |
# File 'lib/metanorma/iso/section.rb', line 42 def term_def_subclause_parse(attrs, xml, node) node.role == "term" and return term_def_subclause_parse1(attrs, xml, node) super end |
#term_defs_boilerplate_cont(src, term, isodoc) ⇒ Object
83 84 85 86 |
# File 'lib/metanorma/iso/cleanup.rb', line 83 def term_defs_boilerplate_cont(src, term, isodoc) @vocab and src.empty? and return super end |
#term_xrefs_validate(xmldoc) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/metanorma/iso/validate.rb', line 81 def term_xrefs_validate(xmldoc) termids = xmldoc .xpath("//sections/terms | //sections/clause[.//terms] | " \ "//annex[.//terms]").each_with_object({}) do |t, m| t.xpath(".//*/@id").each { |a| m[a.text] = true } t.name == "terms" and m[t["id"]] = true end xmldoc.xpath(".//xref").each do |x| term_xrefs_validate1(x, termids) end end |
#term_xrefs_validate1(xref, termids) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/metanorma/iso/validate.rb', line 93 def term_xrefs_validate1(xref, termids) closest_id = xref.xpath("./ancestor::*[@id]")&.last or return (termids[xref["target"]] && !termids[closest_id["id"]]) and @log.add("Style", xref, "only terms clauses can cross-reference terms clause " \ "(#{xref['target']})") (!termids[xref["target"]] && termids[closest_id["id"]]) and @log.add("Style", xref, "non-terms clauses cannot cross-reference terms clause " \ "(#{xref['target']})") end |
#termdef_boilerplate_insert(xmldoc, isodoc, once = false) ⇒ Object
78 79 80 81 |
# File 'lib/metanorma/iso/cleanup.rb', line 78 def termdef_boilerplate_insert(xmldoc, isodoc, once = false) once = true super end |
#termdef_boilerplate_insert_locationx(xmldoc) ⇒ Object
142 143 144 145 146 147 148 |
# File 'lib/metanorma/iso/cleanup.rb', line 142 def termdef_boilerplate_insert_locationx(xmldoc) f = xmldoc.at(self.class::TERM_CLAUSE) root = xmldoc.at("//sections/terms | //sections/clause[.//terms]") !f || !root and return f || root f.at("./preceding-sibling::clause") and return root f end |
#termdef_style(xmldoc) ⇒ Object
ISO/IEC DIR 2, 16.5.6
127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/metanorma/iso/validate.rb', line 127 def termdef_style(xmldoc) xmldoc.xpath("//term").each do |t| para = t.at("./definition/verbal-definition") || return term = t.at("./preferred//name").text @lang == "en" and termdef_warn(para.text, /\A(the|a)\b/i, t, term, "term definition starts with article") %(Cyrl Latn).include?(@script) and termdef_warn(para.text, /\.\Z/i, t, term, "term definition ends with period") end end |
#termdef_warn(text, regex, elem, term, msg) ⇒ Object
76 77 78 |
# File 'lib/metanorma/iso/validate.rb', line 76 def termdef_warn(text, regex, elem, term, msg) regex.match(text) && @log.add("Style", elem, "#{term}: #{msg}") end |
#terms_terms_cleanup(xmldoc) ⇒ Object
93 94 95 96 |
# File 'lib/metanorma/iso/cleanup.rb', line 93 def terms_terms_cleanup(xmldoc) @vocab and return super end |
#title(node, xml) ⇒ Object
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/metanorma/iso/front.rb', line 118 def title(node, xml) %w(en ru 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
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/metanorma/iso/validate_title.rb', line 80 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, xml, lang, at) ⇒ Object
95 96 97 98 99 100 101 102 103 |
# File 'lib/metanorma/iso/front.rb', line 95 def title_amd(node, xml, lang, at) return unless node.attr("title-amendment-#{lang}") xml.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
67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/metanorma/iso/validate_title.rb', line 67 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?) or @log.add("Style", ss, "#{title}: each first-level subclause must have a title") end end end |
#title_full(node, xml, lang, at) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/metanorma/iso/front.rb', line 105 def title_full(node, xml, 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 xml.title **attr_code(at.merge(type: "main")) do |t1| t1 << Metanorma::Utils::asciidoc_sub(title) end end |
#title_intro(node, xml, lang, at) ⇒ Object
73 74 75 76 77 78 79 |
# File 'lib/metanorma/iso/front.rb', line 73 def title_intro(node, xml, lang, at) return unless node.attr("title-intro-#{lang}") xml.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
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/metanorma/iso/validate_title.rb', line 10 def title_intro_validate(root) title_intro_en = title_lang_part(root, "intro", "en") title_intro_fr = title_lang_part(root, "intro", "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_lang_part(doc, part, lang) ⇒ Object
6 7 8 |
# File 'lib/metanorma/iso/validate_title.rb', line 6 def title_lang_part(doc, part, lang) doc.at("//bibdata/title[@type='title-#{part}' and @language='#{lang}']") end |
#title_main(node, xml, lang, at) ⇒ Object
81 82 83 84 85 |
# File 'lib/metanorma/iso/front.rb', line 81 def title_main(node, xml, lang, at) xml.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
21 22 23 24 25 26 27 28 29 30 |
# File 'lib/metanorma/iso/validate_title.rb', line 21 def title_main_validate(root) title_main_en = title_lang_part(root, "main", "en") title_main_fr = title_lang_part(root, "main", "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
53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/metanorma/iso/validate_title.rb', line 53 def title_names_type_validate(root) @lang == "en" or return doctypes = /International\sStandard | Technical\sSpecification | Publicly\sAvailable\sSpecification | Technical\sReport | Guide /xi title_main_en = title_lang_part(root, "main", "en") !title_main_en.nil? && doctypes.match(title_main_en.text) and @log.add("Style", title_main_en, "Main Title may name document type") title_intro_en = title_lang_part(root, "intro", "en") !title_intro_en.nil? && doctypes.match(title_intro_en.text) and @log.add("Style", title_intro_en, "Title Intro may name document type") end |
#title_no_full_stop_validate(root) ⇒ Object
96 97 98 99 100 101 102 103 104 |
# File 'lib/metanorma/iso/validate_title.rb', line 96 def title_no_full_stop_validate(root) root.xpath("//preface//title | //sections//title | //annex//title | " \ "//references/title | //preface//name | //sections//name | " \ "//annex//name").each do |t| style_regex(/\A(?<num>.+\.\Z)/i, "No full stop at end of title or caption", t, t.text.strip) end end |
#title_part(node, xml, lang, at) ⇒ Object
87 88 89 90 91 92 93 |
# File 'lib/metanorma/iso/front.rb', line 87 def title_part(node, xml, lang, at) return unless node.attr("title-part-#{lang}") xml.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
32 33 34 35 36 37 38 39 |
# File 'lib/metanorma/iso/validate_title.rb', line 32 def title_part_validate(root) title_part_en = title_lang_part(root, "part", "en") title_part_fr = title_lang_part(root, "part", "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
42 43 44 45 46 47 48 49 50 |
# File 'lib/metanorma/iso/validate_title.rb', line 42 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']") subpart && !iec and @log.add("Style", docid, "Subpart defined on non-IEC document!") end |
#title_validate(root) ⇒ Object
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/metanorma/iso/validate_title.rb', line 106 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)") title_no_full_stop_validate(root) end |
#toc_default ⇒ Object
63 64 65 |
# File 'lib/metanorma/iso/base.rb', line 63 def toc_default { word_levels: 3, html_levels: 2, pdf_levels: 3 } end |
#unpub_footnotes(xmldoc) ⇒ Object
69 70 71 72 73 74 75 76 |
# File 'lib/metanorma/iso/cleanup.rb', line 69 def unpub_footnotes(xmldoc) xmldoc.xpath("//bibitem/note[@type = 'Unpublished-Status']").each do |n| e = xmldoc.at("//eref[@bibitemid = '#{n.parent['id']}']") or next fn = n.children.to_xml n.elements&.first&.name == "p" or fn = "<p>#{fn}</p>" e.next = "<fn>#{fn}</fn>" end end |
#unpublished_note(xmldoc) ⇒ Object
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 79 def unpublished_note(xmldoc) xmldoc.xpath("//bibitem[not(./ancestor::bibitem)]" \ "[not(note[@type = 'Unpublished-Status'])]").each do |b| pub_class(b) > 2 and next ((s = b.at("./status/stage")) && s.text.match?(/\d/) && (s.text.to_i < 60)) or next insert_unpub_note(b, @i18n.under_preparation .sub("%", b.at("docidentifier").text)) end end |
#validate(doc) ⇒ Object
195 196 197 198 199 200 201 202 203 204 |
# File 'lib/metanorma/iso/validate.rb', line 195 def validate(doc) content_validate(doc) schema = case @doctype when "amendment", "technical-corrigendum" # @amd "isostandard-amd.rng" else "isostandard-compile.rng" end schema_validate(formattedstr_strip(doc.dup), File.join(File.dirname(__FILE__), schema)) end |
#vocab_terms_titles_validate(root) ⇒ Object
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/metanorma/iso/validate_section.rb', line 229 def vocab_terms_titles_validate(root) terms = root.xpath("//sections/terms | //sections/clause[.//terms]") if terms.size == 1 ((t = terms.first.at("./title")) && (t&.text == @i18n.termsdef)) or @log.add("Style", terms.first, "Single terms clause in vocabulary document " \ "should have normal Terms and definitions heading") elsif terms.size > 1 terms.each do |x| ((t = x.at("./title")) && /^#{@i18n.}/.match?(t&.text)) or @log.add("Style", x, "Multiple terms clauses in vocabulary document " \ "should have 'Terms related to' heading") end end end |
#withdrawn_note(xmldoc) ⇒ Object
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 90 def withdrawn_note(xmldoc) xmldoc.xpath("//bibitem[not(note[@type = 'Unpublished-Status'])]") .each do |b| withdrawn_ref?(b) or next if id = replacement_standard(b) insert_unpub_note(b, @i18n.cancelled_and_replaced.sub("%", id)) else insert_unpub_note(b, @i18n.withdrawn) end end end |
#withdrawn_ref?(biblio) ⇒ Boolean
101 102 103 104 105 |
# File 'lib/metanorma/iso/cleanup_biblio.rb', line 101 def withdrawn_ref?(biblio) pub_class(biblio) > 2 and return false (s = biblio.at("./status/stage")) && (s.text.to_i == 95) && (t = biblio.at("./status/substage")) && (t.text.to_i == 99) end |
#xrefs_mandate_validate(xmldoc) ⇒ Object
require that all assets of a particular type be cross-referenced within the document
107 108 109 110 111 112 |
# File 'lib/metanorma/iso/validate.rb', line 107 def xrefs_mandate_validate(xmldoc) xrefs_mandate_validate1(xmldoc, "//annex", "Annex") xrefs_mandate_validate1(xmldoc, "//table", "Table") xrefs_mandate_validate1(xmldoc, "//figure", "Figure") xrefs_mandate_validate1(xmldoc, "//formula", "Formula") end |
#xrefs_mandate_validate1(xmldoc, xpath, name) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/metanorma/iso/validate.rb', line 114 def xrefs_mandate_validate1(xmldoc, xpath, name) exc = %w(table note example figure).map { |x| "//#{x}#{xpath}" } .join(" | ") (xmldoc.xpath(xpath) - xmldoc.xpath(exc)).each do |x| x["unnumbered"] == "true" and next @doc_xrefs[x["id"]] or @log.add("Style", x, "#{name} #{x['id']} has not been " \ "cross-referenced within document", severity: xpath == "//formula" ? 2 : 1) end end |