Class: Metanorma::Collection::FileLookup

Inherits:
Object
  • Object
show all
Defined in:
lib/metanorma/collection/filelookup/utils.rb,
lib/metanorma/collection/filelookup/filelookup.rb,
lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, parent) ⇒ FileLookup

hash for each document in collection of document identifier to: document reference (fileref or id), type of document reference, and bibdata entry for that file

Parameters:

  • path (String)

    path to collection



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 17

def initialize(path, parent)
  @c = HTMLEntities.new
  @files = {}
  @parent = parent
  @xml = parent.xml
  @isodoc = parent.isodoc
  @isodoc_presxml = parent.isodoc_presxml
  @path = path
  @compile = parent.compile
  @documents = parent.documents
  @files_to_delete = []
  @disambig = Util::DisambigFiles.new
  @manifest = parent.manifest
  read_files(@manifest.entry, parent.manifest)
end

Instance Attribute Details

#files_to_deleteObject

Returns the value of attribute files_to_delete.



11
12
13
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 11

def files_to_delete
  @files_to_delete
end

#parentObject

Returns the value of attribute parent.



11
12
13
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 11

def parent
  @parent
end

Instance Method Details

#add_cover_one_doc_coll(manifest, sectionsplit_manifest, key, entry) ⇒ Object



67
68
69
70
71
72
# File 'lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb', line 67

def add_cover_one_doc_coll(manifest, sectionsplit_manifest, key, entry)
  idx = File.join(File.dirname(sectionsplit_manifest.file), "index.html")
  FileUtils.cp entry[:ref], idx
  manifest["#{key}:index1.html"] =
    entry.merge(out_path: "index.html", ref: idx)
end

#add_document_suffix(identifier, doc) ⇒ Object



223
224
225
226
227
228
229
230
231
232
233
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 223

def add_document_suffix(identifier, doc)
  document_suffix = Metanorma::Utils::to_ncname(identifier)
  ids = doc.xpath("./@id | .//@id").map(&:value)
  Util::anchor_id_attributes.each do |(tag_name, attr_name)|
    Util::add_suffix_to_attrs(doc, document_suffix, tag_name, attr_name,
                              @isodoc)
  end
  Util::url_in_css_styles(doc, ids, document_suffix)
  doc.root["document_suffix"] ||= ""
  doc.root["document_suffix"] += document_suffix
end

#add_section_splitObject



6
7
8
9
10
11
12
13
14
15
# File 'lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb', line 6

def add_section_split
  ret = @files.keys.each_with_object({}) do |k, m|
    if @files[k][:sectionsplit] && !@files[k][:attachment]
      original_out_path = process_section_split_instance(k, m)
      cleanup_section_split_instance(k, m, original_out_path)
    end
    m[k] = @files[k]
  end
  @files = ret
end

#add_section_split_attachments(manifest, ident) ⇒ Object



84
85
86
87
88
89
90
91
# File 'lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb', line 84

def add_section_split_attachments(manifest, ident)
  attachments = @sectionsplit
    .section_split_attachments(out: File.dirname(manifest.file))
  attachments or return
  @files[ident][:out_path] = attachments
  { attachment: true, index: false, out_path: attachments,
    ref: File.join(File.dirname(manifest.file), attachments) }
end

#add_section_split_cover(manifest, sectionsplit_manifest, ident) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb', line 54

def add_section_split_cover(manifest, sectionsplit_manifest, ident)
  cover = @sectionsplit
    .section_split_cover(sectionsplit_manifest,
                         @parent.dir_name_cleanse(ident),
                         one_doc_collection?)
  @files[ident][:out_path] = cover
  src = File.join(File.dirname(sectionsplit_manifest.file), cover)
  m = { attachment: true, index: false, out_path: cover, ref: src }
  manifest["#{ident}:index.html"] = m
  one_doc_collection? and
    add_cover_one_doc_coll(manifest, sectionsplit_manifest, ident, m)
end

#add_section_split_instance(file, manifest, key, idx) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb', line 93

