isodoc 1.6.7 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/isodoc.gemspec +1 -1
  3. data/lib/isodoc-yaml/i18n-ar.yaml +19 -25
  4. data/lib/isodoc-yaml/i18n-de.yaml +1 -0
  5. data/lib/isodoc-yaml/i18n-en.yaml +1 -0
  6. data/lib/isodoc-yaml/i18n-es.yaml +1 -0
  7. data/lib/isodoc-yaml/i18n-fr.yaml +1 -0
  8. data/lib/isodoc-yaml/i18n-ru.yaml +1 -0
  9. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +1 -0
  10. data/lib/isodoc.rb +1 -0
  11. data/lib/isodoc/convert.rb +1 -1
  12. data/lib/isodoc/function/blocks.rb +180 -168
  13. data/lib/isodoc/function/form.rb +39 -36
  14. data/lib/isodoc/function/inline.rb +5 -1
  15. data/lib/isodoc/function/references.rb +1 -1
  16. data/lib/isodoc/function/to_word_html.rb +206 -204
  17. data/lib/isodoc/html_convert.rb +0 -4
  18. data/lib/isodoc/html_function/form.rb +48 -45
  19. data/lib/isodoc/html_function/html.rb +2 -0
  20. data/lib/isodoc/html_function/postprocess.rb +9 -4
  21. data/lib/isodoc/presentation_function/block.rb +7 -4
  22. data/lib/isodoc/presentation_function/inline.rb +29 -12
  23. data/lib/isodoc/presentation_function/section.rb +1 -2
  24. data/lib/isodoc/presentation_xml_convert.rb +2 -2
  25. data/lib/isodoc/version.rb +1 -1
  26. data/lib/isodoc/xref.rb +8 -7
  27. data/lib/isodoc/xref/xref_anchor.rb +45 -44
  28. data/lib/isodoc/xref/xref_counter.rb +113 -103
  29. data/lib/isodoc/xref/xref_gen.rb +39 -11
  30. data/lib/metanorma/output.rb +7 -0
  31. data/lib/metanorma/output/base.rb +13 -0
  32. data/lib/metanorma/output/utils.rb +17 -0
  33. data/lib/metanorma/output/xslfo.rb +21 -0
  34. data/spec/assets/outputtest/a.xml +66 -0
  35. data/spec/assets/outputtest/iso.international-standard.xsl +3011 -0
  36. data/spec/isodoc/blocks_spec.rb +327 -243
  37. data/spec/isodoc/form_spec.rb +94 -90
  38. data/spec/isodoc/inline_spec.rb +431 -234
  39. data/spec/isodoc/postproc_spec.rb +68 -25
  40. data/spec/isodoc/terms_spec.rb +2 -2
  41. data/spec/isodoc/xref_spec.rb +274 -652
  42. metadata +8 -18
  43. data/lib/isodoc/html_function/sectionsplit.rb +0 -230
  44. data/spec/isodoc/sectionsplit_spec.rb +0 -190
@@ -1,48 +1,51 @@
1
- module IsoDoc::Function
2
- module Form
3
- def form_parse(node, out)
4
- node.children.each do |n|
5
- parse(n, out)
1
+ module IsoDoc
2
+ module Function
3
+ module Form
4
+ def form_parse(node, out)
5
+ out.div **attr_code(class: node["class"],
6
+ id: node["id"]) do |div|
7
+ node.children.each do |n|
8
+ parse(n, div)
9
+ end
10
+ end
6
11
  end
7
- end
8
12
 
9
- def input_parse(node, out)
10
- case node["type"]
11
- when "button" then out << "[#{node['value'] || 'BUTTON'}]"
12
- when "checkbox" then out << "&#x2610; "
13
- when "date" then text_input(out)
14
- when "file" then text_input(out)
15
- when "password" then text_input(out)
16
- when "radio" then out << "&#x25CE; "
17
- when "submit" # nop
18
- when "text" then text_input(out, node["maxlength"])
13
+ def input_parse(node, out)
14
+ case node["type"]
15
+ when "button" then out << "[#{node['value'] || 'BUTTON'}]"
16
+ when "checkbox" then out << "&#x2610; "
17
+ when "date", "file", "password" then text_input(out)
18
+ when "radio" then out << "&#x25CE; "
19
+ when "submit" # nop
20
+ when "text" then text_input(out, node["maxlength"])
21
+ end
19
22
  end
