module Metanorma module IEEE class Converter < Standoc::Converter BIBLIO = "//bibliography/references[@normative = 'false'][not(@hidden)] | " \ "//bibliography/clause[.//references[@normative = 'false']] | " \ "//annex//references[@normative = 'false'][not(@hidden)]".freeze def boilerplate_cleanup(xmldoc) f = xmldoc.at(BIBLIO) and biblio_preface(f) super end def biblio_preface(ref) if ref.at("./note[@type = 'boilerplate']") unwrap_boilerplate_clauses(ref, ".") else ref.at("./title").next = "

#{@i18n.biblio_pref}

" end end def sort_biblio(bib) @i = IsoDoc::IEEE::PresentationXMLConvert .new({ lang: @lang, script: @script, locale: @locale }) @i.i18n_init(@lang, @script, @locale) sort_keys = bib.each_with_object({}) do |b, m| m[b["id"]] = sort_biblio_key(b) end bib.sort { |a, b| sort_keys[a["id"]] <=> sort_keys[b["id"]] } end # Alphabetic by rendering: author surname or designation, followed by title def sort_biblio_key(bib) name = designator_or_name(bib) title = bib.at("./title[@type = 'main']")&.text || bib.at("./title")&.text || bib.at("./formattedref")&.text title.gsub!(/[[:punct:]]/, "") @c.decode("#{name} #{title}").strip.downcase end def designator_or_name(bib) case bib["type"] when "standard", "techreport" then designator_docid(bib) else bib1 = bib.dup bib1.add_namespace(nil, self.class::XML_NAMESPACE) n = @i.creatornames(bib1) n.nil? && bib["type"].nil? and n = designator_docid(bib) n end end def designator_docid(bib) n = bib.at("./docidentifier[@primary]") || bib.at("./docidentifier[not(#{skip_docid})]") n or return "ZZZZ" @isodoc.docid_prefix(n["type"], n.children.to_xml) end def normref_cleanup(xmldoc) super normref_no_ordinals(xmldoc) normref_reorder(xmldoc) end def normref_no_ordinals(xmldoc) xmldoc.xpath("//references[@normative = 'true']/bibitem/" \ "docidentifier[@type = 'metanorma']").each do |d| /^\[?\d+\]?$/.match?(d.text) and d.remove end end def normref_reorder(xmldoc) xmldoc.xpath("//references[@normative = 'true']").each do |r| biblio_reorder1(r) end end # end of citeas generation def quotesource_cleanup(xmldoc) super trademark_ieee_erefs(xmldoc) end IEEE = "Institute of Electrical and Electronics Engineers".freeze # Style manual 12.3.5 def trademark_ieee_erefs(xmldoc) ieee = xmldoc.xpath("//references/bibitem") .each_with_object({}) do |b, m| bib_pubs(b).include?(IEEE) and m[b["id"]] = b.at("./docidentifier[@scope = 'trademark']")&.text end trademark_ieee_erefs1(xmldoc, "//preface//eref", ieee) trademark_ieee_erefs1(xmldoc, "//sections//eref | //annex//eref", ieee) end def trademark_ieee_erefs1(xmldoc, path, ieee) xmldoc.xpath(path).each_with_object({}) do |e, m| ieee[e["bibitemid"]] or next m[e["bibitemid"]] or e["citeas"] = ieee[e["bibitemid"]] m[e["bibitemid"]] = true end end def biblio_renumber(xmldoc) i = 0 xmldoc.xpath("//references[not(@normative = 'true')]" \ "[not(@hidden = 'true')]").each do |r| r.xpath("./bibitem[not(@hidden = 'true')]").each do |b| i += 1 biblio_renumber1(b, i) end end end def biblio_renumber1(bib, idx) docid = bib.at("./docidentifier[@type = 'metanorma' or " \ "@type = 'metanorma-ordinal']") if /^\[?\d+\]?$/.match?(docid&.text) docid.children = "[B#{idx}]" elsif docid = bib.at("./docidentifier") || bib.at("./title[last()]") || bib.at("./formattedref") docid.next = "[B#{idx}]" end end def select_docid(ref, type = nil) ret = super if %w(standard techreport).include?(ref["type"]) then ret else ref.at("./docidentifier[@type = 'metanorma-ordinal']") || ret end end def section_names_refs_cleanup(xml) @doctype == "whitepaper" or return super replace_title(xml, "//bibliography/references", @i18n&.references, true) end def bibitem_cleanup(xmldoc) super f = File.join(File.dirname(__FILE__), "ieee-footnotes.yaml") @provenance_notes = YAML.safe_load(File.read(f)) withdrawn_note(xmldoc, @provenance_notes) end def biblio_reorder(xmldoc) super available_note(xmldoc, @provenance_notes) end def bib_pubs(bib) bib.xpath("./contributor[role/@type = 'publisher']/organization/name") .map(&:text) end BIBITEM_NO_AVAIL = "//references/bibitem[not(note[@type = 'Availability'])]".freeze def withdrawn_note(xmldoc, provenance_notes) xmldoc.xpath(BIBITEM_NO_AVAIL).each do |b| bib_pubs(b).include?(IEEE) or next b.at("./status/stage")&.text == "withdrawn" or next docid = b.at("./docidentifier[@type = 'IEEE'][not(@scope)]") note = provenance_notes["ieee-withdrawn"].sub("%", docid.text) insert_availability_note(b, note) end end AVAIL_PUBS = { ieee: IEEE, cispr: "International special committee on radio interference", etsi: "European Telecommunications Standards Institute", oasis: "OASIS", "w3c": "World Wide Web Consortium", "3gpp": "3rd Generation Partnership Project", }.freeze def available_note(xmldoc, provenance_notes) iso_iec_available_note(xmldoc, provenance_notes["iso-iec"], true, true) iso_iec_available_note(xmldoc, provenance_notes["iso"], true, false) iso_iec_available_note(xmldoc, provenance_notes["iec"], false, true) itu_available_note(xmldoc, provenance_notes["itut"], true) itu_available_note(xmldoc, provenance_notes["itur"], false) nist_available_note(xmldoc, provenance_notes["fips"], true) nist_available_note(xmldoc, provenance_notes["nist"], false) ietf_available_note(xmldoc, provenance_notes["ietf"]) AVAIL_PUBS.each do |k, v| sdo_available_note(xmldoc, provenance_notes[k.to_s], v) end end def sdo_available_note(xmldoc, note, publisher) ret = xmldoc.xpath(BIBITEM_NO_AVAIL).detect do |b| bib_pubs(b).include?(publisher) end insert_availability_note(ret, note) end def iso_iec_available_note(xmldoc, note, iso, iec) ret = xmldoc.xpath(BIBITEM_NO_AVAIL).detect do |b| pubs = bib_pubs(b) has_iec = pubs.include?("International Electrotechnical Commission") has_iso = pubs.include?("International Organization for Standardization") ((has_iec && iec) || (!has_iec && !iec)) && ((has_iso && iso) || (!has_iso && !iso)) end insert_availability_note(ret, note) end def ietf_available_note(xmldoc, note) ret = xmldoc.xpath(BIBITEM_NO_AVAIL).detect do |b| b.at("./docidentifier[@type = 'IETF']") end insert_availability_note(ret, note) end def itu_available_note(xmldoc, note, itu_t) ret = xmldoc.xpath(BIBITEM_NO_AVAIL).detect do |b| has_itu_t = /^ITU-T/.match?(b.at("./docidentifier[@type = 'ITU']")&.text) bib_pubs(b).include?("International Telecommunication Union") && (!has_itu_t && !itu_t) || (has_itu_t && itu_t) end insert_availability_note(ret, note) end def nist_available_note(xmldoc, note, fips) ret = xmldoc.xpath(BIBITEM_NO_AVAIL).detect do |b| id = b.at("./docidentifier[@type = 'NIST']") has_fips = /\bFIPS\b/.match?(id&.text) id && ((has_fips && !fips) || (!has_fips && fips)) end insert_availability_note(ret, note) end def insert_availability_note(bib, msg) bib or return note = %(

#{msg}

) if b = bib.at("./language | ./script | ./abstract | ./status") b.previous = note else b = bib.at("./contributor") || bib.at("./date") || bib.at("./docnumber") || bib.at("./docidentifier") || bib.at("./title") and b.next = note end end end end end