isodoc 0.4.0 → 0.4.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '0679d357232b392889d42dff130949b390726397'
4
- data.tar.gz: 1c5eb12db5f8c9b1cb29802a5a538bf66dbb8ea9
3
+ metadata.gz: 92ad102a0e0bc53916aaec5d7a4f23d71828f3d4
4
+ data.tar.gz: 7dbbd1969e0e1714c9074ac455a335939f634335
5
5
  SHA512:
6
- metadata.gz: e4fe6d944d1cd243db21b7faca859d7658f22fa8ae5076d31920ef3f979e5804e10a57da7073cbf54a2366fa9b4ac0261aa3289cb146905ebf9e74c7c13e6808
7
- data.tar.gz: 1d0fcdd12674101553cac3a3834a787179000933a22ce07365c6c820557d4c763c17060d2e9cde04039d86a18bc948f6a35bf5975896de500474a5ad6637f9a0
6
+ metadata.gz: 1b570dec93a170716366cf0d433d20dc614026ebe2224b02e659216fccf006b1680a1126e763a953f8d61c8154a0c9b133dfd989b05e25e675b5b3aa1f10d980
7
+ data.tar.gz: b9499b701f2eaca4a27d71ff85ff27926bd58e43a2b255dd429180eaf8b8c72704f8ba3768b2eb894f41128136f887308e6f2a29e89c000b7f02cf2dcb391e51
@@ -1,5 +1,10 @@
1
1
  = isodoc
2
2
 
3
+
4
+ image:https://img.shields.io/gem/v/isodoc.svg["Gem Version", link="https://rubygems.org/gems/isodoc"]
5
+ image:https://img.shields.io/travis/riboseinc/asciidoctor-iso/master.svg["Build Status", link="https://travis-ci.org/riboseinc/isodoc"]
6
+ image:https://codeclimate.com/github/riboseinc/isodoc/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/riboseinc/isodoc"]
7
+
3
8
  This Gem converts documents in the https://github.com/riboseinc/isodoc-models[ISODoc document model] into HTML and Microsoft Word.
4
9
 
5
10
  The Gem is a class called with a hash of file locations:
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency "thread_safe"
38
38
  spec.add_dependency "uuidtools"
39
39
  spec.add_dependency "html2doc"
40
+ spec.add_dependency "liquid"
40
41
 
41
42
  spec.add_development_dependency "bundler", "~> 1.15"
42
43
  spec.add_development_dependency "byebug", "~> 9.1"
@@ -20,6 +20,7 @@ require_relative "isodoc/blocks"
20
20
  require_relative "isodoc/lists"
21
21
  require_relative "isodoc/table"
22
22
  require_relative "isodoc/inline"
23
+ require_relative "isodoc/notes"
23
24
  require_relative "isodoc/xref_gen"
24
25
  require_relative "isodoc/html"
25
26
  require "pp"
@@ -50,9 +51,11 @@ module IsoDoc
50
51
  @sourcecode = false
51
52
  @anchors = {}
52
53
  @meta = {}
54
+ init_metadata
53
55
  @footnotes = []
54
56
  @comments = []
55
57
  @in_footnote = false
58
+ @in_comment = false
56
59
  @in_table = false
57
60
  @in_figure = false
58
61
  @seen_footnote = Set.new
@@ -64,6 +67,7 @@ module IsoDoc
64
67
  docxml.root.default_namespace = ""
65
68
  result = noko do |xml|
66
69
  xml.html do |html|
70
+ html.parent.add_namespace("epub", "http://www.idpf.org/2007/ops")
67
71
  html_header(html, docxml, filename, dir)
68
72
  make_body(html, docxml)
69
73
  end
@@ -80,6 +80,16 @@ module IsoDoc
80
80
  @in_figure = false
81
81
  end
82
82
 
83
+ def example_parse(node, out)
84
+ name = node.at(ns("./name"))
85
+ out.div **attr_code(id: node["id"], class: "figure") do |div|
86
+ node.children.each do |n|
87
+ parse(n, div) unless n.name == "name"
88
+ end
89
+ figure_name_parse(node, div, name) if name
90
+ end
91
+ end
92
+
83
93
  def sourcecode_name_parse(node, div, name)
84
94
  div.p **{ class: "FigureTitle", align: "center" } do |p|
85
95
  p.b do |b|
@@ -109,13 +119,18 @@ module IsoDoc
109
119
  def admonition_parse(node, out)
110
120
  name = node["type"]
111
121
  out.div **{ class: "Admonition" } do |t|
112
- t.p.b { |b| b << name.upcase } if name
122
+ t.title { |b| b << name.upcase } if name
113
123
  node.children.each do |n|
114
124
  parse(n, t)
115
125
  end
116
126
  end
117
127
  end
118
128
 
129
+ def formula_where(dl, out)
130
+ out.p { |p| p << "where" }
131
+ parse(dl, out)
132
+ end
133
+
119
134
  def formula_parse(node, out)
120
135
  dl = node.at(ns("./dl"))
121
136
  out.div **attr_code(id: node["id"], class: "formula") do |div|
@@ -123,17 +138,15 @@ module IsoDoc
123
138
  insert_tab(div, 1)
124
139
  div << "(#{get_anchors()[node['id']][:label]})"
125
140
  end
126
- if dl
127
- out.p { |p| p << "where" }
128
- parse(dl, out)
129
- end
141
+ formula_where(dl, out) if dl
130
142
  end
131
143
 
132
144
  def para_attrs(node)
133
145
  classtype = nil
134
146
  classtype = "Note" if @note
135
- classtype = "MsoFootnoteText" if in_footnote
136
- attrs = { class: classtype }
147
+ # classtype = "MsoFootnoteText" if in_footnote
148
+ classtype = "MsoCommentText" if in_comment
149
+ attrs = { class: classtype, id: node["id"] }
137
150
  unless node["align"].nil?
138
151
  attrs[:align] = node["align"] unless node["align"] == "justify"
139
152
  attrs[:style] = "text-align:#{node["align"]}"
@@ -152,15 +165,18 @@ module IsoDoc
152
165
  end
153
166
 
154
167
  def quote_attribution(node, out)
155
- author = node.at(ns("./author/fullname/"))
168
+ author = node.at(ns("./author"))
156
169
  source = node.at(ns("./source"))
157
- # TODO implement
170
+ out.p **{ class: "QuoteAttribution" } do |p|
171
+ p << "&mdash; #{author.text}, " if author
172
+ eref_parse(source, p)
173
+ end
158
174
  end
159
175
 
160
176
  def quote_parse(node, out)
161
177
  attrs = para_attrs(node)
162
178
  attrs[:class] = "Quote"
163
- out.p **attr_code(attrs) do |p|
179
+ out.div **attr_code(attrs) do |p|
164
180
  node.children.each do
165
181
  |n| parse(n, p) unless ["author", "source"].include? n.name
166
182
  end
@@ -11,9 +11,18 @@ module IsoDoc
11
11
  inline_header_cleanup(docxml)
12
12
  figure_cleanup(docxml)
13
13
  table_cleanup(docxml)
