isodoc 2.10.0 → 3.0.0

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/isodoc.gemspec +9 -4
  4. data/lib/isodoc/base_style/all.css +96 -0
  5. data/lib/isodoc/base_style/reset.css +96 -0
  6. data/lib/isodoc/base_style/reset.scss +75 -0
  7. data/lib/isodoc/base_style/scripts.html +45 -14
  8. data/lib/isodoc/class_utils.rb +4 -2
  9. data/lib/isodoc/convert.rb +0 -21
  10. data/lib/isodoc/css.rb +2 -4
  11. data/lib/isodoc/function/blocks.rb +37 -52
  12. data/lib/isodoc/function/blocks_example_note.rb +75 -29
  13. data/lib/isodoc/function/cleanup.rb +9 -44
  14. data/lib/isodoc/function/inline.rb +67 -13
  15. data/lib/isodoc/function/lists.rb +20 -14
  16. data/lib/isodoc/function/references.rb +9 -126
  17. data/lib/isodoc/function/reqt.rb +4 -3
  18. data/lib/isodoc/function/section.rb +30 -35
  19. data/lib/isodoc/function/section_titles.rb +22 -11
  20. data/lib/isodoc/function/table.rb +3 -3
  21. data/lib/isodoc/function/terms.rb +49 -26
  22. data/lib/isodoc/function/to_word_html.rb +46 -16
  23. data/lib/isodoc/function/utils.rb +11 -12
  24. data/lib/isodoc/gem_tasks.rb +1 -1
  25. data/lib/isodoc/html_function/footnotes.rb +2 -1
  26. data/lib/isodoc/html_function/html.rb +5 -7
  27. data/lib/isodoc/html_function/postprocess.rb +25 -6
  28. data/lib/isodoc/html_function/postprocess_cover.rb +13 -7
  29. data/lib/isodoc/html_function/postprocess_footnotes.rb +52 -47
  30. data/lib/isodoc/init.rb +31 -0
  31. data/lib/isodoc/metadata.rb +20 -13
  32. data/lib/isodoc/metadata_contributor.rb +5 -10
  33. data/lib/isodoc/metadata_date.rb +1 -1
  34. data/lib/isodoc/presentation_function/autonum.rb +153 -0
  35. data/lib/isodoc/presentation_function/bibdata.rb +4 -5
  36. data/lib/isodoc/presentation_function/block.rb +107 -40
  37. data/lib/isodoc/presentation_function/concepts.rb +184 -19
  38. data/lib/isodoc/presentation_function/docid.rb +78 -0
  39. data/lib/isodoc/presentation_function/erefs.rb +55 -31
  40. data/lib/isodoc/presentation_function/image.rb +64 -19
  41. data/lib/isodoc/presentation_function/index.rb +180 -0
  42. data/lib/isodoc/presentation_function/inline.rb +47 -16
  43. data/lib/isodoc/presentation_function/math.rb +128 -71
  44. data/lib/isodoc/presentation_function/metadata.rb +29 -66
  45. data/lib/isodoc/presentation_function/refs.rb +75 -28
  46. data/lib/isodoc/presentation_function/reqt.rb +7 -4
  47. data/lib/isodoc/presentation_function/section.rb +51 -129
  48. data/lib/isodoc/presentation_function/sourcecode.rb +52 -19
  49. data/lib/isodoc/presentation_function/terms.rb +107 -118
  50. data/lib/isodoc/presentation_function/title.rb +107 -0
  51. data/lib/isodoc/presentation_function/xrefs.rb +37 -17
  52. data/lib/isodoc/presentation_xml_convert.rb +24 -10
  53. data/lib/isodoc/version.rb +1 -1
  54. data/lib/isodoc/word_function/body.rb +9 -37
  55. data/lib/isodoc/word_function/comments.rb +0 -1
  56. data/lib/isodoc/word_function/footnotes.rb +1 -1
  57. data/lib/isodoc/word_function/lists.rb +13 -9
  58. data/lib/isodoc/word_function/postprocess.rb +6 -0
  59. data/lib/isodoc/word_function/postprocess_cover.rb +6 -4
  60. data/lib/isodoc/word_function/postprocess_table.rb +1 -1
  61. data/lib/isodoc/word_function/postprocess_toc.rb +10 -6
  62. data/lib/isodoc/word_function/table.rb +2 -2
  63. data/lib/isodoc/xref/clause_order.rb +41 -0
  64. data/lib/isodoc/xref/xref_anchor.rb +31 -16
  65. data/lib/isodoc/xref/xref_counter.rb +18 -3
  66. data/lib/isodoc/xref/xref_counter_types.rb +14 -0
  67. data/lib/isodoc/xref/xref_gen.rb +61 -37
  68. data/lib/isodoc/xref/xref_gen_seq.rb +148 -81
  69. data/lib/isodoc/xref/xref_sect_gen.rb +84 -88
  70. data/lib/isodoc/xref/xref_util.rb +53 -4
  71. data/lib/isodoc/xref.rb +29 -10
  72. data/lib/isodoc/xslfo_convert.rb +14 -9
  73. data/lib/isodoc-yaml/i18n-ar.yaml +17 -13
  74. data/lib/isodoc-yaml/i18n-de.yaml +17 -13
  75. data/lib/isodoc-yaml/i18n-en.yaml +18 -17
  76. data/lib/isodoc-yaml/i18n-es.yaml +17 -13
  77. data/lib/isodoc-yaml/i18n-fr.yaml +17 -13
  78. data/lib/isodoc-yaml/i18n-ja.yaml +56 -52
  79. data/lib/isodoc-yaml/i18n-ru.yaml +17 -16
  80. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +17 -13
  81. data/lib/nokogiri/xml/node.rb +14 -0
  82. data/lib/relaton/render-isodoc/config.yml +1 -1
  83. metadata +90 -13
