metanorma-standoc 1.8.2 → 1.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +11 -41
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +6 -2
  5. data/lib/asciidoctor/standoc/base.rb +3 -1
  6. data/lib/asciidoctor/standoc/biblio.rng +4 -6
  7. data/lib/asciidoctor/standoc/blocks.rb +35 -12
  8. data/lib/asciidoctor/standoc/cleanup.rb +2 -1
  9. data/lib/asciidoctor/standoc/cleanup_block.rb +73 -22
  10. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +3 -3
  11. data/lib/asciidoctor/standoc/cleanup_inline.rb +4 -3
  12. data/lib/asciidoctor/standoc/cleanup_maths.rb +37 -0
  13. data/lib/asciidoctor/standoc/cleanup_ref.rb +4 -13
  14. data/lib/asciidoctor/standoc/cleanup_section.rb +5 -0
  15. data/lib/asciidoctor/standoc/cleanup_terms.rb +2 -2
  16. data/lib/asciidoctor/standoc/inline.rb +7 -15
  17. data/lib/asciidoctor/standoc/isodoc.rng +105 -2
  18. data/lib/asciidoctor/standoc/ref_sect.rb +12 -12
  19. data/lib/asciidoctor/standoc/section.rb +9 -0
  20. data/lib/asciidoctor/standoc/utils.rb +0 -24
  21. data/lib/asciidoctor/standoc/validate.rb +16 -1
  22. data/lib/metanorma/standoc/version.rb +1 -1
  23. data/metanorma-standoc.gemspec +5 -5
  24. data/spec/{asciidoctor-standoc → asciidoctor}/base_spec.rb +4 -0
  25. data/spec/{asciidoctor-standoc → asciidoctor}/blocks_spec.rb +0 -0
  26. data/spec/{asciidoctor-standoc → asciidoctor}/cleanup_sections_spec.rb +14 -14
  27. data/spec/{asciidoctor-standoc → asciidoctor}/cleanup_spec.rb +242 -11
  28. data/spec/{asciidoctor-standoc → asciidoctor}/datamodel/attributes_table_preprocessor_spec.rb +0 -0
  29. data/spec/{asciidoctor-standoc → asciidoctor}/datamodel/diagram_preprocessor_spec.rb +0 -0
  30. data/spec/{asciidoctor-standoc → asciidoctor}/inline_spec.rb +2 -0
  31. data/spec/{asciidoctor-standoc → asciidoctor}/isobib_cache_spec.rb +0 -0
  32. data/spec/{asciidoctor-standoc → asciidoctor}/lists_spec.rb +0 -0
  33. data/spec/{asciidoctor-standoc → asciidoctor}/macros_json2text_spec.rb +0 -0
  34. data/spec/{asciidoctor-standoc → asciidoctor}/macros_plantuml_spec.rb +0 -0
  35. data/spec/{asciidoctor-standoc → asciidoctor}/macros_spec.rb +0 -0
  36. data/spec/{asciidoctor-standoc → asciidoctor}/macros_yaml2text_spec.rb +0 -0
  37. data/spec/{asciidoctor-standoc → asciidoctor}/refs_dl_spec.rb +0 -0
  38. data/spec/{asciidoctor-standoc → asciidoctor}/refs_spec.rb +297 -147
  39. data/spec/{asciidoctor-standoc → asciidoctor}/section_spec.rb +17 -0
  40. data/spec/{asciidoctor-standoc → asciidoctor}/table_spec.rb +0 -0
  41. data/spec/{asciidoctor-standoc → asciidoctor}/validate_spec.rb +20 -0
  42. data/spec/assets/html-override.css +1 -0
  43. data/spec/assets/word-override.css +1 -0
  44. data/spec/fixtures/action_schemaexpg1.svg +122 -0
  45. data/spec/spec_helper.rb +8 -0
  46. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +62 -62
  47. data/spec/vcr_cassettes/isobib_get_123.yml +15 -15
  48. data/spec/vcr_cassettes/isobib_get_123_1.yml +30 -30
  49. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +42 -42
  50. data/spec/vcr_cassettes/isobib_get_123_2001.yml +15 -15
  51. data/spec/vcr_cassettes/isobib_get_124.yml +16 -16
  52. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +94 -30
  53. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +59 -57
  54. metadata +41 -41
  55. data/.rubocop.ribose.yml +0 -66
  56. data/.rubocop.tb.yml +0 -650
  57. data/spec/asciidoctor-standoc/macros_lutaml_spec.rb +0 -80
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90c09f71739f8d485363ce3a4f950b143c0264f5b4657fd0891df83a00c44f72
4
- data.tar.gz: cb0c51236e8c1780aa2a89b7a0c53efeabc2a4af3ef68e6c08aa8936efdea47d
3
+ metadata.gz: df453526eab7a001b67712f6f0bd885a9242d5e489e8a0d8f138bb3a2f653f1e
4
+ data.tar.gz: e632b1a38bff75199ae1047188702e28275ebb3563c921e2a5bc545a5c4ec43f
5
5
  SHA512:
