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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 889ed14c0177867afde418d7d947a4f5963dc533c3c61c0b2d4bd320a1bb02a3
4
- data.tar.gz: 8f9a41c95de57470b68cba90e890d8753c49a36ea7f33658a72877177b5a8aa2
3
+ metadata.gz: 68d6f17f0d5291c6c067bfc6a3a476885b80f128bdc9c4e3e3d8356c6af30482
4
+ data.tar.gz: 2710c48aa2fb9eeee44b586107b07884d52802a53fec81d69c0f3fb68fa988ed
5
5
  SHA512:
6
- metadata.gz: aee9f7048977dabef0312c23c94e7d41b242e7623f7ec5daa252db232250ff9bd150e7d4750ac0000aa8463f79a8a716910b0e7a6929a3949353bbfe268b7327
7
- data.tar.gz: 0be841a473792658efd1221ee01a9011e1744cbe3e9fd4e2d0657ac057f41c057aba67f52d0f712326af915b5df802fc2d352338255fd688b31c1867d6ffac36
6
+ metadata.gz: 1c38cb43027aa1a056d465660449a4a58e1a5b78474a5f0184fca4164f2af2480720329e5a7181fcc1731151ef15db71019aa9fc34175b779de517006bf85fa6
7
+ data.tar.gz: '09503b88edfb1db0b3def003bca81c356b40790014953a9bc08de680af8db75222ded714f43a1f6820ec30dbaa2e3f83ac2a5e386f3c757f0d639f086e0b4b2c'
@@ -1,21 +1,28 @@
1
- # Auto-generated !!! Do not edit it manually
2
- # use ci-master https://github.com/metanorma/metanorma-build-scripts
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
3
3
  name: macos
4
4
 
5
5
  on:
6
6
  push:
7
7
  branches: [ master ]
8
8
  pull_request:
9
- branches: [ '**' ]
9
+ paths-ignore:
10
+ - .github/workflows/ubuntu.yml
11
+ - .github/workflows/windows.yml
10
12
 
11
13
  jobs:
12
14
  test-macos:
13
15
  name: Test on Ruby ${{ matrix.ruby }} macOS
14
16
  runs-on: macos-latest
17
+ continue-on-error: ${{ matrix.experimental }}
15
18
  strategy:
16
19
  fail-fast: false
17
20
  matrix:
18
21
  ruby: [ '2.6', '2.5', '2.4' ]
22
+ experimental: [false]
23
+ include:
24
+ - ruby: '2.7'
25
+ experimental: true
19
26
  steps:
20
27
  - uses: actions/checkout@master
21
28
  - name: Use Ruby
@@ -30,10 +37,10 @@ jobs:
30
37
  - name: Use Node
31
38
  uses: actions/setup-node@v1
32
39
  with:
33
- node-version: '8'
40
+ node-version: '12'
34
41
  - name: Install Puppeteer
35
42
  run: |
36
- npm install -g puppeteer
43
+ npm install -g puppeteer@3.0.1
37
44
  - name: Run specs
38
45
  run: |
39
46
  bundle exec rake
@@ -1,21 +1,28 @@
1
- # Auto-generated !!! Do not edit it manually
2
- # use ci-master https://github.com/metanorma/metanorma-build-scripts
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
3
3
  name: ubuntu
4
4
 
5
5
  on:
6
6
  push:
7
7
  branches: [ master ]
8
8
  pull_request:
9
- branches: [ '**' ]
9
+ paths-ignore:
10
+ - .github/workflows/macos.yml
11
+ - .github/workflows/windows.yml
10
12
 
11
13
  jobs:
12
14
  test-linux:
13
15
  name: Test on Ruby ${{ matrix.ruby }} Ubuntu
14
16
  runs-on: ubuntu-latest
17
+ continue-on-error: ${{ matrix.experimental }}
15
18
  strategy:
16
19
  fail-fast: false
17
20
  matrix:
18
21
  ruby: [ '2.6', '2.5', '2.4' ]
22
+ experimental: [false]
23
+ include:
24
+ - ruby: '2.7'
25
+ experimental: true
19
26
  steps:
20
27
  - uses: actions/checkout@master
21
28
  - name: Use Ruby
@@ -25,15 +32,29 @@ jobs:
25
32
  architecture: 'x64'
26
33
  - name: Update gems
27
34
  run: |
28
- gem install bundler
35
+ gem install bundler
29
36
  bundle install --jobs 4 --retry 3
30
37
  - name: Use Node