@@ -102,40 +102,12 @@ module IsoDoc
102
102
  end
103
103
  end
104
104
 
105
- def note_p_parse(node, div)
106
- name = node.at(ns("./name"))&.remove
107
- div.p class: "Note" do |p|
108
- p.span class: "note_label" do |s|
109
- name&.children&.each { |n| parse(n, s) }
110
- end
111
- insert_tab(p, 1)
112
- node.first_element_child.children.each { |n| parse(n, p) }
113
- end
114
- node.element_children[1..-1].each { |n| parse(n, div) }
105
+ def note_p_class
106
+ "Note"
115
107
  end
116
108
 
117
- def note_parse1(node, div)
118
- name = node.at(ns("./name"))&.remove
119
- div.p class: "Note" do |p|
120
- p.span class: "note_label" do |s|
121
- name&.children&.each { |n| parse(n, s) }
122
- end
123
- insert_tab(p, 1)
124
- end
125
- node.children.each { |n| parse(n, div) }
126
- end
127
-
128
- def termnote_parse(node, out)
129
- name = node&.at(ns("./name"))&.remove
130
- out.div **note_attrs(node) do |div|
131
- div.p class: "Note" do |p|
132
- if name
133
- name.children.each { |n| parse(n, p) }
134
- p << termnote_delim
135
- end
136
- para_then_remainder(node.first_element_child, node, p, div)
137
- end
138
- end
109
+ def termnote_p_class
110
+ "Note"
139
111
  end
140
112
 
141
113
  def para_attrs(node)
@@ -162,10 +134,10 @@ module IsoDoc
162
134
  def formula_parse1(node, out)
163
135
  out.div **attr_code(class: "formula") do |div|
164
136
  div.p do |_p|
165
- parse(node.at(ns("./stem")), div)
137
+ parse(node.at(ns("./fmt-stem")), div)
166
138
  insert_tab(div, 1)
167
- if lbl = node&.at(ns("./name"))&.text
168
- div << "(#{lbl})"
139
+ if lbl = node&.at(ns("./fmt-name"))&.text
140
+ div << lbl
169
141
  end
170
142
  end
171
143
  end
@@ -185,10 +157,10 @@ module IsoDoc
185
157
  page_break(out)
186
158
  out.div **attr_code(preface_attrs(clause)) do |div|
187
159
  div.p class: "zzContents" do |p|
188
- clause.at(ns("./title"))&.children&.each { |c| parse(c, p) }
160
+ clause.at(ns("./fmt-title"))&.children&.each { |c| parse(c, p) }
189
161
  end
