isodoc 1.0.22 → 1.0.27

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +12 -5
  3. data/.github/workflows/ubuntu.yml +27 -6
  4. data/.github/workflows/windows.yml +13 -7
  5. data/README.adoc +3 -2
  6. data/lib/isodoc-yaml/i18n-en.yaml +18 -1
  7. data/lib/isodoc-yaml/i18n-fr.yaml +18 -1
  8. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +18 -1
  9. data/lib/isodoc/base_style/bands.scss +6 -3
  10. data/lib/isodoc/base_style/reset.scss +1 -1
  11. data/lib/isodoc/convert.rb +1 -0
  12. data/lib/isodoc/function/blocks.rb +5 -0
  13. data/lib/isodoc/function/cleanup.rb +12 -1
  14. data/lib/isodoc/function/i18n.rb +5 -5
  15. data/lib/isodoc/function/inline.rb +47 -12
  16. data/lib/isodoc/function/references.rb +47 -33
  17. data/lib/isodoc/function/reqt.rb +21 -6
  18. data/lib/isodoc/function/section.rb +18 -8
  19. data/lib/isodoc/function/table.rb +0 -1
  20. data/lib/isodoc/function/to_word_html.rb +4 -2
  21. data/lib/isodoc/function/utils.rb +10 -4
  22. data/lib/isodoc/function/xref_gen.rb +2 -1
  23. data/lib/isodoc/function/xref_sect_gen.rb +24 -24
  24. data/lib/isodoc/headlesshtml_convert.rb +5 -0
  25. data/lib/isodoc/html_convert.rb +5 -0
  26. data/lib/isodoc/html_function/footnotes.rb +2 -2
  27. data/lib/isodoc/html_function/html.rb +3 -0
  28. data/lib/isodoc/html_function/postprocess.rb +3 -2
  29. data/lib/isodoc/metadata.rb +30 -7
  30. data/lib/isodoc/metadata_date.rb +39 -0
  31. data/lib/isodoc/pdf_convert.rb +5 -0
  32. data/lib/isodoc/version.rb +1 -1
  33. data/lib/isodoc/word_convert.rb +5 -0
  34. data/lib/isodoc/word_function/body.rb +0 -4
  35. data/lib/isodoc/word_function/footnotes.rb +2 -2
  36. data/lib/isodoc/word_function/postprocess.rb +13 -2
  37. data/lib/isodoc/word_function/table.rb +1 -3
  38. data/lib/isodoc/xslfo_convert.rb +5 -0
  39. data/spec/isodoc/blocks_spec.rb +188 -8
  40. data/spec/isodoc/cleanup_spec.rb +181 -18
  41. data/spec/isodoc/i18n_spec.rb +12 -12
  42. data/spec/isodoc/inline_spec.rb +65 -5
  43. data/spec/isodoc/metadata_spec.rb +77 -2
  44. data/spec/isodoc/postproc_spec.rb +33 -11
  45. data/spec/isodoc/ref_spec.rb +12 -6
  46. data/spec/isodoc/section_spec.rb +220 -205
  47. data/spec/isodoc/table_spec.rb +24 -24
  48. data/spec/isodoc/terms_spec.rb +50 -6
  49. data/spec/isodoc/xref_spec.rb +64 -26
  50. metadata +3 -2
@@ -108,7 +108,7 @@ module IsoDoc::HtmlFunction
108
108
  idx = docxml.at("//div[@id = 'toc']") or return docxml
109
109
  toc = "<ul>"
110
110
  path = toclevel_classes.map do |l|
111
- "//main//#{l}[not(@class = 'TermNum')][not(@class = 'noTOC')][not(text())]"
111
+ "//main//#{l}[not(@class = 'TermNum')][not(@class = 'noTOC')][text()]"
112
112
  end
113
113
  docxml.xpath(path.join(" | ")).each_with_index do |h, tocidx|
114
114
  h["id"] ||= "toc#{tocidx}"
@@ -159,7 +159,8 @@ module IsoDoc::HtmlFunction
159
159
  def inject_script(doc)
