module Metanorma class Collection class Renderer # @param elm [Nokogiri::XML::Element] # @return [String] def indexfile_title(entry) if entry.bibdata && x = entry.bibdata.title.detect { |t| t.type == "main" } || entry.bibdata.title.first x.title.content else entry.title end end # uses the identifier to label documents; other attributes (title) can be # looked up in @files[id][:bibdata] # # @param mnf [Collection::Manifest] # @param builder [Nokogiri::XML::Builder] def indexfile_docref(mnf, builder) Array(mnf.entry).detect(&:index) or return "" builder.ul { |b| docrefs(mnf, b) } end def docrefs(mnf, builder) ident = docref_ident(mnf) builder.li do |li| li.a href: index_link(mnf, ident) do |a| a << ident.split(/([<>&])/).map do |x| /[<>&]/.match?(x) ? x : @c.encode(x, :hexadecimal) end.join end end end def docref_ident(docref) ident = docref.identifier.dup @c.decode(@isodoc.docid_prefix(nil, ident)) end def index_link(docref, ident) if docref.file @files.get(ident, :out_path).sub(/\.xml$/, ".html") else "#{docref.id}.html" end end # single level navigation list, with hierarchical nesting def indexfile(mnf) mnfs = Array(mnf) mnfs.empty? and return "" mnfs.map { |m| "" }.join("\n") end def index?(mnf) mnf.index and return true mnf.entry.detect { |e| index?(e) } end def indexfile1(mnf) index?(mnf) or return "" cleanup_indexfile1(build_indexfile1(mnf)) end def build_indexfile1(mnf) Nokogiri::HTML::Builder.new do |b| if mnf.file then docrefs(mnf, b) else b.li do |l| l << indexfile_title(mnf) l.ul do |u| Array(mnf.entry).each { |e| u << indexfile1(e) } end end end end end def cleanup_indexfile1(ret) ret = ret.doc.root ret.xpath("/ul").each do |u| if u.at("./li/ul") && !u.at("./li[text()]") u.replace(u.xpath("./li/ul")) end end ret.to_html end # object to construct navigation out of in Liquid def index_object(mnf) mnf = Array(mnf).first ret = { title: indexfile_title(mnf), level: mnf.type, docrefs: index_object_docrefs(mnf), children: index_object_children(mnf) }.compact ret.keys == [:children] and ret = ret[:children] ret end def index_object_children(mnf) nonfiles = Array(mnf.entry).reject(&:file) c = nonfiles.each_with_object([]) do |d, b| b << index_object(d) end.flatten c.empty? and c = nil c end def index_object_docrefs(mnf) files = Array(mnf.entry).select(&:file) files.empty? and return nil r = Nokogiri::HTML::Builder.new do |b| b.ul do |u| files.each { |f| docrefs(f, u) } end end r.doc.root&.to_html&.gsub("\n", " ") end def liquid_docrefs(mnfs) Array(mnfs).select(&:index).each_with_object([]) do |d, m| if d.file ident = @c.decode(@isodoc.docid_prefix(nil, d.identifier.dup)) m << { "identifier" => ident, "file" => index_link(d, ident), "title" => indexfile_title(d), "level" => d.type } else liquid_docrefs(d.entry).each { |m1| m << m1 } end end end end end end