metanorma-standoc 1.9.2 → 1.10.1
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.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +3 -13
- data/.hound.yml +3 -1
- data/.rubocop.yml +4 -6
- data/lib/asciidoctor/standoc/base.rb +3 -1
- data/lib/asciidoctor/standoc/biblio.rng +1 -0
- data/lib/asciidoctor/standoc/blocks.rb +1 -1
- data/lib/asciidoctor/standoc/cleanup.rb +34 -15
- data/lib/asciidoctor/standoc/cleanup_block.rb +0 -1
- data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +2 -2
- data/lib/asciidoctor/standoc/cleanup_footnotes.rb +0 -1
- data/lib/asciidoctor/standoc/cleanup_inline.rb +117 -77
- data/lib/asciidoctor/standoc/cleanup_maths.rb +0 -1
- data/lib/asciidoctor/standoc/cleanup_ref.rb +7 -0
- data/lib/asciidoctor/standoc/cleanup_section.rb +73 -137
- data/lib/asciidoctor/standoc/cleanup_section_names.rb +75 -0
- data/lib/asciidoctor/standoc/cleanup_terms.rb +19 -18
- data/lib/asciidoctor/standoc/converter.rb +1 -0
- data/lib/asciidoctor/standoc/front.rb +1 -2
- data/lib/asciidoctor/standoc/front_contributor.rb +66 -42
- data/lib/asciidoctor/standoc/inline.rb +45 -34
- data/lib/asciidoctor/standoc/isodoc.rng +66 -10
- data/lib/asciidoctor/standoc/macros.rb +7 -5
- data/lib/asciidoctor/standoc/macros_plantuml.rb +21 -23
- data/lib/asciidoctor/standoc/macros_terms.rb +60 -23
- data/lib/asciidoctor/standoc/section.rb +19 -12
- data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +87 -33
- data/lib/asciidoctor/standoc/terms.rb +1 -1
- data/lib/asciidoctor/standoc/utils.rb +0 -1
- data/lib/asciidoctor/standoc/validate.rb +22 -8
- data/lib/isodoc/html/html_titlepage.html +81 -0
- data/lib/isodoc/html/htmlstyle.css +983 -0
- data/lib/isodoc/html/htmlstyle.scss +714 -0
- data/lib/isodoc/html/scripts.html +71 -0
- data/lib/metanorma/standoc/processor.rb +16 -7
- data/lib/metanorma/standoc/version.rb +1 -1
- data/metanorma-standoc.gemspec +3 -3
- data/spec/asciidoctor/base_spec.rb +697 -557
- data/spec/asciidoctor/blocks_spec.rb +6 -8
- data/spec/asciidoctor/cleanup_sections_spec.rb +14 -14
- data/spec/asciidoctor/cleanup_spec.rb +899 -688
- data/spec/asciidoctor/inline_spec.rb +62 -14
- data/spec/asciidoctor/isobib_cache_spec.rb +4 -6
- data/spec/asciidoctor/lists_spec.rb +149 -137
- data/spec/asciidoctor/macros_json2text_spec.rb +1 -1
- data/spec/asciidoctor/macros_plantuml_spec.rb +8 -8
- data/spec/asciidoctor/macros_spec.rb +646 -169
- data/spec/asciidoctor/refs_dl_spec.rb +4 -4
- data/spec/asciidoctor/refs_spec.rb +1527 -1532
- data/spec/asciidoctor/section_spec.rb +58 -22
- data/spec/asciidoctor/table_spec.rb +6 -6
- data/spec/asciidoctor/validate_spec.rb +352 -304
- data/spec/spec_helper.rb +2 -0
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +49 -49
- data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
- data/spec/vcr_cassettes/isobib_get_123_1.yml +27 -27
- data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +35 -35
- data/spec/vcr_cassettes/isobib_get_123_2001.yml +14 -14
- data/spec/vcr_cassettes/isobib_get_124.yml +14 -14
- data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +44 -44
- metadata +12 -11
- data/lib/liquid/custom_blocks/key_iterator.rb +0 -21
- data/lib/liquid/custom_blocks/with_json_nested_context.rb +0 -18
- data/lib/liquid/custom_blocks/with_yaml_nested_context.rb +0 -19
- data/lib/liquid/custom_filters/values.rb +0 -7
@@ -75,7 +75,7 @@ module Asciidoctor
|
|
75
75
|
def supply_br(lines)
|
76
76
|
ignore = false
|
77
77
|
lines.each_with_index do |l, i|
|
78
|
-
/^(
|
78
|
+
/^(--+|====+|\|===|\.\.\.\.+|\*\*\*\*+|\+\+\+\++|````+|____\+)$/
|
79
79
|
.match(l) && (ignore = !ignore)
|
80
80
|
next if l.empty? || l.match(/ \+$/) || /^\[.*\]$/.match?(l) || ignore
|
81
81
|
next if i == lines.size - 1 ||
|
@@ -107,7 +107,7 @@ module Asciidoctor
|
|
107
107
|
if (attributes.size == 1) && attributes.key?("text")
|
108
108
|
rt = attributes["text"]
|
109
109
|
elsif (attributes.size == 2) && attributes.key?(1) &&
|
110
|
-
|
110
|
+
attributes.key?("rpbegin")
|
111
111
|
rt = attributes[1] || ""
|
112
112
|
else
|
113
113
|
rpbegin = attributes["rpbegin"]
|
@@ -143,7 +143,7 @@ module Asciidoctor
|
|
143
143
|
para.set_attr("caption", "TODO")
|
144
144
|
para.lines[0].sub!(/^TODO: /, "")
|
145
145
|
todo = Block.new(parent, :admonition, attributes: para.attributes,
|
146
|
-
|
146
|
+
source: para.lines, content_model: :compound)
|
147
147
|
parent.blocks[parent.blocks.index(para)] = todo
|
148
148
|
end
|
149
149
|
end
|
@@ -168,9 +168,11 @@ module Asciidoctor
|
|
168
168
|
def process(parent, target, attrs)
|
169
169
|
/^(?<lang>[^-]*)(-(?<script>.*))?$/ =~ target
|
170
170
|
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
171
|
-
script
|
172
|
-
%{<variant lang=#{lang} script=#{script}>#{out}</variant>}
|
171
|
+
if script
|
172
|
+
%{<variant lang=#{lang} script=#{script}>#{out}</variant>}
|
173
|
+
else
|
173
174
|
%{<variant lang=#{lang}>#{out}</variant>}
|
175
|
+
end
|
174
176
|
end
|
175
177
|
end
|
176
178
|
|
@@ -4,18 +4,17 @@ module Asciidoctor
|
|
4
4
|
# https://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
|
5
5
|
def self.plantuml_installed?
|
6
6
|
cmd = "plantuml"
|
7
|
-
exts = ENV[
|
8
|
-
ENV[
|
7
|
+
exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
|
8
|
+
ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
|
9
9
|
exts.each do |ext|
|
10
10
|
exe = File.join(path, "#{cmd}#{ext}")
|
11
11
|
return exe if File.executable?(exe) && !File.directory?(exe)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
raise "PlantUML not installed"
|
15
|
-
nil
|
16
15
|
end
|
17
16
|
|
18
|
-
def self.run
|
17
|
+
def self.run(umlfile, outfile)
|
19
18
|
system "plantuml #{umlfile.path}" or (warn $? and return false)
|
20
19
|
i = 0
|
21
20
|
until !Gem.win_platform? || File.exist?(outfile) || i == 15
|
@@ -29,9 +28,9 @@ module Asciidoctor
|
|
29
28
|
# sleep need for windows because dot works in separate process and
|
30
29
|
# plantuml process may finish earlier then dot, as result png file
|
31
30
|
# maybe not created yet after plantuml finish
|
32
|
-
def self.generate_file
|
31
|
+
def self.generate_file(parent, reader)
|
33
32
|
localdir = Metanorma::Utils::localdir(parent.document)
|
34
|
-
imagesdir = parent.document.attr(
|
33
|
+
imagesdir = parent.document.attr("imagesdir")
|
35
34
|
umlfile, outfile = save_plantuml parent, reader, localdir
|
36
35
|
run(umlfile, outfile) or raise "No image output from PlantUML (#{umlfile}, #{outfile})!"
|
37
36
|
umlfile.unlink
|
@@ -40,7 +39,7 @@ module Asciidoctor
|
|
40
39
|
File.writable?(localdir) or raise "Destination path #{path} not writable for PlantUML!"
|
41
40
|
path.mkpath
|
42
41
|
File.writable?(path) or raise "Destination path #{path} not writable for PlantUML!"
|
43
|
-
#File.exist?(path) or raise "Destination path #{path} already exists for PlantUML!"
|
42
|
+
# File.exist?(path) or raise "Destination path #{path} already exists for PlantUML!"
|
44
43
|
|
45
44
|
# Warning: metanorma/metanorma-standoc#187
|
46
45
|
# Windows Ruby 2.4 will crash if a Tempfile is "mv"ed.
|
@@ -51,21 +50,21 @@ module Asciidoctor
|
|
51
50
|
imagesdir ? filename : File.join(path, filename)
|
52
51
|
end
|
53
52
|
|
54
|
-
def self.save_plantuml
|
53
|
+
def self.save_plantuml(_parent, reader, _localdir)
|
55
54
|
src = reader.source
|
56
55
|
reader.lines.first.sub(/\s+$/, "").match /^@startuml($| )/ or
|
57
56
|
src = "@startuml\n#{src}\n@enduml\n"
|
58
57
|
/^@startuml (?<fn>[^\n]+)\n/ =~ src
|
59
|
-
Tempfile.open(["plantuml", ".pml"], :
|
58
|
+
Tempfile.open(["plantuml", ".pml"], encoding: "utf-8") do |f|
|
60
59
|
f.write(src)
|
61
60
|
[f, File.join(File.dirname(f.path),
|
62
|
-
|
61
|
+
"#{fn || File.basename(f.path, '.pml')}.png")]
|
63
62
|
end
|
64
63
|
end
|
65
64
|
|
66
|
-
def self.generate_attrs
|
67
|
-
|
68
|
-
inject({}) do |memo, key|
|
65
|
+
def self.generate_attrs(attrs)
|
66
|
+
%w(id align float title role width height alt)
|
67
|
+
.inject({}) do |memo, key|
|
69
68
|
memo[key] = attrs[key] if attrs.has_key? key
|
70
69
|
memo
|
71
70
|
end
|
@@ -81,19 +80,18 @@ module Asciidoctor
|
|
81
80
|
def abort(parent, reader, attrs, msg)
|
82
81
|
warn msg
|
83
82
|
attrs["language"] = "plantuml"
|
84
|
-
create_listing_block parent, reader.source,
|
83
|
+
create_listing_block parent, reader.source,
|
84
|
+
(attrs.reject { |k, _v| k == 1 })
|
85
85
|
end
|
86
86
|
|
87
87
|
def process(parent, reader, attrs)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
abort(parent, reader, attrs, e.message)
|
96
|
-
end
|
88
|
+
PlantUMLBlockMacroBackend.plantuml_installed?
|
89
|
+
filename = PlantUMLBlockMacroBackend.generate_file(parent, reader)
|
90
|
+
through_attrs = PlantUMLBlockMacroBackend.generate_attrs attrs
|
91
|
+
through_attrs["target"] = filename
|
92
|
+
create_image_block parent, through_attrs
|
93
|
+
rescue StandardError => e
|
94
|
+
abort(parent, reader, attrs, e.message)
|
97
95
|
end
|
98
96
|
end
|
99
97
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "csv"
|
2
|
+
|
1
3
|
module Asciidoctor
|
2
4
|
module Standoc
|
3
5
|
class AltTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
@@ -36,46 +38,81 @@ module Asciidoctor
|
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
|
-
# Macro to transform `term[X,Y]` into em, termxref xml
|
40
41
|
class TermRefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
41
42
|
use_dsl
|
42
43
|
named :term
|
43
|
-
name_positional_attributes
|
44
|
+
name_positional_attributes "name", "termxref"
|
45
|
+
using_format :short
|
46
|
+
|
47
|
+
def process(_parent, _target, attrs)
|
48
|
+
termref = attrs["termxref"] || attrs["name"]
|
49
|
+
"<concept type='term'><termxref>#{attrs['name']}</termxref>"\
|
50
|
+
"<renderterm>#{termref}</renderterm><xrefrender/></concept>"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class SymbolRefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
55
|
+
use_dsl
|
56
|
+
named :symbol
|
57
|
+
name_positional_attributes "name", "termxref"
|
44
58
|
using_format :short
|
45
59
|
|
46
60
|
def process(_parent, _target, attrs)
|
47
|
-
termref = attrs[
|
48
|
-
"<
|
61
|
+
termref = attrs["termxref"] || attrs["name"]
|
62
|
+
"<concept type='symbol'><termxref>#{attrs['name']}</termxref>"\
|
63
|
+
"<renderterm>#{termref}</renderterm><xrefrender/></concept>"
|
49
64
|
end
|
50
65
|
end
|
51
66
|
|
67
|
+
# Possibilities:
|
68
|
+
# {{<<id>>, term}}
|
69
|
+
# {{<<id>>, term, text}}
|
70
|
+
# {{<<termbase:id>>, term}}
|
71
|
+
# {{<<termbase:id>>, term, text}}
|
72
|
+
# {{term}} equivalent to term:[term]
|
73
|
+
# {{term, text}} equivalent to term:[term, text]
|
74
|
+
# text may optionally be followed by crossreference-rendering, options=""
|
52
75
|
class ConceptInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
53
76
|
use_dsl
|
54
77
|
named :concept
|
55
|
-
name_positional_attributes "id", "word", "term"
|
56
|
-
# match %r{concept:(?<target>[^\[]*)\[(?<content>|.*?[^\\])\]$}
|
57
78
|
match /\{\{(?<content>|.*?[^\\])\}\}/
|
58
79
|
using_format :short
|
59
80
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
81
|
+
def preprocess_attrs(target)
|
82
|
+
m = /^(?<id><<.+?>>)?(?<rest>.*)$/.match(target)
|
83
|
+
ret = { id: m[:id]&.sub(/^<</, "")&.sub(/>>$/, "") }
|
84
|
+
if m2 = /^(?<rest>.*?)(?<opt>,option=.+)$/.match(m[:rest].sub(/^,/, ""))
|
85
|
+
ret[:opt] = CSV.parse_line(m2[:opt].sub(/^,option=/, "")
|
86
|
+
.sub(/^"(.+)"$/, "\\1").sub(/^'(.+)'$/, "\\1"))
|
87
|
+
attrs = CSV.parse_line(m2[:rest]) || []
|
88
|
+
else
|
89
|
+
attrs = CSV.parse_line(m[:rest].sub(/^,/, "")) || []
|
90
|
+
end
|
91
|
+
ret.merge(term: attrs[0], word: attrs[1] || attrs[0],
|
92
|
+
xrefrender: attrs[2])
|
93
|
+
end
|
94
|
+
|
95
|
+
def generate_attrs(opts)
|
96
|
+
ret = ""
|
97
|
+
opts.include?("noital") and ret += " ital='false'"
|
98
|
+
opts.include?("noref") and ret += " ref='false'"
|
99
|
+
opts.include?("ital") and ret += " ital='true'"
|
100
|
+
opts.include?("ref") and ret += " ref='true'"
|
101
|
+
ret
|
68
102
|
end
|
69
103
|
|
70
|
-
def process(parent,
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
104
|
+
def process(parent, target, _attrs)
|
105
|
+
attrs = preprocess_attrs(target)
|
106
|
+
termout = Asciidoctor::Inline.new(parent, :quoted, attrs[:term]).convert
|
107
|
+
wordout = Asciidoctor::Inline.new(parent, :quoted, attrs[:word]).convert
|
108
|
+
xrefout = Asciidoctor::Inline.new(parent, :quoted,
|
109
|
+
attrs[:xrefrender]).convert
|
110
|
+
optout = generate_attrs(attrs[:opt] || [])
|
111
|
+
attrs[:id] and return "<concept#{optout} key='#{attrs[:id]}'><refterm>"\
|
112
|
+
"#{termout}</refterm><renderterm>#{wordout}</renderterm>"\
|
113
|
+
"<xrefrender>#{xrefout}</xrefrender></concept>"
|
114
|
+
"<concept#{optout}><termxref>#{termout}</termxref><renderterm>"\
|
115
|
+
"#{wordout}</renderterm><xrefrender>#{xrefout}</xrefrender></concept>"
|
79
116
|
end
|
80
117
|
end
|
81
118
|
end
|
@@ -12,7 +12,7 @@ module Asciidoctor
|
|
12
12
|
def sectiontype1(node)
|
13
13
|
node&.attr("heading")&.downcase ||
|
14
14
|
node.title.gsub(%r{<index>.*?</index>}m, "").gsub(/<[^>]+>/, "")
|
15
|
-
|
15
|
+
.strip.downcase
|
16
16
|
end
|
17
17
|
|
18
18
|
def sectiontype(node, level = true)
|
@@ -21,6 +21,7 @@ module Asciidoctor
|
|
21
21
|
return ret1 if "symbols and abbreviated terms" == ret1
|
22
22
|
return nil unless !level || node.level == 1
|
23
23
|
return nil if @seen_headers.include? ret
|
24
|
+
|
24
25
|
@seen_headers << ret
|
25
26
|
ret1
|
26
27
|
end
|
@@ -48,11 +49,14 @@ module Asciidoctor
|
|
48
49
|
script: node.attributes["script"],
|
49
50
|
number: node.attributes["number"],
|
50
51
|
type: node.attributes["type"],
|
51
|
-
annex: ( (
|
52
|
-
node.level == 1
|
53
|
-
|
54
|
-
|
52
|
+
annex: (if (node.attr("style") == "appendix" || node.role == "appendix") &&
|
53
|
+
node.level == 1
|
54
|
+
true
|
55
|
+
end),
|
56
|
+
preface: (
|
57
|
+
node.role == "preface" || node.attr("style") == "preface" ? true : nil) }
|
55
58
|
return ret unless node.attributes["change"]
|
59
|
+
|
56
60
|
ret.merge(change: node.attributes["change"],
|
57
61
|
path: node.attributes["path"],
|
58
62
|
path_end: node.attributes["path_end"],
|
@@ -75,7 +79,7 @@ module Asciidoctor
|
|
75
79
|
symbols_parse(symbols_attrs(node, a), xml, node)
|
76
80
|
when "acknowledgements"
|
77
81
|
acknowledgements_parse(a, xml, node)
|
78
|
-
when "bibliography"
|
82
|
+
when "bibliography"
|
79
83
|
bibliography_parse(a, xml, node)
|
80
84
|
else
|
81
85
|
if @term_def then term_def_subclause_parse(a, xml, node)
|
@@ -88,9 +92,9 @@ module Asciidoctor
|
|
88
92
|
bibliography_parse(a, xml, node)
|
89
93
|
elsif node.attr("style") == "bibliography"
|
90
94
|
bibliography_parse(a, xml, node)
|
91
|
-
elsif node.attr("style") == "abstract"
|
95
|
+
elsif node.attr("style") == "abstract"
|
92
96
|
abstract_parse(a, xml, node)
|
93
|
-
elsif node.attr("style") == "index"
|
97
|
+
elsif node.attr("style") == "index"
|
94
98
|
indexsect_parse(a, xml, node)
|
95
99
|
elsif node.attr("style") == "appendix" && node.level == 1
|
96
100
|
annex_parse(a, xml, node)
|
@@ -102,10 +106,13 @@ module Asciidoctor
|
|
102
106
|
end
|
103
107
|
|
104
108
|
def set_obligation(attrs, node)
|
105
|
-
attrs[:obligation] = node.attributes.has_key?("obligation")
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
+
attrs[:obligation] = if node.attributes.has_key?("obligation")
|
110
|
+
node.attr("obligation")
|
111
|
+
elsif node.parent.attributes.has_key?("obligation")
|
112
|
+
node.parent.attr("obligation")
|
113
|
+
else
|
114
|
+
"normative"
|
115
|
+
end
|
109
116
|
end
|
110
117
|
|
111
118
|
def preamble(node)
|
@@ -3,81 +3,135 @@
|
|
3
3
|
module Asciidoctor
|
4
4
|
module Standoc
|
5
5
|
# Intelligent term lookup xml modifier
|
6
|
-
# Lookup all `term` and `calause` tags and replace `termxref` tags with
|
7
|
-
# `xref`:target tag
|
8
6
|
class TermLookupCleanup
|
9
|
-
AUTOMATIC_GENERATED_ID_REGEXP = /\A_
|
10
|
-
EXISTING_TERM_REGEXP = /\Aterm
|
7
|
+
AUTOMATIC_GENERATED_ID_REGEXP = /\A_/.freeze
|
8
|
+
EXISTING_TERM_REGEXP = /\Aterm-/.freeze
|
9
|
+
EXISTING_SYMBOL_REGEXP = /\Asymbol-/.freeze
|
11
10
|
|
12
11
|
attr_reader :xmldoc, :termlookup, :log
|
13
12
|
|
14
13
|
def initialize(xmldoc, log)
|
15
14
|
@xmldoc = xmldoc
|
16
15
|
@log = log
|
17
|
-
@termlookup = {}
|
16
|
+
@termlookup = { term: {}, symbol: {} }
|
17
|
+
@idhash = {}
|
18
18
|
end
|
19
19
|
|
20
20
|
def call
|
21
|
+
@idhash = populate_idhash
|
21
22
|
@termlookup = replace_automatic_generated_ids_terms
|
22
23
|
set_termxref_tags_target
|
24
|
+
concept_cleanup
|
23
25
|
end
|
24
26
|
|
25
27
|
private
|
26
28
|
|
29
|
+
def concept_cleanup
|
30
|
+
xmldoc.xpath("//concept").each do |n|
|
31
|
+
n.delete("type")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def populate_idhash
|
36
|
+
xmldoc.xpath("//*[@id]").each_with_object({}) do |n, mem|
|
37
|
+
next unless /^(term|symbol)-/.match?(n["id"])
|
38
|
+
|
39
|
+
mem[n["id"]] = true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
27
43
|
def set_termxref_tags_target
|
28
|
-
xmldoc.xpath(
|
44
|
+
xmldoc.xpath("//termxref").each do |node|
|
29
45
|
target = normalize_ref_id(node.text)
|
30
|
-
if termlookup[target].nil?
|
46
|
+
if termlookup[:term][target].nil? && termlookup[:symbol][target].nil?
|
31
47
|
remove_missing_ref(node, target)
|
32
48
|
next
|
33
49
|
end
|
34
|
-
|
50
|
+
x = node.at("../xrefrender")
|
51
|
+
modify_ref_node(x, target)
|
52
|
+
node.name = "refterm"
|
35
53
|
end
|
36
54
|
end
|
37
55
|
|
38
56
|
def remove_missing_ref(node, target)
|
39
|
-
|
57
|
+
if node.at("../concept[@type = 'symbol']")
|
58
|
+
remove_missing_ref_symbol(node, target)
|
59
|
+
else
|
60
|
+
remove_missing_ref_term(node, target)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def remove_missing_ref_term(node, target)
|
65
|
+
log.add("AsciiDoc Input", node,
|
40
66
|
%(Error: Term reference in `term[#{target}]` missing: \
|
41
67
|
"#{target}" is not defined in document))
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
node.
|
48
|
-
|
68
|
+
node.name = "strong"
|
69
|
+
node.at("../xrefrender").remove
|
70
|
+
display = node&.at("../renderterm")&.remove&.children
|
71
|
+
display = [] if display.nil? || display&.to_xml == node.text
|
72
|
+
d = display.empty? ? "" : ", display <tt>#{display.to_xml}</tt>"
|
73
|
+
node.children = "term <tt>#{node.text}</tt>#{d} "\
|
74
|
+
"not resolved via ID <tt>#{target}</tt>"
|
75
|
+
end
|
76
|
+
|
77
|
+
def remove_missing_ref_symbol(node, target)
|
78
|
+
log.add("AsciiDoc Input", node,
|
79
|
+
%(Error: Symbol reference in `symbol[#{target}]` missing: \
|
80
|
+
"#{target}" is not defined in document))
|
81
|
+
node.name = "strong"
|
82
|
+
node.at("../xrefrender").remove
|
83
|
+
display = node&.at("../renderterm")&.remove&.children
|
84
|
+
display = [] if display.nil? || display&.to_xml == node.text
|
85
|
+
d = display.empty? ? "" : ", display <tt>#{display.to_xml}</tt>"
|
86
|
+
node.children = "symbol <tt>#{node.text}</tt>#{d} "\
|
87
|
+
"not resolved via ID <tt>#{target}</tt>"
|
49
88
|
end
|
50
89
|
|
51
90
|
def modify_ref_node(node, target)
|
52
|
-
node.name =
|
53
|
-
|
54
|
-
|
55
|
-
node.
|
91
|
+
node.name = "xref"
|
92
|
+
s = termlookup[:symbol][target]
|
93
|
+
t = termlookup[:term][target]
|
94
|
+
type = node.parent["type"]
|
95
|
+
if type == "term" || !type && t
|
96
|
+
node["target"] = t
|
97
|
+
elsif type == "symbol" || !type && s
|
98
|
+
node["target"] = s
|
99
|
+
end
|
56
100
|
end
|
57
101
|
|
58
102
|
def replace_automatic_generated_ids_terms
|
59
|
-
xmldoc.xpath(
|
60
|
-
normalize_id_and_memorize(
|
103
|
+
r = xmldoc.xpath("//term").each.with_object({}) do |n, res|
|
104
|
+
normalize_id_and_memorize(n, res, "./preferred", "term")
|
61
105
|
end
|
106
|
+
s = xmldoc.xpath("//definitions//dt").each.with_object({}) do |n, res|
|
107
|
+
normalize_id_and_memorize(n, res, ".", "symbol")
|
108
|
+
end
|
109
|
+
{ term: r, symbol: s }
|
62
110
|
end
|
63
111
|
|
64
|
-
def normalize_id_and_memorize(
|
65
|
-
term_text = normalize_ref_id(
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
112
|
+
def normalize_id_and_memorize(node, res_table, text_selector, prefix)
|
113
|
+
term_text = normalize_ref_id(node.at(text_selector).text)
|
114
|
+
unless AUTOMATIC_GENERATED_ID_REGEXP.match(node["id"]).nil? &&
|
115
|
+
!node["id"].nil?
|
116
|
+
id = unique_text_id(term_text, prefix)
|
117
|
+
node["id"] = id
|
118
|
+
@idhash[id] = true
|
119
|
+
end
|
120
|
+
res_table[term_text] = node["id"]
|
70
121
|
end
|
71
122
|
|
72
123
|
def normalize_ref_id(text)
|
73
|
-
text.downcase.gsub(/[[:space:]]/,
|
124
|
+
text.downcase.gsub(/[[:space:]]/, "-")
|
74
125
|
end
|
75
126
|
|
76
|
-
def unique_text_id(text)
|
77
|
-
|
127
|
+
def unique_text_id(text, prefix)
|
128
|
+
unless @idhash["#{prefix}-#{text}"]
|
129
|
+
return "#{prefix}-#{text}"
|
130
|
+
end
|
131
|
+
|
78
132
|
(1..Float::INFINITY).lazy.each do |index|
|
79
|
-
|
80
|
-
break("
|
133
|
+
unless @idhash["#{prefix}-#{text}-#{index}"]
|
134
|
+
break("#{prefix}-#{text}-#{index}")
|
81
135
|
end
|
82
136
|
end
|
83
137
|
end
|