160
160
  return doc unless @scripts
161
161
  scripts = File.read(@scripts, encoding: "UTF-8")
162
- doc.sub("</body>", scripts + "\n</body>")
162
+ a = doc.split(%r{</body>})
163
+ a[0] + scripts + "</body>" + a[1]
163
164
  end
164
165
 
165
166
  def update_footnote_filter(fn, x, i, seen)
@@ -1,15 +1,22 @@
1
+ require_relative "./metadata_date"
2
+
1
3
  module IsoDoc
2
4
  class Metadata
3
5
  DATETYPES = %w{published accessed created implemented obsoleted confirmed
4
- updated issued received transmitted copied unchanged circulated}.freeze
6
+ updated issued received transmitted copied unchanged circulated vote-started
7
+ vote-ended}.freeze
5
8
 
6
9
  def ns(xpath)
7
10
  Common::ns(xpath)
8
11
  end
9
12
 
13
+ def l10n(a, b, c)
14
+ IsoDoc::Function::I18n::l10n(a, b, c)
15
+ end
16
+
10
17
  def initialize(lang, script, labels)
11
18
  @metadata = {}
12
- DATETYPES.each { |w| @metadata["#{w}date".to_sym] = "XXX" }
19
+ DATETYPES.each { |w| @metadata["#{w.gsub(/-/, "_")}date".to_sym] = "XXX" }
13
20
  @lang = lang
14
21
  @script = script
15
22
  @c = HTMLEntities.new
@@ -20,6 +27,10 @@ module IsoDoc
20
27
  @metadata
21
28
  end
22
29
 
30
+ def labels
31
+ @labels
32
+ end
33
+
23
34
  def set(key, value)
24
35
  @metadata[key] = value
25
36
  end
@@ -74,7 +85,7 @@ module IsoDoc
74
85
 
75
86
  def bibdate(isoxml, _out)
76
87
  isoxml.xpath(ns("//bibdata/date")).each do |d|
77
- set("#{d['type']}date".to_sym, Common::date_range(d))
88
+ set("#{d['type'].gsub(/-/, "_")}date".to_sym, Common::date_range(d))
78
89
  end
79
90
  end
80
91
 
@@ -93,14 +104,24 @@ module IsoDoc
93
104
 
94
105
  def agency(xml)
95
106
  agency = ""
107
+ publisher = []
96
108
  xml.xpath(ns("//bibdata/contributor[xmlns:role/@type = 'publisher']/"\
97
109
  "organization")).each do |org|
98
110
  name = org&.at(ns("./name"))&.text
99
- abbrev = org&.at(ns("./abbreviation"))&.text
100
- agency1 = abbrev || name
111
+ agency1 = org&.at(ns("./abbreviation"))&.text || name
112
+ publisher << name if name
101
113
  agency = iso?(org) ? "ISO/#{agency}" : "#{agency}#{agency1}/"
102
114
  end
103
115
  set(:agency, agency.sub(%r{/$}, ""))
116
+ set(:publisher, multiple_and(publisher, @labels["and"]))
117
+ end
118
+
119
+ def multiple_and(names, andword)
120
+ return "" if names.length == 0
121
+ return names[0] if names.length == 1
122
+ names.length == 2 and
123
+ return l10n("#{names[0]} #{andword} #{names[1]}", @lang, @script)
124
+ l10n(names[0..-2].join(", ") + " #{andword} #{names[-1]}", @lang, @script)
104
125
  end
105
126
 
106
127
  def docstatus(isoxml, _out)
@@ -148,14 +169,16 @@ module IsoDoc
148
169
  draftinfo += ", #{revdate}" if revdate
149
170
  draftinfo += ")"
150
171
  end
151
- IsoDoc::Function::I18n::l10n(draftinfo, @lang, @script)
172
+ l10n(draftinfo, @lang, @script)
152
173
  end
153
174
 
154
175
  def version(isoxml, _out)
155
176
  set(:edition, isoxml&.at(ns("//bibdata/edition"))&.text)
