lib/metanorma/collection_fileprocess.rb in metanorma-1.6.5 vs lib/metanorma/collection_fileprocess.rb in metanorma-1.6.6

- old
+ new

@@ -73,7 +73,84 @@ file_compile(collection_xml_path, filename, ident) FileUtils.rm(collection_xml_path) end end end + + # gather internal bibitem references + def gather_internal_refs + @files.keys.each_with_object({}) do |i, refs| + @files.get(i, :attachment) and next + file, = @files.targetfile_id(i, read: true) + gather_internal_refs1(file, i, refs) + end + end + + def gather_internal_refs1(file, ident, refs) + f = Nokogiri::XML(file, &:huge) + !@files.get(ident, :sectionsplit) and + gather_internal_refs_indirect(f, refs) + key = @files.get(ident, :indirect_key) and + gather_internal_refs_sectionsplit(f, ident, key, refs) + end + + def gather_internal_refs_indirect(doc, refs) + doc.xpath(ns("//bibitem[@type = 'internal']/" \ + "docidentifier[@type = 'repository']")).each do |d| + a = d.text.split(%r{/}, 2) + a.size > 1 or next + refs[a[0]] ||= {} + refs[a[0]][a[1]] = false + end + end + + def gather_internal_refs_sectionsplit(_doc, ident, key, refs) + refs[key] ||= {} + @files.get(ident, :ids).each_key do |k| + refs[key][k] = false + end + end + + def populate_internal_refs(refs) + @files.keys.reject do |k| + @files.get(k, :attachment) || @files.get(k, :sectionsplit) + end.each do |ident| + locate_internal_refs1(refs, ident, @isodoc.docid_prefix("", ident.dup)) + end + refs + end + + # resolve file location for the target of each internal reference + def locate_internal_refs + refs = populate_internal_refs(gather_internal_refs) + refs.each do |schema, ids| + ids.each do |id, key| + key and next + refs[schema][id] = "Missing:#{schema}:#{id}" + @log&.add("Cross-References", nil, refs[schema][id]) + end + end + refs + end + + def locate_internal_refs1(refs, identifier, ident) + t = locate_internal_refs1_prep(ident) + refs.each do |schema, ids| + ids.keys.select { |id| t[id] }.each do |id| + t[id].at("./ancestor-or-self::*[@type = '#{schema}']") and + refs[schema][id] = identifier + end + end + end + + def locate_internal_refs1_prep(ident) + file, = @files.targetfile_id(ident, read: true) + xml = Nokogiri::XML(file, &:huge) + r = xml.root["document_suffix"] + xml.xpath("//*[@id]").each_with_object({}) do |i, x| + /^semantic_/.match?(i.name) and next + x[i["id"]] = i + r and x[i["id"].sub(/_#{r}$/, "")] = i + end + end end end