metanorma 2.1.4 → 2.5.4

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +23 -2
  3. data/Gemfile +14 -0
  4. data/README.adoc +1 -1
  5. data/lib/metanorma/collection/artifact_store.rb +142 -0
  6. data/lib/metanorma/collection/collection.rb +140 -131
  7. data/lib/metanorma/collection/config/bibdata.rb +1 -1
  8. data/lib/metanorma/collection/config/config.rb +50 -20
  9. data/lib/metanorma/collection/config/converters.rb +89 -31
  10. data/lib/metanorma/collection/config/doc_container.rb +28 -0
  11. data/lib/metanorma/collection/config/manifest.rb +30 -6
  12. data/lib/metanorma/collection/config/namespaces.rb +12 -0
  13. data/lib/metanorma/collection/document/document.rb +54 -15
  14. data/lib/metanorma/collection/filelookup/filelookup.rb +170 -74
  15. data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +62 -27
  16. data/lib/metanorma/collection/filelookup/utils.rb +52 -0
  17. data/lib/metanorma/collection/helpers.rb +82 -0
  18. data/lib/metanorma/collection/log.rb +24 -0
  19. data/lib/metanorma/collection/manifest/manifest.rb +27 -14
  20. data/lib/metanorma/collection/multilingual/multilingual.rb +1 -1
  21. data/lib/metanorma/collection/renderer/filelocation.rb +166 -0
  22. data/lib/metanorma/collection/renderer/fileparse.rb +60 -55
  23. data/lib/metanorma/collection/renderer/fileprocess.rb +184 -40
  24. data/lib/metanorma/collection/renderer/navigation.rb +20 -6
  25. data/lib/metanorma/collection/renderer/render_word.rb +8 -4
  26. data/lib/metanorma/collection/renderer/renderer.rb +202 -19
  27. data/lib/metanorma/collection/renderer/svg.rb +60 -5
  28. data/lib/metanorma/collection/renderer/utils.rb +76 -42
  29. data/lib/metanorma/collection/sectionsplit/collection.rb +14 -4
  30. data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +141 -61
  31. data/lib/metanorma/collection/util/disambig_files.rb +4 -5
  32. data/lib/metanorma/collection/util/util.rb +147 -23
  33. data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +7 -7
  34. data/lib/metanorma/compile/assets/icc-boilerplate.adoc +41 -0
  35. data/lib/metanorma/compile/compile.rb +180 -165
  36. data/lib/metanorma/compile/compile_options.rb +155 -83
  37. data/lib/metanorma/compile/extract.rb +76 -56
  38. data/lib/metanorma/compile/flavor.rb +19 -0
  39. data/lib/metanorma/compile/output_filename.rb +75 -0
  40. data/lib/metanorma/compile/output_filename_config.rb +27 -0
  41. data/lib/metanorma/compile/relaton_drop.rb +56 -0
  42. data/lib/metanorma/compile/render.rb +196 -0
  43. data/lib/metanorma/compile/validator.rb +26 -0
  44. data/lib/metanorma/compile/writeable.rb +12 -0
  45. data/lib/metanorma/util/fontist_helper.rb +35 -19
  46. data/lib/metanorma/version.rb +1 -1
  47. data/lib/metanorma.rb +1 -7
  48. data/metanorma.gemspec +11 -20
  49. data/plans/collection-rendering-architecture-review.md +516 -0
  50. metadata +42 -122
  51. data/.hound.yml +0 -5
  52. data/lib/metanorma/asciidoctor_extensions/glob_include_processor.rb +0 -22
  53. data/lib/metanorma/asciidoctor_extensions.rb +0 -1
  54. data/lib/metanorma/compile/compile_validate.rb +0 -68
  55. data/lib/metanorma/config/config.rb +0 -23
  56. data/lib/metanorma/input/asciidoc.rb +0 -88
  57. data/lib/metanorma/input/base.rb +0 -9
  58. data/lib/metanorma/input.rb +0 -7
  59. data/lib/metanorma/processor/processor.rb +0 -54
  60. data/lib/metanorma/processor.rb +0 -6
  61. data/lib/metanorma/registry/registry.rb +0 -63
  62. data/lib/metanorma/util/util.rb +0 -45
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../util/util"
3
+ require "metanorma-core"
4
4
 