20
- end
21
23
 
22
- def text_input(out, length = 10)
23
- length ||= 10
24
- length = length.to_i
25
- length.zero? and length = 10
26
- out << "_" * length
27
- out << " "
28
- end
24
+ def text_input(out, length = 10)
25
+ length ||= 10
26
+ length = length.to_i
27
+ length.zero? and length = 10
28
+ out << "_" * length
29
+ out << " "
30
+ end
29
31
 
30
- def select_parse(node, out)
31
- text_input(out, node["size"] || 10)
32
- end
32
+ def select_parse(node, out)
33
+ text_input(out, node["size"] || 10)
34
+ end
33
35
 
34
- def label_parse(node, out)
35
- node.children.each do |n|
36
- parse(n, out)
36
+ def label_parse(node, out)
37
+ node.children.each do |n|
38
+ parse(n, out)
39
+ end
37
40
  end
38
- end
39
41
 
40
- def option_parse(node, out); end
42
+ def option_parse(node, out); end
41
43
 
42
- def textarea_parse(_node, out)
43
- out.table **{ border: 1, width: "50%" } do |t|
44
- t.tr do |tr|
45
- tr.td do |td|
44
+ def textarea_parse(_node, out)
45
+ out.table **{ border: 1, width: "50%" } do |t|
46
+ t.tr do |tr|
47
+ tr.td do |td|
48
+ end
46
49
  end
47
50
  end
48
51
  end
@@ -71,7 +71,11 @@ module IsoDoc::Function
71
71
  end
72
72
 
73
73
  def termrefelem_parse(node, out)
74
- out << "Termbase #{node['base']}, term ID #{node['target']}"
74
+ if node.text.strip.empty?
75
+ out << "Termbase #{node['base']}, term ID #{node['target']}"
76
+ else
77
+ node.children.each { |n| parse(n, out) }
78
+ end
75
79
  end
76
80
 
77
81
  def stem_parse(node, out)
@@ -58,7 +58,7 @@ module IsoDoc::Function
58
58
  "@type = 'ISBN']"))
59
59
  return [id, id1, id2] if id || id1 || id2
60
60
 
61
- id = Nokogiri::XML::Node.new("docidentifier", b.document)
61
+ id = Nokogiri::XML::Node.new("docidentifier", bib.document)
62
62
  id << "(NO ID)"
63
63
  [nil, id, nil]
64
64
  end
@@ -1,237 +1,239 @@
1
1
  require "fileutils"
2
2
  require "pathname"
3
3
 
4
- module IsoDoc::Function
5
- module ToWordHtml
6
-
7
- def set_termdomain(termdomain)
8
- @termdomain = termdomain
9
- end
4
+ module IsoDoc
5
+ module Function
6
+ module ToWordHtml
7
+ def set_termdomain(termdomain)
8
+ @termdomain = termdomain
9
+ end
10
10
 
11
- def in_sourcecode
12
- @sourcecode
13
- end
11
+ def in_sourcecode
12
+ @sourcecode
13
+ end
14
14
 
15
- def note?
16
- @note
17
- end
15
+ def note?
16
+ @note
17
+ end
18
18
 
19
- def init_file(filename, debug)
20
- filepath = Pathname.new(filename)
21
- filename = filepath.sub_ext("").sub(/\.presentation$/, "").to_s
22
- dir = init_dir(filename, debug)
23
- @filename = filename
24
- @localdir = "#{filepath.parent}/"
25
- @sourcedir = @localdir
26
- @sourcefilename and
27
- @sourcedir = "#{Pathname.new(@sourcefilename).parent}/"
28
- [filename, dir]
29
- end
19
+ def init_file(filename, debug)
20
+ filepath = Pathname.new(filename)
21
+ filename = filepath.sub_ext("").sub(/\.presentation$/, "").to_s
22
+ dir = init_dir(filename, debug)
23
+ @filename = filename
24
+ @localdir = "#{filepath.parent}/"
25
+ @sourcedir = @localdir
26
+ @sourcefilename and
27
+ @sourcedir = "#{Pathname.new(@sourcefilename).parent}/"
28
+ [filename, dir]
29
+ end
30
30
 
