Class: Metanorma::FileLookup

Inherits:
Object
  • Object
show all
Defined in:
lib/metanorma/files_lookup.rb

Overview

XML collection renderer

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



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/metanorma/files_lookup.rb', line 12

def initialize(path, parent)
  @c = HTMLEntities.new
  @files = {}
  @parent = parent
  @xml = parent.xml
  @isodoc = parent.isodoc
  @path = path
  @compile = parent.compile
  @documents = parent.documents
  read_files
end

Instance Method Details

#add_document_suffix(identifier, doc) ⇒ Object



145
146
147
148
149
150
151
# File 'lib/metanorma/files_lookup.rb', line 145

def add_document_suffix(identifier, doc)
  document_suffix = Metanorma::Utils::to_ncname(identifier)
  Metanorma::Utils::anchor_attributes.each do |(tag_name, attribute_name)|
    add_suffix_to_attributes(doc, document_suffix, tag_name, attribute_name)
  end
  url_in_css_styles(doc, document_suffix)
end

#add_section_splitObject



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/metanorma/files_lookup.rb', line 58

def add_section_split
    #require "debug"; binding.b
  ret = @files.keys.each_with_object({}) do |k, m|
    if @files[k][:sectionsplit] == "true" && !@files[k]["attachment"]
      s, manifest = sectionsplit(@files[k][:ref])
      s.each_with_index do |f1, i|
        add_section_split_instance(f1, m, k, i)
      end
      m["#{k}:index.html"] = add_section_split_cover(manifest, k)
    end
    m[k] = @files[k]
    #require "debug"; binding.b
  end
  @files = ret
end

#add_section_split_cover(manifest, ident) ⇒ Object



74
75
76
77
78
79
# File 'lib/metanorma/files_lookup.rb', line 74

def add_section_split_cover(manifest, ident)
  cover = section_split_cover(manifest, @parent.dir_name_cleanse(ident))
  @files[ident][:out_path] = cover
  { attachment: true, index: false, out_path: cover,
    ref: File.join(File.dirname(manifest.file), cover) }
end

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



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/metanorma/files_lookup.rb', line 95

def add_section_split_instance(file, manifest, key, idx)
  presfile = File.join(File.dirname(@files[key][:ref]),
                       File.basename(file[:url]))
  newkey = key("#{key.strip} #{file[:title]}")
  manifest[newkey] =
    { parentid: key, presentationxml: true, type: "fileref",
      rel_path: file[:url], out_path: File.basename(file[:url]),
      anchors: read_anchors(Nokogiri::XML(File.read(presfile))),
      bibdata: @files[key][:bibdata], ref: presfile }
  manifest[newkey][:bare] = true unless idx.zero?
end

#add_suffix_to_attributes(doc, suffix, tag_name, attribute_name) ⇒ Object



138
139
140
141
142
143
# File 'lib/metanorma/files_lookup.rb', line 138

def add_suffix_to_attributes(doc, suffix, tag_name, attribute_name)
  doc.xpath(ns("//#{tag_name}[@#{attribute_name}]")).each do |elem|
    elem.attributes[attribute_name].value =
      "#{elem.attributes[attribute_name].value}_#{suffix}"
  end
end

#bibdata_process(entry, identifier) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/metanorma/files_lookup.rb', line 38

def bibdata_process(entry, identifier)
  if entry[:attachment]
    entry[:bibdata] = Metanorma::Document
      .attachment_bibitem(identifier).root
  else
    file, _filename = targetfile(entry, read: true)
    xml = Nokogiri::XML(file)
    add_document_suffix(identifier, xml)
    entry[:anchors] = read_anchors(xml)
    entry[:bibdata] = xml.at(ns("//bibdata"))
  end
end

#bibitem_process(entry) ⇒ Object



51
52
53
54
55
56
# File 'lib/metanorma/files_lookup.rb', line 51

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

#eachObject



243
244
245
# File 'lib/metanorma/files_lookup.rb', line 243

def each
  @files.each
end

#each_with_indexObject



247
248
249
# File 'lib/metanorma/files_lookup.rb', line 247

def each_with_index
  @files.each_with_index
end

#file_entry(ref, identifier) ⇒ Object

rel_path is the source file address, determined relative to the YAML. out_path is the destination file address, with any references outside the working directory (../../…) truncated identifier is the id with only spaces, no nbsp



125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/metanorma/files_lookup.rb', line 125

def file_entry(ref, identifier)
  out = ref["attachment"] ? ref["fileref"] : File.basename(ref["fileref"])
  ret = if ref["fileref"]
          { type: "fileref", ref: @documents[identifier].file,
            rel_path: ref["fileref"], out_path: out }
        else { type: "id", ref: ref["id"] } end
  %w(attachment sectionsplit index presentation-xml
     bare-after-first).each do |s|
    ret[s.gsub("-", "").to_sym] = ref[s] if ref[s]
  end
  ret.compact