31
38
  uses: actions/setup-node@v1
32
39
  with:
33
- node-version: '8'
40
+ node-version: '12'
34
41
  - name: Install Puppeteer
35
42
  run: |
36
- npm install -g puppeteer
43
+ sudo apt-get update
44
+ sudo apt-get install libgbm1
45
+ npm install -g puppeteer@3.0.1
37
46
  - name: Run specs
38
47
  run: |
39
48
  bundle exec rake
49
+ - name: Trigger dependent repositories
50
+ if: github.ref == 'refs/heads/master' && matrix.ruby == '2.6'
51
+ env:
52
+ GH_USERNAME: ${{ secrets.PAT_USERNAME }}
53
+ GH_ACCESS_TOKEN: ${{ secrets.PAT_TOKEN }}
54
+ run: |
55
+ curl -LO --retry 3 https://raw.githubusercontent.com/metanorma/metanorma-build-scripts/master/trigger-gh-actions.sh
56
+ [[ -f ".github/workflows/dependent_repos.env" ]] && source .github/workflows/dependent_repos.env
57
+ for repo in $DEPENDENT_REPOS
58
+ do
59
+ sh trigger-gh-actions.sh $ORGANISATION $repo $GH_USERNAME $GH_ACCESS_TOKEN $GITHUB_REPOSITORY
60
+ done
@@ -1,21 +1,28 @@
1
- # Auto-generated !!! Do not edit it manually
2
- # use ci-master https://github.com/metanorma/metanorma-build-scripts
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
3
3
  name: windows
4
4
 
5
5
  on:
6
6
  push:
7
7
  branches: [ master ]
8
8
  pull_request:
9
- branches: [ '**' ]
9
+ paths-ignore:
10
+ - .github/workflows/macos.yml
11
+ - .github/workflows/ubuntu.yml
10
12
 
11
13
  jobs:
12
14
  test-windows:
13
15
  name: Test on Ruby ${{ matrix.ruby }} Windows
14
16
  runs-on: windows-latest
17
+ continue-on-error: ${{ matrix.experimental }}
15
18
  strategy:
16
19
  fail-fast: false
17
20
  matrix:
18
21
  ruby: [ '2.6', '2.5', '2.4' ]
22
+ experimental: [false]
23
+ include:
24
+ - ruby: '2.7'
25
+ experimental: true
19
26
  steps:
20
27
  - uses: actions/checkout@master
21
28
  - name: Use Ruby
@@ -26,17 +33,16 @@ jobs:
26
33
  - name: Update gems
27
34
  shell: pwsh
28
35
  run: |
29
- gem install bundler
36
+ gem install bundler
30
37
  bundle config --local path vendor/bundle
31
- bundle update
32
38
  bundle install --jobs 4 --retry 3
33
39
  - name: Use Node
34
40
  uses: actions/setup-node@v1
35
41
  with:
36
- node-version: '8'
42
+ node-version: '12'
37
43
  - name: Install Puppeteer
38
44
  run: |
39
- npm install -g puppeteer
45
+ npm install -g puppeteer@3.0.1
40
46
  - name: Run specs
41
47
  run: |
42
48
  bundle exec rake
@@ -1,8 +1,9 @@
1
1
  = isodoc: Processor to generate HTML/Word from Metanorma XML
2
2
 
3
3
  image:https://img.shields.io/gem/v/isodoc.svg["Gem Version", link="https://rubygems.org/gems/isodoc"]
4
- image:https://travis-ci.com/metanorma/isodoc.svg["Build Status", link="https://travis-ci.com/metanorma/isodoc"]
5
- image:https://ci.appveyor.com/api/projects/status/f93bvu6qfwxij07x?svg=true["Appveyor Build Status", link="https://ci.appveyor.com/project/metanorma/isodoc"]
4
+ image:https://github.com/metanorma/isodoc/workflows/ubuntu/badge.svg["Ubuntu Build Status", link="https://github.com/metanorma/isodoc/actions?query=workflow%3Aubuntu"]
5
+ image:https://github.com/metanorma/isodoc/workflows/macos/badge.svg["OSX Build Status", link="https://github.com/metanorma/isodoc/actions?query=workflow%3Amacos"]
6
+ image:https://github.com/metanorma/isodoc/workflows/windows/badge.svg["Windows Build Status", link="https://github.com/metanorma/isodoc/actions?query=workflow%3Awindows"]
6
7
  image:https://codeclimate.com/github/metanorma/isodoc/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/isodoc"]