14
+ admonition_cleanup(docxml)
14
15
  docxml
15
16
  end
16
17
 
18
+ def admonition_cleanup(docxml)
19
+ docxml.xpath("//div[@class = 'Admonition'][title]").each do |d|
20
+ title = d.at("./title")
21
+ n = title.next_element
22
+ n&.children&.first&.add_previous_sibling(title.text + "&mdash;")
23
+ end
24
+ end
25
+
17
26
  def figure_get_or_make_dl(t)
18
27
  dl = t.at(".//dl")
19
28
  if dl.nil?
@@ -29,8 +38,8 @@ module IsoDoc
29
38
 
30
39
  def figure_aside_process(f, aside, key)
31
40
  # get rid of footnote link, it is in diagram
32
- f.at("./a[@class='zzFootnote']").remove
33
- fnref = f.at(".//a[@class='zzFootnote']")
41
+ f.at("./a[@class='TableFootnoteRef']").remove
42
+ fnref = f.at(".//a[@class='TableFootnoteRef']")
34
43
  dt = key.add_child("<dt></dt>").first
35
44
  dd = key.add_child("<dd></dd>").first
36
45
  fnref.parent = dt
@@ -64,26 +73,15 @@ module IsoDoc
64
73
  end
65
74
  end
66
75
 
67
- def comment_cleanup(docxml)
68
- docxml.xpath('//div/span[@style="MsoCommentReference"]').
69
- each do |x|
70
- prev = x.previous_element
71
- x.parent = prev unless prev.nil?
72
- end
73
- docxml
74
- end
75
-
76
76
  def footnote_cleanup(docxml)
77
- docxml.xpath('//div[@style="mso-element:footnote"]/a').
78
- each do |x|
79
- n = x.next_element
80
- n&.children&.first&.add_previous_sibling(x.remove)
77
+ docxml.xpath('//a[@epub:type = "footnote"]/sup').each_with_index do |x, i|
78
+ x.content = (i + 1).to_s
81
79
  end
82
80
  docxml
83
81
  end
84
82
 
85
83
  def merge_fnref_into_fn_text(a)
86
- fn = a.at('.//a[@class="zzFootnote"]')
84
+ fn = a.at('.//a[@class="TableFootnoteRef"]')
87
85
  n = fn.next_element
88
86
  n&.children&.first&.add_previous_sibling(fn.remove)
89
87
  end
@@ -113,7 +111,6 @@ module IsoDoc
113
111
  t.add_child("<tfoot></tfoot>")
114
112
  tfoot = t.at(".//tfoot")
115
113
  else
116
- # nuke its bottom border
117
114
  tfoot.xpath(".//td | .//th").each { |td| remove_bottom_border(td) }
118
115
  end
119
116
  tfoot
@@ -135,10 +132,14 @@ module IsoDoc
135
132
  docxml.xpath("//table[div[@class = 'Note']]").each do |t|
136
133
  tfoot = table_get_or_make_tfoot(t)
137
134
  insert_here = new_fullcolspan_row(t, tfoot)
138
- t.xpath("div[@class = 'Note']").each do |d|
139
- d.parent = insert_here
140
- end
135
+ t.xpath("div[@class = 'Note']").each { |d| d.parent = insert_here }
141
136
  end
137
+ # preempt html2doc putting MsoNormal there
138
+ docxml.xpath("//p[not(self::*[@class])]"\
139
+ "[ancestor::*[@class = 'Note']]").each do |p|
140
+ p["class"] = "Note"
141
+ end
142
+
142
143
  end
143
144
 
144
145
  def table_cleanup(docxml)
@@ -2,13 +2,18 @@ module IsoDoc
2
2
  class Convert
3
3
 
4
4
  def toHTML(result, filename)
5
- result = htmlPreface(htmlstyle(Nokogiri::HTML(result))).to_xml
6
- result = populate_template(result)
5
+ # result = html_cleanup(Nokogiri::HTML(result)).to_xml
6
+ result = from_xhtml(html_cleanup(to_xhtml(result)))
7
+ result = populate_template(result, :html)
7
8
  File.open("#{filename}.html", "w") do |f|
8
9
  f.write(result)
9
10
  end
10
11
  end
11
12
 
13
+ def html_cleanup(x)
14
+ footnote_backlinks(move_images(html_footnote_filter(htmlPreface(htmlstyle(x)))))
15
+ end
16
+
12
17
  def htmlPreface(docxml)
13
18
  cover = Nokogiri::HTML(File.read(@htmlcoverpage, encoding: "UTF-8"))
14
19
  d = docxml.at('//div[@class="WordSection1"]')
@@ -39,5 +44,56 @@ module IsoDoc
39
44
  end
40
45
  docxml
41
46
  end
47
+
48
+ def update_footnote_filter(docxml, x, i, seen)
49
+ fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || return
50
+ if seen[fn.text]
51
+ x.at("./sup").content = seen[fn.text][:num].to_s
52
+ fn.remove unless x["href"] == seen[fn.text][:href]
53
+ x["href"] = seen[fn.text][:href]
54
+ else
55
+ seen[fn.text] = { num: i, href: x["href"] }
56
+ x.at("./sup").content = i.to_s
57
+ i += 1
58
+ end
59
+ [i, seen]
60
+ end
61
+
62
+ def html_footnote_filter(docxml)
63
+ seen = {}
64
+ i = 1
65
+ docxml.xpath('//a[@epub:type = "footnote"]').each do |x|
66
+ i, seen = update_footnote_filter(docxml, x, i, seen)
67
+ end
68
+ docxml
69
+ end
70
+
71
+ def footnote_backlinks(docxml)
72
+ seen = {}
73
+ docxml.xpath('//a[@epub:type = "footnote"]').each_with_index do |x, i|
74
+ next if seen[x["href"]]
75
+ seen[x["href"]] = true
76
+ sup = x.at("./sup").text
77
+ fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
78
+ x["id"] || x["id"] = "_footnote#{i + 1}"
79
+ fn.elements.first.children.first.
80
+ add_previous_sibling("<a href='##{x['id']}'>#{sup}) </a>")
81
+ end
82
+ docxml
83
+ end
84
+
85
+ def move_images(docxml)
86
+ system "rm -r _images; mkdir _images"
87
+ docxml.xpath("//*[local-name() = 'img']").each do |i|
88
+ matched = /\.(?<suffix>\S+)$/.match i["src"]
89
+ uuid = UUIDTools::UUID.random_create.to_s
90
+ new_full_filename = File.join("_images", "#{uuid}.#{matched[:suffix]}")
91
+ # presupposes that the image source is local
92
+ system "cp #{i['src']} #{new_full_filename}"
93
+ i["src"] = new_full_filename
94
+ i["width"], i["height"] = Html2Doc.image_resize(i, 800, 1200)
95
+ end
96
+ docxml
97
+ end
42
98
  end
43
99
  end
@@ -2,11 +2,6 @@ require "uuidtools"
2
2
 
3
3
  module IsoDoc
4
4
  class Convert