5
5
  module Metanorma
6
6
  class Collection
@@ -14,17 +14,22 @@ module Metanorma
14
14
  # @param docref [Array<Hash{String=>String}>]
15
15
  # @param manifest [Array<Metanorma::Collection::Manifest>]
16
16
  def initialize(config, collection, dir)
17
- #require "debug"; binding.b
18
17
  @collection = collection
19
18
  @dir = dir
20
19
  @disambig = ::Metanorma::Collection::Util::DisambigFiles.new
21
20
  @config = manifest_postprocess(config)
22
21
  end
23
22
 
23
+ # Ordered pipeline of in-place tree-walks over the manifest; the order is
24
+ # load-bearing. expand_yaml must run early because it grafts nested
25
+ # `fileref` manifests into this tree, so every later pass sees the full
26
+ # entry set; bibdata sets @lang/@script used downstream; compile_adoc
27
+ # turns .adoc sources into .xml before filexist verifies them. Each pass
28
+ # recurses the manifest independently (see the architecture review plan).
24
29
  def manifest_postprocess(config)
25
- #require "debug"; binding.b
26
30
  manifest_bibdata(config)
27
31
  manifest_expand_yaml(config, @dir)
32
+ manifest_output_filenames(config)
28
33
  manifest_compile_adoc(config)
29
34
  manifest_filexist(config)
30
35
  manifest_sectionsplit(config)
@@ -40,6 +45,17 @@ module Metanorma
40
45
 
41
46
  GUID = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
42
47
 
48
+ def manifest_output_filenames(config, parent = nil)
49
+ config.output_filename ||=
50
+ parent&.output_filename # || "{basename}.{document-num}"
51
+ config.sectionsplit_filename ||= parent&.sectionsplit_filename ||
52
+ "{basename_legacy}.{sectionsplit-num}"
53
+ # "{basename}-{document-num}.{sectionsplit-num}"
54
+ Array(config.entry).each do |f|
55
+ manifest_output_filenames(f, config)
56
+ end
57
+ end
58
+
43
59
  def manifest_identifier(config)
44
60
  no_id = populate_id_from_doc(config)
45
61
  config.identifier =
@@ -96,7 +112,6 @@ module Metanorma
96
112
 
97
113
  def manifest_filexist(config)
98
114
  if config.file
99
- #require "debug"; binding.b
100
115
  file = @collection.class.resolve_fileref(@dir, config.file)
101
116
  @collection.class.check_file_existence(file)
102
117
  config.file = Pathname.new(file).relative_path_from(Pathname.new(@dir))
@@ -111,7 +126,6 @@ module Metanorma
111
126
  currdir = dir
112
127
  /\.ya?ml$/.match?(e.file) and
113
128
  currdir = manifest_expand_yaml_entry(e, dir)
114
- #require "debug"; binding.b
115
129
  manifest_expand_yaml(e, currdir)
116
130
  end
117
131
  config
@@ -122,10 +136,8 @@ module Metanorma
122
136
  currdir = File.dirname(f)
123
137
  @collection.class.check_file_existence(f)
124
138
  entry.file = nil
125
- #require 'debug'; binding.b
126
139
  entry.entry = ::Metanorma::Collection::Config::Config.from_yaml(File.read(f)).manifest
127
140
  if currdir != dir
128
- #require "debug"; binding.b
129
141
  prefix = Pathname.new(currdir).relative_path_from(Pathname.new(dir))
130
142
  update_filepaths(entry.entry, prefix.to_s)
131
143
  end
@@ -133,10 +145,9 @@ module Metanorma
133
145
  end
134
146
 
135
147
  def update_filepaths(entry, prefix)
136
- #require "debug"; binding.b
137
148
  entry.file && !(Pathname.new entry.file).absolute? and
138
149
  entry.file = File.join(prefix, entry.file)
139
- entry.entry.each do |f|
150
+ entry&.entry&.each do |f|
140
151
  update_filepaths(f, prefix)
141
152
  end
142
153
  end
@@ -170,18 +181,20 @@ module Metanorma
170
181
  f = (Pathname.new file).absolute? ? file : File.join(@dir, file)
171
182
  File.exist?(f) or raise AdocFileNotFoundException.new "#{f} not found!"
