metanorma 1.7.7 → 2.0.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/Gemfile +5 -1
- data/lib/metanorma/array_monkeypatch.rb +9 -0
- data/lib/metanorma/asciidoctor_extensions/glob_include_processor.rb +13 -11
- data/lib/metanorma/collection/collection.rb +226 -0
- data/lib/metanorma/collection/config/bibdata.rb +12 -0
- data/lib/metanorma/collection/config/compile_options.rb +13 -0
- data/lib/metanorma/collection/config/config.rb +163 -0
- data/lib/metanorma/collection/config/converters.rb +30 -0
- data/lib/metanorma/collection/config/directive.rb +10 -0
- data/lib/metanorma/collection/config/manifest.rb +88 -0
- data/lib/metanorma/collection/document/document.rb +133 -0
- data/lib/metanorma/collection/filelookup/filelookup.rb +250 -0
- data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +87 -0
- data/lib/metanorma/collection/manifest/manifest.rb +237 -0
- data/lib/metanorma/collection/renderer/fileparse.rb +254 -0
- data/lib/metanorma/collection/renderer/fileprocess.rb +174 -0
- data/lib/metanorma/collection/renderer/navigation.rb +133 -0
- data/lib/metanorma/collection/renderer/render_word.rb +133 -0
- data/lib/metanorma/collection/renderer/renderer.rb +157 -0
- data/lib/metanorma/collection/renderer/utils.rb +211 -0
- data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +219 -0
- data/lib/metanorma/collection/util/disambig_files.rb +37 -0
- data/lib/metanorma/collection/util/util.rb +72 -0
- data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +222 -0
- data/lib/metanorma/{compile.rb → compile/compile.rb} +19 -12
- data/lib/metanorma/{compile_options.rb → compile/compile_options.rb} +9 -5
- data/lib/metanorma/{compile_validate.rb → compile/compile_validate.rb} +1 -1
- data/lib/metanorma/{extract.rb → compile/extract.rb} +2 -2
- data/lib/metanorma/{config.rb → config/config.rb} +1 -1
- data/lib/metanorma/input/asciidoc.rb +3 -3
- data/lib/metanorma/input/base.rb +1 -5
- data/lib/metanorma/processor/processor.rb +54 -0
- data/lib/metanorma/processor.rb +1 -49
- data/lib/metanorma/{registry.rb → registry/registry.rb} +0 -1
- data/lib/metanorma/shale_monkeypatch.rb +15 -0
- data/lib/metanorma/util/fontist_helper.rb +130 -0
- data/lib/metanorma/util/util.rb +45 -0
- data/lib/metanorma/util/worker_pool.rb +39 -0
- data/lib/metanorma/version.rb +1 -1
- data/lib/metanorma.rb +13 -8
- data/metanorma.gemspec +2 -1
- metadata +50 -24
- data/lib/metanorma/collection.rb +0 -244
- data/lib/metanorma/collection_fileparse.rb +0 -257
- data/lib/metanorma/collection_fileprocess.rb +0 -168
- data/lib/metanorma/collection_manifest.rb +0 -168
- data/lib/metanorma/collection_render_utils.rb +0 -169
- data/lib/metanorma/collection_render_word.rb +0 -131
- data/lib/metanorma/collection_renderer.rb +0 -237
- data/lib/metanorma/collection_xref_process.rb +0 -217
- data/lib/metanorma/document.rb +0 -133
- data/lib/metanorma/files_lookup.rb +0 -224
- data/lib/metanorma/files_lookup_sectionsplit.rb +0 -84
- data/lib/metanorma/fontist_utils.rb +0 -122
- data/lib/metanorma/sectionsplit.rb +0 -216
- data/lib/metanorma/util.rb +0 -127
- data/lib/metanorma/worker_pool.rb +0 -29
@@ -1,122 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
class FontistUtils
|
3
|
-
class << self
|
4
|
-
private
|
5
|
-
|
6
|
-
def validate_options(options)
|
7
|
-
agree_to_terms = options[:agree_to_terms] || false
|
8
|
-
continue_without_fonts = options[:continue_without_fonts] || false
|
9
|
-
no_progress = options[:no_progress] || false
|
10
|
-
|
11
|
-
[agree_to_terms, continue_without_fonts, no_progress]
|
12
|
-
end
|
13
|
-
|
14
|
-
def validate_install_fonts(processor, options)
|
15
|
-
if options[:no_install_fonts]
|
16
|
-
Util.log("[fontist] Skip font installation because" \
|
17
|
-
" --no-install-fonts argument passed", :debug)
|
18
|
-
return false
|
19
|
-
elsif !has_custom_fonts?(processor, options, options)
|
20
|
-
Util.log("[fontist] Skip font installation because "\
|
21
|
-
"fonts_manifest is missing", :debug)
|
22
|
-
return false
|
23
|
-
end
|
24
|
-
true
|
25
|
-
end
|
26
|
-
|
27
|
-
def install_fonts_safe(manifest, agree, continue, no_progress)
|
28
|
-
fontist_install(manifest, agree, no_progress)
|
29
|
-
rescue Fontist::Errors::LicensingError
|
30
|
-
license_error_log(continue)
|
31
|
-
rescue Fontist::Errors::FontError => e
|
32
|
-
log_level = continue ? :warning : :fatal
|
33
|
-
Util.log("[fontist] '#{e.font}' font is not supported. " \
|
34
|
-
"Please report this issue at github.com/metanorma/metanorma" \
|
35
|
-
"/issues to report this issue.", log_level)
|
36
|
-
rescue Fontist::Errors::FormulaIndexNotFoundError
|
37
|
-
fintist_update_repo(manifest, agree, continue, no_progress)
|
38
|
-
end
|
39
|
-
|
40
|
-
def fontist_install(manifest, agree, no_progress)
|
41
|
-
if agree
|
42
|
-
no_license_log
|
43
|
-
else
|
44
|
-
Fontist.log_level = :info
|
45
|
-
end
|
46
|
-
|
47
|
-
Fontist::Manifest::Install.from_hash(
|
48
|
-
manifest,
|
49
|
-
confirmation: agree ? "yes" : "no",
|
50
|
-
no_progress: no_progress,
|
51
|
-
)
|
52
|
-
end
|
53
|
-
|
54
|
-
def license_error_log(continue)
|
55
|
-
if continue
|
56
|
-
Util.log(
|
57
|
-
"[fontist] Processing will continue without fonts installed",
|
58
|
-
:debug,
|
59
|
-
)
|
60
|
-
else
|
61
|
-
Util.log("[fontist] Aborting without proper fonts installed," \
|
62
|
-
" make sure that you have set option --agree-to-terms",
|
63
|
-
:fatal)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def no_license_log
|
68
|
-
Util.log(
|
69
|
-
"[fontist] Font licenses are not shown with --agree-to-terms option.",
|
70
|
-
:info,
|
71
|
-
)
|
72
|
-
end
|
73
|
-
|
74
|
-
def fintist_update_repo(manifest, agree, continue, no_progress)
|
75
|
-
if @@updated_formulas_repo
|
76
|
-
Util.log(
|
77
|
-
"[fontist] Bug: formula index not found after 'fontist update'",
|
78
|
-
:fatal,
|
79
|
-
)
|
80
|
-
end
|
81
|
-
Util.log("[fontist] Missing formula index. Fetching it...", :debug)
|
82
|
-
Fontist::Formula.update_formulas_repo
|
83
|
-
@@updated_formulas_repo = true
|
84
|
-
install_fonts_safe(manifest, agree, continue, no_progress)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def self.install_fonts(processor, options)
|
89
|
-
return unless validate_install_fonts(processor, options)
|
90
|
-
|
91
|
-
@@updated_formulas_repo = false
|
92
|
-
manifest = processor.fonts_manifest.dup
|
93
|
-
append_source_fonts(manifest, options)
|
94
|
-
agree_to_terms, can_without_fonts, no_progress = validate_options(options)
|
95
|
-
|
96
|
-
install_fonts_safe(
|
97
|
-
manifest,
|
98
|
-
agree_to_terms,
|
99
|
-
can_without_fonts,
|
100
|
-
no_progress,
|
101
|
-
)
|
102
|
-
end
|
103
|
-
|
104
|
-
def self.has_custom_fonts?(processor, options, source_attributes)
|
105
|
-
!options[:no_install_fonts] \
|
106
|
-
&& processor.respond_to?(:fonts_manifest) \
|
107
|
-
&& !processor.fonts_manifest.nil? \
|
108
|
-
|| source_attributes[:fonts]
|
109
|
-
end
|
110
|
-
|
111
|
-
def self.location_manifest(processor, source_attributes)
|
112
|
-
Fontist::Manifest::Locations.from_hash(
|
113
|
-
append_source_fonts(processor.fonts_manifest.dup, source_attributes),
|
114
|
-
)
|
115
|
-
end
|
116
|
-
|
117
|
-
def self.append_source_fonts(manifest, source_attributes)
|
118
|
-
source_attributes[:fonts]&.split(";")&.each { |f| manifest[f] = nil }
|
119
|
-
manifest
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
@@ -1,216 +0,0 @@
|
|
1
|
-
require "yaml"
|
2
|
-
require_relative "util"
|
3
|
-
require_relative "collection_xref_process"
|
4
|
-
|
5
|
-
module Metanorma
|
6
|
-
class Sectionsplit
|
7
|
-
attr_accessor :filecache, :key
|
8
|
-
|
9
|
-
def initialize(opts)
|
10
|
-
@input_filename = opts[:input]
|
11
|
-
@base = opts[:base]
|
12
|
-
@output_filename = opts[:output]
|
13
|
-
@xml = opts[:xml]
|
14
|
-
@dir = opts[:dir]
|
15
|
-
@compile_opts = opts[:compile_opts] || {}
|
16
|
-
@fileslookup = opts[:fileslookup]
|
17
|
-
@ident = opts[:ident]
|
18
|
-
@isodoc = opts[:isodoc]
|
19
|
-
end
|
20
|
-
|
21
|
-
def ns(xpath)
|
22
|
-
@isodoc.ns(xpath)
|
23
|
-
end
|
24
|
-
|
25
|
-
def build_collection
|
26
|
-
collection_setup(@base, @dir)
|
27
|
-
files = sectionsplit # (@input_filename, @base, @dir, @compile_opts)
|
28
|
-
input_xml = Nokogiri::XML(File.read(@input_filename,
|
29
|
-
encoding: "UTF-8"), &:huge)
|
30
|
-
collection_manifest(@base, files, input_xml, @xml, @dir).render(
|
31
|
-
{ format: %i(html), output_folder: "#{@output_filename}_collection",
|
32
|
-
coverpage: File.join(@dir, "cover.html") }.merge(@compile_opts),
|
33
|
-
)
|
34
|
-
end
|
35
|
-
|
36
|
-
def collection_manifest(filename, files, origxml, _presxml, dir)
|
37
|
-
File.open(File.join(dir, "#{filename}.html.yaml"), "w:UTF-8") do |f|
|
38
|
-
f.write(collectionyaml(files, origxml))
|
39
|
-
end
|
40
|
-
Metanorma::Collection.parse File.join(dir, "#{filename}.html.yaml")
|
41
|
-
end
|
42
|
-
|
43
|
-
def collection_setup(filename, dir)
|
44
|
-
FileUtils.mkdir_p "#{filename}_collection" if filename
|
45
|
-
FileUtils.mkdir_p dir
|
46
|
-
File.open(File.join(dir, "cover.html"), "w:UTF-8") do |f|
|
47
|
-
f.write(coll_cover)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def coll_cover
|
52
|
-
<<~COVER
|
53
|
-
<html><head><meta charset="UTF-8"/></head><body>
|
54
|
-
<h1>{{ doctitle }}</h1>
|
55
|
-
<h2>{{ docnumber }}</h2>
|
56
|
-
<nav>{{ navigation }}</nav>
|
57
|
-
</body></html>
|
58
|
-
COVER
|
59
|
-
end
|
60
|
-
|
61
|
-
SPLITSECTIONS =
|
62
|
-
[["//preface/*", "preface"], ["//sections/*", "sections"],
|
63
|
-
["//annex", nil],
|
64
|
-
["//bibliography/*[not(@hidden = 'true')]", "bibliography"],
|
65
|
-
["//indexsect", nil], ["//colophon", nil]].freeze
|
66
|
-
|
67
|
-
# Input XML is Semantic
|
68
|
-
# def sectionsplit(filename, basename, dir, compile_options, fileslookup = nil, ident = nil)
|
69
|
-
def sectionsplit
|
70
|
-
xml = sectionsplit_prep(File.read(@input_filename), @base, @dir)
|
71
|
-
@key = Metanorma::XrefProcess::xref_preprocess(xml, @isodoc)
|
72
|
-
SPLITSECTIONS.each_with_object([]) do |n, ret|
|
73
|
-
conflate_floatingtitles(xml.xpath(ns(n[0]))).each do |s|
|
74
|
-
ret << sectionfile(xml, emptydoc(xml), "#{@base}.#{ret.size}", s,
|
75
|
-
n[1])
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def block?(node)
|
81
|
-
%w(p table formula admonition ol ul dl figure quote sourcecode example
|
82
|
-
pre note pagebrreak hr bookmark requirement recommendation permission
|
83
|
-
svgmap inputform toc passthrough review imagemap).include?(node.name)
|
84
|
-
end
|
85
|
-
|
86
|
-
def conflate_floatingtitles(nodes)
|
87
|
-
holdover = false
|
88
|
-
nodes.each_with_object([]) do |x, m|
|
89
|
-
if holdover then m.last << x
|
90
|
-
else m << [x]
|
91
|
-
end
|
92
|
-
holdover = block?(x)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def sectionsplit_prep(file, filename, dir)
|
97
|
-
@splitdir = dir
|
98
|
-
xml1filename, type = sectionsplit_preprocess_semxml(file, filename)
|
99
|
-
Compile.new.compile(
|
100
|
-
xml1filename,
|
101
|
-
{ format: :asciidoc, extension_keys: [:presentation], type: type }
|
102
|
-
.merge(@compile_opts),
|
103
|
-
)
|
104
|
-
Nokogiri::XML(File.read(xml1filename.sub(/\.xml$/, ".presentation.xml"),
|
105
|
-
encoding: "utf-8"), &:huge)
|
106
|
-
end
|
107
|
-
|
108
|
-
def sectionsplit_preprocess_semxml(file, filename)
|
109
|
-
xml = Nokogiri::XML(file, &:huge)
|
110
|
-
type = xml.root.name.sub("-standard", "").to_sym
|
111
|
-
sectionsplit_update_xrefs(xml)
|
112
|
-
xml1 = sectionsplit_write_semxml(filename, xml)
|
113
|
-
@filecache ||= []
|
114
|
-
@filecache << xml1
|
115
|
-
[xml1.path, type]
|
116
|
-
end
|
117
|
-
|
118
|
-
def sectionsplit_update_xrefs(xml)
|
119
|
-
if c = @fileslookup&.parent
|
120
|
-
n = c.nested
|
121
|
-
c.nested = true # so unresolved erefs are not deleted
|
122
|
-
c.update_xrefs(xml, @ident, {})
|
123
|
-
c.nested = n
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def sectionsplit_write_semxml(filename, xml)
|
128
|
-
Tempfile.open([filename, ".xml"], encoding: "utf-8") do |f|
|
129
|
-
# f.write(@isodoc.to_xml(svg_preprocess(xml)))
|
130
|
-
f.write(@isodoc.to_xml(xml))
|
131
|
-
f
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def emptydoc(xml)
|
136
|
-
out = xml.dup
|
137
|
-
out.xpath(
|
138
|
-
ns("//preface | //sections | //annex | //bibliography/clause | " \
|
139
|
-
"//bibliography/references[not(@hidden = 'true')] | //indexsect | " \
|
140
|
-
"//colophon"),
|
141
|
-
).each(&:remove)
|
142
|
-
out
|
143
|
-
end
|
144
|
-
|
145
|
-
def sectionfile(fulldoc, xml, file, chunks, parentnode)
|
146
|
-
fname = create_sectionfile(fulldoc, xml.dup, file, chunks, parentnode)
|
147
|
-
{ order: chunks.last["displayorder"].to_i, url: fname,
|
148
|
-
title: titlerender(chunks.last) }
|
149
|
-
end
|
150
|
-
|
151
|
-
def create_sectionfile(xml, out, file, chunks, parentnode)
|
152
|
-
ins = out.at(ns("//metanorma-extension")) || out.at(ns("//bibdata"))
|
153
|
-
sectionfile_insert(ins, chunks, parentnode)
|
154
|
-
Metanorma::XrefProcess::xref_process(out, xml, @key, @ident, @isodoc)
|
155
|
-
outname = "#{file}.xml"
|
156
|
-
File.open(File.join(@splitdir, outname), "w:UTF-8") do |f|
|
157
|
-
f.write(out)
|
158
|
-
end
|
159
|
-
outname
|
160
|
-
end
|
161
|
-
|
162
|
-
def sectionfile_insert(ins, chunks, parentnode)
|
163
|
-
if parentnode
|
164
|
-
ins.next = "<#{parentnode}/>"
|
165
|
-
chunks.each { |c| ins.next.add_child(c.dup) }
|
166
|
-
else chunks.each { |c| ins.next = c.dup }
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def titlerender(section)
|
171
|
-
title = section.at(ns("./title")) or return "[Untitled]"
|
172
|
-
t = title.dup
|
173
|
-
t.xpath(ns(".//tab | .//br")).each { |x| x.replace(" ") }
|
174
|
-
t.xpath(ns(".//strong")).each { |x| x.replace(x.children) }
|
175
|
-
t.children.to_xml
|
176
|
-
end
|
177
|
-
|
178
|
-
def collectionyaml(files, xml)
|
179
|
-
ret = {
|
180
|
-
directives: ["presentation-xml", "bare-after-first"],
|
181
|
-
bibdata: {
|
182
|
-
title: {
|
183
|
-
type: "title-main", language: @lang,
|
184
|
-
content: xml.at(ns("//bibdata/title")).text
|
185
|
-
},
|
186
|
-
type: "collection",
|
187
|
-
docid: {
|
188
|
-
type: xml.at(ns("//bibdata/docidentifier/@type")).text,
|
189
|
-
id: xml.at(ns("//bibdata/docidentifier")).text,
|
190
|
-
},
|
191
|
-
},
|
192
|
-
manifest: {
|
193
|
-
level: "collection", title: "Collection",
|
194
|
-
docref: files.sort_by { |f| f[:order] }.each.map do |f|
|
195
|
-
{ fileref: f[:url], identifier: f[:title] }
|
196
|
-
end
|
197
|
-
},
|
198
|
-
}
|
199
|
-
Util::recursive_string_keys(ret).to_yaml
|
200
|
-
end
|
201
|
-
|
202
|
-
def section_split_cover(col, ident, one_doc_coll)
|
203
|
-
dir = File.dirname(col.file)
|
204
|
-
collection_setup(nil, dir)
|
205
|
-
CollectionRenderer.new(col, dir,
|
206
|
-
output_folder: "#{ident}_collection",
|
207
|
-
format: %i(html),
|
208
|
-
coverpage: File.join(dir, "cover.html")).coverpage
|
209
|
-
#filename = one_doc_coll ? "#{ident}_index.html" : "index.html"
|
210
|
-
filename = "#{ident}_index.html"
|
211
|
-
FileUtils.mv "#{ident}_collection/index.html", File.join(dir, filename)
|
212
|
-
FileUtils.rm_rf "#{ident}_collection"
|
213
|
-
filename
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
data/lib/metanorma/util.rb
DELETED
@@ -1,127 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
module Util
|
3
|
-
def self.log(message, type = :info)
|
4
|
-
log_types = Metanorma.configuration.logs.map(&:to_s) || []
|
5
|
-
|
6
|
-
if log_types.include?(type.to_s)
|
7
|
-
puts(message)
|
8
|
-
end
|
9
|
-
|
10
|
-
if type == :fatal
|
11
|
-
exit(1)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# dependency ordering
|
16
|
-
def self.sort_extensions_execution_ord(ext)
|
17
|
-
case ext
|
18
|
-
when :xml then 0
|
19
|
-
when :rxl then 1
|
20
|
-
when :presentation then 2
|
21
|
-
else
|
22
|
-
99
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.sort_extensions_execution(ext)
|
27
|
-
ext.sort do |a, b|
|
28
|
-
sort_extensions_execution_ord(a) <=> sort_extensions_execution_ord(b)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.recursive_string_keys(hash)
|
33
|
-
case hash
|
34
|
-
when Hash then hash.map { |k, v| [k.to_s, recursive_string_keys(v)] }.to_h
|
35
|
-
when Enumerable then hash.map { |v| recursive_string_keys(v) }
|
36
|
-
else
|
37
|
-
hash
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.gather_bibitems(xml)
|
42
|
-
xml.xpath("//xmlns:bibitem[@id]").each_with_object({}) do |b, m|
|
43
|
-
if m[b["id"]]
|
44
|
-
b.remove
|
45
|
-
next # we can't update duplicate bibitem, processing updates wrong one
|
46
|
-
else
|
47
|
-
m[b["id"]] = b
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.gather_bibitemids(xml)
|
53
|
-
xml.xpath("//*[@bibitemid]").each_with_object({}) do |e, m|
|
54
|
-
/^semantic__/.match?(e.name) and next
|
55
|
-
m[e["bibitemid"]] ||= []
|
56
|
-
m[e["bibitemid"]] << e
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.gather_citeases(xml)
|
61
|
-
xml.xpath("//*[@citeas]").each_with_object({}) do |e, m|
|
62
|
-
/^semantic__/.match?(e.name) and next
|
63
|
-
m[e["citeas"]] ||= []
|
64
|
-
m[e["citeas"]] << e
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.add_suffix_to_attributes(doc, suffix, tag_name, attr_name, isodoc)
|
69
|
-
(suffix.nil? || suffix.empty?) and return
|
70
|
-
doc.xpath(isodoc.ns("//#{tag_name}[@#{attr_name}]")).each do |elem|
|
71
|
-
a = elem.attributes[attr_name].value
|
72
|
-
/_#{suffix}$/.match?(a) or
|
73
|
-
elem.attributes[attr_name].value = "#{a}_#{suffix}"
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.hash_key_detect(directives, key, variable)
|
78
|
-
c = directives.detect { |x| x.is_a?(Hash) && x.has_key?(key) } or
|
79
|
-
return variable
|
80
|
-
c[key]
|
81
|
-
end
|
82
|
-
|
83
|
-
def self.rel_path_resolve(dir, path)
|
84
|
-
path.nil? and return path
|
85
|
-
path.empty? and return path
|
86
|
-
p = Pathname.new(path)
|
87
|
-
p.absolute? ? path : File.join(dir, path)
|
88
|
-
end
|
89
|
-
|
90
|
-
def self.key(ident)
|
91
|
-
@c ||= HTMLEntities.new
|
92
|
-
@c.decode(ident).gsub(/(\p{Zs})+/, " ")
|
93
|
-
end
|
94
|
-
|
95
|
-
class DisambigFiles
|
96
|
-
def initialize
|
97
|
-
@seen_filenames = []
|
98
|
-
end
|
99
|
-
|
100
|
-
def strip_root(name)
|
101
|
-
name.sub(%r{^(\./)?(\.\./)+}, "")
|
102
|
-
end
|
103
|
-
|
104
|
-
def source2dest_filename(name, disambig = true)
|
105
|
-
n = strip_root(name)
|
106
|
-
dir = File.dirname(n)
|
107
|
-
base = File.basename(n)
|
108
|
-
if disambig && @seen_filenames.include?(base)
|
109
|
-
base = disambiguate_filename(base)
|
110
|
-
end
|
111
|
-
@seen_filenames << base
|
112
|
-
dir == "." ? base : File.join(dir, base)
|
113
|
-
end
|
114
|
-
|
115
|
-
def disambiguate_filename(base)
|
116
|
-
m = /^(?<start>.+\.)(?!0)(?<num>\d+)\.(?<suff>[^.]*)$/.match(base) ||
|
117
|
-
/^(?<start>.+\.)(?<suff>[^.]*)/.match(base) ||
|
118
|
-
/^(?<start>.+)$/.match(base)
|
119
|
-
i = m.names.include?("num") ? m["num"].to_i + 1 : 1
|
120
|
-
while @seen_filenames.include? base = "#{m['start']}#{i}.#{m['suff']}"
|
121
|
-
i += 1
|
122
|
-
end
|
123
|
-
base
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
class WorkersPool
|
3
|
-
def initialize(workers)
|
4
|
-
@workers = workers
|
5
|
-
@queue = SizedQueue.new(@workers)
|
6
|
-
@threads = Array.new(@workers) do
|
7
|
-
Thread.new do
|
8
|
-
catch(:exit) do
|
9
|
-
loop do
|
10
|
-
job, args = @queue.pop
|
11
|
-
job.call *args
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def schedule(*args, &block)
|
19
|
-
@queue << [block, args]
|
20
|
-
end
|
21
|
-
|
22
|
-
def shutdown
|
23
|
-
@workers.times do
|
24
|
-
schedule { throw :exit }
|
25
|
-
end
|
26
|
-
@threads.map(&:join)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|