6
- metadata.gz: 96533136bca911c4f886e6d0aeaa0e86ce94cf754d721af5537c835b744980fef11555e494d5d485a348c1ea911d1394cfb215f9f02cbf095a90bd652cae2916
7
- data.tar.gz: 80bd100da6d8d05fdc69f8f52d20e9af182bd3196c42074663241dc8e35bee952eb8bf7ef95fbf444dbcd25f1bd45ac7d864f70c394df372f8d24b1e26a385d7
6
+ metadata.gz: 44bba71bdd21993acfd38de5d3ae020df5bf569a31c0bd208b223a2bef628093f476ae9bf18e3f8e1f716b898238648a9f14ffe24446148e38e0719340b826ff
7
+ data.tar.gz: 40a66dea77906193f52dd4fd99023963a1e0ed1f6e584832bef19022e5278933ba28c85e7624feb0282f94f1e95471a13340a189dbd61835129c3f5f8d10f0b4
@@ -16,17 +16,17 @@ jobs:
16
16
  strategy:
17
17
  fail-fast: false
18
18
  matrix:
19
- ruby: [ '2.6', '2.5', '2.4' ]
19
+ ruby: [ '2.7', '2.6', '2.5', '2.4' ]
20
20
  os: [ ubuntu-latest, windows-latest, macos-latest ]
21
21
  experimental: [ false ]
22
22
  include:
23
- - ruby: '2.7'
23
+ - ruby: '3.0'
24
24
  os: 'ubuntu-latest'
25
25
  experimental: true
26
- - ruby: '2.7'
26
+ - ruby: '3.0'
27
27
  os: 'windows-latest'
28
28
  experimental: true
29
- - ruby: '2.7'
29
+ - ruby: '3.0'
30
30
  os: 'macos-latest'
31
31
  experimental: true
32
32
  steps:
@@ -35,49 +35,19 @@ jobs:
35
35
  - uses: ruby/setup-ruby@v1
36
36
  with:
37
37
  ruby-version: ${{ matrix.ruby }}
38
+ bundler-cache: true
38
39
 
39
- - if: matrix.os == 'macos-latest'
40
- run: brew install autoconf automake libtool
41
-
42
- - uses: actions/cache@v2
43
- with:
44
- path: vendor/bundle
45
- key: bundle-${{ matrix.os }}-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}
46
- restore-keys: bundle-${{ matrix.os }}-${{ matrix.ruby }}
47
-
48
- - run: bundle config set path 'vendor/bundle'
49
-
50
- - run: bundle install --jobs 4 --retry 3
51
-
52
- - name: install plantuml ubuntu
53
- if: matrix.os == 'ubuntu-latest'
54
- uses: nick-invision/retry@v1
55
- with:
56
- polling_interval_seconds: 5
57
- timeout_minutes: 5
58
- max_attempts: 3
59
- command: >
60
- sudo apt-get update -y && sudo bash -c
61
- "curl -L https://github.com/metanorma/plantuml-install/raw/master/ubuntu.sh | bash"
62
-
63
- - if: matrix.os == 'macos-latest'
64
- run: brew install plantuml
65
-
66
- - if: matrix.os == 'windows-latest'
67
- run: cinst -y plantuml
40
+ - uses: metanorma/metanorma-build-scripts/plantuml-setup-action@master
68
41
 
69
42
  - run: bundle exec rake
70
43
 
71
44
  tests-passed:
72
45
  needs: rake
73
46
  runs-on: ubuntu-latest
74
- continue-on-error: true
75
47
  steps:
