Class: Metanorma::Iso::Converter

Inherits:
Standoc::Converter
  • Object
show all
Defined in:
lib/metanorma/iso/converter.rb,
lib/metanorma/iso/log.rb,
lib/metanorma/iso/base.rb,
lib/metanorma/iso/front.rb,
lib/metanorma/iso/section.rb,
lib/metanorma/iso/front_id.rb,
lib/metanorma/iso/front_contributor.rb

Overview

A Converter implementation that generates ISO output, and a document schema encapsulation of the document for validation

Constant Summary collapse

ISO_LOG_MESSAGES =
{
  # rubocop:disable Naming/VariableNumber
  "ISO_1": { category: "Style",
             error: "Style override set for ordered list",
             severity: 2 },
  "ISO_2": { category: "Document Attributes",
             error: "invalid technical committee type %s",
             severity: 2 },
  "ISO_3": { category: "Document Attributes",
             error: "invalid subcommittee type %s",
             severity: 2 },
  "ISO_4": { category: "Style",
             error: "term definition starts with article: %s",
             severity: 2 },
  "ISO_5": { category: "Document Attributes",
             error: "%s is not a recognised document type", severity: 2 },
  "ISO_6": { category: "Document Attributes",
             error: "%s is not a recognised iteration", severity: 2 },
  "ISO_7": { category: "Style",
             error: "%s is not permitted in a subfigure", severity: 2 },
  "ISO_8": { category: "Style",
             error: "Reference does not have an associated footnote indicating unpublished status",
             severity: 2 },
  "ISO_9": { category: "Document Attributes",
             error: "Illegal document stage: %s.%s", severity: 2 },
  "ISO_10": { category: "Style", error: "No English Title Intro!",
              severity: 2 },
  "ISO_11": { category: "Style", error: "No French Title Intro!",
              severity: 2 },
  "ISO_12": { category: "Style", error: "No English Title!",
              severity: 2 },
  "ISO_13": { category: "Style", error: "No French Title!", severity: 2 },
  "ISO_14": { category: "Style", error: "No English Title Part!",
              severity: 2 },
  "ISO_15": { category: "Style", error: "No French Title Part!",
              severity: 2 },
  "ISO_16": { category: "Style",
              error: "Subpart defined on non-IEC document!",
              severity: 2 },
  "ISO_17": { category: "Style",
              error: "Main Title may name document type",
              severity: 2 },
  "ISO_18": { category: "Style",
              error: "Title Intro may name document type",
              severity: 2 },
  "ISO_19": { category: "Style",
              error: "%s: each first-level subclause must have a title",
              severity: 2 },
  "ISO_20": { category: "Style",
              error: "%s: all subclauses must have a title, or none",
              severity: 2 },
  "ISO_21": { category: "Style", error: "%s %s has not been cross-referenced within document",
              severity: 1 },
  "ISO_22": { category: "Style", error: "(formula) %s %s has not been cross-referenced within document",
              severity: 2 },
  "ISO_23": { category: "Style", error: "foreword contains subclauses",
              severity: 2 },
  "ISO_24": { category: "Style",
              error: "normative references contains subclauses",
              severity: 2 },
  "ISO_25": { category: "Style",
              error: "Only one Symbols and Abbreviated Terms section in the standard",
              severity: 2 },
  "ISO_26": { category: "Style",
              error: "Symbols and Abbreviated Terms can only contain a definition list",
              severity: 2 },
  "ISO_27": { category: "Style",
              error: "In vocabulary documents, Symbols and Abbreviated Terms are only permitted in annexes",
              severity: 2 },
  "ISO_28": { category: "Style", error: "(section sequencing) %s",
              severity: 2 },
  "ISO_29": { category: "Style", error: "Scope clause missing",
              severity: 2 },
  "ISO_30": { category: "Style", error: "Normative references missing",
              severity: 2 },
  "ISO_31": { category: "Style", error: "Terms & definitions missing",
              severity: 2 },
  "ISO_32": { category: "Style",
              error: "Document must contain at least one clause",
              severity: 2 },
  "ISO_33": { category: "Style",
              error: "Document must contain clause after Terms and Definitions",
              severity: 2 },
  "ISO_34": { category: "Style",
              error: "Scope must not occur after Terms and Definitions",
              severity: 2 },
  "ISO_35": { category: "Style",
              error: "term definition ends with period: %s",
              severity: 2 },
  "ISO_36": { category: "Style",
              error: "Only annexes and references can follow clauses",
              severity: 2 },
  "ISO_37": { category: "Style",
              error: "Only annexes and references can follow terms and clauses",
              severity: 2 },
  "ISO_38": { category: "Style",
              error: "Document must include (references) Normative References",
              severity: 2 },
  "ISO_39": { category: "Style",
              error: "Scope contains subclauses: should be succinct",
              severity: 2 },
  "ISO_40": { category: "Style",
              error: "Final section must be (references) Bibliography",
              severity: 2 },
  "ISO_41": { category: "Style",
              error: "There are sections after the final Bibliography",
              severity: 2 },
  "ISO_42": { category: "Style",
              error: "non-ISO/IEC reference is allowed as normative only subject to the conditions in ISO/IEC DIR 2 10.2: %s",
              severity: 2 },
  "ISO_43": { category: "Style", error: "subclause is only child",
              severity: 2 },
  "ISO_44": { category: "Style",
              error: "Single terms clause in vocabulary document should have normal Terms and definitions heading",
              severity: 2 },
  "ISO_45": { category: "Style",
              error: "Multiple terms clauses in vocabulary document should have 'Terms related to' heading",
              severity: 2 },
  "ISO_46": { category: "Style",
              error: "'see %s' is pointing to a normative section",
              severity: 2 },
  "ISO_47": { category: "Bibliography",
              error: "'%s is not pointing to a real reference",
              severity: 2 },
  "ISO_48": { category: "Style",
              error: "'see %s' is pointing to a normative reference",
              severity: 2 },
  "ISO_49": { category: "Style",
              error: "undated reference %s should not contain specific elements",
              severity: 2 },
  "ISO_50": { category: "Style",
              error: "only terms clauses can cross-reference terms clause (%s)",
              severity: 2 },
  "ISO_51": { category: "Style",
              error: "non-terms clauses cannot cross-reference terms clause (%s)",
              severity: 2 },
  "ISO_52": { category: "Style",
              error: "non-terms clauses cannot cross-reference terms clause (%s)",
              severity: 0 },
}.freeze
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
DOCTYPE2HASHID =
{ directive: :dir, "technical-report": :tr, "guide": :guide,
"technical-specification": :ts,
"publicly-available-specification": :pas,
"committee-document": :tc, "recommendation": :r }.freeze