190
162
  clause.elements.each do |e|
191
- parse(e, div) unless e.name == "title"
163
+ parse(e, div) unless e.name == "fmt-title"
192
164
  end
193
165
  end
194
166
  end
@@ -64,7 +64,6 @@ module IsoDoc
64
64
  'span[@style="MsoCommentReference"]'.freeze
65
65
 
66
66
  def embed_comment_in_comment_list(docxml)
67
- # docxml.xpath(COMMENT_IN_COMMENT_LIST).each do |x|
68
67
  docxml.xpath(COMMENT_IN_COMMENT_LIST1).each do |x|
69
68
  n = x.next_element
70
69
  n&.children&.first&.add_previous_sibling(x.remove)
@@ -83,7 +83,7 @@ module IsoDoc
83
83
 
84
84
  def footnote_parse(node, out)
85
85
  return table_footnote_parse(node, out) if (@in_table || @in_figure) &&
86
- !node.ancestors.map(&:name).include?("name")
86
+ !node.ancestors.map(&:name).include?("fmt-name")
87
87
 
88
88
  fn = node["reference"] || UUIDTools::UUID.random_create.to_s
89
89
  return seen_footnote_parse(node, out, fn) if @seen_footnote.include?(fn)
@@ -24,13 +24,15 @@ module IsoDoc
24
24
  end
25
25
 
26
26
  def dl_parse_nontable(node, out)
27
- node["id"] and bookmark_parse(node, out)
28
- list_title_parse(node, out)
29
- node.elements.select { |n| dt_dd?(n) }
30
- .each_slice(2) do |dt, dd|
31
- dl_parse_nontable1(out, dt, dd)
27
+ out.div **attr_code(class: "figdl") do |div|
28
+ node["id"] and bookmark_parse(node, div)
29
+ list_title_parse(node, div)
30
+ node.elements.select { |n| dt_dd?(n) }
31
+ .each_slice(2) do |dt, dd|
32
+ dl_parse_nontable1(div, dt, dd)
33
+ end
34
+ dl_parse_notes(node, div)
32
35
  end
33
- dl_parse_notes(node, out)
34
36
  end
35
37
 
36
38
  WORD_EMBED_DL_ATTRS =
@@ -56,13 +58,13 @@ module IsoDoc
56
58
 
57
59
  def ddef_other_paras(out, ddef)
58
60
  ddef.elements&.first&.name == "p" or return
59
- ddef.children[1..-1].each { |n| parse(n, out) }
61
+ ddef.children[1..].each { |n| parse(n, out) }
60
62
  end
61
63
 
62
64
  def dl_parse_table(node, out)
63
65
  list_title_parse(node, out)
64
66
  out.table **attr_code(id: node["id"],
65
- class: (node["class"] || "dl")) do |v|
67
+ class: node["class"] || "dl") do |v|
66
68
  node.elements.select { |n| dt_dd?(n) }
67
69
  .each_slice(2) do |dt, dd|
68
70
  dl_parse_table1(v, dt, dd)
@@ -83,7 +85,9 @@ module IsoDoc
83
85
  end
84
86
 
85
87
  def dl_parse_table_notes(node, out)
86
- remainder = node.elements.reject { |n| dt_dd?(n) || n.name == "name" }
88
+ remainder = node.elements.reject do |n|
89
+ dt_dd?(n) || n.name == "fmt-name"
90
+ end
87
91
  remainder.empty? and return
88
92
  out.tr do |tr|
89
93
  tr.td colspan: 2 do |td|
@@ -64,10 +64,16 @@ module IsoDoc
64
64
  word_tab_clean(docxml)
65
65
  authority_cleanup(docxml)
66
66
  word_footnote_format(docxml)
67
+ word_remove_empty_toc(docxml)
67
68
  word_remove_empty_sections(docxml)
68
69
  docxml
69
70
  end
70
71
 
72
+ def word_remove_empty_toc(docxml)
73
+ docxml.at("//div[@class = 'TOC']//p[@class = 'MsoToc1']") and return
74
+ remove_toc_div(docxml)
75
+ end
76
+
71
77
  def word_sourcecode_annotations(html)
72
78
  ann = ".//div[@class = 'annotation']"