76
- - name: Trigger tests passed event
77
- uses: Sibz/github-status-action@v1
48
+ - uses: peter-evans/repository-dispatch@v1
78
49
  with:
79
- authToken: ${{ secrets.METANORMA_CI_PAT_TOKEN || secrets.GITHUB_TOKEN }}
80
- context: 'tests-passed-successfully'
81
- description: 'Tests passed successfully'
82
- state: 'success'
83
- sha: ${{ github.event.pull_request.head.sha || github.sha }}
50
+ token: ${{ secrets.METANORMA_CI_PAT_TOKEN || secrets.GITHUB_TOKEN }}
51
+ repository: ${{ github.repository }}
52
+ event-type: notify
53
+ client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}'
data/.gitignore CHANGED
@@ -10,3 +10,5 @@ spec/examples/rice.html
10
10
  spec/examples/rice.xml
11
11
  spec/examples/rice_files/
12
12
  Gemfile.lock
13
+
14
+ .rubocop-https--*
data/.rubocop.yml CHANGED
@@ -1,10 +1,14 @@
1
1
  # This project follows the Ribose OSS style guide.
2
2
  # https://github.com/riboseinc/oss-guides
3
3
  # All project-specific additions and overrides should be specified in this file.
4
-
5
4
  inherit_from:
6
5
  - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
6
+
7
+ # local repo-specific modifications
8
+
7
9
  AllCops:
8
- TargetRubyVersion: 2.6
10
+ DisplayCopNames: false
11
+ StyleGuideCopsOnly: false
12
+ TargetRubyVersion: 2.4
9
13
  Rails:
10
14
  Enabled: true
@@ -43,6 +43,7 @@ module Asciidoctor
43
43
  i18nyaml: node.attr("i18nyaml"),
44
44
  scope: node.attr("scope"),
45
45
  htmlstylesheet: node.attr("htmlstylesheet"),
46
+ htmlstylesheet_override: node.attr("htmlstylesheet-override"),
46
47
  htmlcoverpage: node.attr("htmlcoverpage"),
47
48
  htmlintropage: node.attr("htmlintropage"),
48
49
  scripts: node.attr("scripts"),
@@ -67,6 +68,7 @@ module Asciidoctor
67
68
  i18nyaml: node.attr("i18nyaml"),
68
69
  scope: node.attr("scope"),
69
70
  wordstylesheet: node.attr("wordstylesheet"),
71
+ wordstylesheet_override: node.attr("wordstylesheet-override"),
70
72
  standardstylesheet: node.attr("standardstylesheet"),
71
73
  header: node.attr("header"),
72
74
  wordcoverpage: node.attr("wordcoverpage"),
@@ -139,7 +141,7 @@ module Asciidoctor
139
141
 
140
142
  def document(node)
141
143
  init(node)
142
- ret = makexml(node).to_xml(indent: 2)
144
+ ret = makexml(node).to_xml(encoding: "US-ASCII", indent: 2)
143
145
  outputs(node, ret) unless node.attr("nodoc") || !node.attr("docfile")
144
146
  clean_exit
145
147
  ret
@@ -124,7 +124,7 @@
124
124
  <value>application/tei+xml</value>
125
125
  <value>text/x-asciidoc</value>
126
126
  <value>text/markdown</value>
127
- <value>application/x-isodoc+xml</value>
127
+ <value>application/x-metanorma+xml</value>
128
128
  <text/>
129
129
  </choice>
130
130
  </attribute>
@@ -452,6 +452,7 @@
452
452
  <attribute name="type">
453
453
  <choice>
454
454
  <value>isni</value>
455
+ <value>orcid</value>
455
456
  <value>uri</value>
456
457
  </choice>
457
458
  </attribute>
@@ -461,10 +462,7 @@
461
462
  <define name="org-identifier">
462
463
  <element name="identifier">
463
464
  <attribute name="type">
464
- <choice>
465
- <value>orcid</value>
466
- <value>uri</value>
467
- </choice>
465
+ <data type="string" datatypeLibrary=""/>
468
466
  </attribute>
469
467
  <text/>
470
468
  </element>
@@ -1106,7 +1104,7 @@
1106
1104
  <value>complementOf</value>
1107
1105
  <value>obsoletes</value>