Instance Method Summary collapse

Instance Method Details

#admonition_name(node) ⇒ Object



75
76
77
78
79
80
81
# File 'lib/metanorma/iso/base.rb', line 75

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

#base_pubidObject



67
68
69
# File 'lib/metanorma/iso/front_id.rb', line 67

def base_pubid
  Pubid::Iso::Identifier
end

#cen?(str) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/metanorma/iso/front_id.rb', line 52

def cen?(str)
  /^C?EN/.match?(str)
end

#cen_id_out(xml, params) ⇒ Object



169
170
171
172
173
# File 'lib/metanorma/iso/front_id.rb', line 169

def cen_id_out(xml, params)
  add_noko_elem(xml, "docidentifier",
                iso_id_default(params).to_s,
                **attr_code(type: "CEN", primary: "true"))
end

#committee_abbrevsObject



74
75
76
77
# File 'lib/metanorma/iso/front_contributor.rb', line 74

def committee_abbrevs
  { "technical-committee" => "TC", "subcommittee" => "SC",
    "workgroup" => "WG" }
end

#committee_contrib_org_prep(node, type, agency, opt) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'lib/metanorma/iso/front_contributor.rb', line 46

def committee_contrib_org_prep(node, type, agency, opt)
  agency_arr, agency_abbrev =
    committee_org_prep_agency(node, type, agency, [], [])
  { source: [type], role: opt[:approval] ? "authorizer" : "author",
    default_org: false, committee: true, agency: agency_arr,
    agency_abbrev:, desc: "committee",
    subdivtype: type.sub(/^approval-/, "").tr("-", " ").capitalize }
    .compact