73
79
  html.xpath("//p[@class = '#{sourcecode_style}'][#{ann}]")
@@ -2,8 +2,10 @@ module IsoDoc
2
2
  module WordFunction
3
3
  module Postprocess
4
4
  def word_preface(docxml)
5
- word_cover(docxml) if @wordcoverpage
6
- word_intro(docxml, @wordToClevels) if @wordintropage
5
+ @wordcoverpage && !@wordcoverpage.empty? and
6
+ word_cover(docxml)
7
+ @wordintropage && !@wordintropage.empty? and
8
+ word_intro(docxml, @wordToClevels)
7
9
  end
8
10
 
9
11
  def word_remove_empty_sections(docxml)
@@ -20,7 +22,7 @@ module IsoDoc
20
22
  cover = File.read(@wordcoverpage, encoding: "UTF-8")
21
23
  cover = populate_template(cover, :word)
22
24
  coverxml = to_word_xhtml_fragment(cover)
23
- ins.children.first.previous = coverxml.to_xml(encoding: "US-ASCII")
25
+ ins.add_first_child coverxml.to_xml(encoding: "US-ASCII")
24
26
  end
25
27
 
26
28
  def word_intro(docxml, level)
@@ -29,7 +31,7 @@ module IsoDoc
29
31
  docxml, level)
30
32
  intro = populate_template(intro, :word)
31
33
  introxml = to_word_xhtml_fragment(intro)
32
- ins.children.first.previous = introxml.to_xml(encoding: "US-ASCII")
34
+ ins.add_first_child introxml.to_xml(encoding: "US-ASCII")
33
35
  end
34
36
 
35
37
  # add namespaces for Word fragments
@@ -44,7 +44,7 @@ module IsoDoc
44
44
 
45
45
  def word_nested_tables(docxml)
46
46
  docxml.xpath("//table").each do |t|
47
- t.xpath(".//table").reverse.each do |tt|
47
+ t.xpath(".//table").reverse_each do |tt|
48
48
  t.next = tt.remove
49
49
  end
50
50
  end
@@ -4,11 +4,7 @@ module IsoDoc
4
4
  def insert_toc(intro, docxml, level)
5
5
  toc = assemble_toc(docxml, level)
6
6
  if intro&.include?("WORDTOC")
7
- if s = docxml.at("//div[@class = 'TOC']")
8
- s&.previous_element&.elements&.first&.name == "br" and
9
- s&.previous_element&.remove # page break
10
- s.remove
11
- end
7
+ remove_toc_div(docxml)
12
8
  intro.sub("WORDTOC", toc)
13
9
  else
14
10
  source = docxml.at("//div[@class = 'TOC']") and
@@ -17,6 +13,14 @@ module IsoDoc
17
13
  end
18
14
  end
19
15
 
16
+ def remove_toc_div(docxml)
17
+ s = docxml.at("//div[@class = 'TOC']") or return
18
+ prev = s.previous_element
19
+ prev&.elements&.first&.name == "br" and
20
+ prev&.remove # page break
21
+ s.remove
22
+ end
23
+
20
24
  def assemble_toc(docxml, level)
21
25
  toc = ""
22
26
  toc += make_WordToC(docxml, level)
@@ -165,7 +169,7 @@ module IsoDoc
165
169
  def recommmendation_sort_key(header)
166
170
  m = /^([^0-9]+) (\d+)/.match(header) || /^([^:]+)/.match(header)
167
171
  m ||= [header, nil]
168
- ret = "#{recommmendation_sort_key1(m[1])}::"
172
+ ret = "#{recommmendation_sort_key1(m[1]&.strip)}::"
169
173
  m[2] and ret += ("%04d" % m[2].to_i).to_s
170
174
  ret
171
175
  end
@@ -34,7 +34,7 @@ module IsoDoc
34
34
  def make_tr_attr_style(cell, row, rowmax, totalrows, opt)
35
35
  top = row.zero? ? "#{SW1} 1.5pt;" : "none;"
36
36
  bottom = "#{SW1} #{rowmax >= totalrows ? '1.5' : '1.0'}pt;"