1108
1106
  <value>obsoletedBy</value>
1109
- <value>cited</value>
1107
+ <value>cites</value>
1110
1108
  <value>isCitedIn</value>
1111
1109
  </choice>
1112
1110
  </define>
@@ -45,8 +45,9 @@ module Asciidoctor
45
45
  noko do |xml|
46
46
  xml.figure **literal_attrs(node) do |f|
47
47
  figure_title(node, f)
48
- f.pre node.lines.join("\n"), **attr_code(id: Metanorma::Utils::anchor_or_uuid,
49
- alt: node.attr("alt"))
48
+ f.pre node.lines.join("\n"),
49
+ **attr_code(id: Metanorma::Utils::anchor_or_uuid,
50
+ alt: node.attr("alt"))
50
51
  end
51
52
  end
52
53
  end
@@ -74,11 +75,30 @@ module Asciidoctor
74
75
  %w(recommendation requirement permission).include?(role) and
75
76
  return requirement(node, role)
76
77
  return pseudocode_example(node) if role == "pseudocode"
78
+ return svgmap_example(node) if role == "svgmap"
77
79
  example_proper(node)
78
80
  end
79
81
 
82
+ def svgmap_attrs(node)
83
+ attr_code( { id: node.id,
84
+ unnumbered: node.option?("unnumbered") ? "true" : nil,
85
+ number: node.attr("number"),
86
+ subsequence: node.attr("subsequence") }.
87
+ merge(keep_attrs(node)))
88
+ end
89
+
90
+ def svgmap_example(node)
91
+ noko do |xml|
92
+ xml.svgmap **attr_code(svgmap_attrs(node).merge(
93
+ src: node.attr("src"), alt: node.attr("alt"))) do |ex|
94
+ figure_title(node, ex)
95
+ ex << node.content
96
+ end
97
+ end.join("\n")
98
+ end
99
+
100
+ # prevent A's and other subs inappropriate for pseudocode
80
101
  def pseudocode_example(node)
81
- # prevent A's and other subs inappropriate for pseudocode
82
102
  node.blocks.each { |b| b.remove_sub(:replacements) }
83
103
  noko do |xml|
84
104
  xml.figure **example_attrs(node).merge(class: "pseudocode") do |ex|
@@ -120,8 +140,9 @@ module Asciidoctor
120
140
  end
121
141
 
122
142
  def para_attrs(node)
123
- attr_code(keep_attrs(node).merge(align: node.attr("align"),
124
- id: Metanorma::Utils::anchor_or_uuid(node)))
143
+ attr_code(keep_attrs(node).
144
+ merge(align: node.attr("align"),
145
+ id: Metanorma::Utils::anchor_or_uuid(node)))
125
146
  end
126
147
 
127
148
  def paragraph(node)
@@ -134,8 +155,9 @@ module Asciidoctor
134
155
  end
135
156
 
136
157
  def quote_attrs(node)
137
- attr_code(keep_attrs(node).merge(align: node.attr("align"),
138
- id: Metanorma::Utils::anchor_or_uuid(node)))
158
+ attr_code(keep_attrs(node).
159
+ merge(align: node.attr("align"),
160
+ id: Metanorma::Utils::anchor_or_uuid(node)))
139
161
  end
140
162
 
141
163
  def quote_attribution(node, out)
@@ -159,11 +181,12 @@ module Asciidoctor
159
181
  end
160
182
 
161
183
  def listing_attrs(node)
162
- attr_code(keep_attrs(node).merge(lang: node.attr("language"),
163
- id: Metanorma::Utils::anchor_or_uuid(node),
164
- unnumbered: node.option?("unnumbered") ? "true" : nil,
165
- number: node.attr("number"),
166
- filename: node.attr("filename")))
184
+ attr_code(keep_attrs(node).
185
+ merge(lang: node.attr("language"),
186
+ id: Metanorma::Utils::anchor_or_uuid(node),
187
+ unnumbered: node.option?("unnumbered") ? "true" : nil,
188
+ number: node.attr("number"),
189
+ filename: node.attr("filename")))
167
190
  end
168
191
 
169
192
  # NOTE: html escaping is performed by Nokogiri
@@ -58,6 +58,7 @@ module Asciidoctor
58
58
  bookmark_cleanup(xmldoc)