31
- def init_dir(filename, debug)
32
- dir = "#{filename}_files"
33
- unless debug
34
- Dir.mkdir(dir, 0o777) unless File.exists?(dir)
35
- FileUtils.rm_rf "#{dir}/*"
31
+ def init_dir(filename, debug)
32
+ dir = "#{filename}_files"
33
+ unless debug
34
+ Dir.mkdir(dir, 0o777) unless File.exists?(dir)
35
+ FileUtils.rm_rf "#{dir}/*"
36
+ end
37
+ dir
36
38
  end
37
- dir
38
- end
39
39
 
40
- # tmp image dir is same directory as @filename
41
- def tmpimagedir
42
- @filename + tmpimagedir_suffix
43
- end
40
+ # tmp image dir is same directory as @filename
41
+ def tmpimagedir
42
+ @filename + tmpimagedir_suffix
43
+ end
44
44
 
45
- def rel_tmpimagedir
46
- Pathname.new(@filename).basename.to_s + tmpimagedir_suffix
47
- end
45
+ def rel_tmpimagedir
46
+ Pathname.new(@filename).basename.to_s + tmpimagedir_suffix
47
+ end
48
48
 
49
- # isodoc.css overrides any CSS injected by Html2Doc, which
50
- # is inserted before this CSS.
51
- def define_head(head, _filename, _dir)
52
- if @standardstylesheet
53
- head.style do |style|
54
- @standardstylesheet.open
55
- stylesheet = @standardstylesheet.read
56
- style.comment "\n#{stylesheet}\n"
49
+ # isodoc.css overrides any CSS injected by Html2Doc, which
50
+ # is inserted before this CSS.
51
+ def define_head(head, _filename, _dir)
52
+ if @standardstylesheet
53
+ head.style do |style|
54
+ @standardstylesheet.open
55
+ stylesheet = @standardstylesheet.read
56
+ style.comment "\n#{stylesheet}\n"
57
+ end
57
58
  end
58
59
  end
59
- end
60
60
 
61
- def body_attr
62
- { lang: @lang.to_s }
63
- end
64
-
65
- def make_body(xml, docxml)
66
- xml.body **body_attr do |body|
67
- make_body1(body, docxml)
68
- make_body2(body, docxml)
69
- make_body3(body, docxml)
61
+ def body_attr
62
+ { lang: @lang.to_s }
70
63
  end
71
- end
72
64
 
73
- def make_body1(body, _docxml)
74
- body.div **{ class: "title-section" } do |div1|
75
- div1.p { |p| p << "&nbsp;" } # placeholder
65
+ def make_body(xml, docxml)
66
+ xml.body **body_attr do |body|
67
+ make_body1(body, docxml)
68
+ make_body2(body, docxml)
69
+ make_body3(body, docxml)
70
+ end
76
71
  end
77
- section_break(body)
78
- end
79
72
 
80
- def make_body2(body, _docxml)
81
- body.div **{ class: "prefatory-section" } do |div2|
82
- div2.p { |p| p << "&nbsp;" } # placeholder
73
+ def make_body1(body, _docxml)
74
+ body.div **{ class: "title-section" } do |div1|
75
+ div1.p { |p| p << "&nbsp;" } # placeholder
76
+ end
77
+ section_break(body)
83
78
  end
84
- section_break(body)
85
- end
86
79
 
87
- def make_body3(body, docxml)
88
- body.div **{ class: "main-section" } do |div3|
89
- boilerplate docxml, div3
90
- preface_block docxml, div3
91
- abstract docxml, div3
92
- foreword docxml, div3
93
- introduction docxml, div3
94
- acknowledgements docxml, div3
95
- middle docxml, div3
96
- footnotes div3
97
- comments div3
80
+ def make_body2(body, _docxml)
81
+ body.div **{ class: "prefatory-section" } do |div2|
82
+ div2.p { |p| p << "&nbsp;" } # placeholder
83
+ end
84
+ section_break(body)
98
85
  end
99
- end
100
86
 