end

#committee_contributors(node, xml, agency, opt) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/metanorma/iso/front_contributor.rb', line 33

def committee_contributors(node, xml, agency, opt)
  t = (opt[:approval] ? node : nil)
  v = t.first
  if committee_number_or_name?(node, v, "")
    node.attr(v) or node.set_attr(v, "")
    o = committee_contrib_org_prep(node, v, agency, opt)
    o[:groups] = t
    o[:approval] = opt[:approval]
    org_contributor(node, xml, o)
  end
  opt[:approval] or committee_contributors_approval(node, xml, agency)
end

#committee_contributors_approval(node, xml, agency) ⇒ Object



68
69
70
71
72
# File 'lib/metanorma/iso/front_contributor.rb', line 68

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

#committee_ident(type, number, level) ⇒ Object



79
80
81
82
83
84
# File 'lib/metanorma/iso/front_contributor.rb', line 79

def committee_ident(type, number, level)
  number.nil? || number.empty? and return
  type ||= committee_abbrevs[level.sub(/^approval-/, "")]
  type == "Other" and type = ""
  "#{type} #{number}".strip
end

#committee_org_prep_agency(node, type, agency, agency_arr, agency_abbr) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/metanorma/iso/front_contributor.rb', line 56

def committee_org_prep_agency(node, type, agency, agency_arr, agency_abbr)
  i = 1
  suffix = ""
  while committee_number_or_name?(node, type, suffix)
    agency_arr << (node.attr("#{type}-agency#{suffix}") || agency)
    agency_abbr << node.attr("#{type}-agency-abbr#{suffix}")
    i += 1
    suffix = "_#{i}"
  end
  [agency_arr, agency_abbr]
end

#compact_blank(hash) ⇒ Object



78
79
80
# File 'lib/metanorma/iso/front_id.rb', line 78

def compact_blank(hash)
  hash.compact.reject { |_, v| v.is_a?(String) && v.empty? }
end

#contributors_committees_filter_empty?(committee) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
89
90
# File 'lib/metanorma/iso/front_contributor.rb', line 86

def contributors_committees_filter_empty?(committee)
  committee[:name].empty? &&
    (committee[:ident].nil? ||
    %w(WG TC SC).include?(committee[:ident]))
end

#default_publisherObject



4
5
6
# File 'lib/metanorma/iso/front_contributor.rb', line 4

def default_publisher
  "ISO"
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

#document_scheme(node) ⇒ Object



85
86
87
88
89
90
91
92
93
# File 'lib/metanorma/iso/base.rb', line 85

def document_scheme(node)
  r = node.attr("document-scheme") and return r
  r = node.attr("copyright-year")&.to_i or return DOCUMENT_SCHEMES[-1]
  DOCUMENT_SCHEMES.each_index do |i|
    i.zero? and next
    r < DOCUMENT_SCHEMES[i] and return DOCUMENT_SCHEMES[i - 1].to_s
  end
  DOCUMENT_SCHEMES[-1]
end

#get_stage(node) ⇒ Object



238
239
240
241
242
243
# File 'lib/metanorma/iso/front_id.rb', line 238

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



245
246
247
248
249
250
# File 'lib/metanorma/iso/front_id.rb', line 245

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)

Parameters:

  • type (nil, :tr, :ts, :amd, :cor, :guide, :dir, :tc, Type)


