metanorma-itu 1.1.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,18 +7,21 @@ module IsoDoc
7
7
  def initialize(lang, script, labels)
8
8
  super
9
9
  here = File.dirname(__FILE__)
10
+ n = "International_Telecommunication_Union_Logo.svg"
10
11
  set(:logo_html,
11
- File.expand_path(File.join(here, "html", "International_Telecommunication_Union_Logo.svg")))
12
+ File.expand_path(File.join(here, "html", n)))
12
13
  set(:logo_comb,
13
14
  File.expand_path(File.join(here, "html", "itu-document-comb.png")))
14
15
  set(:logo_word,
15
- File.expand_path(File.join(here, "html", "International_Telecommunication_Union_Logo.svg")))
16
+ File.expand_path(File.join(here, "html", n)))
16
17
  end
17
18
 
18
19
  def title(isoxml, _out)
19
- main = isoxml&.at(ns("//bibdata/title[@language='#{@lang}'][@type = 'main']"))&.text
20
+ main = isoxml&.at(ns("//bibdata/title[@language='#{@lang}']"\
21
+ "[@type = 'main']"))&.text
20
22
  set(:doctitle, main)
21
- main = isoxml&.at(ns("//bibdata/title[@language='#{@lang}'][@type = 'subtitle']"))&.text
23
+ main = isoxml&.at(ns("//bibdata/title[@language='#{@lang}']"\
24
+ "[@type = 'subtitle']"))&.text
22
25
  set(:docsubtitle, main)
23
26
  series = isoxml&.at(ns("//bibdata/series[@type='main']/title"))&.text
24
27
  set(:series, series)
@@ -50,7 +53,7 @@ module IsoDoc
50
53
  dn = isoxml.at(ns("//bibdata/ext/structuredidentifier/annexid"))
51
54
  oblig = isoxml&.at(ns("//annex/@obligation"))&.text
52
55
  lbl = oblig == "informative" ? @labels["appendix"] : @labels["annex"]
53
- dn and set(:annexid, IsoDoc::Function::I18n::l10n("#{lbl} #{dn&.text}"))
56
+ dn and set(:annexid, @i18n.l10n("#{lbl} #{dn&.text}"))
54
57
  end
55
58
 
56
59
  def unpublished(status)
@@ -1,5 +1,4 @@
1
1
  require "isodoc"
2
- require_relative "metadata"
3
2
  require "fileutils"
4
3
 
5
4
  module IsoDoc
@@ -1,9 +1,54 @@
1
- require_relative "base_convert"
1
+ require_relative "init"
2
2
  require "isodoc"
3
3
 
4
4
  module IsoDoc
5
5
  module ITU
6
6
  class PresentationXMLConvert < IsoDoc::PresentationXMLConvert
7
+ def initialize(options)
8
+ @hierarchical_assets = options[:hierarchical_assets]
9
+ super
10
+ end
11
+
12
+ def prefix_container(container, linkend, _target)
13
+ l10n("#{linkend} #{@i18n.get["in"]} #{@xrefs.anchor(container, :xref)}")
14
+ end
15
+
16
+ def eref(docxml)
17
+ docxml.xpath(ns("//eref")).each do |f|
18
+ eref1(f)
19
+ end
20
+ end
21
+
22
+ def origin(docxml)
23
+ docxml.xpath(ns("//origin[not(termref)]")).each do |f|
24
+ eref1(f)
25
+ end
26
+ end
27
+
28
+ def quotesource(docxml)
29
+ docxml.xpath(ns("//quote/source")).each do |f|
30
+ eref1(f)
31
+ end
32
+ end
33
+
34
+ def eref1(f)
35
+ get_eref_linkend(f)
36
+ end
37
+
38
+ def get_eref_linkend(node)
39
+ contents = non_locality_elems(node).select do |c|
40
+ !c.text? || /\S/.match(c)
41
+ end
42
+ return unless contents.empty?
43
+ link = anchor_linkend(node, docid_l10n(node["target"] || node["citeas"]))
44
+ link && !/^\[.*\]$/.match(link) and link = "[#{link}]"
45
+ link += eref_localities(node.xpath(ns("./locality | ./localityStack")),
46
+ link)
47
+ non_locality_elems(node).each { |n| n.remove }
48
+ node.add_child(link)
49
+ end
50
+
51
+ include Init
7
52
  end