101
- def info(isoxml, out)
102
- @meta.title isoxml, out
103
- @meta.subtitle isoxml, out
104
- @meta.docstatus isoxml, out
105
- @meta.docid isoxml, out
106
- @meta.otherid isoxml, out
107
- @meta.docnumeric isoxml, out
108
- @meta.doctype isoxml, out
109
- @meta.author isoxml, out
110
- @meta.bibdate isoxml, out
111
- @meta.relations isoxml, out
112
- @meta.version isoxml, out
113
- @meta.url isoxml, out
114
- @meta.keywords isoxml, out
115
- @meta.note isoxml, out
116
- @meta.get
117
- end
87
+ def make_body3(body, docxml)
88
+ body.div **{ class: "main-section" } do |div3|
89
+ boilerplate docxml, div3
90
+ preface_block docxml, div3
91
+ abstract docxml, div3
92
+ foreword docxml, div3
93
+ introduction docxml, div3
94
+ acknowledgements docxml, div3
95
+ middle docxml, div3
96
+ footnotes div3
97
+ comments div3
98
+ end
99
+ end
118
100
 
119
- def middle(isoxml, out)
120
- middle_title(isoxml, out)
121
- middle_admonitions(isoxml, out)
122
- i = scope isoxml, out, 0
123
- i = norm_ref isoxml, out, i
124
- i = terms_defs isoxml, out, i
125
- symbols_abbrevs isoxml, out, i
126
- clause isoxml, out
127
- annex isoxml, out
128
- bibliography isoxml, out
129
- end
101
+ def info(isoxml, out)
102
+ @meta.title isoxml, out
103
+ @meta.subtitle isoxml, out
104
+ @meta.docstatus isoxml, out
105
+ @meta.docid isoxml, out
106
+ @meta.otherid isoxml, out
107
+ @meta.docnumeric isoxml, out
108
+ @meta.doctype isoxml, out
109
+ @meta.author isoxml, out
110
+ @meta.bibdate isoxml, out
111
+ @meta.relations isoxml, out
112
+ @meta.version isoxml, out
113
+ @meta.url isoxml, out
114
+ @meta.keywords isoxml, out
115
+ @meta.note isoxml, out
116
+ @meta.get
117
+ end
130
118
 
131
- def boilerplate(node, out)
132
- return if @bare
119
+ def middle(isoxml, out)
120
+ middle_title(isoxml, out)
121
+ middle_admonitions(isoxml, out)
122
+ i = scope isoxml, out, 0
123
+ i = norm_ref isoxml, out, i
124
+ i = terms_defs isoxml, out, i
125
+ symbols_abbrevs isoxml, out, i
126
+ clause isoxml, out
127
+ annex isoxml, out
128
+ bibliography isoxml, out
129
+ end
133
130
 
134
- boilerplate = node.at(ns("//boilerplate")) or return
135
- out.div **{ class: "authority" } do |s|
136
- boilerplate.children.each do |n|
137
- if n.name == "title"
138
- s.h1 do |h|
139
- n.children.each { |nn| parse(nn, h) }
131
+ def boilerplate(node, out)
132
+ return if @bare
133
+
134
+ boilerplate = node.at(ns("//boilerplate")) or return
135
+ out.div **{ class: "authority" } do |s|
136
+ boilerplate.children.each do |n|
137
+ if n.name == "title"
138
+ s.h1 do |h|
139
+ n.children.each { |nn| parse(nn, h) }
140
+ end
141
+ else parse(n, s)
140
142
  end
141
- else parse(n, s)
142
143
  end
143
144
  end
144
145
  end
145
- end
146
146
 
