isodoc 0.5.8 → 0.5.9

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.tb.yml +20 -10
  3. data/lib/isodoc/blocks.rb +13 -13
  4. data/lib/isodoc/cleanup.rb +19 -3
  5. data/lib/isodoc/comments.rb +1 -1
  6. data/lib/isodoc/convert.rb +2 -0
  7. data/lib/isodoc/footnotes.rb +4 -2
  8. data/lib/isodoc/html.rb +28 -10
  9. data/lib/isodoc/i18n-en.yaml +9 -0
  10. data/lib/isodoc/i18n-fr.yaml +12 -3
  11. data/lib/isodoc/i18n-zh-Hans.yaml +10 -1
  12. data/lib/isodoc/i18n.rb +9 -2
  13. data/lib/isodoc/inline.rb +5 -6
  14. data/lib/isodoc/iso2wordhtml.rb +9 -6
  15. data/lib/isodoc/lists.rb +7 -5
  16. data/lib/isodoc/metadata.rb +27 -10
  17. data/lib/isodoc/references.rb +12 -6
  18. data/lib/isodoc/section.rb +17 -11
  19. data/lib/isodoc/table.rb +2 -4
  20. data/lib/isodoc/terms.rb +3 -3
  21. data/lib/isodoc/utils.rb +15 -14
  22. data/lib/isodoc/version.rb +1 -1
  23. data/lib/isodoc/wordconvert/comments.rb +1 -1
  24. data/lib/isodoc/wordconvert/wordconvertmodule.rb +51 -12
  25. data/lib/isodoc/xref_gen.rb +30 -26
  26. data/lib/isodoc/xref_sect_gen.rb +31 -13
  27. data/spec/assets/scripts.html +1 -0
  28. data/spec/isodoc/blocks_spec.rb +50 -49
  29. data/spec/isodoc/cleanup_spec.rb +6 -6
  30. data/spec/isodoc/footnotes_spec.rb +10 -2
  31. data/spec/isodoc/i18n_spec.rb +86 -54
  32. data/spec/isodoc/inline_spec.rb +22 -18
  33. data/spec/isodoc/lists_spec.rb +25 -11
  34. data/spec/isodoc/metadata_spec.rb +4 -3
  35. data/spec/isodoc/postproc_spec.rb +108 -42
  36. data/spec/isodoc/ref_spec.rb +9 -7
  37. data/spec/isodoc/section_spec.rb +162 -141
  38. data/spec/isodoc/table_spec.rb +18 -16
  39. data/spec/isodoc/terms_spec.rb +9 -9
  40. data/spec/isodoc/xref_spec.rb +153 -122
  41. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57ca9a13e94e7c5861ee7694b1c543a304d35e2c
4
- data.tar.gz: 4d1ca9fe799cc66bb3d6e1422585168e09da7c4a
3
+ metadata.gz: 90089f0b90f1392ef99b4d676db3215397bb70fc
4
+ data.tar.gz: 5d82f8fb83a29877f878716df97dc6499a998834
5
5
  SHA512:
6
- metadata.gz: a382164e2ff256407dc864caa9638235970b84bff249291d690588ac880cd832cefd089505336603f4e920dd89053096fc96c5b9d2233fb4f023ac6bf9465d63
7
- data.tar.gz: 54d6a2064d4b1fe1a72a8997ca842b1f9a45094a7f3778a9858af9c560757f72d078d38045cee41782d79043a743ecd6be8dbc2d31b657ab07292d2ac6efa090
6
+ metadata.gz: eb49c04b480775ba01401325d448b9d03181c93f6f456525755ac7a704b8eae5b19a88afd3ac736ff234bb5fc4e7e3a2c0affa0555128efc1e89071eec14f10b
7
+ data.tar.gz: 382f620801c7e6a447f00de270f2d372a81abbc6f7bb878760e7a000527e2c085389ae694483a426f76d3b75fdb48d93d1d40abcd0601d9db68dee5bc6fd3e95
@@ -352,8 +352,18 @@ Style/TrailingCommaInArguments:
352
352
  - no_comma
353
353
  Enabled: true
354
354
 
