asciidoctor-iso 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/Gemfile.lock +18 -13
  4. data/README.adoc +28 -8
  5. data/asciidoctor-iso.gemspec +3 -2
  6. data/lib/asciidoctor-iso.rb +4 -0
  7. data/lib/asciidoctor/iso/base.rb +4 -17
  8. data/lib/asciidoctor/iso/cleanup.rb +16 -1
  9. data/lib/asciidoctor/iso/cleanup_ref.rb +2 -2
  10. data/lib/asciidoctor/iso/front.rb +5 -1
  11. data/lib/asciidoctor/iso/isostandard.rng +17 -1
  12. data/lib/asciidoctor/iso/ref.rb +122 -52
  13. data/lib/asciidoctor/iso/section.rb +8 -2
  14. data/lib/asciidoctor/iso/version.rb +1 -1
  15. data/lib/metanorma/iso.rb +7 -0
  16. data/lib/metanorma/iso/processor.rb +38 -0
  17. data/spec/asciidoctor-iso/base_spec.rb +37 -8
  18. data/spec/asciidoctor-iso/blocks_spec.rb +2 -2
  19. data/spec/asciidoctor-iso/cleanup_spec.rb +71 -203
  20. data/spec/asciidoctor-iso/isobib_cache_spec.rb +164 -0
  21. data/spec/asciidoctor-iso/refs_spec.rb +263 -183
  22. data/spec/asciidoctor-iso/validate_spec.rb +30 -28
  23. data/spec/examples/iso_123_.xml +3 -3
  24. data/spec/examples/iso_123_all_parts.xml +3 -3
  25. data/spec/examples/iso_123_no_year_note.xml +3 -3
  26. data/spec/examples/iso_124_.xml +3 -3
  27. data/spec/spec_helper.rb +42 -1
  28. metadata +23 -17
  29. data/lib/asciidoctor/iso/html/header.html +0 -184
  30. data/lib/asciidoctor/iso/html/html_iso_intro.html +0 -34
  31. data/lib/asciidoctor/iso/html/html_iso_titlepage.html +0 -32
  32. data/lib/asciidoctor/iso/html/htmlstyle.scss +0 -46
  33. data/lib/asciidoctor/iso/html/isodoc.scss +0 -679
  34. data/lib/asciidoctor/iso/html/scripts.html +0 -174
  35. data/lib/asciidoctor/iso/html/style-human.scss +0 -1277
  36. data/lib/asciidoctor/iso/html/style-iso.scss +0 -1257
  37. data/lib/asciidoctor/iso/html/word_iso_intro.html +0 -72
  38. data/lib/asciidoctor/iso/html/word_iso_titlepage.html +0 -58
  39. data/lib/asciidoctor/iso/html/wordstyle.scss +0 -1135
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2119336be461ce4dcf5141195957fe0171251ada29f6735c9b9e96d61a95150
4
- data.tar.gz: 7305fc72ae1e3e01b5315f6bcce6bb382922a9770ba2dc2ff2e84a345f7208d2
3
+ metadata.gz: fb4b3cf95879f9dbc87df7bb4ef5ef0cdd6d8a84d5c025d875686d22fbbccf81
4
+ data.tar.gz: 72922fb815c364609f29b030aea4349dcb8b1b2e62b2aa8a6cd1e553d077c672
5
5
  SHA512:
6
- metadata.gz: 5126540df3ca9efefacd321f5508cd9b21293ecaf5b710afe242cb776261956a3d49d88c292ae45da7af7d4da405c1426294bdd9e7de99f72194e95e24a12115
7
- data.tar.gz: d0d757089a00b7022d4ed69154d93bd3df75dfca1b17448f497cf2d4680d373af2e82569dfe51954929a4cd315e27f88a40da08a1ebc82f5f5438019f73048c3
6
+ metadata.gz: 2598a409d73c5fba6adbe2056428b2ff33c9e3d85ae5bd19a7af1caae42ec8d96716453676c98b50c237a0855108cd79ae4fdf40043f74782b551b504008f1b1
7
+ data.tar.gz: 006c5953314176be6f126765fb4281ffa268e4c5a8faa46470a5ee4dcafebfc888f0f8af98e4ce03360647e1c7f830e546ab278b966a094b9ecc41fd0dcff591
data/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.3
4
+ - 2.5.1
5
5
  before_install:
6
6
  - gem install bundler -v 1.16.1
7
7
  - unset _JAVA_OPTIONS
data/Gemfile.lock CHANGED
@@ -1,16 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- asciidoctor-iso (0.8.0)
4
+ asciidoctor-iso (0.9.0)
5
5
  asciidoctor (~> 1.5.7)
6
- isobib (~> 0.1.4)
7
- isodoc (~> 0.6.2)
6
+ iso-bib-item (~> 0.1.6)
7
+ isobib (~> 0.1.6)
8
+ isodoc (>= 0.8)
8
9
  ruby-jing
9
10
 
10
11
  GEM
11
12
  remote: https://rubygems.org/
12
13
  specs:
13
- algoliasearch (1.22.0)
14
+ algoliasearch (1.23.2)
14
15
  httpclient (~> 2.8, >= 2.8.3)
15
16
  json (>= 1.5.1)
16
17
  asciidoctor (1.5.7.1)
@@ -20,9 +21,10 @@ GEM
20
21
  coderay (1.1.2)
21
22
  diff-lcs (1.3)
22
23
  docile (1.3.1)
24
+ duplicate (1.1.1)
23
25
  equivalent-xml (0.6.0)
24
26
  nokogiri (>= 1.4.3)
25
- ffi (1.9.24)
27
+ ffi (1.9.25)
26
28
  formatador (0.2.5)
27
29
  guard (2.14.2)
28
30
  formatador (>= 0.2.4)
@@ -50,15 +52,16 @@ GEM
50
52
  htmlentities (4.3.4)
51
53
  httpclient (2.8.3)
52
54
  image_size (2.0.0)
53
- iso-bib-item (0.1.3)
55
+ iso-bib-item (0.1.6)
56
+ duplicate
54
57
  isoics (~> 0.1.6)
55
58
  nokogiri
56
- isobib (0.1.4)
59
+ isobib (0.1.6)
57
60
  algoliasearch
58
61
  iso-bib-item (~> 0.1.2)
59
- isodoc (0.6.2)
62
+ isodoc (0.8)
60
63
  asciimath
61
- html2doc
64
+ html2doc (>= 0.7.1)
62
65
  htmlentities (~> 4.3.4)
63
66
  image_size
64
67
  liquid
@@ -70,6 +73,7 @@ GEM
70
73
  thread_safe
71
74
  uuidtools
72
75
  isoics (0.1.6)
76
+ jaro_winkler (1.5.1)
73
77
  json (2.1.0)
74
78
  liquid (4.0.0)
75
79
  listen (3.1.5)
@@ -83,7 +87,7 @@ GEM
83
87
  mime-types-data (3.2016.0521)
84
88
  mini_portile2 (2.3.0)
85
89
  nenv (0.3.0)
86
- nokogiri (1.8.2)
90
+ nokogiri (1.8.3)
87
91
  mini_portile2 (~> 2.3.0)
88
92
  notiffany (0.1.1)
89
93
  nenv (~> 0.1)
@@ -92,7 +96,7 @@ GEM
92
96
  parallel (1.12.1)
93
97
  parser (2.5.1.0)
94
98
  ast (~> 2.4.0)
95
- powerpack (0.1.1)
99
+ powerpack (0.1.2)
96
100
  pry (0.11.3)
97
101
  coderay (~> 1.1.0)
98
102
  method_source (~> 0.9.0)
@@ -115,7 +119,8 @@ GEM
115
119
  diff-lcs (>= 1.2.0, < 2.0)
116
120
  rspec-support (~> 3.7.0)
117
121
  rspec-support (3.7.1)
118
- rubocop (0.56.0)
122
+ rubocop (0.57.2)
123
+ jaro_winkler (~> 1.5.1)
119
124
  parallel (~> 1.10)