8
53
  end
9
54
  end
@@ -11,7 +11,7 @@ module IsoDoc
11
11
  f = isoxml.at(ns(q)) or return num
12
12
  out.div do |div|
13
13
  num = num + 1
14
- clause_name(num, @normref_lbl, div, nil)
14
+ clause_name(num, f.at(ns("./title")), div, nil)
15
15
  biblio_list(f, div, false)
16
16
  end
17
17
  num
@@ -45,9 +45,7 @@ module IsoDoc
45
45
  nonstd_bibitem(tbody, b, i, biblio)
46
46
  else
47
47
  unless %w(title clause references).include? b.name
48
- tbody.tx do |tx|
49
- parse(b, tx)
50
- end
48
+ tbody.tx { |tx| parse(b, tx) }
51
49
  end
52
50
  end
53
51
  end
@@ -77,12 +75,14 @@ module IsoDoc
77
75
  b.at(ns("./docidentifier[@type = 'ITU']")) || super
78
76
  end
79
77
 
80
- IGNORE_IDS =
81
- "@type = 'DOI' or @type = 'ISSN' or @type = 'ISBN' or @type = 'rfc-anchor'".freeze
78
+ IGNORE_IDS = "@type = 'DOI' or @type = 'ISSN' or @type = 'ISBN' or "\
79
+ "@type = 'rfc-anchor'".freeze
82
80
 
83
81
  def multi_bibitem_ref_code(b)
84
- id = b.xpath(ns("./docidentifier[not(@type = 'metanorma' or #{IGNORE_IDS})]"))
85
- id.empty? and id = b.xpath(ns("./docidentifier[not(@type = 'metanorma')]"))
82
+ id = b.xpath(ns("./docidentifier[not(@type = 'metanorma' or "\
83
+ "#{IGNORE_IDS})]"))
84
+ id.empty? and
85
+ id = b.xpath(ns("./docidentifier[not(@type = 'metanorma')]"))
86
86
  return [] if id.empty?
87
87
  id.sort_by { |i| i["type"] == "ITU" ? 0 : 1 }
88
88
  end
@@ -100,7 +100,8 @@ module IsoDoc
100
100
  /^(?<prefix>ITU-[A-Z] [A-Z])[ .-]Sup[a-z]*\.[ ]?(?<num>\d+)$/ =~ id.text
101
101
  "#{prefix}-series Recommendations – Supplement #{num}"
102
102
  else
103
- "#{titlecase(type)} #{docid_prefix(id["type"], id.text.sub(/^\[/, '').sub(/\]$/, ''))}"
103
+ d = docid_prefix(id["type"], id.text.sub(/^\[/, '').sub(/\]$/, ''))
104
+ "#{titlecase(type)} #{d}"
104
105
  end
105
106
  end
106
107
 
@@ -1,15 +1,12 @@
1
1
  module IsoDoc
2
2
  module ITU
3
3
  module BaseConvert
4
- def term_def_title(node)
5
- node
6
- end
7
-
4
+ =begin
8
5
  def terms_defs(node, out, num)
9
6
  f = node.at(ns(IsoDoc::Convert::TERM_CLAUSE)) or return num
10
7
  out.div **attr_code(id: f["id"]) do |div|
11
8
  num = num + 1
12
- clause_name(num, term_def_title(f.at(ns("./title"))), div, nil)
9
+ clause_name(num, f.at(ns("./title")), div, nil)
13
10
  if f.at(ns("./clause | ./terms | ./term")).nil? then out.p "None."
14
11
  else
15
12
  f.children.reject { |c1| c1.name == "title" }.each do |c1|
@@ -31,13 +28,14 @@ module IsoDoc
31
28
  end
32
29
  end
33
30
  end
31
+ =end
34
32
 
35
- def termdef_parse1(node, div, term, defn, source)
33
+ def termdef_parse1(node, div, defn, source)
36
34
  div.p **{ class: "TermNum", id: node["id"] } do |p|
37
35
  p.b do |b|
38
- b << @xrefs.anchor(node["id"], :label)
36
+ node&.at(ns("./name"))&.children&.each { |n| parse(n, b) }
39
37
  insert_tab(b, 1)