5
-
6
- def in_footnote
7
- @in_footnote
8
- end
9
-
10
5
  def section_break(body)
11
6
  body.br **{ clear: "all", class: "section" }
12
7
  end
@@ -30,35 +25,46 @@ module IsoDoc
30
25
 
31
26
  def get_linkend(node)
32
27
  linkend = node["target"] || node["citeas"]
33
- if get_anchors().has_key? node["target"]
28
+ get_anchors().has_key?(node["target"]) &&
34
29
  linkend = get_anchors()[node["target"]][:xref]
35
- end
36
30
  if node["citeas"].nil? && get_anchors().has_key?(node["bibitemid"])
37
31
  linkend = get_anchors()[node["bibitemid"]][:xref]
38
32
  end
33
+ linkend += eref_localities(node.xpath(ns("./locality")))
39
34
  text = node.children.select { |c| c.text? && !c.text.empty? }
40
35
  linkend = text.join(" ") unless text.nil? || text.empty?
41
36
  # so not <origin bibitemid="ISO7301" citeas="ISO 7301">
42
- # <locality type="section">3.1</locality></origin>
37
+ # <locality type="section"><reference>3.1</reference></locality></origin>
43
38
  linkend
44
39
  end
45
40
 
46
41
  def xref_parse(node, out)
47
42
  linkend = get_linkend(node)
48
- out.a **{ "href": node["target"] } { |l| l << linkend }
43
+ out.a **{ "href": "#" + node["target"] } { |l| l << linkend }
44
+ end
45
+
46
+ def eref_localities(r)
47
+ ret = ""
48
+ r.each do |r|
49
+ if r["type"] == "whole"
50
+ ret += ", Whole of text"
51
+ else
52
+ ret += ", #{r["type"].capitalize}"
53
+ ref = r.at(ns("./reference"))
54
+ ret += " #{ref.text}" if ref
55
+ end
56
+ end
57
+ ret
49
58
  end
50
59
 
51
60
  def eref_parse(node, out)
52
61
  linkend = get_linkend(node)
53
- section = node.at(ns("./locality"))
54
- section.nil? or
55
- linkend += ", #{section["type"].capitalize} #{section.text}"
56
62
  if node["type"] == "footnote"
57
63
  out.sup do |s|
58
- s.a **{ "href": node["bibitemid"] } { |l| l << linkend }
64
+ s.a **{ "href": "#" + node["bibitemid"] } { |l| l << linkend }
59
65
  end
60
66
  else
61
- out.a **{ "href": node["bibitemid"] } { |l| l << linkend }
67
+ out.a **{ "href": "#" + node["bibitemid"] } { |l| l << linkend }
62
68
  end
63
69
  end
64
70
 
@@ -68,144 +74,21 @@ module IsoDoc
68
74
  else
69
75
  node.text
70
76
  end
71
- out.span **{ class: "stem" } do |span|
72
- span.parent.add_child ooml
73
- end
74
- end
75
-
76
- def pagebreak_parse(node, out)
77
- attrs = { clear: all, class: "pagebreak" }
78
- out.br **attrs
79
- end
80
-
81
- def error_parse(node, out)
82
- text = node.to_xml.gsub(/</, "&lt;").gsub(/>/, "&gt;")
83
- out.para do |p|
84
- p.b **{ role: "strong" } { |e| e << text }
85
- end
86
- end
87
-
88
- def footnotes(div)
89
- return if @footnotes.empty?
90
- div.div **{ style: "mso-element:footnote-list" } do |div1|
91
- @footnotes.each do |fn|
92
- div1.parent << fn
93
- end
94
- end
95
- end
96
-
97
- def footnote_attributes(fn, is_footnote)
98
- style = nil
99
- style = "mso-footnote-id:ftn#{fn}" if is_footnote
100
- { style: style,
101
- href: "#_ftn#{fn}",
102
- name: "_ftnref#{fn}",
103
- title: "",
104
- class: "zzFootnote" }
105
- end
106
-
107
- def make_footnote_link(a, fnid, fnref, is_footnote)
108
- a.span **{ class: "MsoFootnoteReference" } do |s|
109
- if is_footnote
110
- s.span **{ style: "mso-special-character:footnote" }
111
- else
112
- s.a **{href: fnid} { a << fnref }
113
- end
114
- end
115
- end
116
-
117
- def make_footnote_target(a, fnid, fnref, is_footnote)
118
- a.span **{ class: "MsoFootnoteReference" } do |s|
119
- if is_footnote
120
- s.span **{ style: "mso-special-character:footnote" }
121
- else
122
- s.a **{name: fnid} { a << fnref }
123
- end
124
- end
125
- end
126
-
127
- def make_footnote_text(node, fnid, fnref, is_footnote)
128
- attrs = { style: "mso-element:footnote", id: "ftn#{fnid}" }
129
- attrs[:style] = nil unless is_footnote
130
- noko do |xml|
131
- xml.div **attr_code(attrs) do |div|
132
- div.a **footnote_attributes(fnid, is_footnote) do |a|
133
- make_footnote_target(a, fnid, fnref, is_footnote)
134
- insert_tab(a, 1) unless is_footnote
135
- end
136
- node.children.each { |n| parse(n, div) }
137
- end
138
- end.join("\n")
139
- end
140
-
141
- def get_table_ancestor_id(node)
142
- table = node.ancestors("table") || node.ancestors("figure")
143
- return UUIDTools::UUID.random_create.to_s if table.empty?
144
- table.last["id"]
145
- end
146
-
147
- def table_footnote_parse(node, out)
148
- fn = node["reference"]
149
- tid = get_table_ancestor_id(node)
150
- out.a **footnote_attributes(tid + fn, false) do |a|
151
- make_footnote_link(a, tid + fn, fn, false)
152
- end
153
- # do not output footnote text if we have already seen it for this table
154
- return if @seen_footnote.include?(tid + fn)
155
- @in_footnote = true
156
- out.aside { |a| a << make_footnote_text(node, tid + fn, fn, false) }
157
- @in_footnote = false
158
- @seen_footnote << (tid + fn)
159
- end
160
-
161
- def footnote_parse(node, out)
162
- return table_footnote_parse(node, out) if @in_table || @in_figure
163
- fn = node["reference"]
164
- out.a **footnote_attributes(fn, true) do |a|
165
- make_footnote_link(a, nil, nil, true)
166
- end
167
- @in_footnote = true
168
- @footnotes << make_footnote_text(node, fn, fn, true)
169
- @in_footnote = false
170
- end
171
-
172
- def comments(div)
173
- return if @comments.empty?
174
- div.div **{ style: "mso-element:comment-list" } do |div1|
175
- @comments.each do |fn|
176
- div1.parent << fn
177
- end
178
- end
179
- end
180
-
181
- def make_comment_link(out, fn, date, from)
182
- out.span **{ style: "MsoCommentReference" } do |s1|
183
- s1.span **{ lang: "EN-GB", style: "font-size:9.0pt"} do |s2|
184
- s2.a **{ style: "mso-comment-reference:SMC_#{fn};"\
185
- "mso-comment-date:#{date}" } if from
186
- s2.span **{ style: "mso-special-character:comment" } do |s|
187
- s << "&nbsp;"
188
- end
189
- end
190
- end
77
+ out.span **{ class: "stem" } do |span|
78
+ span.parent.add_child ooml
191
79
  end
