metanorma-standoc 1.4.3 → 1.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ubuntu.yml +1 -1
- data/.rubocop.yml +1 -1
- data/Rakefile +2 -0
- data/lib/asciidoctor/standoc/base.rb +5 -4
- data/lib/asciidoctor/standoc/base_structured_text_preprocessor.rb +123 -0
- data/lib/asciidoctor/standoc/basicdoc.rng +31 -1
- data/lib/asciidoctor/standoc/cleanup.rb +2 -0
- data/lib/asciidoctor/standoc/cleanup_amend.rb +54 -0
- data/lib/asciidoctor/standoc/cleanup_block.rb +0 -2
- data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +11 -24
- data/lib/asciidoctor/standoc/cleanup_footnotes.rb +0 -3
- data/lib/asciidoctor/standoc/cleanup_inline.rb +62 -1
- data/lib/asciidoctor/standoc/cleanup_ref.rb +8 -4
- data/lib/asciidoctor/standoc/cleanup_section.rb +91 -8
- data/lib/asciidoctor/standoc/cleanup_terms.rb +12 -2
- data/lib/asciidoctor/standoc/converter.rb +3 -3
- data/lib/asciidoctor/standoc/front.rb +0 -12
- data/lib/asciidoctor/standoc/front_contributor.rb +43 -10
- data/lib/asciidoctor/standoc/inline.rb +13 -1
- data/lib/asciidoctor/standoc/isodoc.rng +124 -15
- data/lib/asciidoctor/standoc/json2_text_preprocessor.rb +43 -0
- data/lib/asciidoctor/standoc/log.rb +10 -1
- data/lib/asciidoctor/standoc/macros.rb +45 -33
- data/lib/asciidoctor/standoc/ref.rb +24 -25
- data/lib/asciidoctor/standoc/section.rb +39 -30
- data/lib/asciidoctor/standoc/table.rb +3 -2
- data/lib/asciidoctor/standoc/utils.rb +18 -1
- data/lib/asciidoctor/standoc/validate.rb +30 -18
- data/lib/asciidoctor/standoc/validate_section.rb +1 -1
- data/lib/asciidoctor/standoc/views/datamodel/model_representation.adoc.erb +10 -10
- data/lib/asciidoctor/standoc/yaml2_text_preprocessor.rb +43 -0
- data/lib/liquid/custom_blocks/key_iterator.rb +21 -0
- data/lib/liquid/custom_filters/values.rb +7 -0
- data/lib/metanorma/standoc/version.rb +1 -1
- data/metanorma-standoc.gemspec +4 -5
- data/spec/asciidoctor-standoc/base_spec.rb +21 -6
- data/spec/asciidoctor-standoc/blocks_spec.rb +274 -148
- data/spec/asciidoctor-standoc/cleanup_spec.rb +1367 -53
- data/spec/asciidoctor-standoc/inline_spec.rb +5 -2
- data/spec/asciidoctor-standoc/macros_json2text_spec.rb +10 -0
- data/spec/asciidoctor-standoc/macros_spec.rb +43 -23
- data/spec/asciidoctor-standoc/macros_yaml2text_spec.rb +5 -560
- data/spec/asciidoctor-standoc/refs_dl_spec.rb +9 -7
- data/spec/asciidoctor-standoc/refs_spec.rb +16 -16
- data/spec/asciidoctor-standoc/section_spec.rb +42 -39
- data/spec/asciidoctor-standoc/table_spec.rb +119 -113
- data/spec/asciidoctor-standoc/validate_spec.rb +45 -1
- data/spec/assets/{html.css → html.scss} +0 -0
- data/spec/assets/i18n.yaml +17 -2
- data/spec/assets/{word.css → word.scss} +0 -0
- data/spec/examples/codes_table.html +1365 -1365
- data/spec/fixtures/macros_datamodel/address_class_profile.xml +46 -46
- data/spec/fixtures/macros_datamodel/address_component_profile.xml +21 -21
- data/spec/fixtures/macros_datamodel/blank_definition_profile.xml +21 -21
- data/spec/metanorma/processor_spec.rb +1 -2
- data/spec/spec_helper.rb +110 -109
- data/spec/support/shared_examples/structured_data_2_text_preprocessor.rb +583 -0
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +66 -66
- data/spec/vcr_cassettes/isobib_get_123.yml +16 -16
- data/spec/vcr_cassettes/isobib_get_123_1.yml +33 -33
- data/spec/vcr_cassettes/isobib_get_123_2001.yml +19 -19
- data/spec/vcr_cassettes/isobib_get_124.yml +19 -19
- data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +8 -8
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +28 -28
- metadata +44 -13
- data/lib/asciidoctor-yaml/i18n-en.yaml +0 -20
- data/lib/asciidoctor-yaml/i18n-fr.yaml +0 -13
- data/lib/asciidoctor-yaml/i18n-zh-Hans.yaml +0 -15
- data/lib/asciidoctor/standoc/i18n.rb +0 -39
- data/lib/asciidoctor/standoc/macros_yaml2text.rb +0 -165
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7503bfc7dd68c2d6a6b2ded8f08611e92067a15aa4088c02f1e5408ff8e027e6
|
4
|
+
data.tar.gz: 65cd5d4d3648788113fd30437fe8d649c6e498b9ebdab8d5b41d2fadb7439056
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73510f7d926c6acf395377794a753cef6bb0f0658fb66c606df07e23548c17f010c7120b77765b388fb363a4309051fcf03a601d6ea95cf20aca6e4645b1c674
|
7
|
+
data.tar.gz: bae732755cc47dcae17e0d8ef01bcd35173c8941807b2d5844cf45f008f57c199977756d4fd15b0e3c8c558e73432dd9ba88be2b01f61b32cff180308adcd83d
|
@@ -43,7 +43,7 @@ jobs:
|
|
43
43
|
polling_interval_seconds: 5
|
44
44
|
timeout_minutes: 5
|
45
45
|
max_attempts: 3
|
46
|
-
command: sudo bash -c "curl -L https://github.com/metanorma/plantuml-install/raw/master/ubuntu.sh | bash"
|
46
|
+
command: sudo apt-get update -y && sudo bash -c "curl -L https://github.com/metanorma/plantuml-install/raw/master/ubuntu.sh | bash"
|
47
47
|
- name: Run specs
|
48
48
|
run: |
|
49
49
|
bundle exec rake
|
data/.rubocop.yml
CHANGED
data/Rakefile
CHANGED
@@ -111,9 +111,10 @@ module Asciidoctor
|
|
111
111
|
@log = Asciidoctor::Standoc::Log.new
|
112
112
|
init_bib_caches(node)
|
113
113
|
init_iev_caches(node)
|
114
|
-
lang = (node.attr("language") || "en")
|
115
|
-
script = (node.attr("script") || "
|
116
|
-
|
114
|
+
@lang = (node.attr("language") || "en")
|
115
|
+
@script = (node.attr("script") || "Latn")
|
116
|
+
@isodoc = isodoc(@lang, @script, node.attr("i18nyaml"))
|
117
|
+
@i18n = @isodoc.i18n
|
117
118
|
end
|
118
119
|
|
119
120
|
def default_fonts(node)
|
@@ -169,7 +170,7 @@ module Asciidoctor
|
|
169
170
|
end
|
170
171
|
|
171
172
|
def doctype(node)
|
172
|
-
node.attr("doctype")
|
173
|
+
node.attr("doctype")&.gsub(/\s+/, "-")&.downcase
|
173
174
|
end
|
174
175
|
|
175
176
|
def front(node, xml)
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "liquid/custom_blocks/key_iterator"
|
4
|
+
require "liquid/custom_filters/values"
|
5
|
+
|
6
|
+
Liquid::Template.register_tag("keyiterator", Liquid::CustomBlocks::KeyIterator)
|
7
|
+
Liquid::Template.register_filter(Liquid::CustomFilters)
|
8
|
+
|
9
|
+
module Asciidoctor
|
10
|
+
module Standoc
|
11
|
+
# Base class for processing structured data blocks(yaml, json)
|
12
|
+
class BaseStructuredTextPreprocessor < Asciidoctor::Extensions::Preprocessor
|
13
|
+
BLOCK_START_REGEXP = /\{(.+?)\.\*,(.+),(.+)\}/
|
14
|
+
BLOCK_END_REGEXP = /\A\{[A-Z]+\}\z/
|
15
|
+
|
16
|
+
def process(document, reader)
|
17
|
+
input_lines = reader.readlines.to_enum
|
18
|
+
Reader.new(processed_lines(document, input_lines))
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def content_from_file(_document, _file_path)
|
24
|
+
raise ArgumentError, "Implement `content_from_file` in your class"
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def processed_lines(document, input_lines)
|
30
|
+
result = []
|
31
|
+
loop do
|
32
|
+
result.push(*process_text_blocks(document, input_lines))
|
33
|
+
end
|
34
|
+
result
|
35
|
+
end
|
36
|
+
|
37
|
+
def relative_file_path(document, file_path)
|
38
|
+
docfile_directory = File.dirname(document.attributes["docfile"] || ".")
|
39
|
+
document
|
40
|
+
.path_resolver
|
41
|
+
.system_path(file_path, docfile_directory)
|
42
|
+
end
|
43
|
+
|
44
|
+
def process_text_blocks(document, input_lines)
|
45
|
+
line = input_lines.next
|
46
|
+
block_match = line.match(/^\[#{config[:block_name]},(.+?),(.+?)\]/)
|
47
|
+
return [line] if block_match.nil?
|
48
|
+
|
49
|
+
mark = input_lines.next
|
50
|
+
current_block = []
|
51
|
+
while (block_line = input_lines.next) != mark
|
52
|
+
current_block.push(block_line)
|
53
|
+
end
|
54
|
+
read_content_and_parse_template(document,
|
55
|
+
current_block,
|
56
|
+
block_match)
|
57
|
+
end
|
58
|
+
|
59
|
+
def read_content_and_parse_template(document, current_block, block_match)
|
60
|
+
transformed_liquid_lines = current_block
|
61
|
+
.map(&method(:transform_line_liquid))
|
62
|
+
context_items = content_from_file(document, block_match[1])
|
63
|
+
parse_context_block(document: document,
|
64
|
+
context_lines: transformed_liquid_lines,
|
65
|
+
context_items: context_items,
|
66
|
+
context_name: block_match[2])
|
67
|
+
rescue StandardError => exception
|
68
|
+
document.logger
|
69
|
+
.warn("Failed to parse #{config[:block_name]} \
|
70
|
+
block: #{exception.message}")
|
71
|
+
[]
|
72
|
+
end
|
73
|
+
|
74
|
+
def transform_line_liquid(line)
|
75
|
+
if line.match?(BLOCK_START_REGEXP)
|
76
|
+
line.gsub!(BLOCK_START_REGEXP,
|
77
|
+
'{% keyiterator \1, \2 %}')
|
78
|
+
end
|
79
|
+
|
80
|
+
if line.strip.match?(BLOCK_END_REGEXP)
|
81
|
+
line.gsub!(BLOCK_END_REGEXP, "{% endkeyiterator %}")
|
82
|
+
end
|
83
|
+
line
|
84
|
+
.gsub(/(?<!{){(?!%)([^{}]+)(?<!%)}(?!})/, '{{\1}}')
|
85
|
+
.gsub(/[a-z\.]+\#/, "index")
|
86
|
+
.gsub(/{{(.+)\s+\+\s+(\d+)\s*?}}/, '{{ \1 | plus: \2 }}')
|
87
|
+
.gsub(/{{(.+)\s+\-\s+(\d+)\s*?}}/, '{{ \1 | minus: \2 }}')
|
88
|
+
.gsub(/{{(.+).values(.*?)}}/,
|
89
|
+
'{% assign custom_value = \1 | values %}{{custom_value\2}}')
|
90
|
+
end
|
91
|
+
|
92
|
+
def parse_context_block(context_lines:,
|
93
|
+
context_items:,
|
94
|
+
context_name:,
|
95
|
+
document:)
|
96
|
+
render_result, errors = render_liquid_string(
|
97
|
+
template_string: context_lines.join("\n"),
|
98
|
+
context_items: context_items,
|
99
|
+
context_name: context_name
|
100
|
+
)
|
101
|
+
notify_render_errors(document, errors)
|
102
|
+
render_result.split("\n")
|
103
|
+
end
|
104
|
+
|
105
|
+
def render_liquid_string(template_string:, context_items:, context_name:)
|
106
|
+
liquid_template = Liquid::Template.parse(template_string)
|
107
|
+
rendered_string = liquid_template
|
108
|
+
.render(context_name => context_items,
|
109
|
+
strict_variables: true,
|
110
|
+
error_mode: :warn)
|
111
|
+
[rendered_string, liquid_template.errors]
|
112
|
+
end
|
113
|
+
|
114
|
+
def notify_render_errors(document, errors)
|
115
|
+
errors.each do |error_obj|
|
116
|
+
document
|
117
|
+
.logger
|
118
|
+
.warn("Liquid render error: #{error_obj.message}")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -158,7 +158,17 @@
|
|
158
158
|
<data type="ID"/>
|
159
159
|
</attribute>
|
160
160
|
<oneOrMore>
|
161
|
-
<
|
161
|
+
<choice>
|
162
|
+
<ref name="formula"/>
|
163
|
+
<ref name="ul"/>
|
164
|
+
<ref name="ol"/>
|
165
|
+
<ref name="dl"/>
|
166
|
+
<ref name="quote"/>
|
167
|
+
<ref name="sourcecode"/>
|
168
|
+
<ref name="paragraph"/>
|
169
|
+
<ref name="table"/>
|
170
|
+
<ref name="figure"/>
|
171
|
+
</choice>
|
162
172
|
</oneOrMore>
|
163
173
|
</element>
|
164
174
|
</define>
|
@@ -402,6 +412,16 @@
|
|
402
412
|
</choice>
|
403
413
|
</attribute>
|
404
414
|
</optional>
|
415
|
+
<optional>
|
416
|
+
<attribute name="valign">
|
417
|
+
<choice>
|
418
|
+
<value>top</value>
|
419
|
+
<value>middle</value>
|
420
|
+
<value>bottom</value>
|
421
|
+
<value>baseline</value>
|
422
|
+
</choice>
|
423
|
+
</attribute>
|
424
|
+
</optional>
|
405
425
|
<choice>
|
406
426
|
<zeroOrMore>
|
407
427
|
<ref name="TextElement"/>
|
@@ -429,6 +449,16 @@
|
|
429
449
|
</choice>
|
430
450
|
</attribute>
|
431
451
|
</optional>
|
452
|
+
<optional>
|
453
|
+
<attribute name="valign">
|
454
|
+
<choice>
|
455
|
+
<value>top</value>
|
456
|
+
<value>middle</value>
|
457
|
+
<value>bottom</value>
|
458
|
+
<value>baseline</value>
|
459
|
+
</choice>
|
460
|
+
</attribute>
|
461
|
+
</optional>
|
432
462
|
<choice>
|
433
463
|
<zeroOrMore>
|
434
464
|
<ref name="TextElement"/>
|
@@ -9,6 +9,7 @@ require_relative "./cleanup_boilerplate.rb"
|
|
9
9
|
require_relative "./cleanup_section.rb"
|
10
10
|
require_relative "./cleanup_terms.rb"
|
11
11
|
require_relative "./cleanup_inline.rb"
|
12
|
+
require_relative "./cleanup_amend.rb"
|
12
13
|
require "relaton_iev"
|
13
14
|
|
14
15
|
module Asciidoctor
|
@@ -71,6 +72,7 @@ module Asciidoctor
|
|
71
72
|
para_cleanup(xmldoc)
|
72
73
|
empty_element_cleanup(xmldoc)
|
73
74
|
img_cleanup(xmldoc)
|
75
|
+
anchor_cleanup(xmldoc)
|
74
76
|
xmldoc
|
75
77
|
end
|
76
78
|
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Asciidoctor
|
2
|
+
module Standoc
|
3
|
+
module Cleanup
|
4
|
+
def change_clauses(x)
|
5
|
+
x.xpath("//clause[@change]").each do |c|
|
6
|
+
a = create_amend(c)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_amend(c)
|
11
|
+
a = c.add_child("<amend id='_#{UUIDTools::UUID.random_create}'/>").first
|
12
|
+
c.elements.each do |e|
|
13
|
+
e.parent = a unless %w(amend title).include? e.name
|
14
|
+
end
|
15
|
+
create_amend1(c, a)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_amend1(c, a)
|
19
|
+
create_amend2(c, a)
|
20
|
+
d = a.at("./description")
|
21
|
+
d.xpath(".//autonumber").each { |e| d.previous = e }
|
22
|
+
d.xpath(".//p[normalize-space(.)='']").each { |e| e.remove }
|
23
|
+
move_attrs_to_amend(c, a)
|
24
|
+
a
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_amend2(c, a)
|
28
|
+
q = a.at("./quote") and q.name = "newcontent"
|
29
|
+
if q.nil?
|
30
|
+
a.children = "<description>#{a.children.to_xml}</description>"
|
31
|
+
else
|
32
|
+
pre = q&.xpath("./preceding-sibling::*")&.remove
|
33
|
+
post = q&.xpath("./following-sibling::*")&.remove
|
34
|
+
pre.empty? or a << "<description>#{pre.to_xml}</description>"
|
35
|
+
a << q.remove
|
36
|
+
post.empty? or a << "<description>#{post.to_xml}</description>"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def move_attrs_to_amend(c, a)
|
41
|
+
%w(change path path_end title).each do |e|
|
42
|
+
next unless c[e]
|
43
|
+
a[e] = c[e]
|
44
|
+
c.delete(e)
|
45
|
+
end
|
46
|
+
return unless a["locality"]
|
47
|
+
loc = a.children.add_previous_sibling("<location/>")
|
48
|
+
extract_localities1(loc, a["locality"])
|
49
|
+
loc1 = loc.at("./localityStack") and loc.replace(loc1.elements)
|
50
|
+
a.delete("locality")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -2,25 +2,25 @@ module Asciidoctor
|
|
2
2
|
module Standoc
|
3
3
|
module Cleanup
|
4
4
|
def external_terms_boilerplate(sources)
|
5
|
-
|
6
|
-
@external_terms_boilerplate.gsub(/%/, sources || "???"),
|
5
|
+
@i18n.l10n(
|
6
|
+
@i18n.external_terms_boilerplate.gsub(/%/, sources || "???"),
|
7
7
|
@lang, @script)
|
8
8
|
end
|
9
9
|
|
10
10
|
def internal_external_terms_boilerplate(sources)
|
11
|
-
|
12
|
-
@internal_external_terms_boilerplate.gsub(/%/, sources || "??"),
|
11
|
+
@i18n.l10n(
|
12
|
+
@i18n.internal_external_terms_boilerplate.gsub(/%/, sources || "??"),
|
13
13
|
@lang, @script)
|
14
14
|
end
|
15
15
|
|
16
16
|
def term_defs_boilerplate(div, source, term, preface, isodoc)
|
17
|
-
div.next =
|
17
|
+
a = @i18n.term_def_boilerplate and div.next = a
|
18
18
|
source.each do |s|
|
19
19
|
@anchors[s["bibitemid"]] or
|
20
20
|
@log.add("Crossreferences", nil, "term source #{s['bibitemid']} not referenced")
|
21
21
|
end
|
22
22
|
if source.empty? && term.nil?
|
23
|
-
div.next = @no_terms_boilerplate
|
23
|
+
div.next = @i18n.no_terms_boilerplate
|
24
24
|
else
|
25
25
|
div.next = term_defs_boilerplate_cont(source, term, isodoc)
|
26
26
|
end
|
@@ -30,7 +30,7 @@ module Asciidoctor
|
|
30
30
|
sources = isodoc.sentence_join(src.map do |s|
|
31
31
|
%{<eref bibitemid="#{s['bibitemid']}"/>}
|
32
32
|
end)
|
33
|
-
if src.empty? then @internal_terms_boilerplate
|
33
|
+
if src.empty? then @i18n.internal_terms_boilerplate
|
34
34
|
elsif term.nil? then external_terms_boilerplate(sources)
|
35
35
|
else
|
36
36
|
internal_external_terms_boilerplate(sources)
|
@@ -42,7 +42,7 @@ module Asciidoctor
|
|
42
42
|
["reference", "bibitem"].include? e.name
|
43
43
|
end
|
44
44
|
f.at("./title").next =
|
45
|
-
"<p>#{(refs.empty? ? @norm_empty_pref : @norm_with_refs_pref)}</p>"
|
45
|
+
"<p>#{(refs.empty? ? @i18n.norm_empty_pref : @i18n.norm_with_refs_pref)}</p>"
|
46
46
|
end
|
47
47
|
|
48
48
|
TERM_CLAUSE = "//sections/terms | "\
|
@@ -54,13 +54,9 @@ module Asciidoctor
|
|
54
54
|
x = xmldoc.dup
|
55
55
|
x.root.add_namespace(nil, self.class::XML_NAMESPACE)
|
56
56
|
xml = Nokogiri::XML(x.to_xml)
|
57
|
-
|
58
|
-
@
|
59
|
-
@
|
60
|
-
conv.i18n_init(@lang, @script)
|
61
|
-
conv.metadata_init(@lang, @script, conv.labels)
|
62
|
-
conv.info(xml, nil)
|
63
|
-
conv
|
57
|
+
@isodoc ||= isodoc(@lang, @script)
|
58
|
+
@isodoc.info(xml, nil)
|
59
|
+
@isodoc
|
64
60
|
end
|
65
61
|
|
66
62
|
def boilerplate_cleanup(xmldoc)
|
@@ -83,15 +79,6 @@ module Asciidoctor
|
|
83
79
|
preface.previous = b
|
84
80
|
end
|
85
81
|
|
86
|
-
class EmptyAttr
|
87
|
-
def attr(_x)
|
88
|
-
nil
|
89
|
-
end
|
90
|
-
def attributes
|
91
|
-
{}
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
82
|
def boilerplate_file(xmldoc)
|
96
83
|
File.join(@libdir, "boilerplate.xml")
|
97
84
|
end
|
@@ -50,6 +50,10 @@ module Asciidoctor
|
|
50
50
|
|
51
51
|
def extract_localities(x)
|
52
52
|
text = x&.children&.first&.remove&.text
|
53
|
+
extract_localities1(x, text)
|
54
|
+
end
|
55
|
+
|
56
|
+
def extract_localities1(x, text)
|
53
57
|
b = x.add_child("<localityStack/>").first if LOCALITY_RE.match text
|
54
58
|
while (m = LOCALITY_RE.match text)
|
55
59
|
ref = m[:ref] ? "<referenceFrom>#{tq m[:ref]}</referenceFrom>" : ""
|
@@ -117,7 +121,8 @@ module Asciidoctor
|
|
117
121
|
def concept_termbase_cleanup(x)
|
118
122
|
text = x&.children&.first&.remove&.text
|
119
123
|
termbase, key = x["key"].split(/:/, 2)
|
120
|
-
x.add_child(%(<termref base="#{termbase}" target="#{key}"
|
124
|
+
x.add_child(%(<termref base="#{termbase}" target="#{key}">) +
|
125
|
+
"#{text}</termref>")
|
121
126
|
end
|
122
127
|
|
123
128
|
def concept_xref_cleanup(x)
|
@@ -129,6 +134,62 @@ module Asciidoctor
|
|
129
134
|
x.children = "<eref>#{x.children.to_xml}</eref>"
|
130
135
|
extract_localities(x.first_element_child)
|
131
136
|
end
|
137
|
+
|
138
|
+
NAMECHAR = "\u0000-\u0022\u0024\u002c\u002f\u003a-\u0040\\u005b-\u005e"\
|
139
|
+
"\u0060\u007b-\u00b6\u00b8-\u00bf\u00d7\u00f7\u037e\u2000-\u200b"\
|
140
|
+
"\u200e-\u203e\u2041-\u206f\u2190-\u2bff\u2ff0-\u3000".freeze
|
141
|
+
#"\ud800-\uf8ff\ufdd0-\ufdef\ufffe-\uffff".freeze
|
142
|
+
NAMESTARTCHAR = "\\u002d\u002e\u0030-\u0039\u00b7\u0300-\u036f"\
|
143
|
+
"\u203f-\u2040".freeze
|
144
|
+
|
145
|
+
def to_ncname(s)
|
146
|
+
start = s[0]
|
147
|
+
ret1 = %r([#{NAMECHAR}#]).match(start) ? "_" :
|
148
|
+
(%r([#{NAMESTARTCHAR}#]).match(start) ? "_#{start}" : start)
|
149
|
+
ret2 = s[1..-1] || ""
|
150
|
+
ret = (ret1 || "") + ret2.gsub(%r([#{NAMECHAR}#]), "_")
|
151
|
+
ret
|
152
|
+
end
|
153
|
+
|
154
|
+
def to_xreftarget(s)
|
155
|
+
return to_ncname(s) unless /^[^#]+#.+$/.match(s)
|
156
|
+
/^(?<pref>[^#]+)#(?<suff>.+)$/ =~ s
|
157
|
+
pref = pref.gsub(%r([#{NAMECHAR}]), "_")
|
158
|
+
suff = suff.gsub(%r([#{NAMECHAR}]), "_")
|
159
|
+
"#{pref}##{suff}"
|
160
|
+
end
|
161
|
+
|
162
|
+
IDREF = "//*/@id | //review/@from | //review/@to | "\
|
163
|
+
"//callout/@target | //citation/@bibitemid | //eref/@bibitemid".freeze
|
164
|
+
|
165
|
+
def anchor_cleanup(x)
|
166
|
+
anchor_cleanup1(x)
|
167
|
+
xreftarget_cleanup(x)
|
168
|
+
end
|
169
|
+
|
170
|
+
def anchor_cleanup1(x)
|
171
|
+
x.xpath(IDREF).each do |s|
|
172
|
+
if (ret = to_ncname(s.value)) != (orig = s.value)
|
173
|
+
s.value = ret
|
174
|
+
output = s.parent.dup
|
175
|
+
output.children.remove
|
176
|
+
@log.add("Anchors", s.parent, "normalised identifier in #{output} "\
|
177
|
+
"from #{orig}")
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def xreftarget_cleanup(x)
|
183
|
+
x.xpath("//xref/@target").each do |s|
|
184
|
+
if (ret = to_xreftarget(s.value)) != (orig = s.value)
|
185
|
+
s.value = ret
|
186
|
+
output = s.parent.dup
|
187
|
+
output.children.remove
|
188
|
+
@log.add("Anchors", s.parent, "normalised identifier in #{output} "\
|
189
|
+
"from #{orig}")
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
132
193
|
end
|
133
194
|
end
|
134
195
|
end
|