40
- term.children.each { |n| parse(n, b) }
38
+ node&.at(ns("./preferred"))&.children&.each { |n| parse(n, b) }
41
39
  end
42
40
  source and p << " #{bracket_opt(source.value)}"
43
41
  p << ": "
@@ -46,27 +44,20 @@ module IsoDoc
46
44
  end
47
45
 
48
46
  def termdef_parse(node, out)
49
- term = node.at(ns("./preferred"))
50
47
  defn = node.at(ns("./definition"))
51
48
  source = node.at(ns("./termsource/origin/@citeas"))
52
49
  out.div **attr_code(id: node["id"]) do |div|
53
- termdef_parse1(node, div, term, defn, source)
50
+ termdef_parse1(node, div, defn, source)
54
51
  set_termdomain("")
55
52
  node.children.each do |n|
56
- next if %w(preferred definition termsource title).include? n.name
53
+ next if %w(preferred definition termsource title name).include? n.name
57
54
  parse(n, out)
58
55
  end
59
56
  end
60
57
  end
61
58
 
62
- def termnote_parse(node, out)
63
- out.div **note_attrs(node) do |div|
64
- first = node.first_element_child
65
- div.p do |p|
66
- p << note_label(node) # "#{@xrefs.anchor(node['id'], :label) || '???'}: "
67
- para_then_remainder(first, node, p, div)
68
- end
69
- end
59
+ def termnote_delim
60
+ " &ndash; "
70
61
  end
71
62
  end
72
63
  end