80
+ end
192
81
 
193
- def make_comment_text(node, fn)
194
- noko do |xml|
195
- xml.div **{ style: "mso-element:comment" } do |div|
196
- div.span **{ style: %{mso-comment-author:"#{node["reviewer"]}"} }
197
- div.p **{ class: "MsoCommentText" } do |p|
198
- make_comment_link(p, fn, node["date"], false)
199
- node.children.each { |n| parse(n, p) }
200
- end
201
- end
202
- end.join("\n")
203
- end
82
+ def pagebreak_parse(node, out)
83
+ attrs = { clear: all, class: "pagebreak" }
84
+ out.br **attrs
85
+ end
204
86
 
205
- def review_note_parse(node, out)
206
- fn = @comments.length + 1
207
- make_comment_link(out, fn, node["date"], true)
208
- @comments << make_comment_text(node, fn)
87
+ def error_parse(node, out)
88
+ text = node.to_xml.gsub(/</, "&lt;").gsub(/>/, "&gt;")
89
+ out.para do |p|
90
+ p.b **{ role: "strong" } { |e| e << text }
209
91
  end
92
+ end
210
93
  end
211
94
  end
@@ -22,8 +22,7 @@ module IsoDoc
22
22
 
23
23
  def make_body1(body, docxml)
24
24
  body.div **{ class: "WordSection1" } do |div1|
25
- # placeholder
26
- div1.p { |p| p << "&nbsp;" }
25
+ div1.p { |p| p << "&nbsp;" } # placeholder
27
26
  end
28
27
  section_break(body)
29
28
  end
@@ -31,6 +30,7 @@ module IsoDoc
31
30
  def make_body2(body, docxml)
32
31
  body.div **{ class: "WordSection2" } do |div2|
33
32
  info docxml, div2
33
+ div2.p { |p| p << "&nbsp;" } # placeholder
34
34
  end
35
35
  section_break(body)
36
36
  end
@@ -49,6 +49,7 @@ module IsoDoc
49
49
  subtitle isoxml, out
50
50
  id isoxml, out
51
51
  author isoxml, out
52
+ bibdate isoxml, out
52
53
  version isoxml, out
53
54
  foreword isoxml, out
54
55
  introduction isoxml, out
@@ -77,11 +78,16 @@ module IsoDoc
77
78
  end
78
79
 
79
80
  def text_parse(node, out)
81
+ return if node.nil? || node.text.nil?
80
82
  text = node.text
81
- text.gsub!("\n", "<br/>").gsub!(" ", "&nbsp;") if in_sourcecode
83
+ text = text.gsub("\n", "<br/>").gsub(" ", "&nbsp;") if in_sourcecode
82
84
  out << text
83
85
  end
84
86
 
87
+ def bookmark_parse(node, out)
88
+ out.a **attr_code(id: node["id"])
89
+ end
90
+
85
91
  def parse(node, out)
86
92
  if node.text?
87
93
  text_parse(node, out)
@@ -96,6 +102,7 @@ module IsoDoc
96
102
  when "smallcap" then smallcap_parse(node, out)
97
103
  when "br" then out.br
98
104
  when "hr" then out.hr
105
+ when "bookmark" then bookmark_parse(node, out)
99
106
  when "pagebreak" then pagebreak_parse(node, out)
100
107
  when "callout" then callout_parse(node, out)
101
108
  when "stem" then stem_parse(node, out)
@@ -119,6 +126,7 @@ module IsoDoc
119
126
  when "formula" then formula_parse(node, out)
120
127
  when "table" then table_parse(node, out)
121
128
  when "figure" then figure_parse(node, out)
129
+ when "example" then example_parse(node, out)
122
130
  when "image" then image_parse(node["src"], out, nil)
123
131
  when "sourcecode" then sourcecode_parse(node, out)
124
132
  when "annotation" then annotation_parse(node, out)
@@ -3,6 +3,19 @@ require "htmlentities"
3
3
  module IsoDoc
4
4
  class Convert
5
5
 
6
+ def init_metadata
7
+ @meta = {
8
+ tc: "XXXX",
9
+ sc: "XXXX",
10
+ wg: "XXXX",
11
+ editorialgroup: [],
12
+ secretariat: "XXXX",
13
+ }
14
+ %w{published accessed created activated obsoleted}.each do |w|
15
+ @meta["#{w}date".to_sym] = "XXX"
16
+ end
17
+ end
18
+
6
19
  def get_metadata
7
20
  @meta
8
21
  end
@@ -11,22 +24,64 @@ module IsoDoc
11
24
  @meta[key] = value
12
25
  end
13
26
 
14
- def author(isoxml, _out)
15
- # tc = isoxml.at(ns("//technical-committee"))
16
- tc_num = isoxml.at(ns("//technical-committee/@number"))
17
- # sc = isoxml.at(ns("//subcommittee"))
18
- sc_num = isoxml.at(ns("//subcommittee/@number"))
19
- # wg = isoxml.at(ns("//workgroup"))
20
- wg_num = isoxml.at(ns("//workgroup/@number"))
21
- secretariat = isoxml.at(ns("//secretariat"))
22
- set_metadata(:tc, "XXXX")
23
- set_metadata(:sc, "XXXX")
24
- set_metadata(:wg, "XXXX")
25
- set_metadata(:secretariat, "XXXX")
26
- set_metadata(:tc, tc_num.text) if tc_num
27
- set_metadata(:sc, sc_num.text) if sc_num
28
- set_metadata(:wg, wg_num.text) if wg_num
29
- set_metadata(:secretariat, secretariat.text) if secretariat
27
+ def author(xml, _out)
28
+ tc(xml)
29
+ sc(xml)
30
+ wg(xml)
31
+ secretariat(xml)
32
+ agency(xml)
33
+ end
34
+
35
+ def tc(xml)
36
+ tc_num = xml.at(ns("//editorialgroup/technical-committee/@number"))
37
+ tc_type = xml.at(ns("//editorialgroup/technical-committee/@type"))&.
38
+ text || "TC"
39
+ if tc_num
40
+ tcid = "#{tc_type} #{tc_num.text}"
41
+ set_metadata(:tc, tcid)
42
+ set_metadata(:editorialgroup, get_metadata[:editorialgroup] << tcid)
43
+ end
44
+ end
45
+
46
+ def sc(xml)
47
+ sc_num = xml.at(ns("//editorialgroup/subcommittee/@number"))
48
+ sc_type = xml.at(ns("//editorialgroup/subcommittee/@type"))&.text || "SC"
49
+ if sc_num
50
+ scid = "#{sc_type} #{sc_num.text}"
51
+ set_metadata(:sc, scid)
52
+ set_metadata(:editorialgroup, get_metadata[:editorialgroup] << scid)
53
+ end
54
+ end
55
+
56
+ def wg(xml)
57
+ wg_num = xml.at(ns("//editorialgroup/workgroup/@number"))
58
+ wg_type = xml.at(ns("//editorialgroup/workgroup/@type"))&.text || "WG"
59
+ if wg_num
60
+ wgid = "#{wg_type} #{wg_num.text}"
61
+ set_metadata(:wg, wgid)
62
+ set_metadata(:editorialgroup, get_metadata[:editorialgroup] << wgid)
63
+ end
64
+ end
65
+
66
+ def secretariat(xml)
67
+ sec = xml.at(ns("//editorialgroup/secretariat"))
68
+ set_metadata(:secretariat, sec.text) if sec
69
+ end
70
+
71
+ def bibdate(isoxml, _out)
72
+ isoxml.xpath(ns("//bibdata/date")).each do |d|
73
+ set_metadata("#{d["type"]}date".to_sym, d.text)
74
+ end
75
+ end
76
+
77
+ def agency(xml)
78
+ agency = ""
79
+ pub = xml.xpath(ns("//bibdata/contributor"\
80
+ "[xmlns:role/@type = 'publisher']/"\
81
+ "organization/name")).each do |org|
82
+ agency = org.text == "ISO" ? "ISO/#{agency}" : "#{agency}#{org.text}/"
83
+ end
84
+ set_metadata(:agency, agency.sub(%r{/$}, ""))
30
85
  end