120
125
  parser (>= 2.5)
121
126
  powerpack (~> 0.1)
@@ -141,7 +146,7 @@ GEM
141
146
  thor (0.20.0)
142
147
  thread_safe (0.3.6)
143
148
  timecop (0.9.1)
144
- unicode-display_width (1.3.3)
149
+ unicode-display_width (1.4.0)
145
150
  uuidtools (2.1.5)
146
151
 
147
152
  PLATFORMS
data/README.adoc CHANGED
@@ -25,14 +25,19 @@ International Standards.
25
25
  as end deliverable ISO standard drafts.
26
26
  ** Microsoft Word output (`.doc`), following the style conventions of the
27
27
  https://www.iso.org/iso-templates.html[ISO Standard Microsoft Word template].
28
- ** PDF (forthcoming)
29
- ** HTML (in development)
28
+ ** HTML. For ISO, two HTML files are generated: the `.html` file follows ISO
29
+ conventions in rendering, which looks very similar to the Word output, while
30
+ the `-alt.html` file has richer styling.
31
+ ** PDF. Not supported for the ISO gem, but available for other other specification,
32
+ generated from the HTML file.
30
33
 
31
34
  This AsciiDoc syntax for writing ISO standards is hereby named "AsciiISO".
32
35
 
33
36
  This README provides an overview of the functionality of the gem; see also
34
37
  https://github.com/riboseinc/asciidoctor-iso/wiki/Guidance-for-authoring[Guidance for authoring]
35
- ISO standards using the gem.
38
+ ISO standards using the gem. The
39
+ https://github.com/riboseinc/asciidoctor-iso/wiki/Quickstart-Guide[Quickstart guide]
40
+ gives a summary overview.
36
41
 
37
42
  == Usage
38
43
 
@@ -331,14 +336,18 @@ consisting of a conical sample divider
331
336
  === Bibliographic details
332
337
 
333
338
  Citations can include details of where in the document the citation is located; these
334
- are entered by suffixing the type of locality, followed by the reference. Multiple
335
- instances of locality and reference can be provided, delimited by comma or colon. For
339
+ are entered by suffixing the type of locality, then an equals sign, then the reference.
340
+ The word "whole" on its own is also treated as a locality. Multiple
341
+ instances of locality and reference can be provided, delimited by comma or colon. Any trailing
342
+ text after the sequence of locality=reference (or locality, space, reference) are treated
343
+ as substitute text, as would occur normally in an Asciidoctor crossreference. For
336
344
  example:
337
345
 
338
346
  [source,asciidoctor]
339
347
  --
340
- <<ISO712,section 5, page 8-10>> # renders as: ISO 712, Section 5, Page 8-10
341
- <<ISO712,section 5, page 8-10: 5:8-10>> # renders as ISO 712, 5:8-10
348
+ <<ISO712,the foregoing reference>> # renders as: the foregoing reference
349
+ <<ISO712,section=5, page 8-10>> # renders as: ISO 712, Section 5, Page 8-10
350
+ <<ISO712,section=5, page=8-10: 5:8-10>> # renders as ISO 712, 5:8-10 ("5:8-10" treated as replacement text for all the foregoing)
342
351
  <<ISO712,whole>> # renders as: ISO 712, Whole of text
343
352
  --
344
353
 
@@ -349,7 +358,7 @@ A custom locality can be entered by prefixing it with `locality:`:
349
358
 
350
359
  [source,asciidoctor]
351
360
  --
352
- <<ISO712,locality:frontispiece 5, page 8-10>> # renders as: ISO 712, Frontispiece 5, Page 8-10
361
+ <<ISO712,locality:frontispiece=5, page=8-10>> # renders as: ISO 712, Frontispiece 5, Page 8-10
353
362
  --
354
363
 
355
364
  Custom localities may not contain commas, colons, or space. Localities with the `locality:`
@@ -528,6 +537,11 @@ in the file `filename`.relaton.json. The local cache overrides entries in
528
537
  the global cache, and can be manually edited. The local cache is only used