@@ -0,0 +1,152 @@
1
+ module IsoDoc
2
+ module ITU
3
+ class WordConvert < IsoDoc::WordConvert
4
+ def word_preface_cleanup(docxml)
5
+ docxml.xpath("//h1[@class = 'AbstractTitle'] | "\
6
+ "//h1[@class = 'IntroTitle']").each do |h2|
7
+ h2.name = "p"
8
+ h2["class"] = "h1Preface"
9
+ end
10
+ end
11
+
12
+ def word_term_cleanup(docxml)
13
+ end
14
+
15
+ def word_cleanup(docxml)
16
+ word_footnote_cleanup(docxml)
17
+ word_title_cleanup(docxml)
18
+ word_preface_cleanup(docxml)
19
+ word_term_cleanup(docxml)
20
+ word_history_cleanup(docxml)
21
+ authority_hdr_cleanup(docxml)
22
+ table_list_style(docxml)
23
+ super
24
+ docxml
25
+ end
26
+
27
+ def word_footnote_cleanup(docxml)
28
+ docxml.xpath("//aside").each do |a|
29
+ a.first_element_child.children.first.previous =
30
+ '<span style="mso-tab-count:1"/>'
31
+ end
32
+ end
33
+
34
+ def word_title_cleanup(docxml)
35
+ docxml.xpath("//p[@class = 'annex_obligation']").each do |h|
36
+ h&.next_element&.name == "p" or next
37
+ h.next_element["class"] ||= "Normalaftertitle"
38
+ end
39
+ docxml.xpath("//p[@class = 'FigureTitle']").each do |h|
40
+ h&.parent&.next_element&.name == "p" or next
41
+ h.parent.next_element["class"] ||= "Normalaftertitle"
42
+ end
43
+ end
44
+
45
+ def word_history_cleanup(docxml)
46
+ docxml.xpath("//div[@id='_history']//table").each do |t|
47
+ t["class"] = "MsoNormalTable"
48
+ t.xpath(".//td").each { |td| td["style"] = nil }
49
+ end
50
+ end
51
+
52
+ def word_preface(docxml)
53
+ super
54
+ abstractbox = docxml.at("//div[@id='abstractbox']")
55
+ historybox = docxml.at("//div[@id='historybox']")
56
+ sourcebox = docxml.at("//div[@id='sourcebox']")
57
+ keywordsbox = docxml.at("//div[@id='keywordsbox']")
58
+ abstract = docxml.at("//div[@class = 'Abstract']")
59
+ history = docxml.at("//div[@class = 'history']")
60
+ source = docxml.at("//div[@class = 'source']")
61
+ keywords = docxml.at("//div[@class = 'Keywords']")
62
+ abstract.parent = abstractbox if abstract && abstractbox
63
+ history.parent = historybox if history && historybox
64
+ source.parent = sourcebox if source && sourcebox
65
+ keywords.parent = keywordsbox if keywords && keywordsbox
66
+ end
67
+
68
+ def toWord(result, filename, dir, header)
69
+ result = populate_template(result, :word)
70
+ result = from_xhtml(word_cleanup(to_xhtml(result)))
71
+ unless @landscapestyle.nil? || @landscapestyle.empty?
72
+ @wordstylesheet&.open
73
+ @wordstylesheet&.write(@landscapestyle)
74
+ @wordstylesheet&.close
75
+ end
76
+ Html2Doc.process(
77
+ result, filename: filename,
78
+ stylesheet: @wordstylesheet&.path,
79
+ header_file: header&.path, dir: dir,
80
+ asciimathdelims: [@openmathdelim, @closemathdelim],
81
+ liststyles: { ul: @ulstyle, ol: @olstyle, steps: "l4" })
82
+ header&.unlink
83
+ @wordstylesheet&.unlink
84
+ end
85
+
86
+ def authority_hdr_cleanup(docxml)
87
+ docxml&.xpath("//div[@id = 'draft-warning']").each do |d|
88
+ d.xpath(".//h1 | .//h2").each do |p|
89
+ p.name = "p"
90
+ p["class"] = "draftwarningHdr"
91
+ end
92
+ end
93
+ %w(copyright license legal).each do |t|
94
+ docxml&.xpath("//div[@class = 'boilerplate-#{t}']").each do |d|
95
+ p = d&.at("./descendant::h1[2]") and
96
+ p.previous = "<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>"
97
+ d.xpath(".//h1 | .//h2").each do |p|
98
+ p.name = "p"
99
+ p["class"] = "boilerplateHdr"
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ def authority_cleanup(docxml)
106
+ dest = docxml.at("//div[@class = 'draft-warning']")
107
+ auth = docxml.at("//div[@id = 'draft-warning']")
108
+ dest and auth and dest.replace(auth.remove)
109
+ %w(copyright license legal).each do |t|
110
+ dest = docxml.at("//div[@id = 'boilerplate-#{t}-destination']")
111
+ auth = docxml.at("//div[@class = 'boilerplate-#{t}']")
112
+ next unless auth && dest
113
+ t == "copyright" and p = auth&.at(".//p") and
114
+ p["class"] = "boilerplateHdr"
115
+ auth&.xpath(".//p[not(@class)]")&.each_with_index do |p, i|
116
+ p["class"] = "boilerplate"
117
+ #i == 0 && t == "copyright" and p["style"] = "text-align:center;"
118
+ end
119
+ t == "copyright" or
120
+ auth << "<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>"
121
+ dest.replace(auth.remove)
122
+ end
123
+ end
124
+
125
+ TOPLIST = "[not(ancestor::ul) and not(ancestor::ol)]".freeze
126
+
127
+ def table_list_style(xml)
128
+ xml.xpath("//table//ul#{TOPLIST} | //table//ol#{TOPLIST}").each do |t|
129
+ table_list_style1(t, 1)
130
+ end
131
+ end
132
+
133
+ def table_list_style1(t, num)
134
+ (t.xpath(".//li") - t.xpath(".//ol//li | .//ul//li")).each do |t1|
135
+ indent_list(t1, num)
136
+ t1.xpath("./div | ./p").each { |p| indent_list(p, num) }
137
+ (t1.xpath(".//ul") - t1.xpath(".//ul//ul | .//ol//ul")).each do |t2|
138
+ table_list_style1(t2, num + 1)
139
+ end
140
+ (t1.xpath(".//ol") - t1.xpath(".//ul//ol | .//ol//ol")).each do |t2|
141
+ table_list_style1(t2, num + 1)
142
+ end
143
+ end
144
+ end
145
+
146
+ def indent_list(li, num)
147
+ li["style"] = (li["style"] ? li["style"] + ";" : "")
148
+ li["style"] += "margin-left: #{num * 0.5}cm;text-indent: -0.5cm;"
149
+ end
150
+ end
151
+ end
152
+ end
@@ -1,12 +1,10 @@
1
1
  require "isodoc"
2
- require_relative "metadata"
2
+ require_relative "init"
3
+ require_relative "word_cleanup"
3
4
  require "fileutils"