172
183
  compile_adoc_file?(file) or return
173
- ::Metanorma::Util.log("[metanorma] Info: Compiling #{f}...", :info)
184
+ ::Metanorma::Util.log("[metanorma] Info: Compiling #{f}...", :warning)
174
185
  ::Metanorma::Compile.new
175
186
  .compile(f, agree_to_terms: true, install_fonts: false,
176
187
  extension_keys: [:xml])
177
- ::Metanorma::Util.log("[metanorma] Info: Compiling #{f}...done!", :info)
188
+ ::Metanorma::Util.log("[metanorma] Info: Compiling #{f}...done!",
189
+ :warning)
178
190
  end
179
191
 
180
192
  def compile_adoc_file?(file)
193
+ !File.exist?(file.sub(/\.adoc$/, ".xml")) and return true
181
194
  @collection.directives.detect do |d|
182
- d.key == "recompile-xml"
183
- end and return true
184
- !File.exist?(file.sub(/\.adoc$/, ".xml"))
195
+ d.key == "recompile-xml" && d.value == "false"
196
+ end and return false
197
+ true
185
198
  end
186
199
 
187
200
  def documents(mnf = @config)
@@ -617,7 +617,7 @@ module Metanorma
617
617
  end
618
618
 
619
619
  def htmlconv
620
- x = Asciidoctor.load nil, backend: @flavor
620
+ x = Asciidoctor.load nil, backend: Util::taste2flavor(@flavor)
621
621
  x.converter.html_converter(@converter_opt)
622
622
  end