156
177
  set(:docyear, isoxml&.at(ns("//bibdata/copyright/from"))&.text)
157
178
  set(:draft, isoxml&.at(ns("//version/draft"))&.text)
158
- set(:revdate, isoxml&.at(ns("//version/revision-date"))&.text)
179
+ revdate = isoxml&.at(ns("//version/revision-date"))&.text
180
+ set(:revdate, revdate)
181
+ set(:revdate_monthyear, monthyr(revdate))
159
182
  set(:draftinfo,
160
183
  draftinfo(get[:draft], get[:revdate]))
161
184
  end
@@ -0,0 +1,39 @@
1
+ module IsoDoc
2
+ class Metadata
3
+ def months
4
+ {
5
+ "01": @labels["month_january"],
6
+ "02": @labels["month_february"],
7
+ "03": @labels["month_march"],
8
+ "04": @labels["month_april"],
9
+ "05": @labels["month_may"],
10
+ "06": @labels["month_june"],
11
+ "07": @labels["month_july"],
12
+ "08": @labels["month_august"],
13
+ "09": @labels["month_september"],
14
+ "10": @labels["month_october"],
15
+ "11": @labels["month_november"],
16
+ "12": @labels["month_december"],
17
+ }
18
+ end
19
+
20
+ def monthyr(isodate)
21
+ m = /(?<yr>\d\d\d\d)-(?<mo>\d\d)/.match isodate
22
+ return isodate unless m && m[:yr] && m[:mo]
23
+ IsoDoc::Function::I18n::l10n("#{months[m[:mo].to_sym]} #{m[:yr]}",
24
+ @lang, @script)
25
+ end
26
+
27
+ def MMMddyyyy(isodate)
28
+ return nil if isodate.nil?
29
+ arr = isodate.split("-")
30
+ date = if arr.size == 1 and (/^\d+$/.match isodate)
31
+ Date.new(*arr.map(&:to_i)).strftime("%Y")
32
+ elsif arr.size == 2
33
+ Date.new(*arr.map(&:to_i)).strftime("%B %Y")
34
+ else
35
+ Date.parse(isodate).strftime("%B %d, %Y")
36
+ end
37
+ end
38
+ end
39
+ end
@@ -22,6 +22,11 @@ module IsoDoc
22
22
  "_pdfimages"
23
23
  end
24
24
 
25
+ def initialize(options)
26
+ @format = :pdf
27
+ super
28
+ end
29
+
25
30
  def convert(filename, file = nil, debug = false)
26
31
  file = File.read(filename, encoding: "utf-8") if file.nil?
27
32
  @openmathdelim, @closemathdelim = extract_delims(file)
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.0.22".freeze
2
+ VERSION = "1.0.27".freeze
3
3
  end
@@ -30,6 +30,11 @@ module IsoDoc
30
30
  include WordFunction::Body
31
31
  include WordFunction::Postprocess
32
32
 
33
+ def initialize(options)
34
+ @format = :doc
35
+ super
36
+ end
37
+
33
38
  def convert(filename, file = nil, debug = false)
34
39
  ret = super
35
40
  FileUtils.rm_rf tmpimagedir
@@ -204,10 +204,6 @@ module IsoDoc::WordFunction
204
204
  alt: node["alt"],
205
205
  title: node["title"],
206
206
  width: node["width"] }
207
- if node["height"] == "auto" || node["width"] == "auto"
208
- attrs[:height] = nil
209
- attrs[:width] = nil
210
- end
211
207
  out.img **attr_code(attrs)
212
208
  image_title_parse(out, caption)
213
209
  end
@@ -56,7 +56,7 @@ module IsoDoc::WordFunction
56
56
  end
57
57
 
58
58
  def table_footnote_parse(node, out)
59
- fn = node["reference"]
59
+ fn = node["reference"] || UUIDTools::UUID.random_create.to_s
60
60
  tid = get_table_ancestor_id(node)
61
61
  make_table_footnote_link(out, tid + fn, fn)