4
5
 
5
6
  module IsoDoc
6
7
  module ITU
7
- # A {Converter} implementation that generates Word output, and a document
8
- # schema encapsulation of the document for validation
9
-
10
8
  class WordConvert < IsoDoc::WordConvert
11
9
  def initialize(options)
12
10
  @libdir = File.dirname(__FILE__)
@@ -27,6 +25,7 @@ module IsoDoc
27
25
  body.div **{ class: "WordSection2" } do |div2|
28
26
  info docxml, div2
29
27
  boilerplate docxml, div2
28
+ preface_block docxml, div2
30
29
  abstract docxml, div2
31
30
  keywords docxml, div2
32
31
  preface docxml, div2
@@ -37,7 +36,7 @@ module IsoDoc
37
36
 
38
37
  def abstract(isoxml, out)
39
38
  f = isoxml.at(ns("//preface/abstract")) || return
40
- out.div **attr_code(id: f["id"]) do |s|
39
+ out.div **attr_code(id: f["id"], class: "Abstract") do |s|
41
40
  clause_name(nil, "Summary", s, class: "AbstractTitle")
42
41
  f.elements.each { |e| parse(e, s) unless e.name == "title" }
43
42
  end
@@ -46,84 +45,18 @@ module IsoDoc
46
45
  def keywords(_docxml, out)
47
46
  kw = @meta.get[:keywords]
48
47
  kw.nil? || kw.empty? and return
49
- out.div do |div|
48
+ out.div **attr_code(class: "Keyword") do |div|
50
49
  clause_name(nil, "Keywords", div, class: "IntroTitle")
51
50
  div.p kw.join(", ") + "."
52
51
  end
53
52
  end
54
53
 
55
- def word_preface_cleanup(docxml)
56
- docxml.xpath("//h1[@class = 'AbstractTitle'] | "\
57
- "//h1[@class = 'IntroTitle']").each do |h2|
58
- h2.name = "p"
59
- h2["class"] = "h1Preface"
60
- end
61
- end
62
-
63
- def word_term_cleanup(docxml)
64
- docxml.xpath("//p[@class = 'TermNum']").each do |t|
65
- end
66
- end
67
-
68
- def word_cleanup(docxml)
69
- word_footnote_cleanup(docxml)
70
- word_title_cleanup(docxml)
71
- word_preface_cleanup(docxml)
72
- word_term_cleanup(docxml)
73
- word_history_cleanup(docxml)
74
- authority_hdr_cleanup(docxml)
75
- super
76
- docxml
77
- end
78
-
79
- def word_footnote_cleanup(docxml)
80
- docxml.xpath("//aside").each do |a|
81
- a.first_element_child.children.first.previous =
82
- '<span style="mso-tab-count:1"/>'
83
- end
84
- end
85
-
86
- def word_title_cleanup(docxml)
87
- docxml.xpath("//p[@class = 'annex_obligation']").each do |h|
88
- h&.next_element&.name == "p" or next
89
- h.next_element["class"] ||= "Normalaftertitle"
90
- end
91
- docxml.xpath("//p[@class = 'FigureTitle']").each do |h|
92
- h&.parent&.next_element&.name == "p" or next
93
- h.parent.next_element["class"] ||= "Normalaftertitle"
94
- end
95
- end
96
-
97
- def word_history_cleanup(docxml)
98
- docxml.xpath("//div[@id='_history']//table").each do |t|
99
- t["class"] = "MsoNormalTable"
100
- t.xpath(".//td").each { |td| td["style"] = nil }
101
- end
102
- end
103
-
104
- def word_preface(docxml)
105
- super
106
- abstractbox = docxml.at("//div[@id='abstractbox']")
107
- historybox = docxml.at("//div[@id='historybox']")
108
- sourcebox = docxml.at("//div[@id='sourcebox']")
109
- keywordsbox = docxml.at("//div[@id='keywordsbox']")
110
- abstract = docxml.at("//p[@class = 'h1Preface' and text() = 'Summary']/..")
111
- history = docxml.at("//p[@class = 'h1Preface' and text() = 'History']/..")
112
- source = docxml.at("//p[@class = 'h1Preface' and text() = 'Source']/..")
113
- keywords = docxml.at("//p[@class = 'h1Preface' and text() = 'Keywords']/..")
114
- abstract.parent = abstractbox if abstract && abstractbox
115
- history.parent = historybox if history && historybox
116
- source.parent = sourcebox if source && sourcebox
117
- keywords.parent = keywordsbox if keywords && keywordsbox
118
- end
119
-
120
54
  def formula_parse1(node, out)