def add_section_split_instance(file, manifest, key, idx)
  presfile, newkey, xml = add_section_split_instance_prep(file, key)
  anchors = read_anchors(xml)
  # Preserve directory structure in out_path if parent has custom sectionsplit_filename with directory
  sectionsplit_fname = @files[key][:sectionsplit_filename]

  # file[:url] from sectionsplit.rb already has placeholders substituted and includes full path
  # Use it directly for out_path (without .xml extension)
  base_filename = File.basename(file[:url], ".xml")

  # Get the directory from file[:url] which already has placeholders substituted
  file_dir = File.dirname(file[:url])

  # If file[:url] has a directory (i.e., placeholders were substituted), use it
  out_path_value = if file_dir == "."
                     base_filename
                   else
                     File.join(file_dir, base_filename)
                   end

  m = { parentid: key, presentationxml: true, type: "fileref",
        rel_path: out_path_value, out_path: out_path_value,
        anchors: anchors, anchors_lookup: anchors_lookup(anchors),
        ids: read_ids(xml), format: @files[key][:format],
        sectionsplit_output: true, indirect_key: @sectionsplit.key,
        bibdata: @files[key][:bibdata], ref: presfile,
        sectionsplit_filename: sectionsplit_fname,
        idx: @files[key][:idx] }
  m[:bare] = true unless idx.zero?
  manifest[newkey] = m
  # Don't delete split output files - we want to keep them!
  # The original parent HTML file is deleted in cleanup_section_split_instance
end

#add_section_split_instance_prep(file, key) ⇒ Object



127
128
129
130
131
132
133
134
135
# File 'lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb', line 127

def add_section_split_instance_prep(file, key)
  # XML files are always stored flat in the _files directory (no subdirectories)
  # file[:url] contains full path with directory for HTML output, but XML is basename only
  xml_basename = File.basename(file[:url])
  presfile = File.join(File.dirname(@files[key][:ref]), xml_basename)
  newkey = entry_key("#{key.strip} #{file[:title]}")
  xml = Nokogiri::XML(File.read(presfile), &:huge)
  [presfile, newkey, xml]
end

#anchors_lookup(anchors) ⇒ Object



4
5
6
7
8
# File 'lib/metanorma/collection/filelookup/utils.rb', line 4

def anchors_lookup(anchors)
  anchors.values.each_with_object({}) do |v, m|
    v.each_value { |v1| m[v1] = true }
  end
end

#bibdata_extract(xml) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 87

def bibdata_extract(xml)
  anchors = read_anchors(xml)
  { anchors: anchors, anchors_lookup: anchors_lookup(anchors),
    ids: read_ids(xml),
    bibdata: xml.at(ns("//bibdata")),
    document_suffix: xml.root["document_suffix"] }
end

#bibdata_process(entry, ident) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 75

def bibdata_process(entry, ident)
  if entry[:attachment]
    entry[:bibdata] =
      Metanorma::Collection::Document.attachment_bibitem(ident).root
  else
    file, _filename = targetfile(entry, read: true)
    xml = Nokogiri::XML(file, &:huge)
    add_document_suffix(ident, xml)
    entry.merge!(bibdata_extract(xml))
  end
end

#bibitem_process(entry) ⇒ Object



95
96
97
98
99
100
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 95

def bibitem_process(entry)
  entry[:bibitem] = entry[:bibdata].dup
  entry[:bibitem].name = "bibitem"
  entry[:bibitem]["hidden"] = "true"
  entry[:bibitem].at("./*[local-name() = 'ext']")&.remove
end

#cleanup_section_split_instance(key, manifest, original_out_path) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb', line 31

def cleanup_section_split_instance(key, manifest, original_out_path)
  # Delete the sectionsplit index.html from source directory after it's copied to output
  @files_to_delete << manifest["#{key}:index.html"][:ref]
  # Delete the original files when sectionsplit happens (all formats: html, xml, presentation.xml)
  # Use the saved original out_path (before it was changed to index.html)
  if original_out_path
    base = File.join(@parent.outdir, original_out_path.sub(/\.xml$/, ""))
    @files_to_delete << "#{base}.html"
    @files_to_delete << "#{base}.xml"
    @files_to_delete << "#{base}.presentation.xml"
  end
  # @files[key].delete(:ids).delete(:anchors)
  @files[key][:indirect_key] = @sectionsplit.key
  # sectionsplit is HTML-only; hand the parent its whole Presentation XML
  # so the collection PDF/presentation concatenation inlines the document
  # intact (raw_file) instead of degrading to a bibdata-only, namespace-
  # less stub. file_compile early-returns for sectionsplit, so this
  # :outputs entry is what concatenate1 consumes.
  # https://github.com/metanorma/iso-10303/issues/208
  @files[key][:outputs] =
    { presentation: @sectionsplit.whole_presentation_file }