623
623
 
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ class Collection
5
+ class Renderer
6
+ def file_compile_formats(filename, identifier, opts)
7
+ f = @files.get(identifier, :outputs)
8
+ format = opts[:extension_keys]
9
+ concatenate_presentation?({ format: }) and format << :presentation
10
+ format.each do |e|
11
+ e == :pdf and output_filename = opts[:pdffile]
12
+ file_compile_format(filename, identifier, e, f, output_filename)
13
+ end
14
+ @files.set(identifier, :outputs, f)
15
+ end
16
+
17
+ # Generate output filename with correct extension
18
+ def output_filename_with_extension(fname, format)
19
+ ext = @compile.processor.output_formats[format]
20
+ fname_base = File.basename(fname)
21
+ # ONLY replace .xml or .html extensions, NEVER remove section numbers
22
+ if /\.(xml|html)$/.match?(fname_base)
23
+ fname_base.sub(/\.(xml|html)$/, ".#{ext}")
24
+ else
25
+ "#{fname_base}.#{ext}"
26
+ end
27
+ end
28
+
29
+ # Move file to new output filename if specified. A member that
30
+ # failed to render has nothing to move: keep the original name
31
+ # registered so output verification reports it as missing, rather
32
+ # than crashing the whole collection on the mv (#586).
33
+ def handle_new_output_filename(output_fname, new_output_fname)
34
+ return output_fname unless new_output_fname
35
+
36
+ src = File.join(@outdir, output_fname)
37
+ File.exist?(src) or return output_fname
38
+ FileUtils.mv(src, File.join(@outdir, new_output_fname))
39
+ new_output_fname
40
+ end
41
+
42
+ # Apply custom filename pattern with substitutions
43
+ def apply_custom_filename_pattern(ident, custom_fname, output_fname,
44
+ format)
45
+ idx = @files.get(ident, :idx)
46
+ original_file = @files.get(ident, :ref)
47
+ basename = File.basename(original_file, ".*")
48
+ basename_legacy = File.basename(original_file)
49
+ custom_fname = @files.substitute_filename_pattern(
50
+ custom_fname, document_num: idx,
51
+ basename: basename, basename_legacy: basename_legacy
52
+ )
53
+ if File.dirname(custom_fname) == "."
54
+ output_fname
55
+ else
56
+ preserve_output_dir_structure(custom_fname, output_fname,
57
+ format, explicit_custom: true)
58
+ end
59
+ end
60
+
61
+ # Apply directory preservation for files with directory structure
62
+ def apply_directory_preservation(fname, output_fname, format)
63
+ fname_dir = File.dirname(fname)
64
+ output_fname = File.join(fname_dir, output_fname)
65
+ preserve_output_dir_structure(fname, output_fname, format)
66
+ end
67
+
68
+ # Compile single format for a file and update outputs hash
69
+ def file_compile_format(fname, ident, format, outputs, new_output_fname)
70
+ ext = @compile.processor.output_formats[format]
71
+ output_fname = output_filename_with_extension(fname, format)
72
+ output_fname = handle_new_output_filename(output_fname,
73
+ new_output_fname)
74
+ if !new_output_fname && (custom = @files.preserve_directory_structure?(ident))
75
+ output_fname = apply_custom_filename_pattern(ident, custom,
76
+ output_fname, format)
77
+ elsif !new_output_fname && File.dirname(fname) != "."
78
+ output_fname = apply_directory_preservation(fname, output_fname,
79
+ format)
80
+ end
81
+ should_skip = /html$/.match?(ext) && @files.get(ident, :sectionsplit)
82
+ should_skip or outputs[format] = File.join(@outdir, output_fname)
83
+ end
84
+
85
+ # Determine if file should be moved to subdirectory
86
+ def should_move_to_subdirectory?(ext, output_basename, explicit_custom)
87
+ if explicit_custom
88
+ # For explicit output-filename: move html, doc, pdf, presentation.xml
89
+ ext.end_with?("html") || ext == "doc" || ext == "pdf" ||
90
+ output_basename.end_with?(".presentation.xml")
91
+ else
92
+ # Default: only HTML and presentation files
93
+ ext.end_with?("html") ||
94
+ output_basename.end_with?(".html", ".presentation.xml")
95
+ end
96
+ end
97
+
98
+ # Move file from root to subdirectory
99
+ def move_file_to_subdirectory(fname_dir, output_basename)
100
+ output_with_dir = File.join(fname_dir, output_basename)
101
+ output_dest = File.join(@outdir, output_with_dir)
102
+ output_src = File.join(@outdir, output_basename)
103
+ return nil unless File.exist?(output_src) && output_src != output_dest
104
+
105
+ FileUtils.mkdir_p(File.dirname(output_dest))
106
+ FileUtils.mv(output_src, output_dest)
107
+ output_with_dir
108
+ end
109
+
110
+ # Handle case where destination already exists
111
+ def handle_existing_destination(output_with_dir, output_src)
112
+ output_dest = File.join(@outdir, output_with_dir)
113
+ return nil unless File.exist?(output_dest)
114
+ return output_with_dir unless File.exist?(output_src)
115
+
116
+ FileUtils.rm_f(output_src)
117
+ err_src = output_src.sub(/\.html$/, ".err.html")
118
+ FileUtils.rm_f(err_src) if File.exist?(err_src)
119
+ output_with_dir
120
+ end
121
+
122
+ # Generate custom basename with extension
123
+ def custom_basename_with_extension(fname, output_basename)
124
+ custom_basename = File.basename(fname, ".*")
125
+ ext = File.extname(output_basename)
126
+ "#{custom_basename}#{ext}"
127
+ end
128
+
129
+ # Preserve directory structure from input filename in output
130
+ def preserve_output_dir_structure(fname, output_fname, format = nil,
131
+ explicit_custom: false)
132
+ fname_dir = File.dirname(fname)
133
+ return output_fname if fname_dir == "."
134
+
135
+ output_basename = File.basename(output_fname)
136
+ ext = format ? @compile.processor.output_formats[format].to_s : ""
137
+ should_move = should_move_to_subdirectory?(ext, output_basename,
138
+ explicit_custom)
139
+ if should_move
140
+ result = move_file_to_subdirectory(fname_dir, output_basename)
141
+ return result if result
142
+
143
+ handle_existing_destination(File.join(fname_dir, output_basename),
144
+ File.join(@outdir,
145
+ output_basename)) || output_fname
146
+ elsif explicit_custom
147
+ custom_basename_with_extension(fname, output_basename)
148
+ else
149
+ output_basename
150
+ end
151
+ end
152
+
153
+ def copy_file_to_dest(identifier)
154
+ out = Pathname.new(@files.get(identifier, :out_path)).cleanpath
155
+ out.absolute? and
156
+ out = out.relative_path_from(File.expand_path(FileUtils.pwd))
157
+ dest = File.join(@outdir,
158
+ @disambig.source2dest_filename(out.to_s,
159
+ preserve_dirs: true))
160
+ FileUtils.mkdir_p(File.dirname(dest))
161
+ source = @files.get(identifier, :ref)
162
+ source != dest and FileUtils.cp_r source, dest, remove_destination: true
163
+ end
164
+ end
165
+ end
166
+ end
@@ -4,7 +4,7 @@ module Metanorma
4
4
  # Resolves references to other files in the collection. Three routines:
5
5
  # 1. Eref to a document that has been split into multiple documents
6
6
  # (sectionsplit) are resolved to direct eref to the split document
7
- # 2. Indirect erefs to a file anchor in an unknwon file in the collection
7
+ # 2. Indirect erefs to a file anchor in an unknown file in the collection
8
8
  # (bibitem[@type = 'internal'] ) are resolved to direct eref to the
9
9
  # containing document
10
10
  # 3. Direct erefs to other files in collection
@@ -14,25 +14,46 @@ module Metanorma
14
14
  # @param internal_refs [Hash{String=>Hash{String=>String}] schema name to
15
15
  # anchor to filename
16
16
  # @return [String] XML content
17
+ # Each pass below mutates the SAME Nokogiri tree in place; the inline
18
+ # comments state the post-condition each pass guarantees on exit. The
19
+ # contract between passes is "the tree is now in state X" -- there is no
20
+ # intermediate typed representation, so the ordering is load-bearing.
21
+ # `sso` truthy (sectionsplit_output) => `xml` is Presentation XML and the
22
+ # semantic-only passes are skipped; otherwise `xml` is Semantic XML.
23
+ # See the pipeline map in the collection architecture review plan.
17
24
  def update_xrefs(file, docid, internal_refs)
18
25
  xml, sso = update_xrefs_prep(file, docid)
19
- #require "debug"; binding.b if /This document is also unrelated/.match?(xml.to_xml)
20
- #warn (/fmt-title/.match?(xml.to_xml) ? "*** PRESENTATION" : "*** SEMANTIC")
21
- @nested || sso or
26
+ # post: repository docidentifiers supplied on bibitems naming a
27
+ # collection file; `sso` resolved (Presentation vs Semantic).
28
+ @nested || sso || @reinflate or
22
29
  Metanorma::Collection::XrefProcess::xref_process(xml, xml, nil, docid,
23
30
  @isodoc, sso)
31
+ # post (semantic only): intra-doc xref/eref turned into internal erefs;
32
+ # repo bibitems copied; indirect bibliography inserted.
24
33
  @ncnames = {}
25
34
  @nested or update_indirect_refs_to_docs(xml, docid, internal_refs, sso)
26
- @files.add_document_suffix(docid, xml)
27
- @nested or update_sectionsplit_refs_to_docs(xml, internal_refs, sso)
35
+ # post: bibitem[@type='internal'] anchors resolved to the containing
36
+ # collection document.
37
+ @reinflate or @files.add_document_suffix(docid, xml)
38
+ # post: every @id/@anchor namespaced with this doc's NCName suffix, so
39
+ # concatenated documents do not collide.
40
+ @nested or update_sectionsplit_refs_to_docs(xml, docid, internal_refs,
41
+ sso)
42
+ # post: erefs targeting a sectionsplit document point at the specific
43
+ # split section file that holds the anchor.
28
44
  update_direct_refs_to_docs(xml, docid, sso)
29
- hide_refs(xml)
45
+ # post: repo(current-metanorma-collection/x) bibitems replaced in situ
46
+ # with resolved bibdata + citation URI; their erefs become hyperlinks.
47
+ ::Metanorma::Collection::Util::hide_refs(xml)
48
+ # post: references containers with only hidden bibitems flagged hidden.
30
49
  sso and eref2link(xml, sso)
31
- @nested or svgmap_resolve(xml, docid, sso)
50
+ @nested || @reinflate or svgmap_resolve(xml, docid, sso)
32
51
  xml.to_xml
33
52
  end
34
53
 
35
- ## sso files are Presentation XML; otherwise, Semantic XML
54
+ ## sso (sectionsplit_output) truthy => Presentation XML, else Semantic.
55
+ ## This is the single discriminator that decides which grammar `xml`
56
+ ## carries and therefore which passes in update_xrefs run.
36
57
  def update_xrefs_prep(file, docid)