37
- ret = <<~STYLE.gsub(/\n/, "")
37
+ ret = <<~STYLE.delete("\n")
38
38
  border-top:#{top}mso-border-top-alt:#{top}
39
39
  border-bottom:#{bottom}mso-border-bottom-alt:#{bottom}
40
40
  STYLE
@@ -46,7 +46,7 @@ module IsoDoc
46
46
  def keep_rows_together(_cell, rowmax, totalrows, opt)
47
47
  opt[:header] and return true
48
48
  @table_line_count > 15 and return false
49
- (totalrows <= 10 && rowmax < totalrows)
49
+ totalrows <= 10 && rowmax < totalrows
50
50
  end
51
51
 
52
52
  def tbody_parse(node, table)
@@ -0,0 +1,41 @@
1
+ module IsoDoc
2
+ module XrefGen
3
+ module Sections
4
+ def clause_order(docxml)
5
+ { preface: clause_order_preface(docxml),
6
+ main: clause_order_main(docxml),
7
+ annex: clause_order_annex(docxml),
8
+ back: clause_order_back(docxml) }
9
+ end
10
+
11
+ def clause_order_preface(_docxml)
12
+ [{ path: "//preface/*", multi: true }]
13
+ end
14
+
15
+ def clause_order_main(docxml)
16
+ [
17
+ { path: "//sections/clause[@type = 'scope']" },
18
+ { path: @klass.norm_ref_xpath },
19
+ { path: "//sections/terms | " \
20
+ "//sections/clause[descendant::terms]", multi: true },
21
+ { path: "//sections/definitions | " \
22
+ "//sections/clause[descendant::definitions]" \
23
+ "[not(descendant::terms)]", multi: true },
24
+ { path: @klass.middle_clause(docxml), multi: true },
25
+ ]
26
+ end
27
+
28
+ def clause_order_annex(_docxml)
29
+ [{ path: "//annex", multi: true }]
30
+ end
31
+
32
+ def clause_order_back(_docxml)
33
+ [
34
+ { path: @klass.bibliography_xpath },
35
+ { path: "//indexsect", multi: true },
36
+ { path: "//colophon/*", multi: true },
37
+ ]
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,4 +1,5 @@
1
1
  require "singleton"
2
+ require_relative "xref_util"
2
3
 
3
4
  module IsoDoc
4
5
  module XrefGen
@@ -29,37 +30,51 @@ module IsoDoc
29
30
  @anchors
30
31
  end
31
32
 
32
- def anchor_struct_label(lbl, elem)
33
+ def anchor_struct_label(lbl, node, elem)
33
34
  case elem
34
- when @labels["appendix"] then l10n("#{elem} #{lbl}")
35
+ when @labels["appendix"]
36
+ s = "<semx element='autonum' source='#{node['id'] || node[:id]}'>" \
37
+ "#{lbl}</semx>"
38
+ "<span class='fmt-element-name'>#{elem}</span> #{s}"
35
39
  else
36
- lbl.to_s
40
+ anchor_struct_value(lbl, elem)
37
41
  end
38
42
  end
39
43
 
40
- def anchor_struct_xref(lbl, elem)
41
- l10n("#{elem} #{anchor_struct_value(lbl, elem)}")
44
+ def anchor_struct_xref(lbl, node, elem)
45
+ unless lbl.blank?
46
+ lbl = semx(node, lbl)
47
+ s = " #{anchor_struct_value(lbl, elem)}"
48
+ end
49
+ l10n("<span class='fmt-element-name'>#{elem}</span>#{s}")
50
+ .gsub(/ $/, "")
42
51
  end
43
52
 
44
53
  def anchor_struct_value(lbl, elem)
45
54
  case elem
46
- when @labels["formula"], @labels["inequality"] then "(#{lbl})"
55
+ # TODO hardcoded ( ) ?
56
+ when @labels["formula"], @labels["inequality"] then <<~SPAN.strip
57
+ #{delim_wrap('(')}#{lbl}#{delim_wrap(')')}
58
+ SPAN
47
59
  else
48
- lbl
60
+ lbl.to_s
49
61
  end
50
62
  end
51
63
 