end

#derive_format(entry, parent) ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 45

def derive_format(entry, parent)
  entry.attachment and return
  if Array(entry.format).empty?
    parent_fmt = Array(parent.format)
    entry.format = parent_fmt.empty? ? %w(xml presentation html) : parent_fmt.dup
  end
  entry.format |= ["xml", "presentation"]
end

#eachObject



39
40
41
# File 'lib/metanorma/collection/filelookup/utils.rb', line 39

def each
  @files.each
end

#each_with_indexObject



43
44
45
# File 'lib/metanorma/collection/filelookup/utils.rb', line 43

def each_with_index
  @files.each_with_index
end

#entry_key(ident) ⇒ Object

Normalise an identifier to its @files hash key: decode entities, squeeze whitespace, and strip a leading "metanorma-collection " prefix. Distinct from Util::key, which does NOT strip that prefix.



20
21
22
23
# File 'lib/metanorma/collection/filelookup/utils.rb', line 20

def entry_key(ident)
  @c.decode(ident).gsub(/(\p{Zs})+/, " ")
    .sub(/^metanorma-collection /, "")
end

#file_entry(ref, identifier, idx) ⇒ Object

ref is the absolute source file address rel_path is the relative source file address, relative to the YAML location out_path is the destination file address, with any references outside the working directory (../../...) truncated, and based on relative path identifier is the id with only spaces, no nbsp idx is the index of the document in the manifest



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 108

def file_entry(ref, identifier, idx)
  ref.file or return
  abs = @documents[Util::key identifier].file
  # For sectionsplit outputs from YAML manifest, we need to compute the full path
  # by combining sectionsplit_filename directory with ref.file basename
  sso = ref.respond_to?(:sectionsplit_output) && ref.sectionsplit_output
  out_path, rel_path = file_entry_paths(ref, idx, sso)
  ret = if ref.file
          { type: "fileref", ref: abs, rel_path: rel_path, url: ref.url,
            out_path: out_path, idx: idx,
            output_filename: ref.output_filename,
            sectionsplit_filename: ref.sectionsplit_filename,
            pdffile: ref.pdffile, format: ref.format&.map(&:to_sym) }
            .compact
        else { type: "id", ref: ref.id }
        end
  file_entry_copy(ref, ret)
  ret.compact
end

#file_entry_copy(ref, ret) ⇒ Object



214
215
216
217
218
219
220
221
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 214

def file_entry_copy(ref, ret)
  %w(attachment sectionsplit index presentation-xml url
     bare-after-first output_filename sectionsplit_filename
     sectionsplit_output).each do |s|
    ref.respond_to?(s.to_sym) and
      ret[s.delete("-").to_sym] = ref.send(s)
  end
end

#file_entry_paths(ref, idx, sso) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 145

def file_entry_paths(ref, idx, sso)
  base = File.basename(ref.file, ".xml")
  if sso && ref.respond_to?(:sectionsplit_filename) &&
      ref.sectionsplit_filename
    # Extract directory from sectionsplit_filename
    dir = File.dirname(ref.sectionsplit_filename)
    if dir == "." # No directory in pattern
      [output_file_path(ref, idx), ref.file]
    else # Pattern has directory, prepend it
      full_path = File.join(dir, base)
      [full_path, "#{full_path}.xml"]
    end
  else [output_file_path(ref, idx), ref.file]
  end
end

#file_entry_struct(ref, abs) ⇒ Object

ref is the absolute source file address rel_path is the relative source file address, relative to the YAML location out_path is the destination file address, with any references outside the working directory (../../...) truncated, and based on relative path identifier is the id with only spaces, no nbsp extract_opts are the compilation options extracted as document attributes



135
136
137
138
139
140
141
142
143
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 135