37
58
  docxml = file.is_a?(String) ? Nokogiri::XML(file, &:huge) : file
38
59
  supply_repo_ids(docxml)
@@ -40,7 +61,8 @@ module Metanorma
40
61
  [docxml, sso]
41
62
  end
42
63
 
43
- def update_sectionsplit_refs_to_docs(docxml, internal_refs, presxml)
64
+ def update_sectionsplit_refs_to_docs(docxml, docid, internal_refs,
65
+ presxml)
44
66
  Util::gather_citeases(docxml, presxml).each do |k, v|
45
67
  (@files.get(k) && @files.get(k, :sectionsplit)) or next
46
68
  opts = { key: @files.get(k, :indirect_key),
@@ -49,7 +71,7 @@ module Metanorma
49
71
  refs = v.each_with_object({}) do |eref, m|
50
72
  update_sectionsplit_eref_to_doc(eref, internal_refs, m, opts)
51
73
  end
52
- add_hidden_bibliography(docxml, refs)
74
+ add_hidden_bibliography(docxml, refs, docid)
53
75
  end
54
76
  end
55
77
 
@@ -65,8 +87,9 @@ module Metanorma
65
87
  doclist
66
88
  end
67
89
 
68
- BIBITEM_NOT_REPO_XPATH = "//bibitem[not(ancestor::bibitem)]" \
69
- "[not(./docidentifier[@type = 'repository'])]".freeze
90
+ BIBITEM_NOT_REPO_XPATH = <<~XPATH.strip
91
+ //bibitem[not(ancestor::bibitem)][not(ancestor::bibdata)][not(./docidentifier[@type = 'repository'])]
92
+ XPATH
70
93
 
71
94
  def supply_repo_ids(doc)
72
95
  doc.xpath(ns(BIBITEM_NOT_REPO_XPATH)).each do |b|
@@ -84,10 +107,11 @@ module Metanorma
84
107
  # Any erefs to that bibitem id are replaced with relative URL
85
108
  # Preferably with anchor, and is a job to realise dynamic lookup
86
109
  # of localities.
87
- def update_direct_refs_to_docs(docxml, identifier, presxml)
110
+ def update_direct_refs_to_docs(xml, identifier, presxml)
88
111
  erefs, erefs_no_anchor, anchors, erefs1 =
89
- update_direct_refs_to_docs_prep(docxml, presxml)
90
- docxml.xpath(ns("//bibitem")).each do |b|
112
+ update_direct_refs_to_docs_prep(xml, presxml)
113
+ x = xml.xpath(ns("//bibitem")) - xml.xpath(ns("//bibdata//bibitem"))
114
+ x.each do |b|
91
115
  docid = b.at(ns("./docidentifier[@type = 'repository']")) or next
92
116
  strip_unresolved_repo_erefs(identifier, docid, erefs1, b) or next
93
117
  update_bibitem(b, identifier)
@@ -106,10 +130,10 @@ module Metanorma
106
130
  erefs.each do |k, v|
107
131
  v.each do |e|
108
132
  if loc = e.at(".//#{ANCHOR_XPATH}") then anchors[k] << loc
109
- else no_anchor[k] << e end
133
+ else no_anchor[k] << e
134
+ end
110
135
  end
111
136
  end
112
- #require "debug"; binding.b
113
137
  [erefs, no_anchor, anchors, Util::gather_bibitemids(docxml, presxml)]
114
138
  end
115
139
 
@@ -119,8 +143,13 @@ module Metanorma
119
143
  # Do not do this if this is a sectionsplit collection or a nested manifest.
120
144
  # Return false if bibitem is not to be further processed
121
145
  def strip_unresolved_repo_erefs(_document_id, bib_docid, erefs, bibitem)
122
- %r{^current-metanorma-collection/(?!Missing:)}.match?(bib_docid.text) and
146
+ if %r{^current-metanorma-collection/(?!Missing:)}.match?(bib_docid.text)
147
+ # Isolated build: keep the cross-document ref as a stub (its bibitemid
148
+ # and repository docidentifier intact) for a later reinflation pass to
149
+ # relink, rather than resolving it now against an absent target.
150
+ @preserve_unresolved and return false
123
151
  return true
152
+ end
124
153
  @nested and return false
125
154
  erefs[bibitem["id"]]&.each { |x| x.parent and strip_eref(x) }
126
155
  false
@@ -128,8 +157,9 @@ module Metanorma
128
157
 
129
158
  # Resolve erefs to a container of ids in another doc,
130
159
  # to an anchor eref (direct link)
131
- def update_indirect_refs_to_docs(docxml, _docidentifier, internal_refs, presxml)
132
- bib, erefs, doc_suffix, doc_type, f = update_indirect_refs_prep(docxml, presxml)
160
+ def update_indirect_refs_to_docs(docxml, _docid, internal_refs, presxml)
161
+ bib, erefs, doc_suffix, doc_type, f = update_indirect_refs_prep(docxml,
162
+ presxml)
133
163
  internal_refs.each do |schema, ids|
134
164
  add_suffix = doc_suffix && doc_type && doc_type != schema
135
165
  ids.each do |id, file|
@@ -149,37 +179,15 @@ module Metanorma
149
179
  docxml.root["document_suffix"], docxml.root["type"], {}]
