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