59
59
  requirement_cleanup(xmldoc)
60
60
  bibdata_cleanup(xmldoc)
61
+ svgmap_cleanup(xmldoc)
61
62
  boilerplate_cleanup(xmldoc)
62
63
  smartquotes_cleanup(xmldoc)
63
64
  variant_cleanup(xmldoc)
@@ -171,7 +172,7 @@ module Asciidoctor
171
172
 
172
173
  def img_cleanup(xmldoc)
173
174
  return xmldoc unless @datauriimage
174
- xmldoc.xpath("//image").each { |i| i["src"] = datauri(i["src"]) }
175
+ xmldoc.xpath("//image").each { |i| i["src"] = Metanorma::Utils::datauri(i["src"], @localdir) }
175
176
  end
176
177
 
177
178
  def variant_cleanup(xmldoc)
@@ -1,6 +1,5 @@
1
1
  require "date"
2
2
  require "htmlentities"
3
- require "json"
4
3
  require "open-uri"
5
4
 
6
5
  module Asciidoctor
@@ -22,9 +21,7 @@ module Asciidoctor
22
21
  def dl1_table_cleanup(xmldoc)
23
22
  q = "//table/following-sibling::*[1][self::dl]"
24
23
  xmldoc.xpath(q).each do |s|
25
- if s["key"] == "true"
26
- s.previous_element << s.remove
27
- end
24
+ s["key"] == "true" and s.previous_element << s.remove
28
25
  end
29
26
  end
30
27
 
@@ -32,7 +29,7 @@ module Asciidoctor
32
29
  def dl2_table_cleanup(xmldoc)
33
30
  q = "//table/following-sibling::*[1][self::p]"
34
31
  xmldoc.xpath(q).each do |s|
35
- if s.text =~ /^\s*key[^a-z]*$/i && !s.next_element.nil? && s.next_element.name == "dl"
32
+ if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
36
33
  s.next_element["key"] = "true"
37
34
  s.previous_element << s.next_element.remove
38
35
  s.remove
@@ -91,16 +88,14 @@ module Asciidoctor
91
88
  def formula_cleanup_where1(x)
92
89
  q = "//formula/following-sibling::*[1][self::dl]"
93
90
  x.xpath(q).each do |s|
94
- if s["key"] == "true"
95
- s.previous_element << s.remove
96
- end
91
+ s["key"] == "true" and s.previous_element << s.remove
97
92
  end
98
93
  end
99
94
 
100
95
  def formula_cleanup_where2(x)
101
96
  q = "//formula/following-sibling::*[1][self::p]"
102
97
  x.xpath(q).each do |s|
103
- if s.text =~ /^\s*where[^a-z]*$/i && !s.next_element.nil? && s.next_element.name == "dl"
98
+ if s.text =~ /^\s*where[^a-z]*$/i && s&.next_element&.name == "dl"
104
99
  s.next_element["key"] = "true"
105
100
  s.previous_element << s.next_element.remove
106
101
  s.remove
@@ -111,9 +106,7 @@ module Asciidoctor
111
106
  def figure_dl_cleanup1(xmldoc)
112
107
  q = "//figure/following-sibling::*[self::dl]"
113
108
  xmldoc.xpath(q).each do |s|
114
- if s["key"] == "true"
115
- s.previous_element << s.remove
116
- end
109
+ s["key"] == "true" and s.previous_element << s.remove
117
110
  end
118
111
  end
119
112
 
@@ -121,8 +114,7 @@ module Asciidoctor
121
114
  def figure_dl_cleanup2(xmldoc)
122
115
  q = "//figure/following-sibling::*[self::p]"
123
116
  xmldoc.xpath(q).each do |s|
124
- if s.text =~ /^\s*key[^a-z]*$/i && !s.next_element.nil? &&
125
- s.next_element.name == "dl"
117
+ if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
126
118
  s.next_element["key"] = "true"
127
119
  s.previous_element << s.next_element.remove
128
120
  s.remove
@@ -133,8 +125,9 @@ module Asciidoctor
133
125
  # examples containing only figures become subfigures of figures
134
126
  def subfigure_cleanup(xmldoc)
135
127
  xmldoc.xpath("//example[figure]").each do |e|