529
538
  if the `:local-cache:` document attribute is set.
530
539
 
540
+ If the document attribute `:no-isobib:` is set, the reference details for
541
+ items are not looked up via `isobib`, and the `isobib` caches are not used.
542
+ If the document attribute `:no-isobib-cache:` is set, the reference details for
543
+ items are still looked up via `isobib`, but the `isobib` caches are not used.
544
+
531
545
  == Document Attributes
532
546
 
533
547
  The gem relies on Asciidoctor document attributes to provide necessary
@@ -542,6 +556,12 @@ Can be used as a command-line option (like all other document attributes):
542
556
  `:flush-caches:`:: If set, delete and reinitialise the <<cache,cache>> of `isobib` searches
543
557
  for ISO references from the ISO web site.
544
558
 
559
+ `:no-isobib:`:: If set, do not use the `isobib` gem functionality to look up
560
+ ISO references online, nor the <<cache,cache>> of `isobib` searches.
561
+
562
+ `:no-isobib-cache:`:: If set, use the `isobib` gem functionality to look up
563
+ ISO references online, but do not use the <<cache,cache>> of `isobib` searches.
564
+
545
565
  `:local-cache:`:: Use the local isobib search cache to override the global isobib search
546
566
  cache.
547
567
 
@@ -29,8 +29,9 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.add_dependency "asciidoctor", "~> 1.5.7"
31
31
  spec.add_dependency "ruby-jing"
32
- spec.add_dependency "isodoc", ">= 0.7.0"
33
- spec.add_dependency "isobib", "~> 0.1.4"
32
+ spec.add_dependency "isodoc", ">= 0.8"
33
+ spec.add_dependency "isobib", "~> 0.1.6"
34
+ spec.add_dependency "iso-bib-item", "~> 0.1.6"
34
35
 
35
36
  spec.add_development_dependency "bundler", "~> 1.15"
36
37
  spec.add_development_dependency "byebug", "~> 9.1"
@@ -3,3 +3,7 @@ require_relative "asciidoctor/iso/converter"
3
3
  require_relative "asciidoctor/iso/version"
4
4
  require "asciidoctor/extensions"
5
5
 
6
+ if defined? Metanorma
7
+ require_relative "metanorma/iso"
8
+ Metanorma::Registry.instance.register(Metanorma::Iso::Processor)
9
+ end
@@ -28,22 +28,8 @@ module Asciidoctor
28
28
  nil
29
29
  end
30
30
 