def file_entry_struct(ref, abs)
  adoc = abs.sub(/\.xml$/, ".adoc")
  if adoc.end_with?(".adoc") && File.exist?(adoc)
    opts = Metanorma::Input::Asciidoc.new.extract_options(File.read(adoc))
  end
  { type: "fileref", ref: abs, rel_path: ref.file, url: ref.url,
    out_path: output_file_path(ref), pdffile: ref.pdffile,
    format: ref.format&.map(&:to_sym), extract_opts: opts }.compact
end

#get(ident, attr = nil) ⇒ Object



29
30
31
32
33
# File 'lib/metanorma/collection/filelookup/utils.rb', line 29

def get(ident, attr = nil)
  if attr then @files[entry_key(ident)][attr]
  else @files[entry_key(ident)]
  end
end

#keysObject



25
26
27
# File 'lib/metanorma/collection/filelookup/utils.rb', line 25

def keys
  @files.keys
end

#ns(xpath) ⇒ Object



47
48
49
# File 'lib/metanorma/collection/filelookup/utils.rb', line 47

def ns(xpath)
  @isodoc.ns(xpath)
end

#one_doc_collection?Boolean

Returns:

  • (Boolean)


74
75
76
77
78
79
80
81
82
# File 'lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb', line 74

def one_doc_collection?
  docs = 0
  @files.each_value do |v|
    v[:attachment] and next
    v[:presentationxml] and next
    docs += 1
  end
  docs <= 1
end

#output_file_path(ref, idx) ⇒ Object

TODO make the output file location reflect source location universally, not just for attachments: no File.basename

For files with custom directory structure, construct path with directory For files with output_filename, use that (with substitutions) For others, use basename of ref.file



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 173

def output_file_path(ref, idx)
  has_custom_dir, file_has_dir, params = output_file_path_prep(ref, idx)
  # Apply sectionsplit_filename directory structure if:
  # 1. File has sectionsplit enabled (parent document being split), OR
  # 2. File is a sectionsplit output (from collection or single-file sectionsplit)
  # Regular files that inherit sectionsplit_filename from collection level
  # but are not sectionsplit outputs should NOT use it
  is_sectionsplit_output = ref.respond_to?(:sectionsplit_output) && ref.sectionsplit_output
  use_sectionsplit_dir = ref.sectionsplit_filename && has_custom_dir &&
    (ref.sectionsplit || is_sectionsplit_output || file_has_dir)
  f = if use_sectionsplit_dir
        # For sectionsplit outputs, return just the basename
        # The directory will be applied during file_compile_format
        # via preserve_directory_structure?
        File.basename(ref.file)
      elsif ref.output_filename
        substitute_filename_pattern(ref.output_filename, **params)
      elsif file_has_dir
        ref.file # Preserve directory structure already in ref.file
      elsif ref.attachment
        ref.file
      else File.basename(ref.file)
      end
  ret = @disambig.source2dest_filename(f, preserve_dirs: ref.attachment)
  warn ret
  ret
end

#output_file_path_prep(ref, idx) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 201

def output_file_path_prep(ref, idx)
  b = File.basename(ref.file)
  b_no_ext = File.basename(ref.file, ".*")
  # Check for sectionsplit_filename (for both parent and split output files)
  # or output_filename
  custom_filename = ref.sectionsplit_filename || ref.output_filename
  has_custom_dir = custom_filename && File.dirname(custom_filename) != "."
  # Also check if ref.file itself contains a directory
  file_has_dir = File.dirname(ref.file) != "."
  params = { document_num: idx, basename: b_no_ext, basename_legacy: b }
  [has_custom_dir, file_has_dir, params]
end

#preserve_directory_structure?(ident) ⇒ Boolean

Check if we should preserve directory structure for an identifier Returns the custom filename if directory structure should be preserved, nil otherwise

Returns:

  • (Boolean)


345
346
347
348
349
350
351
352
353
354
355
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 345

def preserve_directory_structure?(ident)
  ret = if get(ident, :sectionsplit_output)
          # For sectionsplit outputs, use rel_path which has the directory
          get(ident, :rel_path) || get(ident, :out_path)
        elsif get(ident, :sectionsplit)
          get(ident, :sectionsplit_filename)
        else get(ident, :output_filename)
        end
  # Return the custom filename only if it contains a directory
  ret && File.dirname(ret) != "." ? ret : nil