28
29
30
31
32
33
# File 'lib/metanorma/iso/front_id.rb', line 28

def get_typeabbr(node, amd: false)
  node.attr("amendment-number") and return :amd
  node.attr("addendum-number") and return :add
  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



231
232
233
234
235
236
# File 'lib/metanorma/iso/front_id.rb', line 231

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

#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

#iso_id_default(params) ⇒ Object



204
205
206
207
208
209
# File 'lib/metanorma/iso/front_id.rb', line 204

def iso_id_default(params)
  params_nolang = params.dup.tap { |hs| hs.delete(:language) }
  params1 = params_nolang
  params1.delete(:unpublished)
  pubid_select(params1).create(**params1)
end

#iso_id_out(xml, params, with_prf) ⇒ Object



159
160
161
162
163
164
165
166
167
# File 'lib/metanorma/iso/front_id.rb', line 159

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
  @log.add("ISO_52", "Document identifier: #{e}")
  clean_abort("Document identifier: #{e}", xml)
end

#iso_id_out_common(xml, params, with_prf) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/metanorma/iso/front_id.rb', line 175

def iso_id_out_common(xml, params, with_prf)
  params1 = skip_60_60(params)
  add_noko_elem(xml, "docidentifier",
                iso_id_default(params1).to_s(with_prf:),
                **attr_code(type: "ISO", primary: "true"))
  add_noko_elem(xml, "docidentifier", iso_id_reference(params1)
                .to_s(format: :ref_num_short, with_prf:),
                **attr_code(type: "iso-reference"))
  add_noko_elem(xml, "docidentifier", iso_id_reference(params).urn,
                **attr_code(type: "URN"))
end

#iso_id_out_non_amd(xml, params, with_prf) ⇒ Object



187
188
189
190
191
192
193
194
195
# File 'lib/metanorma/iso/front_id.rb', line 187

def iso_id_out_non_amd(xml, params, with_prf)
  params1 = skip_60_60(params)
  add_noko_elem(xml, "docidentifier",
                iso_id_undated(params1).to_s(with_prf:),
                **attr_code(type: "iso-undated"))
  add_noko_elem(xml, "docidentifier",
                iso_id_with_lang(params1).to_s(format: :ref_num_long, with_prf:),
                **attr_code(type: "iso-with-lang"))
end

#iso_id_params(node) ⇒ Object



42
43
44
45
46
47
48
49
50
# File 'lib/metanorma/iso/front_id.rb', line 42

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



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/metanorma/iso/front_id.rb', line 102