31
86
 
32
87
  def id(isoxml, _out)
@@ -66,33 +121,41 @@ module IsoDoc
66
121
  set_metadata(:draftinfo, draftinfo(draft, revdate))
67
122
  end
68
123
 
124
+ def part_label(lang)
125
+ case lang
126
+ when "en" then "Part"
127
+ when "fr" then "Part"
128
+ end
129
+ end
69
130
 
70
- def compose_title(main, intro, part, partnumber)
131
+ def compose_title(main, intro, part, partnum, lang)
71
132
  c = HTMLEntities.new
72
133
  main = c.encode(main.text, :hexadecimal)
73
134
  intro &&
74
135
  main = "#{c.encode(intro.text, :hexadecimal)}&nbsp;&mdash; #{main}"
75
- part &&
76
- main = "#{main}&nbsp;&mdash; Part&nbsp;#{partnumber}: "\
77
- "#{c.encode(part.text, :hexadecimal)}"
136
+ if part
137
+ suffix = c.encode(part.text, :hexadecimal)
138
+ suffix = "#{part_label(lang)}&nbsp;#{partnum}: " + suffix if partnum
139
+ main = "#{main}&nbsp;&mdash; #{suffix}"
140
+ end
78
141
  main
79
142
  end
80
143
 
81
144
  def title(isoxml, _out)
82
- intro = isoxml.at(ns("//title[@language='en']/title-intro"))
83
- main = isoxml.at(ns("//title[@language='en']/title-main"))
84
- part = isoxml.at(ns("//title[@language='en']/title-part"))
85
- partnumber = isoxml.at(ns("//id/project-number/@part"))
86
- main = compose_title(main, intro, part, partnumber)
145
+ intro = isoxml.at(ns("//title-intro[@language='en']"))
146
+ main = isoxml.at(ns("//title-main[@language='en']"))
147
+ part = isoxml.at(ns("//title-part[@language='en']"))
148
+ partnumber = isoxml.at(ns("//project-number/@part"))
149
+ main = compose_title(main, intro, part, partnumber, "en")
87
150
  set_metadata(:doctitle, main)
88
151
  end
89
152
 
90
153
  def subtitle(isoxml, _out)
91
- intro = isoxml.at(ns("//title[@language='fr']/title-intro"))
92
- main = isoxml.at(ns("//title[@language='fr']/title-main"))
93
- part = isoxml.at(ns("//title[@language='fr']/title-part"))
94
- partnumber = isoxml.at(ns("//id/project-number/@part"))
95
- main = compose_title(main, intro, part, partnumber)
154
+ intro = isoxml.at(ns("//title-intro[@language='fr']"))
155
+ main = isoxml.at(ns("//title-main[@language='fr']"))
156
+ part = isoxml.at(ns("//title-part[@language='fr']"))
157
+ partnumber = isoxml.at(ns("//project-number/@part"))
158
+ main = compose_title(main, intro, part, partnumber, "fr")
96
159
  set_metadata(:docsubtitle, main)
97
160
  end
98
161
  end