62
62
  # do not output footnote text if we have already seen it for this table
@@ -80,7 +80,7 @@ module IsoDoc::WordFunction
80
80
  def footnote_parse(node, out)
81
81
  return table_footnote_parse(node, out) if (@in_table || @in_figure) &&
82
82
  !node.ancestors.map {|m| m.name }.include?("name")
83
- fn = node["reference"]
83
+ fn = node["reference"] || UUIDTools::UUID.random_create.to_s
84
84
  return seen_footnote_parse(node, out, fn) if @seen_footnote.include?(fn)
85
85
  @fn_bookmarks[fn] = bookmarkid
86
86
  out.span **{style: "mso-bookmark:_Ref#{@fn_bookmarks[fn]}"} do |s|
@@ -39,7 +39,6 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
39
39
  end
40
40
 
41
41
  def toWord(result, filename, dir, header)
42
- #result = populate_template(result, :word)
43
42
  result = from_xhtml(word_cleanup(to_xhtml(result)))
44
43
  unless @landscapestyle.empty?
45
44
  @wordstylesheet&.open
@@ -196,6 +195,8 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
196
195
  @landscapestyle = ""
197
196
  word_section_breaks1(docxml, "WordSection2")
198
197
  word_section_breaks1(docxml, "WordSection3")
198
+ word_remove_pb_before_annex(docxml)
199
+ docxml.xpath("//br[@orientation]").each { |br| br.delete("orientation") }
199
200
  end
200
201
 
201
202
  def word_section_breaks1(docxml, sect)
@@ -203,7 +204,6 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
203
204
  each_with_index do |br, i|
204
205
  @landscapestyle += "\ndiv.#{sect}_#{i} {page:#{sect}"\
205
206
  "#{br["orientation"] == "landscape" ? "L" : "P"};}\n"
206
- br.delete("orientation")
207
207
  split_at_section_break(docxml, sect, br, i)
208
208
  end
209
209
  end
@@ -219,6 +219,17 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
219
219
  end
220
220
  end
221
221
 
222
+ # applies for <div class="WordSectionN_M"><p><pagebreak/></p>...
223
+ def word_remove_pb_before_annex(docxml)
224
+ docxml.xpath("//div[p/br]").each do |d|
225
+ /^WordSection\d+_\d+$/.match(d["class"]) or next
226
+ d.elements[0].name == "p" && !d.elements[0].elements.empty? or next
227
+ d.elements[0].elements[0].name == "br" && d.elements[0].elements[0]["style"] ==
228
+ "mso-special-character:line-break;page-break-before:always" or next
229
+ d.elements[0].remove
230
+ end
231
+ end
232
+
222
233
  def word_footnote_format(docxml)
223
234
  # the content is in a[@epub:type = 'footnote']//sup, but in Word,
224
235
  # we need to inject content around the autonumbered footnote reference
@@ -37,9 +37,7 @@ module IsoDoc::WordFunction
37
37
  super.merge(attr_code({
38
38
  summary: node["summary"],
39
39
  width: node["width"],
40
- style: "mso-table-lspace:15.0cm;margin-left:423.0pt;"\
41
- "mso-table-rspace:15.0cm;margin-right:423.0pt;"\
42
- "mso-table-anchor-horizontal:column;"\
40
+ style: "mso-table-anchor-horizontal:column;"\
43
41
  "mso-table-overlap:never;border-spacing:0;border-width:1px;"
44
42
  }))
45
43
  end
@@ -13,6 +13,11 @@ module IsoDoc
13
13
  "_pdfimages"
14
14
  end
15
15
 
16
+ def initialize(options)
17
+ @format = :pdf
18
+ super
19
+ end
20
+
16
21
  def convert(filename, file = nil, debug = false)
17
22
  file = File.read(filename, encoding: "utf-8") if file.nil?
18
23
  docxml, outname_html, dir = convert_init(file, filename, debug)
@@ -417,8 +417,8 @@ B
417
417
  <div id="figureA-1" class="figure">