def iso_id_params_add(node)
  stage = iso_id_stage(node)
  ret = { number: node.attr("amendment-number") ||
    node.attr("corrigendum-number") ||
    node.attr("addendum-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



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/metanorma/iso/front_id.rb', line 83

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



144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/metanorma/iso/front_id.rb', line 144

def iso_id_params_resolve(params, params2, node, orig_id)
  if orig_id && (node.attr("amendment-number") ||
      node.attr("corrigendum-number") ||
                node.attr("addendum-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



96
97
98
99
100
# File 'lib/metanorma/iso/front_id.rb', line 96

def iso_id_pub(node)
  (node.attr("publisher_abbr") || node.attr("publisher") ||
   default_publisher).split(/[;,]/)
    .map(&:strip).map { |x| org_abbrev[x] || x }
end

#iso_id_reference(params) ⇒ Object



226
227
228
229
# File 'lib/metanorma/iso/front_id.rb', line 226

def iso_id_reference(params)
  params1 = params.dup.tap { |hs| hs.delete(:unpublished) }
  pubid_select(params1).create(**params1)
end

#iso_id_stage(node) ⇒ Object



134
135
136
# File 'lib/metanorma/iso/front_id.rb', line 134

def iso_id_stage(node)
  "#{get_stage(node)}.#{get_substage(node)}"
end

#iso_id_stage_populate(ret, node, stage) ⇒ Object



125
126
127
128
129
130
131
132
# File 'lib/metanorma/iso/front_id.rb', line 125

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
    # ret[:stage] == "60.60" and ret[:stage] = nil
  end
  ret
end

#iso_id_undated(params) ⇒ Object



211
212
213
214
215
216
217
218
# File 'lib/metanorma/iso/front_id.rb', line 211

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



220
221
222
223
224
# File 'lib/metanorma/iso/front_id.rb', line 220

def iso_id_with_lang(params)
  params1 = params
  params1.delete(:unpublished)
  pubid_select(params1).create(**params1)
end

#iso_id_year(node) ⇒ Object



138
139
140
141
142
# File 'lib/metanorma/iso/front_id.rb', line 138

def iso_id_year(node)
  (node.attr("copyright-year") || node.attr("updated-date") ||
   node.attr("published-date"))
    &.sub(/-.*$/, "") || Date.today.year
end

#log_messagesObject

rubocop:enable Naming/VariableNumber



146
147
148
# File 'lib/metanorma/iso/log.rb', line 146

def log_messages
  super.merge(ISO_LOG_MESSAGES)
end

#metadata_approval_committee_types(node) ⇒ Object



101
102
103
104
105
106
107
# File 'lib/metanorma/iso/front_contributor.rb', line 101

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



14
15
16
17
# File 'lib/metanorma/iso/front_contributor.rb', line 14

def (node, xml)
  super
  secretariat_contributor(node, xml, default_publisher)
end

#metadata_ext(node, xml) ⇒ Object



13
14
15
16
# File 'lib/metanorma/iso/front.rb', line 13

def (node, xml)
  super
  (node, xml)
end

#metadata_ext_iso(node, xml) ⇒ Object



18
19
20
21
22
23
24
25
26
27
# File 'lib/metanorma/iso/front.rb', line 18

def (node, xml)
  add_noko_elem(xml, "horizontal", node.attr("horizontal"))
  (node, xml)
  @amd and
    add_noko_elem(xml, "updates_document_type",
                  node.attr("updates-document-type"))
  a = node.attr("fast-track") and xml.send "fast-track", a != "false"
  add_noko_elem(xml, "price_code", node.attr("price-code"))
  node.attr("iso-cen-parallel") and xml.iso_cen_parallel true
end

#metadata_id_nonprimary(node, xml) ⇒ Object



14
15
16
17
18
# File 'lib/metanorma/iso/front_id.rb', line 14

def (node, xml)
  node.attr("tc-docnumber")&.split(/,\s*/)&.each do |n|
    add_noko_elem(xml, "docidentifier", n, type: "iso-tc")
  end
end

#metadata_id_primary(node, xml) ⇒ Object



35
36
37
38
39
40
# File 'lib/metanorma/iso/front_id.rb', line 35

def (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

#metadata_id_primary_type(node) ⇒ Object



10
11
12
# File 'lib/metanorma/iso/front_id.rb', line 10

def (node)
  "ISO"
end

#metadata_publisher(node, xml) ⇒ Object



92
93
94
95
96
97
98
99
# File 'lib/metanorma/iso/front_contributor.rb', line 92

def (node, xml)
  super
  # approvals
  committee_contributors(
    node, xml,
    node.attr("approval-agency") || default_publisher, { approval: true }
  )
end

#metadata_stage(node, xml) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/metanorma/iso/front.rb', line 33

def (node, xml)
  id = iso_id_default(iso_id_params(node))
  id.stage or return
  if abbr = id.typed_stage_abbrev
    # remove IS: work around breakages in pubid-iso
    abbr = abbr.to_s.upcase.strip.sub(/^IS /, "")
  end
  xml.stagename (id)&.strip,
                **attr_code(abbreviation: abbr)
rescue *STAGE_ERROR
end

#metadata_stagename(id) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/metanorma/iso/front.rb', line 45

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



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/metanorma/iso/front.rb', line 58

def (node, xml)
  stage = get_stage(node)
  substage = get_substage(node)
  abbrev = node.attr("docstage-abbrev") ||
    iso_id_default(iso_id_params(node)).stage&.abbr&.upcase
  xml.status do |s|
    add_noko_elem(s, "stage", stage, **attr_code(abbreviation: abbrev))
    add_noko_elem(s, "substage", substage)
    add_noko_elem(s, "iteration", node.attr("iteration"))
  end
rescue *STAGE_ERROR
  report_illegal_stage(stage, substage)
end

#ol_attrs(node) ⇒ Object



67
68
69
70
71
72
73
# File 'lib/metanorma/iso/base.rb', line 67

def ol_attrs(node)
  ret = super
  ret.delete(:type)
  # test
  #ret[:display] = node.attr("display")
  ret
end

#org_abbrevObject



8
9
10
11
12
# File 'lib/metanorma/iso/front_contributor.rb', line 8

def org_abbrev
  { "International Organization for Standardization" => "ISO",
    "International Electrotechnical Commission" => "IEC",
    "International Organization for Standardization, International Electrotechnical Commission" => "ISO/IEC" }
end

#org_organization(node, xml, org) ⇒ Object



19
20
21
22
23
24
# File 'lib/metanorma/iso/front_contributor.rb', line 19

def org_organization(node, xml, org)
  if org[:committee]
    contrib_committee_build(xml, org[:agency], org)
  else super
  end
end

#orig_id_parse(orig) ⇒ Object



56
57
58
59
60
61
62
63
64
65
# File 'lib/metanorma/iso/front_id.rb', line 56

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

#outputs(node, ret) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/metanorma/iso/base.rb', line 95

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



17
18
19
20
21
22
# File 'lib/metanorma/iso/section.rb', line 17

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

#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

#pubid_select(params) ⇒ Object



71
72
73
74
75
76
# File 'lib/metanorma/iso/front_id.rb', line 71

def pubid_select(params)
  if cen?(Array(params[:publisher])&.first || "")
    Pubid::Cen::Identifier
  else base_pubid
  end
end

#relaton_relation_descriptionsObject



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/metanorma/iso/front.rb', line 126

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_relationsObject



121
122
123
124
# File 'lib/metanorma/iso/front.rb', line 121

def relaton_relations
  super + %w(obsoletes successor-of manifestation-of related
             annotation-of has-draft)
end

#report_illegal_stage(stage, substage) ⇒ Object



72
73
74
# File 'lib/metanorma/iso/front.rb', line 72

def report_illegal_stage(stage, substage)
  @log.add("ISO_9", nil, params: [stage, substage])
end

#requirements_processorObject



16
17
18
# File 'lib/metanorma/iso/base.rb', line 16

def requirements_processor
  ::Metanorma::Requirements::Iso
end

#scope_parse(attrs, xml, node) ⇒ Object



8
9
10
11
# File 'lib/metanorma/iso/section.rb', line 8

def scope_parse(attrs, xml, node)
  attrs = attrs.merge(type: "scope") unless @amd
  clause_parse(attrs, xml, node)
end

#secretariat_contributor(node, xml, agency) ⇒ Object



26
27
28
29
30
31
# File 'lib/metanorma/iso/front_contributor.rb', line 26

def secretariat_contributor(node, xml, agency)
  node.attr("secretariat") or return
  o = committee_contrib_org_prep(node, "secretariat", agency, {})
  o[:desc] = "secretariat"
  org_contributor(node, xml, o)
end

#sectiontype(node, level = true) ⇒ Object



24
25
26
27
28
29
30
31
# File 'lib/metanorma/iso/section.rb', line 24

def sectiontype(node, level = true)
  return nil if @amd

  ret = sectiontype_streamline(sectiontype1(node))
  return ret if ret == "terms and definitions" && @vocab

  super
end

#skip_60_60(params) ⇒ Object

work around breakages in pubid-iso



198
199
200
201
202
# File 'lib/metanorma/iso/front_id.rb', line 198

def skip_60_60(params)
  ret = params.dup
  ret[:stage] == "60.60" and ret[:stage] = nil
  ret
end

#structured_id(node, xml) ⇒ Object



143
144
145
146
147
148
149
150
151
152
# File 'lib/metanorma/iso/front.rb', line 143

def structured_id(node, xml)
  node.attr("docnumber") or return # allow empty node.attr("docnumber")
  xml.structuredidentifier do |i|
    i.project_number(node.attr("docnumber"), **attr_code(
      title_nums_prep(node).merge(
        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

#support_appendix?(_node) ⇒ Boolean

Returns:

  • (Boolean)


13
14
15
# File 'lib/metanorma/iso/section.rb', line 13

def support_appendix?(_node)
  true
end

#tc_number(ret, node) ⇒ Object



114
115
116
117
118
119
120
121
122
123
# File 'lib/metanorma/iso/front_id.rb', line 114

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

#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”



42
43
44
45
46
# File 'lib/metanorma/iso/section.rb', line 42

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



33
34
35
36
37
# File 'lib/metanorma/iso/section.rb', line 33

def term_def_subclause_parse(attrs, xml, node)
  node.role == "term" and
    return term_def_subclause_parse1(attrs, xml, node)
  super
end

#title(node, xml) ⇒ Object



101
102
103
104
105
106
# File 'lib/metanorma/iso/front.rb', line 101

def title(node, xml)
  %w(en ru fr).each do |lang|
    node.attr("title-main-#{lang}") or next
    title1(node, xml, lang)
  end
end

#title1(node, xml, lang) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/metanorma/iso/front.rb', line 108

def title1(node, xml, lang)
  title_full(node, xml, lang)
  %w(intro main part complementary).each do |w|
    title_component(node, xml, lang, { name: w, abbr: w })
  end
  @amd and title_component(node, xml, lang,
                           { name: "amendment", abbr: "amd" })
  node.attr("addendum-number") and
    title_component(node, xml, lang,
                    { name: "addendum", abbr: "add" })
  title_nums(node, xml, lang)
end

#title_component(node, xml, lang, comp) ⇒ Object



76
77
78
79
# File 'lib/metanorma/iso/front.rb', line 76

def title_component(node, xml, lang, comp)
  t = node.attr("title-#{comp[:name]}-#{lang}") or return
  add_title_xml(xml, t, lang, "title-#{comp[:abbr]}")
end

#title_full(node, xml, lang) ⇒ Object



81
82
83
84
85
86
87
88
# File 'lib/metanorma/iso/front.rb', line 81

def title_full(node, xml, lang)
  title, intro, part, amd, add = title_full_prep(node, lang)
  title = "#{intro} -- #{title}" if intro
  title = "#{title} -- #{part}" if part
  title = "#{title} -- #{amd}" if amd
  title = "#{title} -- #{add}" if add
  add_title_xml(xml, title, lang, "main")
end

#title_full_prep(node, lang) ⇒ Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/metanorma/iso/front.rb', line 90

def title_full_prep(node, lang)
  title = node.attr("title-main-#{lang}")
  intro = node.attr("title-intro-#{lang}")
  part = node.attr("title-part-#{lang}") ||
    node.attr("title-complementary-#{lang}")
  @amd and amd = node.attr("title-amendment-#{lang}")
  node.attr("addendum-number") and
    add = node.attr("title-addendum-#{lang}")
  [title, intro, part, amd, add].map { |x| x&.empty? ? nil : x }
end

#toc_defaultObject



63
64
65
# File 'lib/metanorma/iso/base.rb', line 63

def toc_default
  { word_levels: 3, html_levels: 2, pdf_levels: 3 }
end