52
- def anchor_struct(lbl, container, elem, type, unnumb = false)
53
- ret = {}
54
- ret[:label] = unnumb == "true" ? nil : anchor_struct_label(lbl, elem)
55
- ret[:xref] = anchor_struct_xref(unnumb == "true" ? "(??)" : lbl, elem)
56
- ret[:xref].gsub!(/ $/, "")
57
- ret[:container] = @klass.get_clause_id(container) unless container.nil?
58
- ret[:type] = type
59
- ret[:elem] = elem
60
- ret[:value] = anchor_struct_value(lbl, elem)
64
+ # def anchor_struct(lbl, container, elem, type, unnumb = false)
65
+ def anchor_struct(lbl, node, elem_name, type, opt = {})
66
+ ret = { type: type, elem: elem_name, label: nil }
67
+ opt[:unnumb] != "true" and
68
+ ret[:label] = anchor_struct_label(lbl, node, elem_name)
69
+ ret[:xref] =
70
+ anchor_struct_xref(opt[:unnumb] == "true" ? "(??)" : lbl, node,
71
+ elem_name)
72
+ ret[:container] = @klass.get_clause_id(node) if opt[:container]
73
+ ret[:value] = stripsemx(lbl)
61
74
  ret
62
75
  end
76
+
77
+ include ::IsoDoc::XrefGen::Util
63
78
  end
64
79
  end
65
80
  end
@@ -1,4 +1,5 @@
1
1
  require "roman-numerals"
2
+ require "twitter_cldr"
2
3
 
3
4
  module IsoDoc
4
5
  module XrefGen
@@ -26,6 +27,7 @@ module IsoDoc
26
27
  @style = opts[:numerals]
27
28
  @skip_i = opts[:skip_i]
28
29
  @prefix = opts[:prefix]
30
+ @separator = opts[:separator] || "."
29
31
  @base = ""
30
32
  if num.is_a? String
31
33
  if /^\d+$/.match?(num)
@@ -139,7 +141,8 @@ module IsoDoc
139
141
  end
140
142
 
141
143
  def increment(node)
142
- @unnumbered = (node["unnumbered"] || node["hidden"]) and return self
144
+ @unnumbered = node["unnumbered"] == "true" ||
145
+ node["hidden"] == "true" and return self
143
146
  reset_overrides
144
147
  if node["subsequence"] != @subseq &&
145
148
  !(blank?(node["subsequence"]) && blank?(@subseq))
@@ -150,12 +153,23 @@ module IsoDoc
150
153
  self
151
154
  end
152
155
 
156
+ def style_number(num)
157
+ num.nil? and return num
158
+ case @style
159
+ when :roman then RomanNumerals.to_roman(num)
160
+ when :japanese then num.localize(:ja).spellout
161
+ else num
162
+ end
163
+ end
164
+
153
165
  def print
154
166
  @unnumbered and return nil
155
167
  @prefix_override and return @prefix_override
156
168
  num = @number_override || @num
157
- out = @style == :roman && !num.nil? ? RomanNumerals.to_roman(num) : num
158
- "#{@prefix}#{@base}#{out}#{@letter_override || @letter}"
169
+ out = style_number(num)
170
+ prefix = @prefix
171
+ prefix &&= "#{prefix}#{@separator}"
172
+ "#{prefix}#{@base}#{out}#{@letter_override || @letter}"
159
173
  end
160
174
 
161
175
  def ol_type(list, depth)
@@ -176,6 +190,7 @@ module IsoDoc
176
190
  when :alphabet_upper then (64 + @num).chr.to_s
177
191
  when :roman then RomanNumerals.to_roman(@num).downcase
178
192
  when :roman_upper then RomanNumerals.to_roman(@num).upcase
193
+ when :japanese then num.localize(:ja).spellout
179
194
  end
180
195
  end
181
196
  end
@@ -0,0 +1,14 @@
1
+ require_relative "xref_counter"
2
+
3
+ module IsoDoc
4
+ class Xref
5
+ def clause_counter(num = 0, opts = {})
6
+ opts[:numerals] ||= :arabic
7
+ ::IsoDoc::XrefGen::Counter.new(num, opts)
8
+ end
9
+
10
+ def list_counter(num = 0, opts = {})
11
+ ::IsoDoc::XrefGen::Counter.new(num, opts)
12
+ end
13
+ end
14
+ end