150
180
  end
151
181
 
152
- # KILL
153
- def indirect_ref_key(schema, id, doc_suffix, doc_type)
154
- /^#{schema}_/.match?(id) and return id
155
- key = [schema, id, doc_suffix, doc_type].join("::")
156
- x = @indirect_keys[key] and return x
157
- ret = "#{schema}_#{id}"
158
- doc_suffix && doc_type && doc_type != schema and
159
- ret = "#{ret}_#{doc_suffix}"
160
- @indirect_keys[key] = ret
161
- ret
162
- end
163
-
164
182
  def indirect_ref_key(schema, id, doc_suffix, add_suffix)
165
183
  /^#{schema}_/.match?(id) and return id
166
- #key = "#{schema}_#{id}"
167
184
  x = @indirect_keys.dig(schema, id) and return x
168
185
  @indirect_keys[schema] ||= {}
169
186
  @indirect_keys[schema][id] = if add_suffix
170
- "#{schema}_#{id}_#{doc_suffix}"
171
- else
172
- "#{schema}_#{id}"
173
- end
174
- end
175
-
176
- # KILL
177
- def indirect_ref_keyx(schema, id, doc_suffix, doc_type)
178
- /^#{schema}_/.match?(id) and return id
179
- ret = "#{schema}_#{id}"
180
- doc_suffix && doc_type && doc_type != schema and
181
- ret = "#{ret}_#{doc_suffix}"
182
- ret
187
+ "#{schema}_#{id}_#{doc_suffix}"
188
+ else
189
+ "#{schema}_#{id}"
190
+ end
183
191
  end
184
192
 
185
193
  def update_indirect_refs_to_docs1(filec, key, file, bibitems, erefs)
@@ -196,13 +204,10 @@ module Metanorma
196
204
  parentid and file = "#{parentid}_#{file}"
197
205
  existing = a.text
198
206
  anchor = if url then existing
199
- else
200
- #suffix_anchor_indirect(existing, suffix)
201
- #k = "#{existing}_#{file}"
202
- #@ncnames[k] ||= Metanorma::Utils::to_ncname(k)
203
- @indirect_keys[existing] ||= {}
204
- @indirect_keys[existing][file] ||= Metanorma::Utils::to_ncname("#{existing}_#{file}")
205
- end
207
+ else
208
+ @indirect_keys[existing] ||= {}
209
+ @indirect_keys[existing][file] ||= Metanorma::Utils::to_ncname("#{existing}_#{file}")
210
+ end
206
211
  @updated_anchors[existing] or a.children = anchor
207
212
  @updated_anchors[anchor] = true
208
213
  end
@@ -254,7 +259,7 @@ module Metanorma
254
259
  type = "clause" if type == "annex"
255
260
  ref = ins.at(ns("./locality/referenceFrom"))&.text
256
261
  a = @files.get(docid, :anchors).dig(type, ref) or return
257
- ins << "<locality type='anchor'><referenceFrom>#{a.sub(/^_/, '')}" \
262
+ ins << "<locality type='anchor'><referenceFrom>#{a}" \
258
263
  "</referenceFrom></locality>"
259
264
  end
260
265
  end