isodoc 1.0.26 → 1.1.1
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 +4 -4
- data/.github/workflows/macos.yml +12 -8
- data/.github/workflows/ubuntu.yml +26 -16
- data/.github/workflows/windows.yml +12 -8
- data/isodoc.gemspec +2 -2
- data/lib/isodoc.rb +2 -0
- data/lib/isodoc/common.rb +0 -4
- data/lib/isodoc/convert.rb +18 -8
- data/lib/isodoc/function/blocks.rb +43 -54
- data/lib/isodoc/function/blocks_example_note.rb +108 -0
- data/lib/isodoc/function/cleanup.rb +14 -2
- data/lib/isodoc/function/i18n.rb +1 -0
- data/lib/isodoc/function/inline.rb +76 -82
- data/lib/isodoc/function/inline_simple.rb +72 -0
- data/lib/isodoc/function/lists.rb +12 -6
- data/lib/isodoc/function/references.rb +65 -57
- data/lib/isodoc/function/reqt.rb +14 -5
- data/lib/isodoc/function/section.rb +8 -11
- data/lib/isodoc/function/table.rb +4 -5
- data/lib/isodoc/function/terms.rb +3 -3
- data/lib/isodoc/function/to_word_html.rb +22 -13
- data/lib/isodoc/function/utils.rb +9 -3
- data/lib/isodoc/headlesshtml_convert.rb +7 -6
- data/lib/isodoc/html_convert.rb +2 -1
- data/lib/isodoc/html_function/footnotes.rb +1 -1
- data/lib/isodoc/html_function/html.rb +16 -1
- data/lib/isodoc/html_function/postprocess.rb +6 -5
- data/lib/isodoc/metadata.rb +6 -0
- data/lib/isodoc/pdf_convert.rb +8 -6
- data/lib/isodoc/presentation_xml_convert.rb +29 -0
- data/lib/isodoc/version.rb +1 -1
- data/lib/isodoc/word_convert.rb +2 -1
- data/lib/isodoc/word_function/body.rb +14 -48
- data/lib/isodoc/word_function/footnotes.rb +1 -1
- data/lib/isodoc/word_function/inline.rb +75 -0
- data/lib/isodoc/word_function/postprocess.rb +1 -0
- data/lib/isodoc/word_function/table.rb +3 -3
- data/lib/isodoc/xref.rb +59 -0
- data/lib/isodoc/{function → xref}/xref_anchor.rb +10 -21
- data/lib/isodoc/xref/xref_counter.rb +74 -0
- data/lib/isodoc/{function → xref}/xref_gen.rb +9 -22
- data/lib/isodoc/{function → xref}/xref_gen_seq.rb +41 -32
- data/lib/isodoc/{function → xref}/xref_sect_gen.rb +33 -23
- data/lib/isodoc/xslfo_convert.rb +16 -4
- data/spec/assets/i18n.yaml +4 -1
- data/spec/assets/odf.emf +0 -0
- data/spec/assets/odf.svg +4 -0
- data/spec/assets/odf1.svg +4 -0
- data/spec/isodoc/blocks_spec.rb +240 -59
- data/spec/isodoc/cleanup_spec.rb +139 -17
- data/spec/isodoc/footnotes_spec.rb +20 -5
- data/spec/isodoc/inline_spec.rb +296 -1
- data/spec/isodoc/lists_spec.rb +8 -8
- data/spec/isodoc/metadata_spec.rb +110 -3
- data/spec/isodoc/postproc_spec.rb +10 -14
- data/spec/isodoc/presentation_xml_spec.rb +20 -0
- data/spec/isodoc/ref_spec.rb +119 -50
- data/spec/isodoc/section_spec.rb +84 -18
- data/spec/isodoc/table_spec.rb +28 -28
- data/spec/isodoc/terms_spec.rb +7 -7
- data/spec/isodoc/xref_spec.rb +177 -57
- metadata +24 -17
- data/lib/isodoc/function/blocks_example.rb +0 -53
- data/lib/isodoc/function/xref_counter.rb +0 -50
@@ -0,0 +1,108 @@
|
|
1
|
+
module IsoDoc::Function
|
2
|
+
module Blocks
|
3
|
+
def example_label(node, div, name)
|
4
|
+
n = @xrefs.get[node["id"]]
|
5
|
+
div.p **{ class: "example-title" } do |p|
|
6
|
+
lbl = (n.nil? || n[:label].nil? || n[:label].empty?) ? @example_lbl :
|
7
|
+
l10n("#{@example_lbl} #{n[:label]}")
|
8
|
+
p << lbl
|
9
|
+
name and !lbl.nil? and p << " — "
|
10
|
+
name and name.children.each { |n| parse(n, div) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
EXAMPLE_TBL_ATTR =
|
15
|
+
{ class: "example_label", style: "width:82.8pt;padding:0 0 0 0;\
|
16
|
+
margin-left:0pt;vertical-align:top;" }.freeze
|
17
|
+
|
18
|
+
def example_div_attr(node)
|
19
|
+
attr_code(id: node["id"], class: "example", style: keep_style(node))
|
20
|
+
end
|
21
|
+
|
22
|
+
# used if we are boxing examples
|
23
|
+
def example_div_parse(node, out)
|
24
|
+
out.div **example_div_attr(node) do |div|
|
25
|
+
example_label(node, div, node.at(ns("./name")))
|
26
|
+
node.children.each do |n|
|
27
|
+
parse(n, div) unless n.name == "name"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def example_table_attr(node)
|
33
|
+
attr_code(id: node["id"], class: "example",
|
34
|
+
style: "border-collapse:collapse;border-spacing:0;"\
|
35
|
+
"#{keep_style(node)}" )
|
36
|
+
end
|
37
|
+
|
38
|
+
EXAMPLE_TD_ATTR =
|
39
|
+
{ style: "vertical-align:top;padding:0;", class: "example" }.freeze
|
40
|
+
|
41
|
+
def example_table_parse(node, out)
|
42
|
+
out.table **example_table_attr(node) do |t|
|
43
|
+
t.tr do |tr|
|
44
|
+
tr.td **EXAMPLE_TBL_ATTR do |td|
|
45
|
+
example_label(node, td, node.at(ns("./name")))
|
46
|
+
end
|
47
|
+
tr.td **EXAMPLE_TD_ATTR do |td|
|
48
|
+
node.children.each { |n| parse(n, td) unless n.name == "name" }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def example_parse(node, out)
|
55
|
+
example_div_parse(node, out)
|
56
|
+
end
|
57
|
+
|
58
|
+
def note_label(node)
|
59
|
+
n = @xrefs.get[node["id"]]
|
60
|
+
return @note_lbl if n.nil? || n[:label].nil? || n[:label].empty?
|
61
|
+
l10n("#{@note_lbl} #{n[:label]}")
|
62
|
+
end
|
63
|
+
|
64
|
+
def note_p_parse(node, div)
|
65
|
+
div.p do |p|
|
66
|
+
p.span **{ class: "note_label" } do |s|
|
67
|
+
s << note_label(node)
|
68
|
+
end
|
69
|
+
insert_tab(p, 1)
|
70
|
+
node.first_element_child.children.each { |n| parse(n, p) }
|
71
|
+
end
|
72
|
+
node.element_children[1..-1].each { |n| parse(n, div) }
|
73
|
+
end
|
74
|
+
|
75
|
+
def note_parse1(node, div)
|
76
|
+
div.p do |p|
|
77
|
+
p.span **{ class: "note_label" } do |s|
|
78
|
+
s << note_label(node)
|
79
|
+
end
|
80
|
+
insert_tab(p, 1)
|
81
|
+
end
|
82
|
+
node.children.each { |n| parse(n, div) }
|
83
|
+
end
|
84
|
+
|
85
|
+
def keep_style(node)
|
86
|
+
ret = ""
|
87
|
+
node["keep-with-next"] == "true" and
|
88
|
+
ret += "page-break-after: avoid;"
|
89
|
+
node["keep-lines-together"] == "true" and
|
90
|
+
ret += "page-break-inside: avoid;"
|
91
|
+
return nil if ret.empty?
|
92
|
+
ret
|
93
|
+
end
|
94
|
+
|
95
|
+
def note_attrs(node)
|
96
|
+
attr_code(id: node["id"], class: "Note", style: keep_style(node))
|
97
|
+
end
|
98
|
+
|
99
|
+
def note_parse(node, out)
|
100
|
+
@note = true
|
101
|
+
out.div **note_attrs(node) do |div|
|
102
|
+
node.first_element_child.name == "p" ?
|
103
|
+
note_p_parse(node, div) : note_parse1(node, div)
|
104
|
+
end
|
105
|
+
@note = false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -1,13 +1,25 @@
|
|
1
1
|
module IsoDoc::Function
|
2
2
|
module Cleanup
|
3
3
|
def textcleanup(docxml)
|
4
|
+
docxml = termref_cleanup(passthrough_cleanup(docxml))
|
5
|
+
end
|
6
|
+
|
7
|
+
def termref_cleanup(docxml)
|
4
8
|
docxml.
|
9
|
+
gsub(%r{\s*\[/TERMREF\]\s*</p>\s*<p>\s*\[TERMREF\]}, "; ").
|
5
10
|
gsub(/\[TERMREF\]\s*/, l10n("[#{@source_lbl}: ")).
|
6
11
|
gsub(/\s*\[MODIFICATION\]\s*\[\/TERMREF\]/, l10n(", #{@modified_lbl} [/TERMREF]")).
|
7
|
-
gsub(
|
12
|
+
gsub(%r{\s*\[\/TERMREF\]\s*}, l10n("]")).
|
8
13
|
gsub(/\s*\[MODIFICATION\]/, l10n(", #{@modified_lbl} — "))
|
9
14
|
end
|
10
15
|
|
16
|
+
def passthrough_cleanup(docxml)
|
17
|
+
docxml.split(%r{(<passthrough>|</passthrough>)}).each_slice(4).map do |a|
|
18
|
+
a.size > 2 and a[2] = HTMLEntities.new.decode(a[2])
|
19
|
+
[a[0], a[2]]
|
20
|
+
end.join
|
21
|
+
end
|
22
|
+
|
11
23
|
def cleanup(docxml)
|
12
24
|
comment_cleanup(docxml)
|
13
25
|
footnote_cleanup(docxml)
|
@@ -118,7 +130,7 @@ module IsoDoc::Function
|
|
118
130
|
end
|
119
131
|
|
120
132
|
def footnote_cleanup(docxml)
|
121
|
-
docxml.xpath('//a[@
|
133
|
+
docxml.xpath('//a[@class = "FootnoteRef"]/sup').each_with_index do |x, i|
|
122
134
|
x.content = (i + 1).to_s
|
123
135
|
end
|
124
136
|
docxml
|
data/lib/isodoc/function/i18n.rb
CHANGED
@@ -87,6 +87,7 @@ module IsoDoc::Function
|
|
87
87
|
|
88
88
|
# TODO: move to localization file
|
89
89
|
def eref_localities1(target, type, from, to, delim, lang = "en")
|
90
|
+
return "" if type == "anchor"
|
90
91
|
return l10n(eref_localities1_zh(target, type, from, to, delim)) if lang == "zh"
|
91
92
|
ret = delim
|
92
93
|
loc = @locality[type] || type.sub(/^locality:/, "").capitalize
|
@@ -1,28 +1,7 @@
|
|
1
|
+
require_relative "inline_simple"
|
2
|
+
|
1
3
|
module IsoDoc::Function
|
2
4
|
module Inline
|
3
|
-
def section_break(body)
|
4
|
-
body.br
|
5
|
-
end
|
6
|
-
|
7
|
-
def page_break(out)
|
8
|
-
out.br
|
9
|
-
end
|
10
|
-
|
11
|
-
def pagebreak_parse(_node, out)
|
12
|
-
out.br
|
13
|
-
end
|
14
|
-
|
15
|
-
def hr_parse(node, out)
|
16
|
-
out.hr
|
17
|
-
end
|
18
|
-
|
19
|
-
def br_parse(node, out)
|
20
|
-
out.br
|
21
|
-
end
|
22
|
-
|
23
|
-
def index_parse(node, out)
|
24
|
-
end
|
25
|
-
|
26
5
|
def link_parse(node, out)
|
27
6
|
out.a **attr_code(href: node["target"], title: node["alt"]) do |l|
|
28
7
|
if node.text.empty?
|
@@ -38,29 +17,51 @@ module IsoDoc::Function
|
|
38
17
|
end
|
39
18
|
|
40
19
|
def prefix_container(container, linkend, _target)
|
41
|
-
l10n(anchor(container, :xref) + ", " + linkend)
|
20
|
+
l10n(@xrefs.anchor(container, :xref) + ", " + linkend)
|
42
21
|
end
|
43
22
|
|
44
23
|
def anchor_linkend(node, linkend)
|
45
24
|
if node["citeas"].nil? && node["bibitemid"]
|
46
|
-
return anchor(node["bibitemid"] ,:xref) || "???"
|
25
|
+
return @xrefs.anchor(node["bibitemid"] ,:xref) || "???"
|
47
26
|
elsif node["target"] && !/.#./.match(node["target"])
|
48
|
-
linkend = anchor(node["target"], :xref)
|
49
|
-
container = anchor(node["target"], :container, false)
|
27
|
+
linkend = @xrefs.anchor(node["target"], :xref)
|
28
|
+
container = @xrefs.anchor(node["target"], :container, false)
|
50
29
|
(container && get_note_container_id(node) != container &&
|
51
|
-
@
|
30
|
+
@xrefs.get[node["target"]]) &&
|
52
31
|
linkend = prefix_container(container, linkend, node["target"])
|
32
|
+
linkend = capitalise_xref(node, linkend)
|
53
33
|
end
|
54
34
|
linkend || "???"
|
55
35
|
end
|
56
36
|
|
37
|
+
def capitalise_xref(node, linkend)
|
38
|
+
return linkend unless %w(Latn Cyrl Grek).include? @script
|
39
|
+
return linkend&.capitalize if node["case"] == "capital"
|
40
|
+
return linkend&.downcase if node["case"] == "lowercase"
|
41
|
+
return linkend if linkend[0,1].match(/\p{Upper}/)
|
42
|
+
prec = nearest_block_parent(node).xpath("./descendant-or-self::text()") &
|
43
|
+
node.xpath("./preceding::text()")
|
44
|
+
(prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map { |p| p.text }.join)) ?
|
45
|
+
linkend&.capitalize : linkend
|
46
|
+
end
|
47
|
+
|
48
|
+
def nearest_block_parent(node)
|
49
|
+
until %w(p title td th name formula
|
50
|
+
li dt dd sourcecode pre).include?(node.name)
|
51
|
+
node = node.parent
|
52
|
+
end
|
53
|
+
node
|
54
|
+
end
|
55
|
+
|
57
56
|
def get_linkend(node)
|
58
|
-
contents = node.children.select
|
59
|
-
|
57
|
+
contents = node.children.select do |c|
|
58
|
+
!%w{locality localityStack}.include? c.name
|
59
|
+
end.select { |c| !c.text? || /\S/.match(c) }
|
60
60
|
!contents.empty? and
|
61
61
|
return Nokogiri::XML::NodeSet.new(node.document, contents).to_xml
|
62
62
|
link = anchor_linkend(node, docid_l10n(node["target"] || node["citeas"]))
|
63
|
-
link + eref_localities(node.xpath(ns("./locality | ./localityStack")),
|
63
|
+
link + eref_localities(node.xpath(ns("./locality | ./localityStack")),
|
64
|
+
link)
|
64
65
|
# so not <origin bibitemid="ISO7301" citeas="ISO 7301">
|
65
66
|
# <locality type="section"><reference>3.1</reference></locality></origin>
|
66
67
|
end
|
@@ -83,27 +84,44 @@ module IsoDoc::Function
|
|
83
84
|
end
|
84
85
|
else
|
85
86
|
ret += eref_localities0(r, i, target, delim)
|
86
|
-
|
87
|
+
end
|
87
88
|
end
|
88
89
|
ret
|
89
90
|
end
|
90
91
|
|
91
92
|
def eref_localities0(r, i, target, delim)
|
92
|
-
if r["type"] == "whole" then l10n("#{delim} #{@
|
93
|
+
if r["type"] == "whole" then l10n("#{delim} #{@wholeoftext_lbl}")
|
93
94
|
else
|
94
95
|
eref_localities1(target, r["type"], r.at(ns("./referenceFrom")),
|
95
96
|
r.at(ns("./referenceTo")), delim, @lang)
|
96
97
|
end
|
97
98
|
end
|
98
99
|
|
100
|
+
def suffix_url(url)
|
101
|
+
return url if %r{^http[s]?://}.match(url)
|
102
|
+
url.sub(/#{File.extname(url)}$/, ".html")
|
103
|
+
end
|
104
|
+
|
105
|
+
def eref_target(node)
|
106
|
+
href = "#" + node["bibitemid"]
|
107
|
+
url = node.at(ns("//bibitem[@id = '#{node['bibitemid']}']/"\
|
108
|
+
"uri[@type = 'citation']"))
|
109
|
+
return href unless url
|
110
|
+
href = suffix_url(url.text)
|
111
|
+
anchor = node&.at(ns(".//locality[@type = 'anchor']"))&.text
|
112
|
+
anchor and href += "##{anchor}"
|
113
|
+
href
|
114
|
+
end
|
115
|
+
|
99
116
|
def eref_parse(node, out)
|
100
117
|
linkend = get_linkend(node)
|
118
|
+
href = eref_target(node)
|
101
119
|
if node["type"] == "footnote"
|
102
120
|
out.sup do |s|
|
103
|
-
s.a(**{ "href":
|
121
|
+
s.a(**{ "href": href }) { |l| l << linkend }
|
104
122
|
end
|
105
123
|
else
|
106
|
-
out.a(**{ "href":
|
124
|
+
out.a(**{ "href": href }) { |l| l << linkend }
|
107
125
|
end
|
108
126
|
end
|
109
127
|
|
@@ -120,8 +138,9 @@ module IsoDoc::Function
|
|
120
138
|
end
|
121
139
|
|
122
140
|
def concept_parse(node, out)
|
123
|
-
content = node.first_element_child.children.select
|
124
|
-
|
141
|
+
content = node.first_element_child.children.select do |c|
|
142
|
+
!%w{locality localityStack}.include? c.name
|
143
|
+
end.select { |c| !c.text? || /\S/.match(c) }
|
125
144
|
if content.empty?
|
126
145
|
out << "[Term defined in "
|
127
146
|
parse(node.first_element_child, out)
|
@@ -133,7 +152,8 @@ module IsoDoc::Function
|
|
133
152
|
|
134
153
|
def stem_parse(node, out)
|
135
154
|
ooml = if node["type"] == "AsciiMath"
|
136
|
-
"#{@openmathdelim}#{HTMLEntities.new.encode(node.text)}
|
155
|
+
"#{@openmathdelim}#{HTMLEntities.new.encode(node.text)}"\
|
156
|
+
"#{@closemathdelim}"
|
137
157
|
elsif node["type"] == "MathML" then node.first_element_child.to_s
|
138
158
|
else
|
139
159
|
HTMLEntities.new.encode(node.text)
|
@@ -175,57 +195,31 @@ module IsoDoc::Function
|
|
175
195
|
out << text
|
176
196
|
end
|
177
197
|
|
178
|
-
def
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
def keyword_parse(node, out)
|
183
|
-
out.span **{ class: "keyword" } do |s|
|
184
|
-
node.children.each { |n| parse(n, s) }
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
def em_parse(node, out)
|
189
|
-
out.i do |e|
|
190
|
-
node.children.each { |n| parse(n, e) }
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
def strong_parse(node, out)
|
195
|
-
out.b do |e|
|
196
|
-
node.children.each { |n| parse(n, e) }
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def sup_parse(node, out)
|
201
|
-
out.sup do |e|
|
202
|
-
node.children.each { |n| parse(n, e) }
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
def sub_parse(node, out)
|
207
|
-
out.sub do |e|
|
208
|
-
node.children.each { |n| parse(n, e) }
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
def tt_parse(node, out)
|
213
|
-
out.tt do |e|
|
214
|
-
node.children.each { |n| parse(n, e) }
|
198
|
+
def error_parse(node, out)
|
199
|
+
text = node.to_xml.gsub(/</, "<").gsub(/>/, ">")
|
200
|
+
out.para do |p|
|
201
|
+
p.b(**{ role: "strong" }) { |e| e << text }
|
215
202
|
end
|
216
203
|
end
|
217
204
|
|
218
|
-
def
|
219
|
-
|
220
|
-
node.children.each { |n| parse(n,
|
205
|
+
def variant_parse(node, out)
|
206
|
+
if node["lang"] == @lang && node["script"] == @script
|
207
|
+
node.children.each { |n| parse(n, out) }
|
208
|
+
else
|
209
|
+
return if found_matching_variant_sibling(node)
|
210
|
+
return unless !node.at("./preceding-sibling::xmlns:variant")
|
211
|
+
node.children.each { |n| parse(n, out) }
|
221
212
|
end
|
222
213
|
end
|
223
214
|
|
224
|
-
def
|
225
|
-
|
226
|
-
|
227
|
-
|
215
|
+
def found_matching_variant_sibling(node)
|
216
|
+
prev = node.xpath("./preceding-sibling::xmlns:variant")
|
217
|
+
foll = node.xpath("./following-sibling::xmlns:variant")
|
218
|
+
found = false
|
219
|
+
(prev + foll).each do |n|
|
220
|
+
found = true if n["lang"] == @lang && n["script"] == @script
|
228
221
|
end
|
222
|
+
found
|
229
223
|
end
|
230
224
|
end
|
231
225
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module IsoDoc::Function
|
2
|
+
module Inline
|
3
|
+
def section_break(body)
|
4
|
+
body.br
|
5
|
+
end
|
6
|
+
|
7
|
+
def page_break(out)
|
8
|
+
out.br
|
9
|
+
end
|
10
|
+
|
11
|
+
def pagebreak_parse(_node, out)
|
12
|
+
out.br
|
13
|
+
end
|
14
|
+
|
15
|
+
def hr_parse(node, out)
|
16
|
+
out.hr
|
17
|
+
end
|
18
|
+
|
19
|
+
def br_parse(node, out)
|
20
|
+
out.br
|
21
|
+
end
|
22
|
+
|
23
|
+
def index_parse(node, out)
|
24
|
+
end
|
25
|
+
|
26
|
+
def bookmark_parse(node, out)
|
27
|
+
out.a **attr_code(id: node["id"])
|
28
|
+
end
|
29
|
+
|
30
|
+
def keyword_parse(node, out)
|
31
|
+
out.span **{ class: "keyword" } do |s|
|
32
|
+
node.children.each { |n| parse(n, s) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def em_parse(node, out)
|
37
|
+
out.i do |e|
|
38
|
+
node.children.each { |n| parse(n, e) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def strong_parse(node, out)
|
43
|
+
out.b do |e|
|
44
|
+
node.children.each { |n| parse(n, e) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def sup_parse(node, out)
|
49
|
+
out.sup do |e|
|
50
|
+
node.children.each { |n| parse(n, e) }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def sub_parse(node, out)
|
55
|
+
out.sub do |e|
|
56
|
+
node.children.each { |n| parse(n, e) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def tt_parse(node, out)
|
61
|
+
out.tt do |e|
|
62
|
+
node.children.each { |n| parse(n, e) }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def strike_parse(node, out)
|
67
|
+
out.s do |e|
|
68
|
+
node.children.each { |n| parse(n, e) }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|