136
- next unless e.elements.map { |m| m.name }.
137
- reject { |m| %w(name figure).include? m }.empty?
128
+ next unless e.elements.map { |m| m.name }.reject do |m|
129
+ %w(name figure).include? m
130
+ end.empty?
138
131
  e.name = "figure"
139
132
  end
140
133
  end
@@ -146,11 +139,10 @@ module Asciidoctor
146
139
  subfigure_cleanup(xmldoc)
147
140
  end
148
141
 
149
- ELEMS_ALLOW_NOTES =
150
- %w[p formula ul ol dl figure].freeze
142
+ ELEMS_ALLOW_NOTES = %w[p formula ul ol dl figure].freeze
151
143
 
152
144
  # if a note is at the end of a section, it is left alone
153
- # if a note is followed by a non-note block,
145
+ # if a note is followed by a non-note block,
154
146
  # it is moved inside its preceding block if it is not delimited
155
147
  # (so there was no way of making that block include the note)
156
148
  def note_cleanup(xmldoc)
@@ -161,8 +153,10 @@ module Asciidoctor
161
153
  prev = n.previous_element || next
162
154
  n.parent = prev if ELEMS_ALLOW_NOTES.include? prev.name
163
155
  end
164
- xmldoc.xpath("//note[@keep-separate]").each { |n| n.delete("keep-separate") }
165
- xmldoc.xpath("//termnote[@keep-separate]").each { |n| n.delete("keep-separate") }
156
+ xmldoc.xpath("//note[@keep-separate] | "\
157
+ "//termnote[@keep-separate]").each do |n|
158
+ n.delete("keep-separate")
159
+ end
166
160
  end
167
161
 
168
162
  def requirement_cleanup(x)
@@ -195,7 +189,8 @@ module Asciidoctor
195
189
  end
196
190
 
197
191
  def requirement_cleanup1(r)
198
- while d = r.at("./description[following-sibling::*[1][self::description]]")
192
+ while d = r.at("./description[following-sibling::*[1]"\
193
+ "[self::description]]")
199
194
  n = d.next.remove
200
195
  d << n.children
201
196
  end
@@ -203,6 +198,62 @@ module Asciidoctor
203
198
  d.replace("\n")
204
199
  end
205
200
  end
201
+
202
+ def svgmap_cleanup(xmldoc)
203
+ svgmap_moveattrs(xmldoc)
204
+ svgmap_populate(xmldoc)
205
+ Metanorma::Utils::svgmap_rewrite(xmldoc, @localdir)
206
+ end
207
+
208
+ def guid?(x)
209
+ /^_[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i.
210
+ match(x)
211
+ end
212
+
213
+ def svgmap_moveattrs(xmldoc)
214
+ xmldoc.xpath("//svgmap").each do |s|
215
+ f = s.at(".//figure") or next
216
+ if t = s.at("./name") and !f.at("./name")
217
+ f.children.first.previous = t.remove
218
+ end
219
+ if s["id"] && guid?(f["id"])
220
+ f["id"] = s["id"]
221
+ s.delete("id")
222
+ end
223
+ svgmap_moveattrs1(s, f)
224
+ end
225
+ end
226
+
227
+ def svgmap_moveattrs1(s, f)
228
+ %w(unnumbered number subsequence keep-with-next
229
+ keep-lines-together).each do |a|
230
+ next if f[a] || !s[a]
231
+ f[a] = s[a]
232
+ s.delete(a)
233
+ end
234
+ end
235
+
236
+ def svgmap_populate(xmldoc)
237
+ xmldoc.xpath("//svgmap").each do |s|
238
+ s1 = s.dup
239
+ s.children.remove
240
+ f = s1.at(".//figure") and s << f
241
+ s1.xpath(".//li").each do |li|
242
+ t = li&.at(".//eref | .//link | .//xref") or next
243
+ href = t.xpath("./following-sibling::node()")
244
+ href.empty? or
245
+ s << %[<target href="#{svgmap_target(href)}">#{t.to_xml}</target>]
246
+ end
247
+ end
248
+ end
249
+
250
+ def svgmap_target(nodeset)
251
+ nodeset.each do |n|
252
+ next unless n.name == "link"
253
+ n.children = n["target"]
254
+ end
255
+ nodeset.text.sub(/^[,; ]/, "").strip
256
+ end
206
257
  end
207
258
  end
208
259
  end