@@ -0,0 +1,218 @@
1
+ require "uuidtools"
2
+
3
+ module IsoDoc
4
+ class Convert
5
+ def in_footnote
6
+ @in_footnote
7
+ end
8
+
9
+ def in_comment
10
+ @in_comment
11
+ end
12
+
13
+ def footnotes(div)
14
+ return if @footnotes.empty?
15
+ @footnotes.each { |fn| div.parent << fn }
16
+ end
17
+
18
+ def make_table_footnote_link(out, fnid, fnref)
19
+ attrs = { href: "##{fnid}", class: "TableFootnoteRef" }
20
+ out.a **attrs do |a|
21
+ a << fnref
22
+ end
23
+ end
24
+
25
+ def make_table_footnote_target(out, fnid, fnref)
26
+ attrs = { id: fnid, class: "TableFootnoteRef" }
27
+ out.a **attrs do |a|
28
+ a << fnref
29
+ insert_tab(a, 1)
30
+ end
31
+ end
32
+
33
+ def make_table_footnote_text(node, fnid, fnref)
34
+ attrs = { id: "ftn#{fnid}" }
35
+ noko do |xml|
36
+ xml.div **attr_code(attrs) do |div|
37
+ make_table_footnote_target(div, fnid, fnref)
38
+ node.children.each { |n| parse(n, div) }
39
+ end
40
+ end.join("\n")
41
+ end
42
+
43
+ def make_generic_footnote_text(node, fnid, fn_ref)
44
+ noko do |xml|
45
+ xml.aside **{ id: "ftn#{fnid}" } do |div|
46
+ node.children.each { |n| parse(n, div) }
47
+ end
48
+ end.join("\n")
49
+ end
50
+
51
+ def get_table_ancestor_id(node)
52
+ table = node.ancestors("table") || node.ancestors("figure")
53
+ return UUIDTools::UUID.random_create.to_s if table.empty?
54
+ table.last["id"]
55
+ end
56
+
57
+ def table_footnote_parse(node, out)
58
+ fn = node["reference"]
59
+ tid = get_table_ancestor_id(node)
60
+ make_table_footnote_link(out, tid + fn, fn)
61
+ # do not output footnote text if we have already seen it for this table
62
+ return if @seen_footnote.include?(tid + fn)
63
+ @in_footnote = true
64
+ out.aside { |a| a << make_table_footnote_text(node, tid + fn, fn) }
65
+ @in_footnote = false
66
+ @seen_footnote << (tid + fn)
67
+ end
68
+
69
+ def footnote_parse(node, out)
70
+ return table_footnote_parse(node, out) if @in_table || @in_figure
71
+ fn = node["reference"]
72
+ out.a **{"epub:type": "footnote", href: "#ftn#{fn}" } do |a|
73
+ a.sup { |sup| sup << fn }
74
+ end
75
+ return if @seen_footnote.include?(fn)
76
+ @in_footnote = true
77
+ @footnotes << make_generic_footnote_text(node, fn, fn)
78
+ @in_footnote = false
79
+ @seen_footnote << fn
80
+ end
81
+
82
+ def comments(div)
83
+ return if @comments.empty?
84
+ div.div **{ style: "mso-element:comment-list" } do |div1|
85
+ @comments.each { |fn| div1.parent << fn }
86
+ end
87
+ end
88
+
89
+ def review_note_parse(node, out)
90
+ fn = @comments.length + 1
91
+ make_comment_link(out, fn, node)
92
+ @in_comment = true
93
+ @comments << make_comment_text(node, fn)
94
+ @in_comment = false
95
+ end
96
+
97
+ # add in from and to links to move the comment into place
98
+ def make_comment_link(out, fn, node)
99
+ out.span **{ style: "MsoCommentReference", target: fn,
100
+ class: "commentLink", from: node['from'],
101
+ to: node['to']} do |s1|
102
+ s1.span **{ lang: "EN-GB", style: "font-size:9.0pt"} do |s2|
103
+ s2.a **{ style: "mso-comment-reference:SMC_#{fn};"\
104
+ "mso-comment-date:#{node['date']}"}
105
+ s2.span **{ style: "mso-special-character:comment",
106
+ target: fn } # do |s|
107
+ #s << "&nbsp;"
108
+ #end
109
+ end
110
+ end
111
+ end
112
+
113
+ def make_comment_target(out)
114
+ out.span **{ style: "MsoCommentReference" } do |s1|
115
+ s1.span **{ lang: "EN-GB", style: "font-size:9.0pt"} do |s2|
116
+ s2.span **{ style: "mso-special-character:comment" } # do |s|
117
+ # s << "&nbsp;"
118
+ # end
119
+ end
120
+ end
121
+ end
122
+
123
+ def make_comment_text(node, fn)
124
+ noko do |xml|
125
+ xml.div **{ style: "mso-element:comment", id: fn } do |div|
126
+ div.span **{ style: %{mso-comment-author:"#{node["reviewer"]}"} }
127
+ make_comment_target(div)
128
+ node.children.each { |n| parse(n, div) }
129
+ end
130
+ end.join("\n")
131
+ end
132
+
133
+ def comment_cleanup(docxml)
134
+ move_comment_link_to_from(docxml)
135
+ reorder_comments_by_comment_link(docxml)
136
+ embed_comment_in_comment_list(docxml)
137
+ end
138
+
139
+ COMMENT_IN_COMMENT_LIST =
140
+ '//div[@style="mso-element:comment-list"]//'\
141
+ 'span[@style="MsoCommentReference"]'
142
+
143
+ def embed_comment_in_comment_list(docxml)
144
+ docxml.xpath(COMMENT_IN_COMMENT_LIST).each do |x|
145
+ n = x.next_element
146
+ n&.children&.first&.add_previous_sibling(x.remove)
147
+ end
148
+ docxml
149
+ end
150
+
151
+ def move_comment_link_to_from1(x, fromlink, docxml)
152
+ x.remove
153
+ link = x.at(".//a")
154
+ fromlink.replace(x)
155
+ link.children = fromlink
156
+ end
157
+
158
+ def comment_attributes(docxml, x)
159
+ fromlink = docxml.at("//*[@id='#{x["from"]}']")
160
+ return(nil) if fromlink.nil?
161
+ tolink = docxml.at("//*[@id='#{x["to"]}']") || fromlink
162
+ target = docxml.at("//*[@id='#{x["target"]}']")
163
+ { from: fromlink, to: tolink, target: target }
164
+ end
165
+
166
+ def wrap_comment_cont(from, target)
167
+ s = from.replace("<span style='mso-comment-continuation:#{target}'>")
168
+ s.first.children = from
169
+ end
170
+
171
+ def skip_comment_wrap(from)
172
+ from["style"] != "mso-special-character:comment"
173
+ end
174
+
175
+ def insert_comment_cont(from, to, target, docxml)
176
+ # includes_to = from.at(".//*[@id='#{to}']")
177
+ while !from.nil? && from["id"] != to
178
+ following = from.xpath("./following::*")
179
+ (from = following.shift) && incl_to = from.at(".//*[@id='#{to}']")
180
+ while !incl_to.nil? && !from.nil? && skip_comment_wrap(from)
181
+ (from = following.shift) && incl_to = from.at(".//*[@id='#{to}']")
182
+ end
183
+ wrap_comment_cont(from, target) if !from.nil?
184
+ end
185
+ end
186
+
187
+ def move_comment_link_to_from(docxml)
188
+ docxml.xpath('//span[@style="MsoCommentReference"][@from]').each do |x|
189
+ attrs = comment_attributes(docxml, x) || next
190
+ move_comment_link_to_from1(x, attrs[:from], docxml)
191
+ insert_comment_cont(attrs[:from], x["to"], x["target"], docxml)
192
+ end
193
+ end
194
+
195
+ def get_comments_from_text(docxml, link_order)
196
+ comments = []
197
+ docxml.xpath("//div[@style='mso-element:comment']").each do |c|
198
+ next unless c["id"] && !link_order[c["id"]].nil?
199
+ comments << { text: c.remove.to_s, id: c["id"] }
200
+ end
201
+ comments.sort! { |a, b| link_order[a[:id]] <=> link_order[b[:id]] }
202
+ comments
203
+ end
204
+
205
+ COMMENT_TARGET_XREFS =
206
+ "//span[@style='mso-special-character:comment']/@target"
207
+
208
+ def reorder_comments_by_comment_link(docxml)
209
+ link_order = {}
210
+ docxml.xpath(COMMENT_TARGET_XREFS).each_with_index do |target, i|
211
+ link_order[target.value] = i
212
+ end
213
+ comments = get_comments_from_text(docxml, link_order)
214
+ list = docxml.at("//*[@style='mso-element:comment-list']") or return
215
+ list.children = comments.map { |c| c[:text] }.join("\n")
216
+ end
217
+ end
218
+ end
@@ -1,6 +1,7 @@
1
1
  require "html2doc"
2
2
  require "htmlentities"
3
3
  require "nokogiri"
4
+ require "liquid"
4
5
  require "pp"
5
6
 
6
7
  module IsoDoc
@@ -15,7 +16,7 @@ module IsoDoc
15
16
 
16
17
  def toWord(result, filename, dir)
17
18
  result = from_xhtml(wordCleanup(to_xhtml(result)))
18
- result = populate_template(result)
19
+ result = populate_template(result, :word)
19
20
  Html2Doc.process(result, filename, @wordstylesheet, "header.html",
20
21
  dir, ['`', '`'])
21
22
  end
@@ -45,33 +46,24 @@ module IsoDoc
45
46
  d.children.first.add_previous_sibling intro.to_xml(encoding: 'US-ASCII')
46
47
  end
47
48
 
48
- def populate_template(docxml)
49
+ def populate_template(docxml, _format)
49
50
  meta = get_metadata