355
- Style/TrailingCommaInLiteral:
356
- Description: 'Checks for trailing comma in array and hash literals.'
355
+ Style/TrailingCommaInArrayLiteral:
356
+ Description: 'Checks for trailing comma in array literals.'
357
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
358
+ EnforcedStyleForMultiline: comma
359
+ SupportedStylesForMultiline:
360
+ - comma
361
+ - consistent_comma
362
+ - no_comma
363
+ Enabled: true
364
+
365
+ Style/TrailingCommaInHashLiteral:
366
+ Description: 'Checks for trailing comma in hash literals.'
357
367
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
358
368
  EnforcedStyleForMultiline: comma
359
369
  SupportedStylesForMultiline:
@@ -398,6 +408,13 @@ Layout/AlignParameters:
398
408
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-double-indent'
399
409
  Enabled: false
400
410
 
411
+ Layout/ConditionPosition:
412
+ Description: >-
413
+ Checks for condition placed in a confusing position relative to
414
+ the keyword.
415
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#same-line-condition'
416
+ Enabled: false
417
+
401
418
  Layout/DotPosition:
402
419
  Description: 'Checks the position of the dot in multi-line method calls.'
403
420
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains'
@@ -450,13 +467,6 @@ Lint/CircularArgumentReference:
450
467
  Description: "Don't refer to the keyword argument in the default value."
451
468
  Enabled: false
452
469
 
453
- Lint/ConditionPosition:
454
- Description: >-
455
- Checks for condition placed in a confusing position relative to
456
- the keyword.
457
- StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#same-line-condition'
458
- Enabled: false
459
-
460
470
  Lint/DeprecatedClassMethods:
461
471
  Description: 'Check for deprecated class method calls.'
462
472
  Enabled: false
@@ -523,7 +533,7 @@ Lint/UnderscorePrefixedVariableName:
523
533
  Description: 'Do not use prefix `_` for a variable that is used.'
524
534
  Enabled: false
525
535
 
526
- Lint/UnneededDisable:
536
+ Lint/UnneededCopDisableDirective:
527
537
  Description: >-
528
538
  Checks for rubocop:disable comments that can be removed.
529
539
  Note: this cop is not disabled when disabling all cops.
@@ -10,7 +10,9 @@ module IsoDoc
10
10
 
11
11
  def note_p_parse(node, div)
12
12
  div.p **{ class: "Note" } do |p|
13
- p << note_label(node)
13
+ p.span **{ class: "note_label" } do |s|
14
+ s << note_label(node)
15
+ end
14
16
  insert_tab(p, 1)
15
17
  node.first_element_child.children.each { |n| parse(n, p) }
16
18
  end
@@ -19,7 +21,9 @@ module IsoDoc
19
21
 
20
22
  def note_parse1(node, div)
21
23
  div.p **{ class: "Note" } do |p|
22
- p << note_label(node)
24
+ p.span **{ class: "note_label" } do |s|
25
+ s << note_label(node)
26
+ end
23
27
  insert_tab(p, 1)
24
28
  end
25
29
  node.children.each { |n| parse(n, div) }
@@ -39,10 +43,8 @@ module IsoDoc
39
43
 
40
44
  def figure_name_parse(node, div, name)
41
45
  div.p **{ class: "FigureTitle", align: "center" } do |p|
42
- p.b do |b|
43
- b << l10n("#{@figure_lbl} #{get_anchors[node['id']][:label]}")
44
- b << "&nbsp;&mdash; #{name.text}" if name
45
- end
46
+ p << l10n("#{@figure_lbl} #{get_anchors[node['id']][:label]}")
47
+ p << "&nbsp;&mdash; #{name.text}" if name
46
48
  end
47
49
  end
48
50
 
@@ -72,7 +74,7 @@ module IsoDoc
72
74
  end
73
75
 
74
76
  EXAMPLE_TBL_ATTR =
