metanorma-standoc 1.9.2 → 1.10.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|