7
8
  image:https://img.shields.io/github/issues-pr-raw/metanorma/isodoc.svg["Pull Requests", link="https://github.com/metanorma/isodoc/pulls"]
8
9
  image:https://img.shields.io/github/commits-since/metanorma/isodoc/latest.svg["Commits since latest",link="https://github.com/metanorma/isodoc/releases"]
@@ -6,7 +6,9 @@ introduction: Introduction
6
6
  foreword: Foreword
7
7
  abstract: Abstract
8
8
  termsdef: Terms and definitions
9
- termsdefsymbols: Terms, definitions, symbols and abbreviated terms
9
+ termsdefsymbolsabbrev: Terms, definitions, symbols and abbreviated terms
10
+ termsdefsymbols: Terms, definitions and symbols
11
+ termsdefabbrev: Terms, definitions and abbreviated terms
10
12
  normref: Normative references
11
13
  bibliography: Bibliography
12
14
  clause: Clause
@@ -55,6 +57,21 @@ deprecated: DEPRECATED
55
57
  source: SOURCE
56
58
  and: and
57
59
  all_parts: All Parts
60
+ month_january: January
61
+ month_february: February
62
+ month_march: March
63
+ month_april: April
64
+ month_may: May
65
+ month_june: June
66
+ month_july: July
67
+ month_august: August
68
+ month_september: September
69
+ month_october: October
70
+ month_november: November
71
+ month_december: December
72
+ obligation: Obligation
73
+ subject: Subject
74
+ inherits: Inherits
58
75
  admonition: {
59
76
  danger: Danger,
60
77
  warning: Warning,
@@ -6,7 +6,9 @@ introduction: Introduction
6
6
  foreword: Avant-propos
7
7
  abstract: Résumé
8
8
  termsdef: Terms et définitions
9
- termsdefsymbols: Terms, définitions, symboles et termes abrégés
9
+ termsdefsymbolsabbrev: Terms, définitions, symboles et termes abrégés
10
+ termsdefsymbols: Terms, définitions et symboles
11
+ termsdefabbrev: Terms, définitions et termes abrégés
10
12
  normref: Références normatives
11
13
  bibliography: Bibliographie
12
14
  clause: Article
@@ -48,6 +50,21 @@ deprecated: DÉCONSEILLÉ
48
50
  source: SOURCE
49
51
  and: et
50
52
  all_parts: toutes les parties
53
+ month_january: Janvier
54
+ month_february: Février
55
+ month_march: Mars
56
+ month_april: Avril
57
+ month_may: Mai
58
+ month_june: Juin
59
+ month_july: Juillet
60
+ month_august: Août
61
+ month_september: Septembre
62
+ month_october: Octobre
63
+ month_november: Novembre
64
+ month_december: Décembre
65
+ obligation: Obligation
66
+ subject: Sujet
67
+ inherits: Hérite
51
68
  admonition: {
52
69
  danger: Danger,
53
70
  warning: Avertissement,
@@ -6,7 +6,9 @@ introduction: 引言
6
6
  foreword: 前言
7
7
  abstract: 摘要
8
8
  termsdef: 术语和定义
9
- termsdefsymbols: 术语、定义、符号、代号和缩略语
9
+ termsdefsymbolsabbrev: 术语、定义、符号、代号和缩略语
10
+ termsdefsymbols: 术语、定义、符号和代号
11
+ termsdefabbrev: 术语、定义、符号和缩略语
10
12
  normref: 规范性引用文件
11
13
  bibliography: 参考文献
12
14
  clause: 条
@@ -50,6 +52,21 @@ deprecated: 被取代
50
52
  source: 定义
51
53
  and: 和
52
54
  all_parts: 所有部分
55
+ month_january: 一月
56
+ month_february: 二月
57
+ month_march: 三月
58
+ month_april: 四月
59
+ month_may: 五月
60
+ month_june: 六月
61
+ month_july: 七月
62
+ month_august: 八月
63
+ month_september: 九月
64
+ month_october: 十月
65
+ month_november: 十一月
66
+ month_december: 十二月
67
+ obligation: 义务
68
+ subject: 主体
69
+ inherits: 继承自
53
70
  admonition: {
54
71
  danger: 危险,
55
72
  warning: 警告,
@@ -7,7 +7,10 @@
7
7
  }
8
8
 
9
9
  font-weight: $fontWeight;
10
- height: $length;
10
+
11
+ @if $length {
12
+ height: $length;
13
+ }
11
14
 
12
15
  color: $color;
13
16
  text-transform: uppercase;
@@ -28,9 +31,9 @@
28
31
 
29
32
  @mixin docBand(
30
33
  $order,
31
- $textLength,
34
+ $textLength: null,
32
35
  $offset: 0,
33
- $color: white,
36
+ $color: white,
34
37
  $fontWeight: 400,
35
38
  $fontFamily: null) {
36
39
 
@@ -125,5 +125,5 @@ b, strong {
125
125
  }
126
126
 
127
127
  div.document-stage-band, div.document-type-band {
128
- background-color: #FFFFFF;
128
+ background-color: #333333;
129
129
  }
@@ -48,6 +48,7 @@ module IsoDoc
48
48
  @olstyle = options[:olstyle]
49
49
  @datauriimage = options[:datauriimage]
50
50
  @suppressheadingnumbers = options[:suppressheadingnumbers]
51
+ @break_up_urls_in_tables = options[:break_up_urls_in_tables] == "true"
51
52
  @termdomain = ""
52
53
  @termexample = false
53
54
  @note = false
@@ -222,5 +222,10 @@ module IsoDoc::Function
222
222
  quote_attribution(node, out)
223
223
  end
224
224
  end
225
+
226
+ def passthrough_parse(node, out)
227
+ return if node["format"] and !(node["format"].split(/,/).include? @format.to_s)
228
+ out.passthrough node.text
229
+ end
225
230
  end
226
231
  end
@@ -1,6 +1,7 @@
1
1
  module IsoDoc::Function
2
2
  module Cleanup
3
3
  def textcleanup(docxml)
4
+ docxml = passthrough_cleanup(docxml)
4
5
  docxml.
5
6
  gsub(/\[TERMREF\]\s*/, l10n("[#{@source_lbl}: ")).
6
7
  gsub(/\s*\[MODIFICATION\]\s*\[\/TERMREF\]/, l10n(", #{@modified_lbl} [/TERMREF]")).
@@ -8,6 +9,13 @@ module IsoDoc::Function
8
9
  gsub(/\s*\[MODIFICATION\]/, l10n(", #{@modified_lbl} — "))
9
10
  end
10
11
 
12
+ def passthrough_cleanup(docxml)
13
+ docxml = docxml.split(%r{(<passthrough>|</passthrough>)}).each_slice(4).map do |a|
14
+ a.size > 2 and a[2] = HTMLEntities.new.decode(a[2])
15
+ [a[0], a[2]]
16
+ end.join
17
+ end
18
+
11
19
  def cleanup(docxml)
12
20
  comment_cleanup(docxml)
13
21
  footnote_cleanup(docxml)
@@ -20,15 +28,18 @@ module IsoDoc::Function
20
28
  end
21
29
 
22
30
  def table_long_strings_cleanup(docxml)
31
+ return unless @break_up_urls_in_tables == true
23
32
  docxml.xpath("//td | //th").each do |d|
24
33
  d.traverse do |n|
25
34
  next unless n.text?
26
- n.replace(break_up_long_strings(n.text))
35
+ n.replace(HTMLEntities.new.encode(
36
+ break_up_long_strings(n.text)))
27
37
  end
28
38
  end
29
39
  end
30
40
 
31
41
  def break_up_long_strings(t)
42
+ return t if t.match(/^\s*$/)
32
43
  t.split(/(?=\s)/).map do |w|
33
44
  (/^\s*$/.match(t) or w.size < 30) ? w :
34
45
  w.scan(/.{,30}/).map do |w1|
@@ -77,8 +77,8 @@ module IsoDoc::Function
77
77
  end
78
78
 
79
79
  # TODO: move to localization file
80
- def eref_localities1_zh(target, type, from, to)
81
- ret = ", 第#{from.text}" if from
80
+ def eref_localities1_zh(target, type, from, to, delim)
81
+ ret = "#{delim} 第#{from.text}" if from
82
82
  ret += "&ndash;#{to}" if to
83
83
  loc = (@locality[type] || type.sub(/^locality:/, "").capitalize )
84
84
  ret += " #{loc}"
@@ -86,9 +86,9 @@ module IsoDoc::Function
86
86
  end
87
87
 
88
88
  # TODO: move to localization file
89
- def eref_localities1(target, type, from, to, lang = "en")
90
- return l10n(eref_localities1_zh(target, type, from, to)) if lang == "zh"
91
- ret = ","
89
+ def eref_localities1(target, type, from, to, delim, lang = "en")
90
+ return l10n(eref_localities1_zh(target, type, from, to, delim)) if lang == "zh"
91
+ ret = delim
92
92
  loc = @locality[type] || type.sub(/^locality:/, "").capitalize
93
93
  ret += " #{loc}"
94
94
  ret += " #{from.text}" if from
@@ -55,12 +55,12 @@ module IsoDoc::Function
55
55
  end
56
56
 
57
57
  def get_linkend(node)
58
- link = anchor_linkend(node, docid_l10n(node["target"] || node["citeas"]))
59
- link += eref_localities(node.xpath(ns("./locality")), link)
60
- contents = node.children.select { |c| c.name != "locality" }.
58
+ contents = node.children.select { |c| !%w{locality localityStack}.include? c.name }.
61
59
  select { |c| !c.text? || /\S/.match(c) }
62
- return link if contents.nil? || contents.empty?
63
- Nokogiri::XML::NodeSet.new(node.document, contents).to_xml
60
+ !contents.empty? and
61
+ return Nokogiri::XML::NodeSet.new(node.document, contents).to_xml
62
+ link = anchor_linkend(node, docid_l10n(node["target"] || node["citeas"]))
63
+ link + eref_localities(node.xpath(ns("./locality | ./localityStack")), link)
64
64
  # so not <origin bibitemid="ISO7301" citeas="ISO 7301">
65
65
  # <locality type="section"><reference>3.1</reference></locality></origin>
66
66
  end
@@ -73,16 +73,29 @@ module IsoDoc::Function
73
73
 
74
74
  def eref_localities(refs, target)
75
75
  ret = ""
76
- refs.each do |r|
77
- ret += if r["type"] == "whole" then l10n(", #{@whole_of_text}")
78
- else
79
- eref_localities1(target, r["type"], r.at(ns("./referenceFrom")),
80
- r.at(ns("./referenceTo")), @lang)
81
- end
76
+ refs.each_with_index do |r, i|
77
+ delim = ","
78
+ delim = ";" if r.name == "localityStack" && i>0
79
+ if r.name == "localityStack"
80
+ r.elements.each_with_index do |rr, j|
81
+ ret += eref_localities0(rr, j, target, delim)
82
+ delim = ","
83
+ end
84
+ else
85
+ ret += eref_localities0(r, i, target, delim)
86
+ end
82
87
  end
83
88
  ret
84
89
  end
85
90
 
91
+ def eref_localities0(r, i, target, delim)
92
+ if r["type"] == "whole" then l10n("#{delim} #{@whole_of_text}")
93
+ else
94
+ eref_localities1(target, r["type"], r.at(ns("./referenceFrom")),
95
+ r.at(ns("./referenceTo")), delim, @lang)
96
+ end
97
+ end
98
+
86
99
  def eref_parse(node, out)
87
100
  linkend = get_linkend(node)
88
101
  if node["type"] == "footnote"
@@ -94,12 +107,20 @@ module IsoDoc::Function
94
107
  end
95
108
  end
96
109
 
110
+ def origin_parse(node, out)
111
+ if t = node.at(ns("./termref"))
112
+ termrefelem_parse(t, out)
113
+ else
114
+ eref_parse(node, out)
115
+ end
116
+ end
117
+
97
118
  def termrefelem_parse(node, out)
98
119
  out << "Termbase #{node['base']}, term ID #{node['target']}"
99
120
  end
100
121
 
101
122
  def concept_parse(node, out)
102
- content = node.first_element_child.children.select { |c| c.name != "locality" }.
123
+ content = node.first_element_child.children.select { |c| !%w{locality localityStack}.include? c.name }.
103
124
  select { |c| !c.text? || /\S/.match(c) }
104
125
  if content.empty?
105
126
  out << "[Term defined in "
@@ -206,5 +227,19 @@ module IsoDoc::Function
206
227
  p.b(**{ role: "strong" }) { |e| e << text }
207
228
  end
208
229
  end
230
+
231
+ def variant_parse(node, out)
232
+ if node["lang"] == @lang && node["script"] == @script
233
+ node.children.each { |n| parse(n, out) }
234
+ else
235
+ prev = node.xpath("./preceding-sibling::xmlns:variant")
236
+ foll = node.xpath("./following-sibling::xmlns:variant")
237
+ found = false
238
+ (prev + foll).each { |n| found = true if n["lang"] == @lang && n["script"] == @script }
239
+ return if found
240
+ return unless prev.empty?
241
+ node.children.each { |n| parse(n, out) }
242
+ end
243
+ end
209
244
  end
210
245
  end