147
- def parse(node, out)
148
- if node.text? then text_parse(node, out)
149
- else
150
- case node.name
151
- when "em" then em_parse(node, out)
152
- when "strong" then strong_parse(node, out)
153
- when "sup" then sup_parse(node, out)
154
- when "sub" then sub_parse(node, out)
155
- when "tt" then tt_parse(node, out)
156
- when "strike" then strike_parse(node, out)
157
- when "underline" then underline_parse(node, out)
158
- when "keyword" then keyword_parse(node, out)
159
- when "smallcap" then smallcap_parse(node, out)
160
- when "br" then br_parse(node, out)
161
- when "hr" then hr_parse(node, out)
162
- when "bookmark" then bookmark_parse(node, out)
163
- when "pagebreak" then pagebreak_parse(node, out)
164
- when "callout" then callout_parse(node, out)
165
- when "stem" then stem_parse(node, out)
166
- when "clause" then clause_parse(node, out)
167
- when "xref" then xref_parse(node, out)
168
- when "eref" then eref_parse(node, out)
169
- when "origin" then origin_parse(node, out)
170
- when "link" then link_parse(node, out)
171
- when "ul" then ul_parse(node, out)
172
- when "ol" then ol_parse(node, out)
173
- when "li" then li_parse(node, out)
174
- when "dl" then dl_parse(node, out)
175
- when "fn" then footnote_parse(node, out)
176
- when "p" then para_parse(node, out)
177
- when "quote" then quote_parse(node, out)
178
- when "tr" then tr_parse(node, out)
179
- when "note" then note_parse(node, out)
180
- when "review" then review_note_parse(node, out)
181
- when "admonition" then admonition_parse(node, out)
182
- when "formula" then formula_parse(node, out)
183
- when "table" then table_parse(node, out)
184
- when "figure" then figure_parse(node, out)
185
- when "example" then example_parse(node, out)
186
- when "image" then image_parse(node, out, nil)
187
- when "sourcecode" then sourcecode_parse(node, out)
188
- when "pre" then pre_parse(node, out)
189
- when "annotation" then annotation_parse(node, out)
190
- when "term" then termdef_parse(node, out)
191
- when "preferred" then term_parse(node, out)
192
- when "admitted" then admitted_term_parse(node, out)
193
- when "deprecates" then deprecated_term_parse(node, out)
194
- when "domain" then set_termdomain(node.text)
195
- when "definition" then definition_parse(node, out)
196
- when "termsource" then termref_parse(node, out)
197
- when "modification" then modification_parse(node, out)
198
- when "termnote" then termnote_parse(node, out)
199
- when "termexample" then example_parse(node, out)
200
- when "terms" then terms_parse(node, out)
201
- when "definitions" then symbols_parse(node, out)
202
- when "references" then bibliography_parse(node, out)
203
- when "termdocsource" then termdocsource_parse(node, out)
204
- when "requirement" then requirement_parse(node, out)
205
- when "recommendation" then recommendation_parse(node, out)
206
- when "permission" then permission_parse(node, out)
207
- when "subject" then requirement_skip_parse(node, out)
208
- when "classification" then requirement_skip_parse(node, out)
209
- when "inherit" then requirement_component_parse(node, out)
210
- when "description" then requirement_component_parse(node, out)
211
- when "specification" then requirement_component_parse(node, out)
212
- when "measurement-target" then requirement_component_parse(node, out)
213
- when "verification" then requirement_component_parse(node, out)
214
- when "import" then requirement_component_parse(node, out)
215
- when "index" then index_parse(node, out)
216
- when "index-xref" then index_xref_parse(node, out)
217
- when "termref" then termrefelem_parse(node, out)
218
- when "copyright-statement" then copyright_parse(node, out)
219
- when "license-statement" then license_parse(node, out)
220
- when "legal-statement" then legal_parse(node, out)
221
- when "feedback-statement" then feedback_parse(node, out)
222
- when "passthrough" then passthrough_parse(node, out)
223
- when "amend" then amend_parse(node, out)
224
- when "tab" then clausedelimspace(out) # in Presentation XML only
225
- when "svg" then svg_parse(node, out) # in Presentation XML only
226
- when "add" then add_parse(node, out)
227
- when "del" then del_parse(node, out)
228
- when "form" then form_parse(node, out)
229
- when "input" then input_parse(node, out)
230
- when "select" then select_parse(node, out)
231
- when "label" then label_parse(node, out)
232
- when "option" then option_parse(node, out)
233
- when "textarea" then textarea_parse(node, out)
234
- else error_parse(node, out)
147
+ def parse(node, out)
148
+ if node.text? then text_parse(node, out)
149
+ else
150
+ case node.name
151
+ when "em" then em_parse(node, out)
152
+ when "strong" then strong_parse(node, out)
153
+ when "sup" then sup_parse(node, out)
154
+ when "sub" then sub_parse(node, out)
155
+ when "tt" then tt_parse(node, out)
156
+ when "strike" then strike_parse(node, out)
157
+ when "underline" then underline_parse(node, out)
158
+ when "keyword" then keyword_parse(node, out)
159
+ when "smallcap" then smallcap_parse(node, out)
160
+ when "br" then br_parse(node, out)
161
+ when "hr" then hr_parse(node, out)
162
+ when "bookmark" then bookmark_parse(node, out)
163
+ when "pagebreak" then pagebreak_parse(node, out)
164
+ when "callout" then callout_parse(node, out)
165
+ when "stem" then stem_parse(node, out)
166
+ when "clause" then clause_parse(node, out)
167
+ when "xref" then xref_parse(node, out)
168
+ when "eref" then eref_parse(node, out)
169
+ when "origin" then origin_parse(node, out)
170
+ when "link" then link_parse(node, out)
171
+ when "ul" then ul_parse(node, out)
172
+ when "ol" then ol_parse(node, out)
173
+ when "li" then li_parse(node, out)
174
+ when "dl" then dl_parse(node, out)
175
+ when "fn" then footnote_parse(node, out)
176
+ when "p" then para_parse(node, out)
177
+ when "quote" then quote_parse(node, out)
178
+ when "tr" then tr_parse(node, out)
179
+ when "note" then note_parse(node, out)
180
+ when "review" then review_note_parse(node, out)
181
+ when "admonition" then admonition_parse(node, out)
182
+ when "formula" then formula_parse(node, out)
183
+ when "table" then table_parse(node, out)
184
+ when "figure" then figure_parse(node, out)
185
+ when "example" then example_parse(node, out)
186
+ when "image" then image_parse(node, out, nil)
187
+ when "sourcecode" then sourcecode_parse(node, out)
188
+ when "pre" then pre_parse(node, out)
189
+ when "annotation" then annotation_parse(node, out)
190
+ when "term" then termdef_parse(node, out)
191
+ when "preferred" then term_parse(node, out)
192
+ when "admitted" then admitted_term_parse(node, out)
193
+ when "deprecates" then deprecated_term_parse(node, out)
194
+ when "domain" then set_termdomain(node.text)
195
+ when "definition" then definition_parse(node, out)
196
+ when "termsource" then termref_parse(node, out)
197
+ when "modification" then modification_parse(node, out)
198
+ when "termnote" then termnote_parse(node, out)
199
+ when "termexample" then example_parse(node, out)
200
+ when "terms" then terms_parse(node, out)
201
+ when "definitions" then symbols_parse(node, out)
202
+ when "references" then bibliography_parse(node, out)
203
+ when "termdocsource" then termdocsource_parse(node, out)
204
+ when "requirement" then requirement_parse(node, out)
205
+ when "recommendation" then recommendation_parse(node, out)
206
+ when "permission" then permission_parse(node, out)
207
+ when "subject" then requirement_skip_parse(node, out)
208
+ when "classification" then requirement_skip_parse(node, out)
209
+ when "inherit" then requirement_component_parse(node, out)
210
+ when "description" then requirement_component_parse(node, out)
211
+ when "specification" then requirement_component_parse(node, out)
212
+ when "measurement-target" then requirement_component_parse(node, out)
213
+ when "verification" then requirement_component_parse(node, out)
214
+ when "import" then requirement_component_parse(node, out)
215
+ when "index" then index_parse(node, out)
216
+ when "index-xref" then index_xref_parse(node, out)
217
+ when "termref" then termrefelem_parse(node, out)
218
+ when "copyright-statement" then copyright_parse(node, out)
219
+ when "license-statement" then license_parse(node, out)
220
+ when "legal-statement" then legal_parse(node, out)
221
+ when "feedback-statement" then feedback_parse(node, out)
222
+ when "passthrough" then passthrough_parse(node, out)
223
+ when "amend" then amend_parse(node, out)
224
+ when "tab" then clausedelimspace(out) # in Presentation XML only
225
+ when "svg" then svg_parse(node, out) # in Presentation XML only
226
+ when "add" then add_parse(node, out)
227
+ when "del" then del_parse(node, out)
228
+ when "form" then form_parse(node, out)
229
+ when "input" then input_parse(node, out)
230
+ when "select" then select_parse(node, out)
231
+ when "label" then label_parse(node, out)
232
+ when "option" then option_parse(node, out)
233
+ when "textarea" then textarea_parse(node, out)
234
+ when "toc" then toc_parse(node, out)
235
+ else error_parse(node, out)
236
+ end
235
237
  end
236
238
  end
237
239
  end