end

#process_section_split_instance(key, manifest) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb', line 17

def process_section_split_instance(key, manifest)
  # Save the original out_path before it gets modified
  original_out_path = @files[key][:out_path]
  s, sectionsplit_manifest = sectionsplit(key)
  s.each_with_index do |f1, i|
    add_section_split_instance(f1, manifest, key, i)
  end
  a = add_section_split_attachments(sectionsplit_manifest, key) and
    manifest["#{key}:attachments"] = a
  add_section_split_cover(manifest, sectionsplit_manifest, key)
  # Return the original path for cleanup
  original_out_path
end

#read_anchors(xml) ⇒ Object

map locality type and label (e.g. "clause" "1") to id = anchor for a document Note: will only key clauses, which have unambiguous reference label in locality. Notes, examples etc with containers are just plunked against UUIDs, so that their IDs can at least be registered to be tracked as existing.



312
313
314
315
316
317
318
319
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 312

def read_anchors(xml)
  xrefs = @isodoc.xref_init(@lang, @script, @isodoc, @isodoc.i18n,
                            { locale: @locale })
  xrefs.parse xml
  xrefs.get.each_with_object({}) do |(k, v), ret|
    read_anchors1(k, v, ret)
  end
end

#read_anchors1(key, val, ret) ⇒ Object



321
322
323
324
325
326
327
328
329
330
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 321

def read_anchors1(key, val, ret)
  val[:type] ||= "clause"
  ret[val[:type]] ||= {}
  index = if val[:container] || val[:label].nil? || val[:label].empty?
            UUIDTools::UUID.random_create.to_s
          else val[:label].gsub(%r{<[^>]+>}, "")
          end
  ret[val[:type]][index] = key
  v = val[:value] and ret[val[:type]][v.gsub(%r{<[^>]+>}, "")] = key
end

#read_file(manifest, idx) ⇒ Object



54
55
56
57
58
59
60
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 54

def read_file(manifest, idx)
  i, k = read_file_idents(manifest)
  entry = file_entry(manifest, k, idx) or return
  bibdata_process(entry, i)
  bibitem_process(entry)
  @files[entry_key(i)] = entry
end

#read_file_idents(manifest) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 62

def read_file_idents(manifest)
  id = manifest.identifier
  sanitised_id =
    entry_key(@isodoc.docid_prefix("", manifest.identifier.dup))
  #       if manifest.bibdata and # NO, DO NOT FISH FOR THE GENUINE IDENTIFIER IN BIBDATA
  #         d = manifest.bibdata.docidentifier.detect { |x| x.primary } ||
  #           manifest.bibdata.docidentifier.first
  #         k = d.id
  #         i = entry_key(@isodoc.docid_prefix(d.type, d.id.dup))
  #       end
  [id, sanitised_id]
end

#read_files(entries, parent, idx = 0) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 33

def read_files(entries, parent, idx = 0)
  Array(entries).each do |e|
    derive_format(e, parent)
    if e.file
      read_file(e, idx)
      idx += 1
    end
    idx = read_files(e.entry, e, idx)
  end
  idx
end

#read_ids(xml) ⇒ Object