418
418
 
419
419
  <img src="rice_images/rice_image1.png" height="20" width="30" alt="alttext" title="titletext"/>
420
- <img src="rice_images/rice_image1.png"/>
421
- <img src="_.gif"/>
420
+ <img src="rice_images/rice_image1.png" height='20' width='auto'/>
421
+ <img src='_.gif' height='20' width='auto'/>
422
422
  <a href="#_" class="TableFootnoteRef">a</a><aside><div id="ftn_"><span><span id="_" class="TableFootnoteRef">a</span><span style="mso-tab-count:1">&#160; </span></span>
423
423
  <p id="_">The time <span class="stem">(#(t_90)#)</span> was estimated to be 18,2 min for this example.</p>
424
424
  </div></aside>
@@ -969,7 +969,7 @@ World

969
969
  INPUT
970
970
  #{HTML_HDR}
971
971
  <p class="zzSTDTitle1"/>
972
- <div><h1>1.&#160; Terms and definitions</h1>
972
+ <div><h1>1.&#160; </h1>
973
973
  <p class="TermNum" id="_extraneous_matter">1.1.</p><p class="Terms" style="text-align:left;">extraneous matter</p><p class="AltTerms" style="text-align:left;">EM</p>
974
974
 
975
975
  <p id="_318b3939-be09-46c4-a284-93f9826b981e">&lt;rice&gt; organic and inorganic components other than whole or broken kernels</p>
@@ -987,7 +987,7 @@ World

987
987
  <permission id="_">
988
988
  <label>/ogc/recommendation/wfs/2</label>
989
989
  <inherit>/ss/584/2015/level/1</inherit>
990
- <inherit>/ss/584/2015/level/2</inherit>
990
+ <inherit><eref type="inline" bibitemid="rfc2616" citeas="RFC 2616">RFC 2616 (HTTP/1.1)</eref></inherit>
991
991
  <subject>user</subject>
992
992
  <classification> <tag>control-class</tag> <value>Technical</value> </classification><classification> <tag>priority</tag> <value>P0</value> </classification><classification> <tag>family</tag> <value>System and Communications Protection</value> </classification><classification> <tag>family</tag> <value>System and Communications Protocols</value> </classification>
993
993
  <description>
@@ -1030,6 +1030,12 @@ World

1030
1030
  </import>
1031
1031
  </permission>
1032
1032
  </foreword></preface>
1033
+ <bibliography><references id="_bibliography" obligation="informative" normative="false">
1034
+ <title>Bibliography</title>
1035
+ <bibitem id="rfc2616" type="standard"> <fetched>2020-03-27</fetched> <title format="text/plain" language="en" script="Latn">Hypertext Transfer Protocol — HTTP/1.1</title> <uri type="xml">https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2616.xml</uri> <uri type="src">https://www.rfc-editor.org/info/rfc2616</uri> <docidentifier type="IETF">RFC 2616</docidentifier> <docidentifier type="rfc-anchor">RFC2616</docidentifier> <docidentifier type="DOI">10.17487/RFC2616</docidentifier> <date type="published"> <on>1999-06</on> </date> <contributor> <role type="author"/> <person> <name> <completename language="en">R. Fielding</completename> </name> <affiliation> <organization> <name>IETF</name> <abbreviation>IETF</abbreviation> </organization> </affiliation> </person> </contributor> <contributor> <role type="author"/> <person> <name> <completename language="en">J. Gettys</completename> </name> <affiliation> <organization> <name>IETF</name> <abbreviation>IETF</abbreviation> </organization> </affiliation> </person> </contributor> <contributor> <role type="author"/> <person> <name> <completename language="en">J. Mogul</completename> </name> <affiliation> <organization> <name>IETF</name> <abbreviation>IETF</abbreviation> </organization> </affiliation> </person> </contributor> <contributor> <role type="author"/> <person> <name> <completename language="en">H. Frystyk</completename> </name> <affiliation> <organization> <name>IETF</name> <abbreviation>IETF</abbreviation> </organization> </affiliation> </person> </contributor> <contributor> <role type="author"/> <person> <name> <completename language="en">L. Masinter</completename> </name> <affiliation> <organization> <name>IETF</name> <abbreviation>IETF</abbreviation> </organization> </affiliation> </person> </contributor> <contributor> <role type="author"/> <person> <name> <completename language="en">P. Leach</completename> </name> <affiliation> <organization> <name>IETF</name> <abbreviation>IETF</abbreviation> </organization> </affiliation> </person> </contributor> <contributor> <role type="author"/> <person> <name> <completename language="en">T. Berners-Lee</completename> </name> <affiliation> <organization> <name>IETF</name> <abbreviation>IETF</abbreviation> </organization> </affiliation> </person> </contributor> <language>en</language> <script>Latn</script> <abstract format="text/plain" language="en" script="Latn">HTTP has been in use by the World-Wide Web global information initiative since 1990. This specification defines the protocol referred to as “HTTP/1.1”, and is an update to RFC 2068. [STANDARDS-TRACK]</abstract> <series type="main"> <title format="text/plain" language="en" script="Latn">RFC</title> <number>2616</number> </series> <place>Fremont, CA</place></bibitem>
1036
+
1037
+
1038
+ </references></bibliography>
1033
1039
  </iso-standard>
1034
1040
  INPUT
1035
1041
  #{HTML_HDR}
@@ -1038,9 +1044,9 @@ World

1038
1044
  <h1 class="ForewordTitle">Foreword</h1>
1039
1045
  <div class="permission"><p class="RecommendationTitle">Permission 1:<br/>/ogc/recommendation/wfs/2</p>
1040
1046
  <p><i>Subject: user<br/>
1041
- Inherit: /ss/584/2015/level/1
1047
+ Inherits: /ss/584/2015/level/1
1042
1048
  <br/>
1043
- Inherit: /ss/584/2015/level/2
1049
+ Inherits: <a href='#rfc2616'>RFC 2616 (HTTP/1.1)</a>
1044
1050
  <br/>Control-class: Technical<br/>Priority: P0<br/>Family: System and Communications Protection<br/>Family: System and Communications Protocols</i></p>
1045
1051
 
1046
1052
  <div class="requirement-description">
@@ -1064,6 +1070,14 @@ Inherit: /ss/584/2015/level/2
1064
1070
  </div>
1065
1071
  </div>
1066
1072
  <p class="zzSTDTitle1"/>
1073
+ <br/>
1074
+ <div>
1075
+ <h1 class='Section3'>Bibliography</h1>
1076
+ <p id='rfc2616' class='Biblio'>
1077
+ [1]&#160; IETF RFC 2616,
1078
+ <i>Hypertext Transfer Protocol&#8201;&#8212;&#8201;HTTP/1.1</i>
1079
+ </p>
1080
+ </div>
1067
1081
  </div>
1068
1082
  </body>
1069
1083
  </html>
@@ -1125,7 +1139,7 @@ Inherit: /ss/584/2015/level/2
1125
1139
  <br/>
1126
1140
  <div>
1127
1141
  <h1 class="ForewordTitle">Foreword</h1>
1128
- <div class="require"><p class="RecommendationTitle">Requirement:<br/>/ogc/recommendation/wfs/2. A New Requirement</p><p><i>Subject: user<br/>Inherit: /ss/584/2015/level/1</i></p>
1142
+ <div class="require"><p class="RecommendationTitle">Requirement:<br/>/ogc/recommendation/wfs/2. A New Requirement</p><p><i>Subject: user<br/>Inherits: /ss/584/2015/level/1</i></p>
1129
1143
 
1130
1144
  <div class="requirement-description">
1131
1145
  <p id="_">I recommend <i>this</i>.</p>
@@ -1154,6 +1168,121 @@ Inherit: /ss/584/2015/level/2
1154
1168
  OUTPUT
1155
1169
  end
1156
1170
 
1171
+ it "processes requirements in French" do
1172
+ expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
1173
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1174
+ <bibdata>
1175
+ <language>fr</language>
1176
+ <script>Latn</script>
1177
+ </bibdata>
1178
+ <preface><foreword>
1179
+ <requirement id="A" unnumbered="true">
1180
+ <title>A New Requirement</title>
1181
+ <label>/ogc/recommendation/wfs/2</label>
1182
+ <inherit>/ss/584/2015/level/1</inherit>
1183
+ <subject>user</subject>
1184
+ <description>
1185
+ <p id="_">I recommend <em>this</em>.</p>
1186
+ </description>
1187
+ <specification exclude="true" type="tabular">
1188
+ <p id="_">This is the object of the recommendation:</p>
1189
+ <table id="_">
1190
+ <tbody>
1191
+ <tr>
1192
+ <td style="text-align:left;">Object</td>
1193
+ <td style="text-align:left;">Value</td>
1194
+ </tr>
1195
+ <tr>
1196
+ <td style="text-align:left;">Mission</td>
1197
+ <td style="text-align:left;">Accomplished</td>
1198
+ </tr>
1199
+ </tbody>
1200
+ </table>
1201
+ </specification>
1202
+ <description>
1203
+ <p id="_">As for the measurement targets,</p>
1204
+ </description>
1205
+ <measurement-target exclude="false">
1206
+ <p id="_">The measurement target shall be measured as:</p>
1207
+ <formula id="B">
1208
+ <stem type="AsciiMath">r/1 = 0</stem>
1209
+ </formula>
1210
+ </measurement-target>
1211
+ <verification exclude="false">
1212
+ <p id="_">The following code will be run for verification:</p>
1213
+ <sourcecode id="_">CoreRoot(success): HttpResponse
1214
+ if (success)
1215
+ recommendation(label: success-response)
1216
+ end
1217
+ </sourcecode>
1218
+ </verification>
1219
+ <import exclude="true">
1220
+ <sourcecode id="_">success-response()</sourcecode>
1221
+ </import>
1222
+ </requirement>
1223
+ </foreword></preface>
1224
+ </iso-standard>
1225
+ INPUT
1226
+ #{HTML_HDR.gsub(/"en"/, '"fr"')}
1227
+ <br/>
1228
+ <div>
1229
+ <h1 class='ForewordTitle'>Avant-propos</h1>
1230
+ <div class='require'>
1231
+ <p class='RecommendationTitle'>
1232
+ Exigence:
1233
+ <br/>
1234
+ /ogc/recommendation/wfs/2. A New Requirement
1235
+ </p>
1236
+ <p>
1237
+ <i>
1238
+ Sujet: user
1239
+ <br/>
1240
+ H&#233;rite: /ss/584/2015/level/1
1241
+ </i>
1242
+ </p>
1243
+ <div class='requirement-description'>
1244
+ <p id='_'>
1245
+ I recommend
1246
+ <i>this</i>
1247
+ .
1248
+ </p>
1249
+ </div>
1250
+ <div class='requirement-description'>
1251
+ <p id='_'>As for the measurement targets,</p>
1252
+ </div>
1253
+ <div class='requirement-measurement-target'>
1254
+ <p id='_'>The measurement target shall be measured as:</p>
1255
+ <div id='B' class='formula'>
1256
+ <p>
1257
+ <span class='stem'>(#(r/1 = 0)#)</span>
1258
+ &#160; (1)
1259
+ </p>
1260
+ </div>
1261
+ </div>
1262
+ <div class='requirement-verification'>
1263
+ <p id='_'>The following code will be run for verification:</p>
1264
+ <pre id='_' class='prettyprint '>
1265
+ CoreRoot(success): HttpResponse
1266
+ <br/>
1267
+ &#160;&#160;&#160;&#160;&#160; if (success)
1268
+ <br/>
1269
+ &#160;&#160;&#160;&#160;&#160; recommendation(label:
1270
+ success-response)
1271
+ <br/>
1272
+ &#160;&#160;&#160;&#160;&#160; end
1273
+ <br/>
1274
+ &#160;&#160;&#160;
1275
+ </pre>
1276
+ </div>
1277
+ </div>
1278
+ </div>
1279
+ <p class='zzSTDTitle1'/>
1280
+ </div>
1281
+ </body>
1282
+ </html>
1283
+ OUTPUT
1284
+ end
1285
+
1157
1286
  it "processes recommendation" do
1158
1287
  expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
1159
1288
  <iso-standard xmlns="http://riboseinc.com/isoxml">
@@ -1210,7 +1339,7 @@ Inherit: /ss/584/2015/level/2
1210
1339
  <br/>
1211
1340
  <div>
1212
1341
  <h1 class="ForewordTitle">Foreword</h1>
1213
- <div class="recommend"><p class="RecommendationTitle">Recommendation 1:<br/>/ogc/recommendation/wfs/2</p><p><i>Obligation: shall,could<br/>Subject: user<br/>Inherit: /ss/584/2015/level/1<br/>Type: text<br/>Language: BASIC</i></p>
1342
+ <div class="recommend"><p class="RecommendationTitle">Recommendation 1:<br/>/ogc/recommendation/wfs/2</p><p><i>Obligation: shall,could<br/>Subject: user<br/>Inherits: /ss/584/2015/level/1<br/>Type: text<br/>Language: BASIC</i></p>
1214
1343
  <div class="requirement-description">
1215
1344
  <p id="_">I recommend <i>this</i>.</p>
1216
1345
  </div>
@@ -1333,5 +1462,56 @@ INPUT
1333
1462
  OUTPUT
1334
1463
  end
1335
1464
 
1465
+ it "processes passthrough with compatible format" do
1466
+ FileUtils.rm_f "test.html"
1467
+ IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", false)
1468
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1469
+ <preface><foreword>
1470
+ <passthrough format="html,rfc">&lt;A&gt;</passthrough><em>Hello</em><passthrough format="html,rfc">&lt;/A&gt;</passthrough>
1471
+ </foreword></preface>
1472
+ </iso-standard>
1473
+ INPUT
1474
+ expect(( File.read("test.html").gsub(%r{^.*<h1 class="ForewordTitle">Foreword</h1>}m, "").gsub(%r{</div>.*}m, ""))).to be_equivalent_to xmlpp(<<~"OUTPUT")
1475
+ <A><i>Hello</i></A>
1476
+ OUTPUT
1477
+ end
1478
+
1479
+ it "aborts if passthrough results in malformed XML" do
1480
+ FileUtils.rm_f "test.html"
1481
+ FileUtils.rm_f "test.html.err"
1482
+ begin
1483
+ expect { IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", false) }.to raise_error(SystemExit)
1484
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1485
+ <preface><foreword>
1486
+ <passthrough format="html,rfc">&lt;A&gt;</passthrough><em>Hello</em>
1487
+ </foreword></preface>
1488
+ </iso-standard>
1489
+ INPUT
1490
+ rescue SystemExit
1491
+ end
1492
+ expect(File.exist?("test.html.err")).to be true
1493
+ end
1494
+
1495
+ it "ignore passthrough with incompatible format" do
1496
+ expect(xmlpp(IsoDoc::HtmlConvert.new({}).convert("test", <<~"INPUT", true))).to be_equivalent_to xmlpp(<<~"OUTPUT")
1497
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
1498
+ <preface><foreword>
1499
+ <passthrough format="doc,rfc">&lt;A&gt;</passthrough>
1500
+ </foreword></preface>
1501
+ </iso-standard>
1502
+ INPUT
1503
+ #{HTML_HDR}
1504
+ <br/>
1505
+ <div>
1506
+ <h1 class='ForewordTitle'>Foreword</h1>
1507
+ </div>
1508
+ <p class='zzSTDTitle1'/>
1509
+ </div>
1510
+ </body>
1511
+ </html>
1512
+ OUTPUT
1513
+ end
1514
+
1515
+
1336
1516
 
1337
1517
  end