50
51
  docxml.
51
- gsub(/DOCYEAR/, meta[:docyear]).
52
- gsub(/DOCNUMBER/, meta[:docnumber]).
53
- gsub(/TCNUM/, meta[:tc]).
54
- gsub(/SCNUM/, meta[:sc]).
55
- gsub(/WGNUM/, meta[:wg]).
56
- gsub(/DOCTITLE/, meta[:doctitle]).
57
- gsub(/DOCSUBTITLE/, meta[:docsubtitle]).
58
- gsub(/SECRETARIAT/, meta[:secretariat]).
59
- gsub(/[ ]?DRAFTINFO/, meta[:draftinfo]).
60
52
  gsub(/\[TERMREF\]\s*/, "[SOURCE: ").
61
53
  gsub(/\s*\[\/TERMREF\]\s*/, "]").
62
54
  gsub(/\s*\[ISOSECTION\]/, ", ").
63
- gsub(/\s*\[MODIFICATION\]/, ", modified &mdash; ").
64
- gsub(%r{WD/CD/DIS/FDIS}, meta[:stageabbr])
55
+ gsub(/\s*\[MODIFICATION\]/, ", modified &mdash; ")
56
+ template = Liquid::Template.parse(docxml)
57
+ template.render(meta.map { |k, v| [k.to_s, v] }.to_h)
65
58
  end
66
59
 
67
60
  def generate_header(filename, dir)
68
- header = File.read(@header, encoding: "UTF-8").
69
- gsub(/FILENAME/, filename).
70
- gsub(/DOCYEAR/, get_metadata()[:docyear]).
71
- gsub(/[ ]?DRAFTINFO/, get_metadata()[:draftinfo]).
72
- gsub(/DOCNUMBER/, get_metadata()[:docnumber])
61
+ template = Liquid::Template.parse(File.read(@header, encoding: "UTF-8"))
62
+ meta = get_metadata
63
+ meta[:filename] = filename
64
+ params = meta.map { |k, v| [k.to_s, v] }.to_h
73
65
  File.open("header.html", "w") do |f|
74
- f.write(header)
66
+ f.write(template.render(params))
75
67
  end
76
68
  end
77
69
 
@@ -138,8 +130,17 @@ module IsoDoc
138
130
  TOC
139
131
 
140
132
  def header_strip(h)
141
- h.to_s.gsub(%r{<br/>}, " ").
133
+ h = h.to_s.gsub(%r{<br/>}, " ").
142
134
  sub(/<h[12][^>]*>/, "").sub(%r{</h[12]>}, "")
135
+ h1 = to_xhtml_fragment(h)
136
+ #h1.xpath(".//*[@style = 'MsoCommentReference']").each do |x|
137
+ h1.xpath(".//*").each do |x|
138
+ if x.name == "span" && x['style'] == "MsoCommentReference"
139
+ x.children.remove
140
+ x.content = ""
141
+ end
142
+ end
143
+ from_xhtml(h1)
143
144
  end
144
145
 
145
146
  def makeWordToC(docxml)
@@ -2,20 +2,18 @@ module IsoDoc
2
2
  class Convert
3
3
  def iso_bibitem_ref_code(b)
4
4
  isocode = b.at(ns("./docidentifier"))
5
- isodate = b.at(ns("./publishdate"))
5
+ isodate = b.at(ns("./date[@type = 'published']"))
6
6
  reference = "ISO #{isocode.text}"
7
7
  reference += ": #{isodate.text}" if isodate
8
8
  reference
9
9
  end
10
10
 
11
11
  def date_note_process(b, ref)
12
- date_note = b.xpath(ns("./note[text()][contains(.,'ISO DATE:')]"))
13
- unless date_note.empty?
14
- date_note.first.content =
15
- date_note.first.content.gsub(/ISO DATE: /, "")
16
- date_note.wrap("<p></p>")
17
- footnote_parse(date_note.first, ref)
18
- end
12
+ date_note = b.at(ns("./note[text()][contains(.,'ISO DATE:')]"))
13
+ return if date_note.nil?
14
+ date_note.content = date_note.content.gsub(/ISO DATE: /, "")
15
+ date_note.children.first.replace("<p>#{date_note.content}</p>")
16
+ footnote_parse(date_note, ref)
19
17
  end
20
18
 
21
19
  def iso_bibitem_entry(list, b, ordinal, biblio)
@@ -28,7 +26,7 @@ module IsoDoc
28
26
  ref << iso_bibitem_ref_code(b)
29
27
  date_note_process(b, ref)
30
28
  ref << ", " if biblio
31
- ref.i { |i| i << " #{b.at(ns('./name')).text}" }
29
+ ref.i { |i| i << " #{b.at(ns('./title')).text}" }
32
30
  end
33
31
  end
34
32
 
@@ -54,18 +52,21 @@ module IsoDoc
54
52
 
55
53
  def noniso_bibitem(list, b, ordinal, bibliography)
56
54
  ref = b.at(ns("./docidentifier"))
57
- para = b.at(ns("./formatted"))
55
+ para = b.at(ns("./formattedref"))
58
56
  list.p **attr_code("id": b["id"], class: "Biblio") do |r|
59
57
  ref_entry_code(r, ordinal, ref.text.gsub(/[\[\]]/, ""))
60
58
  para.children.each { |n| parse(n, r) }
61
59
  end
62
60
  end
63
61
 
62
+ ISO_PUBLISHER_XPATH =
63
+ "./contributor[xmlns:role/@type = 'publisher']/organization[name = 'ISO']"
64
+
64
65
  def split_bibitems(f)
65
66
  iso_bibitem = []
66
67
  non_iso_bibitem = []
67
68
  f.xpath(ns("./bibitem")).each do |x|
68
- if x.at(ns("./publisher/affiliation[name = 'ISO']")).nil?
69
+ if x.at(ns(ISO_PUBLISHER_XPATH)).nil?
69
70
  non_iso_bibitem << x
70
71
  else
71
72
  iso_bibitem << x
@@ -99,12 +100,15 @@ module IsoDoc
99
100
  refs = f.elements.select do |e|
100
101
  ["reference", "bibitem"].include? e.name
101
102
  end
102
- pref = refs.empty? ? NORM_EMPTY_PREF : NORM_WITH_REFS_PREF
103
+ pref = if refs.empty? then self.class::NORM_EMPTY_PREF
104
+ else
105
+ self.class::NORM_WITH_REFS_PREF
106
+ end
103
107
  div.p pref
104
108
  end
105
109
 
106
110
  def norm_ref(isoxml, out)
107
- q = "//sections/references[title = 'Normative References']"
111
+ q = "./*/references[title = 'Normative References']"
108
112
  f = isoxml.at(ns(q)) or return
109
113
  out.div do |div|
110
114
  clause_name("2.", "Normative References", div, false)
@@ -114,7 +118,7 @@ module IsoDoc
114
118
  end
115
119
 
116
120
  def bibliography(isoxml, out)
117
- q = "//sections/references[title = 'Bibliography']"
121
+ q = "./*/references[title = 'Bibliography']"
118
122
  f = isoxml.at(ns(q)) or return