Also parse all ids in doc (including ones which won't be xref targets)



333
334
335
336
337
338
339
340
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 333

def read_ids(xml)
  ret = {}
  xml.traverse do |x|
    x.text? and next
    x["id"] and ret[x["id"]] = true
  end
  ret
end

#ref_file(ref, data, read, doc) ⇒ Object



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 266

def ref_file(ref, data, read, doc)
  file = File.read(ref, encoding: "utf-8") if read
  # Use the actual output path from :outputs if available (set after compilation)
  # Otherwise fall back to :out_path (set at initialization)
  filename = if doc && data[:outputs] && data[:outputs][:html]
               data[:outputs][:html].sub(
                 %r{^#{Regexp.escape(@parent.outdir)}/}, ""
               )
             else
               data[:out_path].dup
             end
  if doc && !data[:outputs]
    filename = ref_file_xml2html(filename)
  end
  [file, filename]
end

#ref_file_xml2html(filename) ⇒ Object

Check if file has a recognized MIME type (other than XML) If so, don't append .html (e.g., .svg, .png, .jpg, etc.) Only process if it doesn't have a recognized non-XML extension If filename ends in .xml, replace with .html Otherwise (including sectionsplit files like "file.xml.0" or custom titles), append .html



289
290
291
292
293
294
295
296
297
298
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 289

def ref_file_xml2html(filename)
  unless Util::mime_file_recognised?(filename) &&
      !filename.end_with?(".xml")
    filename = if filename.end_with?(".xml")
                 filename.sub(/\.xml$/, ".html")
               else "#{filename}.html"
               end
  end
  filename
end

#sectionsplit(ident) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb', line 137

def sectionsplit(ident)
  file = @files[ident][:ref]
  # @base must always be just basename, never contain directory components
  # Directory structure comes from sectionsplit_filename pattern only
  base = File.basename(@files[ident][:out_path] || file)
  @sectionsplit = ::Metanorma::Collection::Sectionsplit
    .new(input: file, base: base,
         dir: File.dirname(file), output: @files[ident][:out_path],
         compile_opts: @parent.compile_options, ident: ident,
         fileslookup: self, isodoc: @isodoc,
         parent_idx: @files[ident][:idx],
         sectionsplit_filename: @files[ident][:sectionsplit_filename],
         isodoc_presxml: @isodoc_presxml,
         document_suffix: @files[ident][:document_suffix])
  coll = @sectionsplit.sectionsplit.sort_by { |f| f[:order] }
  xml = Nokogiri::XML(File.read(file, encoding: "UTF-8"), &:huge)
  [coll, @sectionsplit
    .collection_manifest(File.basename(file), coll, xml, nil,
                         File.dirname(file))]
end

#set(ident, attr, value) ⇒ Object



35
36
37
# File 'lib/metanorma/collection/filelookup/utils.rb', line 35

def set(ident, attr, value)
  @files[entry_key(ident)][attr] = value
end

#substitute_filename_pattern(pattern, options = {}) ⇒ Object

Substitute special strings in filename patterns. See Util.substitute_filename_pattern.



163
164
165
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 163

def substitute_filename_pattern(pattern, options = {})
  Util.substitute_filename_pattern(pattern, options)
end

#targetfile(data, options) ⇒ Array<String, nil>

return file contents + output filename for each file in the collection, given a docref entry so my URL should end with html or pdf or whatever formed relative to YAML file, not input path, relative to calling function

Parameters:

  • data (Hash)

    docref entry

  • read (Boolean)

    read the file in and return it

  • doc (Boolean)

    I am a Metanorma document,

  • relative (Boolean)

    Return output path,

Returns:



252
253
254
255
256
257
258
259
260
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 252

def targetfile(data, options)
  options = { read: false, doc: true, relative: false }.merge(options)
  path = options[:relative] ? data[:rel_path] : data[:ref]
  if data[:type] == "fileref"
    ref_file path, data, options[:read], options[:doc]
  else
    xml_file data[:id], options[:read]
  end
end

#targetfile_id(ident, options) ⇒ Object



262
263
264
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 262

def targetfile_id(ident, options)
  targetfile(get(ident), options)
end

#url(ident, options) ⇒ Object

return citation url for file so my URL should end with html or pdf or whatever

Parameters:

  • doc (Boolean)

    I am a Metanorma document,



238
239
240
241
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 238

def url(ident, options)
  data = get(ident)
  data[:url] || targetfile(data, options)[1]
end

#url?(ident) ⇒ Boolean

are references to the file to be linked to a file in the collection, or externally? Determines whether file suffix anchors are to be used

Returns:

  • (Boolean)


12
13
14
15
# File 'lib/metanorma/collection/filelookup/utils.rb', line 12

def url?(ident)
  data = get(ident) or return false
  data[:url]
end

#xml_file(id, read) ⇒ Object



300
301
302
303
304
# File 'lib/metanorma/collection/filelookup/filelookup.rb', line 300

def xml_file(id, read)
  file = @xml.at(ns("//doc-container[@id = '#{id}']")).to_xml if read
  filename = "#{id}.html"
  [file, filename]
end