75
- { width: "110pt", valign: "top",
77
+ { width: "110pt", valign: "top", class: "example_label",
76
78
  style: "width:82.8pt;padding:.75pt .75pt .75pt .75pt" }.freeze
77
79
 
78
80
  # used if we are boxing examples
@@ -91,7 +93,7 @@ module IsoDoc
91
93
  tr.td **EXAMPLE_TBL_ATTR do |td|
92
94
  td << example_label(node)
93
95
  end
94
- tr.td **{ valign: "top" } do |td|
96
+ tr.td **{ valign: "top", class: "example" } do |td|
95
97
  node.children.each { |n| parse(n, td) }
96
98
  end
97
99
  end
@@ -100,9 +102,7 @@ module IsoDoc
100
102
 
101
103
  def sourcecode_name_parse(_node, div, name)
102
104
  div.p **{ class: "FigureTitle", align: "center" } do |p|
103
- p.b do |b|
104
- b << name.text
105
- end
105
+ p << name.text
106
106
  end
107
107
  end
108
108
 
@@ -124,14 +124,14 @@ module IsoDoc
124
124
  out.span **{ class: "zzMoveToFollowing" } do |s|
125
125
  s << "&lt;#{node.at(ns("//callout[@target='#{node['id']}']")).text}&gt; "
126
126
  end
127
- node.children.each { |n| parse(n, out) }
127
+ node.children.each { |n| parse(n, out) }
128
128
  @annotation = false
129
129
  end
130
130
 
131
131
  def admonition_parse(node, out)
132
132
  name = node["type"]
133
133
  out.div **{ class: "Admonition" } do |t|
134
- t.title { |b| b << name.upcase } if name
134
+ t.title { |b| b << @admonition[name].upcase } if name
135
135
  node.children.each do |n|
136
136
  parse(n, t)
137
137
  end
@@ -12,6 +12,7 @@ module IsoDoc
12
12
  figure_cleanup(docxml)
13
13
  table_cleanup(docxml)
14
14
  symbols_cleanup(docxml)
15
+ example_cleanup(docxml)
15
16
  admonition_cleanup(docxml)
16
17
  end
17
18
 
@@ -24,6 +25,13 @@ module IsoDoc
24
25
  docxml
25
26
  end
26
27
 
28
+ def example_cleanup(docxml)
29
+ docxml.xpath("//table[@class = 'example']//p[not(@class)]").each do |p|
30
+ p["class"] = "example"
31
+ end
32
+ docxml
33
+ end
34
+
27
35
  def figure_get_or_make_dl(t)
28
36
  dl = t.at(".//dl")
29
37
  if dl.nil?
@@ -93,10 +101,15 @@ module IsoDoc
93
101
  t.xpath(".//aside").each do |a|
94
102
  merge_fnref_into_fn_text(a)
95
103
  a.name = "div"
96
- a["class"] = "Note"
104
+ a["class"] = "TableFootnote"
97
105
  t << a.remove
98
106
  end
99
107
  end
108
+ # preempt html2doc putting MsoNormal there
109
+ docxml.xpath("//p[not(self::*[@class])]"\
110
+ "[ancestor::*[@class = 'TableFootnote']]").each do |p|
111
+ p["class"] = "TableFootnote"
112
+ end
100
113
  end
101
114
 
102
115
  def remove_bottom_border(td)
@@ -127,10 +140,13 @@ module IsoDoc
127
140
  end
128
141
 
129
142
  def table_note_cleanup(docxml)
130
- docxml.xpath("//table[div[@class = 'Note']]").each do |t|
143
+ docxml.xpath("//table[div[@class = 'Note' or "\
144
+ "@class = 'TableFootnote']]").each do |t|
131
145
  tfoot = table_get_or_make_tfoot(t)
132
146
  insert_here = new_fullcolspan_row(t, tfoot)
133
- t.xpath("div[@class = 'Note']").each { |d| d.parent = insert_here }
147
+ t.xpath("div[@class = 'Note' or @class = 'TableFootnote']").each do |d|
148
+ d.parent = insert_here
149
+ end
134
150
  end
135
151
  # preempt html2doc putting MsoNormal there
136
152
  docxml.xpath("//p[not(self::*[@class])]"\
@@ -32,7 +32,7 @@ module IsoDoc
32
32
  out.span(**comment_link_attrs(fn, node)) do |s1|
33
33
  s1.span **{ lang: "EN-GB", style: "font-size:9.0pt" } do |s2|
34
34
  s2.a **{ style: "mso-comment-reference:SMC_#{fn};"\
35
- "mso-comment-date:#{node['date']}" }
35
+ "mso-comment-date:#{node['date'].gsub(/[-:Z]/, '')}" }
36
36
  s2.span **{ style: "mso-special-character:comment",
37
37
  target: fn } # do |s|
38
38
  end
@@ -39,6 +39,7 @@ module IsoDoc
39
39
  @wordcoverpage = options[:wordcoverpage]
40
40
  @htmlintropage = options[:htmlintropage]
41
41
  @wordintropage = options[:wordintropage]
42
+ @scripts = options[:scripts]
42
43
  @i18nyaml = options[:i18nyaml]
43
44
  @ulstyle = options[:ulstyle]
44
45
  @olstyle = options[:olstyle]
@@ -61,6 +62,7 @@ module IsoDoc
61
62
  @closemathdelim = "`"
62
63
  @lang = "en"
63
64
  @script = "Latn"
65
+ @files_to_delete = []
64
66
  end
65
67
 
66
68
  def convert1(docxml, filename, dir)
@@ -34,7 +34,7 @@ module IsoDoc
34
34
 
35
35
  def make_generic_footnote_text(node, fnid)
36
36
  noko do |xml|
37
- xml.aside **{ id: "ftn#{fnid}" } do |div|
37
+ xml.aside **{ id: "ftn#{fnid}", class: "footnote" } do |div|
38
38
  node.children.each { |n| parse(n, div) }
39
39
  end
40
40
  end.join("\n")
@@ -53,7 +53,9 @@ module IsoDoc
53
53
  # do not output footnote text if we have already seen it for this table
54
54
  return if @seen_footnote.include?(tid + fn)
55
55
  @in_footnote = true
56
- out.aside { |a| a << make_table_footnote_text(node, tid + fn, fn) }
56
+ out.aside **{ class: "footnote" } do |a|
57
+ a << make_table_footnote_text(node, tid + fn, fn)
58
+ end
57
59
  @in_footnote = false
58
60
  @seen_footnote << (tid + fn)
59
61
  end
@@ -3,10 +3,13 @@ module IsoDoc
3
3
  def postprocess(result, filename, dir)
4
4
  result = from_xhtml(cleanup(to_xhtml(result)))
5
5
  toHTML(result, filename)
6
+ @files_to_delete.each { |f| system "rm #{f}" }
6
7
  end
7
8
 
8
9
  def toHTML(result, filename)
9
- result = from_xhtml(html_cleanup(to_xhtml(result)))
10
+ result = from_xhtml(html_cleanup(to_xhtml(result))).
11
+ gsub(%r{<script><!\[CDATA\[}, "<script>").
12
+ gsub(%r{\]\]></script>}, "</script>")
10
13
  result = populate_template(result, :html)
11
14
  File.open("#{filename}.html", "w") do |f|
12
15
  f.write(result)
@@ -14,8 +17,8 @@ module IsoDoc
14
17
  end
15
18
 
16
19
  def html_cleanup(x)
17
- footnote_backlinks(
18
- html_toc(move_images(html_footnote_filter(html_preface(htmlstyle(x)))))
20
+ footnote_backlinks(html_toc(
21
+ term_header(move_images(html_footnote_filter(html_preface(htmlstyle(x))))))
19
22
  )
20
23
  end
21
24
 
@@ -36,24 +39,38 @@ module IsoDoc
36
39
  MATHJAX.gsub("OPEN", open).gsub("CLOSE", close)
37
40
  end
38
41
 
42
+ def term_header(docxml)
43
+ %w(h1 h2 h3 h4 h5 h6 h7 h8).each do |h|
44
+ docxml.xpath("//p[@class = 'TermNum'][../#{h}]").each do |p|
45
+ p.name = "h#{h[1].to_i + 1}"
46
+ end
47
+ end
48
+ docxml
49
+ end
50
+
39
51
  def html_preface(docxml)
40
52
  html_cover(docxml) if @htmlcoverpage
41
53
  html_intro(docxml) if @htmlintropage
42
- docxml.at("//*[local-name() = 'body']") << mathjax(@openmathdelim,
43
- @closemathdelim)
54
+ docxml.at("//body") << mathjax(@openmathdelim, @closemathdelim)
55
+ if @scripts
56
+ scripts = File.read(@scripts, encoding: "UTF-8")
57
+ docxml.at("//body").add_child scripts #scripts.to_xml(encoding: "US-ASCII")
58
+ end
44
59
  docxml
45
60
  end
46
61
 
47
62
  def html_cover(docxml)
48
- cover = Nokogiri::HTML(File.read(@htmlcoverpage, encoding: "UTF-8"))
63
+ cover = File.read(@htmlcoverpage, encoding: "UTF-8")
64
+ coverxml = to_xhtml_fragment(cover)
49
65
  d = docxml.at('//div[@class="WordSection1"]')
50
- d.children.first.add_previous_sibling cover.to_xml(encoding: "US-ASCII")
66
+ d.children.first.add_previous_sibling coverxml.to_xml(encoding: "US-ASCII")
51
67
  end
52
68
 
53
69
  def html_intro(docxml)
54
- cover = Nokogiri::HTML(File.read(@htmlintropage, encoding: "UTF-8"))
70
+ intro = File.read(@htmlintropage, encoding: "UTF-8")
71
+ introxml = to_xhtml_fragment(intro)
55
72
  d = docxml.at('//div[@class="WordSection2"]')
56
- d.children.first.add_previous_sibling cover.to_xml(encoding: "US-ASCII")
73
+ d.children.first.add_previous_sibling introxml.to_xml(encoding: "US-ASCII")
57
74
  end
58
75
 
59
76
  def htmlstylesheet
@@ -140,7 +157,8 @@ module IsoDoc
140
157
  ret = ""
141
158
  prevname = ""
142
159
  docxml.xpath("//h1 | //h2").each do |h|
143
- ret = html_toc1(h, ret, prevname) unless h["class"] == "toc-contents"
160
+ next if ["toc-contents", "TermNum"].include? h["class"]
161
+ ret = html_toc1(h, ret, prevname)
144
162
  prevname = h.name
145
163
  end
146
164
  ret += "<ul>" if prevname == "h2"
@@ -10,6 +10,7 @@ term_def_boilerplate: |
10
10
  </p> </li> </ul>
11
11
  scope: Scope
12
12
  symbols: Symbols and Abbreviated Terms
13
+ table_of_contents: Table of Contents
13
14
  introduction: Introduction
14
15
  foreword: Foreword
15
16
  termsdef: Terms and Definitions
@@ -18,6 +19,7 @@ normref: Normative References
18
19
  bibliography: Bibliography
19
20
  clause: Clause
20
21
  annex: Annex
22
+ appendix: Appendix
21
23
  no_terms_boilerplate: |
22
24
  <p>No terms and definitions are listed in this document.</p>
23
25
  internal_terms_boilerplate: |
@@ -57,6 +59,13 @@ deprecated: DEPRECATED
57
59
  source: SOURCE
58
60
  and: and
59
61
  all_parts: All Parts
62
+ admonition: {
63
+ danger: Danger,
64
+ warning: Warning,
65
+ caution: Caution,
66
+ important: Important,
67
+ safety precautions: Safety Precautions,
68
+ }
60
69
  locality: {
61
70
  section: Section,
62
71
  clause: Clause,
@@ -10,14 +10,16 @@ term_def_boilerplate: |
10
10
  </p> </li> </ul>
11
11
  scope: Domaine d'application
12
12
  symbols: Symboles et termes abrégés
13
+ table_of_contents: Sommaire
13
14
  introduction: Introduction
14
15
  foreword: Avant-propos
15
16
  termsdef: Terms et définitions
16
17
  termsdefsymbols: Terms, définitions, symboles et termes abrégés
17
18
  normref: Références normatives
18
- bibliography: then Bibliographie
19
- clause: then Article
19
+ bibliography: Bibliographie
20
+ clause: Article
20
21
  annex: Annexe
22
+ appendix: Appendice
21
23
  no_terms_boilerplate: |
22
24
  <p>Aucun terme n'est defini dans le présent document.</p>
23
25
  internal_terms_boilerplate: |
@@ -50,6 +52,13 @@ deprecated: DÉCONSEILLÉ
50
52
  source: SOURCE
51
53
  and: et
52
54
  all_parts: toutes les parties
55
+ admonition: {
56
+ danger: Danger,
57
+ warning: Avertissement,
58
+ caution: Attention,
59
+ important: Important,
60
+ safety precautions: Précautions de Sécurité,
61
+ }
53
62
  locality: {
54
63
  section: Section,
55
64
  clause: Article,
@@ -63,4 +72,4 @@ locality: {
63
72
  example: Exemple,
64
73
  note: Note,
65
74
  formula: Formule
66
- }
75
+ }
@@ -8,6 +8,7 @@ term_def_boilerplate: |
8
8
  </p> </li> </ul>
9
9
  scope: 范围
10
10
  symbols: 符号、代号和缩略语
11
+ table_of_contents: 目次
11
12
  introduction: 引言
12
13
  foreword: 前言
13
14
  termsdef: 术语和定义
@@ -15,7 +16,8 @@ termsdefsymbols_lbl: 术语、定义、符号、代号和缩略语
15
16
  normref: 规范性引用文件
16
17
  bibliography: 参考文献
17
18
  clause: 条
18
- annex: 附录
19
+ annex: 附件
20
+ appendix: 附录
19
21
  no_terms_boilerplate: |
20
22
  <p>本文件不提供术语和定义。</p>
21
23
  internal_terms_boilerplate: |
@@ -50,6 +52,13 @@ deprecated: 被取代
50
52
  source: 定义
51
53
  and: 和
52
54
  all_parts: 所有部分
55
+ admonition: {
56
+ danger: 危险,
57
+ warning: 警告,
58
+ caution: 注意,
59
+ important: 重要,
60
+ safety precautions: 安全须知,
61
+ }
53
62
  locality: {
54
63
  section: 条,
55
64
  clause: 条,
@@ -20,6 +20,7 @@ module IsoDoc
20
20
  @term_def_boilerplate = y["term_def_boilerplate"]
21
21
  @scope_lbl = y["scope"]
22
22
  @symbols_lbl = y["symbols"]
23
+ @table_of_contents_lbl = y["table_of_contents"]
23
24
  @introduction_lbl = y["introduction"]
24
25
  @foreword_lbl = y["foreword"]
25
26
  @termsdef_lbl = y["termsdef"]
@@ -28,6 +29,7 @@ module IsoDoc
28
29
  @bibliography_lbl = y["bibliography"]
29
30
  @clause_lbl = y["clause"]
30
31
  @annex_lbl = y["annex"]
32
+ @appendix_lbl = y["appendix"]
31
33
  @no_terms_boilerplate = y["no_terms_boilerplate"]
32
34
  @internal_terms_boilerplate = y["internal_terms_boilerplate"]
33
35
  @norm_with_refs_pref = y["norm_with_refs_pref"]
@@ -56,12 +58,16 @@ module IsoDoc
56
58
  @and_lbl = y["and"]
57
59
  @all_parts_lbl = y["all_parts"]
58
60
  @locality = y["locality"]
61
+ @admonition = y["admonition"]
62
+ @labels = y
63
+ @labels["language"] = @lang
64
+ @labels["script"] = @script
59
65
  end
60
66
 
61
67
  def eref_localities1_zh(type, from, to)
62
68
  ret = ", 第#{from.text}" if from
63
69
  ret += "&ndash;#{to}" if to
64
- ret += @locality[type]
70
+ ret += (@locality[type] || type.sub(/^locality:/, "").capitalize )
65
71
  ret
66
72
  end
67
73
 
@@ -69,7 +75,8 @@ module IsoDoc
69
75
  subsection = from&.text&.match?(/\./)
70
76
  return l10n(eref_localities1_zh(type, from, to)) if lang == "zh"
71
77
  ret = ","
72
- ret += " #{@locality[type]}" unless subsection && type == "clause"
78
+ loc = @locality[type] || type.sub(/^locality:/, "").capitalize
79
+ ret += " #{loc}" unless subsection && type == "clause"
73
80
  ret += " #{from.text}" if from
74
81
  ret += "&ndash;#{to.text}" if to
75
82
  l10n(ret)