end

#get(ident, attr = nil) ⇒ Object



231
232
233
234
235
236
237
# File 'lib/metanorma/files_lookup.rb', line 231

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

#key(ident) ⇒ Object



223
224
225
# File 'lib/metanorma/files_lookup.rb', line 223

def key(ident)
  @c.decode(ident).gsub(/(\s|[ ])+/, " ")
end

#keysObject



227
228
229
# File 'lib/metanorma/files_lookup.rb', line 227

def keys
  @files.keys
end

#ns(xpath) ⇒ Object



251
252
253
# File 'lib/metanorma/files_lookup.rb', line 251

def ns(xpath)
  @isodoc.ns(xpath)
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.



203
204
205
206
207
208
209
210
# File 'lib/metanorma/files_lookup.rb', line 203

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



212
213
214
215
216
217
218
219
220
221
# File 'lib/metanorma/files_lookup.rb', line 212

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]
          end
  ret[val[:type]][index] = key
  ret[val[:type]][val[:value]] = key if val[:value]
end

#read_file(docref) ⇒ Object



29
30
31
32
33
34
35
36
# File 'lib/metanorma/files_lookup.rb', line 29

def read_file(docref)
  ident = docref.at(ns("./identifier"))
  i = key(@isodoc.docid_prefix(ident["type"], ident.children.to_xml))
  entry = file_entry(docref, ident.children.to_xml)
  bibdata_process(entry, i)
  bibitem_process(entry)
  @files[i] = entry
end

#read_filesObject



24
25
26
27
# File 'lib/metanorma/files_lookup.rb', line 24

def read_files
  @xml.xpath(ns("//docref")).each { |d| read_file(d) }
  add_section_split
end

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



184
185
186
187
188
189
# File 'lib/metanorma/files_lookup.rb', line 184

def ref_file(ref, out, read, doc)
  file = File.read(ref, encoding: "utf-8") if read
  filename = out.dup
  filename.sub!(/\.xml$/, ".html") if doc
  [file, filename]
end

#section_split_cover(col, ident) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/metanorma/files_lookup.rb', line 81

def section_split_cover(col, ident)
  dir = File.dirname(col.file)
  @compile.collection_setup(nil, dir)
  #require "debug";binding.b
  CollectionRenderer.new(col, dir,
                         output_folder: "#{ident}_collection",
                         format: %i(html),
                         coverpage: File.join(dir, "cover.html")).coverpage
  FileUtils.mv "#{ident}_collection/index.html",
               File.join(dir, "#{ident}_index.html")
  FileUtils.rm_rf "#{ident}_collection"
  "#{ident}_index.html"
end

#sectionsplit(file) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/metanorma/files_lookup.rb', line 107

def sectionsplit(file)
  #require "debug"; binding.b
  @compile.compile(
    file, { format: :asciidoc, extension_keys: [:presentation] }
    .merge(@parent.compile_options)
  )
  r = file.sub(/\.xml$/, ".presentation.xml")
  xml = Nokogiri::XML(File.read(r))
  s = @compile.sectionsplit(xml, File.basename(r), File.dirname(r))
    .sort_by { |f| f[:order] }
  [s, @compile.collection_manifest(File.basename(r), s, xml, nil,
                                   File.dirname(r))]
end

#set(ident, attr, value) ⇒ Object



239
240
241
# File 'lib/metanorma/files_lookup.rb', line 239

def set(ident, attr, value)
  @files[key(ident)][attr] = value
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:

  • (Array<String, nil>)


170
171
172
173
174
175
176
177
178
# File 'lib/metanorma/files_lookup.rb', line 170

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[:out_path], options[:read], options[:doc]
  else
    xml_file data[:id], options[:read]
  end
end

#targetfile_id(ident, options) ⇒ Object



180
181
182
# File 'lib/metanorma/files_lookup.rb', line 180

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

#url_in_css_styles(doc, document_suffix) ⇒ Object

update relative URLs, url(#…), in CSS in @style attrs (including SVG)



154
155
156
157
158
159
# File 'lib/metanorma/files_lookup.rb', line 154

def url_in_css_styles(doc, document_suffix)
  doc.xpath("//*[@style]").each do |s|
    s["style"] = s["style"]
      .gsub(%r{url\(#([^)]+)\)}, "url(#\\1_#{document_suffix})")
  end
end

#xml_file(id, read) ⇒ Object



191
192
193
194
195
# File 'lib/metanorma/files_lookup.rb', line 191

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