119
123
  page_break(out)
120
124
  out.div do |div|
@@ -1,7 +1,7 @@
1
1
  module IsoDoc
2
2
  class Convert
3
3
  def clause_parse(node, out)
4
- out.div **attr_code("id": node["id"]) do |s|
4
+ out.div **attr_code(id: node["id"]) do |s|
5
5
  node.children.each do |c1|
6
6
  if c1.name == "title"
7
7
  if node["inline-header"]
@@ -42,7 +42,7 @@ module IsoDoc
42
42
  def clause(isoxml, out)
43
43
  isoxml.xpath(ns("//clause[parent::sections]")).each do |c|
44
44
  next if c.at(ns("./title")).text == "Scope"
45
- out.div **attr_code("id": c["id"]) do |s|
45
+ out.div **attr_code(id: c["id"]) do |s|
46
46
  c.elements.each do |c1|
47
47
  if c1.name == "title"
48
48
  clause_name("#{get_anchors()[c['id']][:label]}.",
@@ -65,7 +65,7 @@ module IsoDoc
65
65
  def annex(isoxml, out)
66
66
  isoxml.xpath(ns("//annex")).each do |c|
67
67
  page_break(out)
68
- out.div **attr_code("id": c["id"], class: "Section3" ) do |s|
68
+ out.div **attr_code(id: c["id"], class: "Section3" ) do |s|
69
69
  #s1.div **{ class: "annex" } do |s|
70
70
  c.elements.each do |c1|
71
71
  if c1.name == "title" then annex_name(c, c1, s)
@@ -80,7 +80,7 @@ module IsoDoc
80
80
 
81
81
  def scope(isoxml, out)
82
82
  f = isoxml.at(ns("//clause[title = 'Scope']")) || return
83
- out.div do |div|
83
+ out.div **attr_code(id: f["id"]) do |div|
84
84
  clause_name("1.", "Scope", div, false)
85
85
  f.elements.each do |e|
86
86
  parse(e, div) unless e.name == "title"
@@ -90,7 +90,7 @@ module IsoDoc
90
90
 
91
91
  def terms_defs(isoxml, out)
92
92
  f = isoxml.at(ns("//terms")) || return
93
- out.div do |div|
93
+ out.div **attr_code(id: f["id"]) do |div|
94
94
  clause_name("3.", "Terms and Definitions", div, false)
95
95
  f.elements.each do |e|
96
96
  parse(e, div) unless e.name == "title"
@@ -100,7 +100,7 @@ module IsoDoc
100
100
 
101
101
  def symbols_abbrevs(isoxml, out)
102
102
  f = isoxml.at(ns("//symbols-abbrevs")) || return
103
- out.div do |div|
103
+ out.div **attr_code(id: f["id"]) do |div|
104
104
  clause_name("4.", "Symbols and Abbreviations", div, false)
105
105
  f.elements.each do |e|
106
106
  parse(e, div) unless e.name == "title"
@@ -109,10 +109,10 @@ module IsoDoc
109
109
  end
110
110
 
111
111
  def introduction(isoxml, out)
112
- f = isoxml.at(ns("//content[title = 'Introduction']")) || return
112
+ f = isoxml.at(ns("//introduction")) || return
113
113
  title_attr = { class: "IntroTitle" }
114
114
  page_break(out)
115
- out.div **{ class: "Section3" } do |div|
115
+ out.div **{ class: "Section3", id: f["id"] } do |div|
116
116
  div.h1 "Introduction", **attr_code(title_attr)
117
117
  f.elements.each do |e|
118
118
  if e.name == "patent-notice"
@@ -125,9 +125,9 @@ module IsoDoc
125
125
  end
126
126
 
127
127
  def foreword(isoxml, out)
128
- f = isoxml.at(ns("//content[title = 'Foreword']")) || return
128
+ f = isoxml.at(ns("//foreword")) || return
129
129
  page_break(out)
130
- out.div do |s|
130
+ out.div **attr_code(id: f["id"]) do |s|
131
131
  s.h1 **{ class: "ForewordTitle" } { |h1| h1 << "Foreword" }
132
132
  f.elements.each { |e| parse(e, s) unless e.name == "title" }
133
133
  end
@@ -58,14 +58,6 @@ module IsoDoc
58
58
  end.to_h
59
59
  end
60
60
 
61
- NOKOHEAD = <<~HERE
62
- <!DOCTYPE html SYSTEM
63
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
64
- <html xmlns="http://www.w3.org/1999/xhtml">
65
- <head> <title></title> <meta charset="UTF-8" /> </head>
66
- <body> </body> </html>
67
- HERE
68
-
69
61
  def to_xhtml(xml)
70
62
  xml.gsub!(/<\?xml[^>]*>/, "")
71
63
  unless /<!DOCTYPE /.match? xml
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "0.4.0".freeze
2
+ VERSION = "0.4.5".freeze
3
3
  end
@@ -20,7 +20,7 @@ module IsoDoc
20
20
  end
21
21
 
22
22
  def initial_anchor_names(d)
23
- introduction_names(d.at(ns("//content[title = 'Introduction']")))
23
+ introduction_names(d.at(ns("//introduction")))
24
24
  section_names(d.at(ns("//clause[title = 'Scope']")), "1", 1)
25
25
  section_names(d.at(ns(
26
26
  "//references[title = 'Normative References']")), "2", 1)
@@ -135,8 +135,9 @@ module IsoDoc
135
135
  end
136
136
 
137
137
  def introduction_names(clause)
138
+ return if clause.nil?
138
139
  clause.xpath(ns("./subsection")).each_with_index do |c, i|
139
- section_names(c, "0.#{i + 1}")
140
+ section_names1(c, "0.#{i + 1}", 2)
140
141
  end
141
142
  end
142
143
 
@@ -186,10 +187,10 @@ module IsoDoc
186
187
  end
187
188
 
188
189
  def reference_names(ref)
189
- isopub = ref.at(ns("./publisher/affiliation[name = 'ISO']"))
190
+ isopub = ref.at(ns(ISO_PUBLISHER_XPATH))
190
191
  docid = ref.at(ns("./docidentifier"))
191
192
  return ref_names(ref) unless docid
192
- date = ref.at(ns("./publisherdate"))
193
+ date = ref.at(ns("./date[@type = 'published']"))
193
194
  reference = format_ref(docid.text, isopub)
194
195
  reference += ": #{date.text}" if date && isopub
195
196
  @anchors[ref["id"]] = { xref: reference }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isodoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-06 00:00:00.000000000 Z
11
+ date: 2018-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciimath
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: liquid
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: bundler
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -303,6 +317,7 @@ files:
303
317
  - lib/isodoc/iso2wordhtml.rb
304
318
  - lib/isodoc/lists.rb
305
319
  - lib/isodoc/metadata.rb
320
+ - lib/isodoc/notes.rb
306
321
  - lib/isodoc/postprocessing.rb
307
322
  - lib/isodoc/references.rb
308
323
  - lib/isodoc/section.rb