isodoc 0.4.0 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
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