31
- def html_doc_path(file)
32
- File.join(File.dirname(__FILE__), File.join("html", file))
33
- end
34
-
35
- def generate_css(filename, stripwordcss, fontheader)
36
- stylesheet = File.read(filename, encoding: "UTF-8")
37
- stylesheet.gsub!(/(\s|\{)mso-[^:]+:[^;]+;/m, "\\1") if stripwordcss
38
- engine = Sass::Engine.new(fontheader + stylesheet, syntax: :scss)
39
- outname = File.basename(filename, ".*") + ".css"
40
- File.open(outname, "w") { |f| f.write(engine.render) }
41
- @files_to_delete << outname
42
- outname
43
- end
44
-
45
31
  def html_converter(node)
46
- IsoDoc::Iso::Convert.new(
32
+ IsoDoc::Iso::HtmlConvert.new(
47
33
  script: node.attr("script"),
48
34
  bodyfont: node.attr("body-font"),
49
35
  headerfont: node.attr("header-font"),
@@ -53,7 +39,7 @@ module Asciidoctor
53
39
  end
54
40
 
55
41
  def html_converter_alt(node)
56
- IsoDoc::Iso::Convert.new(
42
+ IsoDoc::Iso::HtmlConvert.new(
57
43
  script: node.attr("script"),
58
44
  bodyfont: node.attr("body-font"),
59
45
  headerfont: node.attr("header-font"),
@@ -82,8 +68,9 @@ module Asciidoctor
82
68
  @novalid = node.attr("novalid")
83
69
  @fontheader = default_fonts(node)
84
70
  @files_to_delete = []
85
- @filename = node.attr("docfile") ?
71
+ @filename = node.attr("docfile") ?
86
72
  node.attr("docfile").gsub(/\.adoc$/, "").gsub(%r{^.*/}, "") : ""
73
+ @no_isobib_cache = node.attr("no-isobib-cache")
87
74
  @bibliodb = open_cache_biblio(node, true)
88
75
  @local_bibliodb = node.attr("local-cache") ?
89
76
  open_cache_biblio(node, false) : nil
@@ -37,17 +37,32 @@ module Asciidoctor
37
37
  empty_element_cleanup(xmldoc)
38
38
  mathml_cleanup(xmldoc)
39
39
  script_cleanup(xmldoc)
40
+ docidentifier_cleanup(xmldoc)
40
41
  bookmark_cleanup(xmldoc)
41
42
  xmldoc
42
43
  end
43
44
 
45
+ def docidentifier_cleanup(xmldoc)
46
+ id = xmldoc.at("//bibdata/docidentifier/project-number")
47
+ return unless id
48
+
49
+ prefix = []
50
+ xmldoc.xpath("//bibdata/contributor[role/@type = 'publisher']"\
51
+ "/organization").each do |x|
52
+ x1 = x.at("abbreviation")&.text || x.at("name")&.text
53
+ x1 == "ISO" and prefix.unshift("ISO") or prefix << x1
54
+ end
55
+
56
+ id.content = prefix.join("/") + " " + id.text
57
+ end
58
+
44
59
  TEXT_ELEMS =
45
60
  %w{status language script version author name callout phone
46
61
  email street city state country postcode identifier referenceFrom
47
62
  referenceTo docidentifier prefix initial addition surname forename
48
63
  title draft secretariat title-main title-intro title-part}.freeze
49
64
 
50
- # it seems Nokogiri::XML is treating the content of <script> as cdata,
65
+ # it seems Nokogiri::XML is treating the content of <script> as cdata,
51
66
  # because of its use in HTML. Bad nokogiri. Undoing that, since we use
52
67
  # script as a normal tag
53
68
  def script_cleanup(xmldoc)
@@ -6,7 +6,7 @@ module Asciidoctor
6
6
  LOCALITY_REGEX_STR = <<~REGEXP.freeze
7
7
  ^((?<locality>section|clause|part|paragraph|chapter|page|
8
8
  table|annex|figure|example|note|formula|
9
- locality:[^ \\t\\n\\r:,]+)\\s+
9
+ locality:[^ \\t\\n\\r:,]+)(\\s+|=)
10
10
  (?<ref>[^ \\t\\n,:-]+)(-(?<to>[^ \\t\\n,:-]+))?|
11
11
  (?<locality2>whole|locality:[^ \\t\\n\\r:,]+))[,:]?\\s*
12
12
  (?<text>.*)$
@@ -107,7 +107,7 @@ module Asciidoctor
107
107
  end
108
108
 
109
109
  def reference_names(xmldoc)
110
- xmldoc.xpath("//bibitem").each do |ref|
110
+ xmldoc.xpath("//bibitem[not(ancestor::bibitem)]").each do |ref|
111
111
  isopub = ref.at(ISO_PUBLISHER_XPATH)
112
112
  docid = ref.at("./docidentifier")
113
113
  date = ref.at("./date[@type = 'published']")
@@ -99,7 +99,11 @@ module Asciidoctor
99
99
 
100
100
  def metadata_ics(node, xml)
101
101
  ics = node.attr("library-ics")
102
- ics && ics.split(/,\s*/).each { |i| xml.ics i }
102
+ ics && ics.split(/,\s*/).each do |i|
103
+ xml.ics do |ics|
104
+ ics.code i
105
+ end
106
+ end
103
107
  end
104
108
 
105
109
  def metadata(node, xml)
@@ -114,6 +114,9 @@
114
114
  <zeroOrMore>
115
115
  <ref name="ics"/>
116
116
  </zeroOrMore>
117
+ <optional>
118
+ <ref name="allParts"/>
119
+ </optional>
117
120
  </define>
118
121
  <define name="BibData">
119
122
  <optional>
@@ -165,6 +168,9 @@
165
168
  <zeroOrMore>
166
169
  <ref name="ics"/>
167
170
  </zeroOrMore>
171
+ <optional>
172
+ <ref name="allParts"/>
173
+ </optional>
168
174
  </define>
169
175
  <define name="bdate">
170
176
  <element name="date">
@@ -852,6 +858,11 @@
852
858
  <ref name="FormattedString"/>
853
859
  </element>
854
860
  </define>
861
+ <define name="allParts">
862
+ <element name="allParts">
863
+ <data type="boolean"/>
864
+ </element>
865
+ </define>
855
866
  <define name="clause-hanging-paragraph-with-footnote">
856
867
  <element name="clause">
857
868
  <optional>
@@ -905,7 +916,12 @@
905
916
  </define>
906
917
  <define name="ics">
907
918
  <element name="ics">
908
- <text/>
919
+ <element name="code">
920
+ <text/>
921
+ </element>
922
+ <element name="text">
923
+ <text/>
924
+ </element>
909
925
  </element>
910
926
  </define>
911
927
  <define name="term-clause">
@@ -71,80 +71,147 @@ module Asciidoctor
71
71
  return use_my_anchor(ref, m[:anchor]) if ref
72
72
  xml.bibitem(**attr_code(ref_attributes(m))) do |t|
73
73
  t.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
74
- t.docidentifier "#{m[:code]}:All Parts"
74
+ t.docidentifier "#{m[:code]}"
75
75
  if m.named_captures.has_key?("year")
76
76
  t.date(**{ type: "published" }) { |d| set_date_range(d, m[:year]) }
77
77
  end
78
78
  iso_publisher(t, m[:code])
79
+ t.allParts "true"
79
80
  end
80
81
  end
81
82
 
82
- def fetch_year_check(hit, code, year, opts)
83
- ret =nil
84
- if year.nil? || year.to_i == hit.hit["year"]
85
- ret = hit.to_xml opts
86
- @bibliodb[code] = ret if @bibliodb
87
- @local_bibliodb[code] = ret if @local_bibliodb
83
+ # --- ISOBIB
84
+ def fetch_ref_err(code, year, missed_years)
85
+ id = year ? "#{code}:#{year}" : code
86
+ warn "WARNING: no match found on the ISO website for #{id}. "\
87
+ "The code must be exactly like it is on the website."
88
+ warn "(There was no match for #{year}, though there were matches "\
89
+ "found for #{missed_years.join(', ')}.)" unless missed_years.empty?
90
+ if /\d-\d/.match? code
91
+ warn "The provided document part may not exist, or the document "\
92
+ "may no longer be published in parts."
88
93
  else
89
- warn "WARNING: cited year #{year} does not match year "\
90
- "#{hit.hit['year']} found on the ISO website for #{code}"
94
+ warn "If you wanted to cite all document parts for the reference, "\
95
+ "use \"#{code} (all parts)\".\nIf the document is not a standard, "\
96
+ "use its document type abbreviation (TS, TR, PAS, Guide)."
91
97
  end
92
- ret
98
+ nil
93
99
  end
94
100
 
95
- def first_with_title(result)
96
- result.first.each do |x|
97
- next unless x.hit["title"]
98
- return x
99
- end
100
- return nil
101
+ def fetch_pages(s, n)
102
+ workers = WorkersPool.new n
103
+ workers.worker { |w| { i: w[:i], hit: w[:hit].fetch } }
104
+ s.each_with_index { |hit, i| workers << { i: i, hit: hit } }
105
+ workers.end
106
+ workers.result.sort { |x, y| x[:i] <=> y[:i] }.map { |x| x[:hit] }
101
107
  end
102
108
 
103
- def first_year_match_hit(result, code, year)
104
- return first_with_title(result) if year.nil?
105
- return nil unless result.first && result.first.is_a?(Array)
106
- coderegex = %r{^(ISO|IEC)[^0-9]*\s[0-9-]+}
107
- result.first.each do |x|
108
- next unless x.hit["title"]
109
- return x if x.hit["title"].match(coderegex).to_s == code &&
110
- year.to_i == x.hit["year"]
111
- end
112
- return first_with_title(result)
109
+ def isobib_search_filter(code)
110
+ docidrx = %r{^(ISO|IEC)[^0-9]*\s[0-9-]+}
111
+ corrigrx = %r{^(ISO|IEC)[^0-9]*\s[0-9-]+:[0-9]+/}
112
+ warn "fetching #{code}..."
113
+ result = Isobib::IsoBibliography.search(code)
114
+ result.first.select do |i|
115
+ i.hit["title"] &&
116
+ i.hit["title"].match(docidrx).to_s == code &&
117
+ !corrigrx.match?(i.hit["title"])
118
+ end
113
119
  end
114
120
 
115
- def fetch_ref_err(code)
116
- warn "WARNING: no match found on the ISO website for #{code}."
117
- if /\d-\d/.match? code
118
- warn "The provided document part may not exist, or the document may no longer be published in parts."
119
- else
120
- warn "If you wanted to cite all document parts for the reference, use #{code}:All Parts"
121
- end
121
+ def iev
122
+ Nokogiri::XML.fragment(<<~"END")
123
+ <bibitem type="international-standard" id="IEV">
124
+ <title format="text/plain" language="en" script="Latn">Electropedia:
125
+ The World's Online Electrotechnical Vocabulary</title>
126
+ <source type="src">http://www.electropedia.org</source>
127
+ <docidentifier>IEV</docidentifier>
128
+ <date type="published"> <on>#{Date.today.year}</on> </date>
129
+ <contributor>
130
+ <role type="publisher"/>
131
+ <organization>
132
+ <name>International Electrotechnical Commission</name>
133
+ <abbreviation>IEC</abbreviation>
134
+ <uri>www.iec.ch</uri>
135
+ </organization>
136
+ </contributor>
137
+ <language>en</language> <language>fr</language>
138
+ <script>Latn</script>
139
+ <copyright>
140
+ <from>#{Date.today.year}</from>
141
+ <owner>
142
+ <organization>
143
+ <name>International Electrotechnical Commission</name>
144
+ <abbreviation>IEC</abbreviation>
145
+ <uri>www.iec.ch</uri>
146
+ </organization>
147
+ </owner>
148
+ </copyright>
149
+ <relation type="updates">
150
+ <bibitem>
151
+ <formattedref>IEC 60050</formattedref>
152
+ </bibitem>
153
+ </relation>
154
+ </bibitem>
155
+ END
122
156
  end
123
157
 
124
- def fetch_ref2(code, year, opts)
125
- result = Isobib::IsoBibliography.search(code)
126
- ret = nil
127
- hit = first_year_match_hit(result, code, year)
128
- coderegex = %r{^(ISO|IEC)[^0-9]*\s[0-9-]+}
129
- if hit && hit.hit["title"]&.match(coderegex)&.to_s == code
130
- ret = fetch_year_check(hit, code, year, opts)
131
- else
132
- fetch_ref_err(code)
158
+ # Sort through the results from Isobib, fetching them three at a time,
159
+ # and return the first result that matches the code,
160
+ # matches the year (if provided), and which # has a title (amendments do not).
161
+ # Only expects the first page of results to be populated.
162
+ # Does not match corrigenda etc (e.g. ISO 3166-1:2006/Cor 1:2007)
163
+ # If no match, returns any years which caused mismatch, for error reporting
164
+ def isobib_results_filter(result, year)
165
+ missed_years = []
166
+ result.each_slice(3) do |s| # ISO website only allows 3 connections
167
+ fetch_pages(s, 3).each_with_index do |r, i|
168
+ return { ret: r } if !year
169
+ r.dates.select { |d| d.type == "published" }.each do |d|
170
+ return { ret: r } if year.to_i == d.on.year
171
+ missed_years << d.on.year
172
+ end
173
+ end
133
174
  end
175
+ { years: missed_years }
176
+ end
177
+
178
+ def isobib_get1(code, year, opts)
179
+ return iev if code.casecmp? "IEV"
180
+ result = isobib_search_filter(code) or return nil
181
+ ret = isobib_results_filter(result, year)
182
+ return ret[:ret] if ret[:ret]
183
+ fetch_ref_err(code, year, ret[:years])
184
+ end
185
+
186
+ def isobib_get(code, year, opts)
187
+ code += "-1" if opts[:all_parts]
188
+ ret = isobib_get1(code, year, opts)
189
+ return nil if ret.nil?
190
+ ret.to_most_recent_reference if !year
191
+ ret.to_all_parts if opts[:all_parts]
192
+ ret.to_xml
193
+ end
194
+
195
+ # --- ISOBIB
196
+
197
+ def iso_id(code, year, all_parts)
198
+ ret = code
199
+ ret += ":#{year}" if year
200
+ ret += " (all parts)" if all_parts
134
201
  ret
135
202
  end
136
203
 
137
204
  def fetch_ref1(code, year, opts)
205
+ id = iso_id(code, year, opts[:all_parts])
138
206
  return nil if @bibliodb.nil? # signals we will not be using isobib
139
- @bibliodb[code] = fetch_ref2(code, year, opts) unless @bibliodb[code]
140
- @local_bibliodb[code] = @bibliodb[code] if !@local_bibliodb.nil? &&
141
- !@local_bibliodb[code]
142
- return @local_bibliodb[code] unless @local_bibliodb.nil?
143
- @bibliodb[code]
207
+ @bibliodb[id] = isobib_get(code, year, opts) unless @bibliodb[id]
208
+ @local_bibliodb[id] = @bibliodb[id] if !@local_bibliodb.nil? &&
209
+ !@local_bibliodb[id]
210
+ return @local_bibliodb[id] unless @local_bibliodb.nil?
211
+ @bibliodb[id]
144
212
  end
145
213
 
146
214
  def fetch_ref(xml, code, year, **opts)
147
- warn "fetching #{code}..."
148
215
  hit = fetch_ref1(code, year, opts)
149
216
  return nil if hit.nil?
150
217
  xml.parent.add_child(hit)
@@ -181,7 +248,8 @@ module Asciidoctor
181
248
  end
182
249
 
183
250
  ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
184
- \[(?<code>(ISO|IEC)[^0-9]*\s[0-9-]+)(:(?<year>[0-9][0-9-]+))?\]</ref>,?\s
251
+ \[(?<code>(ISO|IEC)[^0-9]*\s[0-9-]+|IEV)
252
+ (:(?<year>[0-9][0-9-]+))?\]</ref>,?\s
185
253
  (?<text>.*)$}xm
186
254
 
187
255
  ISO_REF_NO_YEAR = %r{^<ref\sid="(?<anchor>[^"]+)">
@@ -235,9 +303,11 @@ module Asciidoctor
235
303
 
236
304
  # if returns nil, then biblio caching is disabled, and so is use of isobib
237
305
  def open_cache_biblio(node, global)
238
- return nil # disabling for now
306
+ # return nil # disabling for now
307
+ return nil if node.attr("no-isobib")
308
+ return {} if @no_isobib_cache
239
309
  filename = bibliocache_name(global)
240
- system("rm -f #{filename}") if node.attr("flush-caches") == "true"
310
+ system("rm -f #{filename}") if node.attr("flush-caches")
241
311
  biblio = {}
242
312
  if Pathname.new(filename).file?
243
313
  File.open(filename, "r") do |f|
@@ -248,7 +318,7 @@ module Asciidoctor
248
318
  end
249
319
 
250
320
  def save_cache_biblio(biblio, global)
251
- return if biblio.nil?
321
+ return if biblio.nil? || @no_isobib_cache
252
322
  filename = bibliocache_name(global)
253
323
  File.open(filename, "w") do |b|
254
324
  b << biblio.to_json