121
55
  out.div **attr_code(class: "formula") do |div|
122
56
  div.p **attr_code(class: "formula") do |p|
123
57
  insert_tab(div, 1)
124
58
  parse(node.at(ns("./stem")), div)
125
- lbl = @xrefs.anchor(node['id'], :label, false)
126
- unless lbl.nil?
59
+ if lbl = node&.at(ns("./name"))&.text
127
60
  insert_tab(div, 1)
128
61
  div << "(#{lbl})"
129
62
  end
@@ -157,24 +90,9 @@ module IsoDoc
157
90
  { class: node["class"], id: node["id"], style: keep_style(node) }
158
91
  end
159
92
 
160
- def toWord(result, filename, dir, header)
161
- result = populate_template(result, :word)
162
- result = from_xhtml(word_cleanup(to_xhtml(result)))
163
- unless @landscapestyle.nil? || @landscapestyle.empty?
164
- @wordstylesheet&.open
165
- @wordstylesheet&.write(@landscapestyle)
166
- @wordstylesheet&.close
167
- end
168
- Html2Doc.process(result, filename: filename, stylesheet: @wordstylesheet&.path,
169
- header_file: header&.path, dir: dir,
170
- asciimathdelims: [@openmathdelim, @closemathdelim],
171
- liststyles: { ul: @ulstyle, ol: @olstyle, steps: "l4" })
172
- header&.unlink
173
- @wordstylesheet&.unlink
174
- end
175
-
176
93
  def link_parse(node, out)
177
- out.a **attr_code(href: node["target"], title: node["alt"], class: "url") do |l|
94
+ out.a **attr_code(href: node["target"], title: node["alt"],
95
+ class: "url") do |l|
178
96
  if node.text.empty?
179
97
  l << node["target"].sub(/^mailto:/, "")
180
98
  else
@@ -183,45 +101,15 @@ module IsoDoc
183
101
  end
184
102
  end
185
103
 
186
- def authority_hdr_cleanup(docxml)
187
- docxml&.xpath("//div[@id = 'draft-warning']").each do |d|
188
- d.xpath(".//h1 | .//h2").each do |p|
189
- p.name = "p"
190
- p["class"] = "draftwarningHdr"
191
- end
192
- end
193
- %w(copyright license legal).each do |t|
194
- docxml&.xpath("//div[@class = 'boilerplate-#{t}']").each do |d|
195
- p = d&.at("./descendant::h1[2]") and
196
- p.previous = "<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>"
197
- d.xpath(".//h1 | .//h2").each do |p|
198
- p.name = "p"
199
- p["class"] = "boilerplateHdr"
200
- end
201
- end
202
- end
203
- end
204
-
205
- def authority_cleanup(docxml)
206
- dest = docxml.at("//div[@class = 'draft-warning']")
207
- auth = docxml.at("//div[@id = 'draft-warning']")
208
- dest and auth and dest.replace(auth.remove)
209
- %w(copyright license legal).each do |t|
210
- dest = docxml.at("//div[@id = 'boilerplate-#{t}-destination']")
211
- auth = docxml.at("//div[@class = 'boilerplate-#{t}']")
212
- next unless auth && dest
213
- t == "copyright" and p = auth&.at(".//p") and
214
- p["class"] = "boilerplateHdr"
215
- auth&.xpath(".//p[not(@class)]")&.each_with_index do |p, i|
216
- p["class"] = "boilerplate"
217
- i == 0 && t == "copyright" and p["style"] = "text-align:center;"
218
- end
219
- auth << "<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>" unless t == "copyright"
220
- dest.replace(auth.remove)
221
- end
104
+ def clause_attrs(node)
105
+ ret = {}
106
+ %w(source history).include?(node["type"]) and
107
+ ret = { class: node["type"] }
108
+ super.merge(ret)
222
109
  end
223
110
 
224
111
  include BaseConvert
112
+ include Init
225
113
  end
226
114
  end
227
115
  end