module Metanorma::Utils
def anchor_or_uuid(node = nil)
def anchor_or_uuid(node = nil) uuid = UUIDTools::UUID.random_create node.nil? || node.id.nil? || node.id.empty? ? "_" + uuid : node.id end
def asciidoc_sub(x)
def asciidoc_sub(x) return nil if x.nil? return "" if x.empty? d = Asciidoctor::Document.new(x.lines.entries, { header_footer: false, backend: :html }) b = d.parse.blocks.first b.apply_subs(b.source) end
def endash_date(elem)
def endash_date(elem) elem.traverse do |n| n.text? and n.replace(n.text.gsub(/\s+--?\s+/, "–").gsub(/--/, "–")) end end
def flatten_rawtext(node)
if node contains blocks, flatten them into a single line;
not currently used
def flatten_rawtext(node) result = [] if node.respond_to?(:blocks) && node.blocks? node.blocks.each { |b| result << flatten_rawtext(b) } elsif node.respond_to?(:lines) result = flatten_rawtext_lines(node, result) elsif node.respond_to?(:text) result << node.text.gsub(/<[^>]*>+/, "") else result << node.content.gsub(/<[^>]*>+/, "") end result.reject(&:empty?) end
def flatten_rawtext_lines(node, result)
def flatten_rawtext_lines(node, result) node.lines.each do |x| if node.respond_to?(:context) && (node.context == :literal || node.context == :listing) result << x.gsub(/</, "<").gsub(/>/, ">") else # strip not only HTML <tag>, and Asciidoc xrefs <<xref>> result << x.gsub(/<[^>]*>+/, "") end end result end
def localdir(node)
def localdir(node) docfile = node.attr("docfile") docfile.nil? ? './' : Pathname.new(docfile).parent.to_s + '/' end
def set_nested_value(hash, keys, new_val)
Set hash value using keys path
def set_nested_value(hash, keys, new_val) key = keys[0] if keys.length == 1 hash[key] = hash[key].is_a?(Array) ? (hash[key] << new_val) : hash[key].nil? ? new_val : [hash[key], new_val] else if hash[key].is_a?(Array) hash[key][-1] = {} if !hash[key].empty? && hash[key][-1].nil? hash[key] << {} if hash[key].empty? || !hash[key][-1].is_a?(Hash) set_nested_value(hash[key][-1], keys[1..-1], new_val) elsif hash[key].nil? || hash[key].empty? hash[key] = {} set_nested_value(hash[key], keys[1..-1], new_val) elsif hash[key].is_a?(Hash) && !hash[key][keys[1]] set_nested_value(hash[key], keys[1..-1], new_val) elsif !hash[key][keys[1]] hash[key] = [hash[key], {}] set_nested_value(hash[key][-1], keys[1..-1], new_val) else set_nested_value(hash[key], keys[1..-1], new_val) end end hash end
def smartformat(n)
def smartformat(n) n.gsub(/ --? /, " — "). gsub(/--/, "—").smart_format.gsub(/</, "<").gsub(/>/, ">") end
def svgmap_rewrite(xmldoc, localdir = "")
def svgmap_rewrite(xmldoc, localdir = "") xmldoc.xpath("//svgmap").each do |s| next unless src = s.at(".//image/@src") path = File.file?(src) ? src : localdir + src File.file?(path) or next svg = Nokogiri::XML(File.read(path, encoding: "utf-8")) svgmap_rewrite1(s, svg, path) next if s.at("./target/eref") s.replace(s.at("./figure")) end end
def svgmap_rewrite1(s, svg, path)
def svgmap_rewrite1(s, svg, path) targets = s.xpath("./target").each_with_object({}) do |t, m| x = t.at("./xref") and m[t["href"]] = "##{x['target']}" x = t.at("./link") and m[t["href"]] = x['target'] t.remove if t.at("./xref | ./link") end svg.xpath(".//xmlns:a").each do |a| x = targets[a["xlink:href"]] and a["xlink:href"] = x end File.open(path, "w", encoding: "utf-8") { |f| f.write(svg.to_xml) } end
def to_ncname(s)
def to_ncname(s) start = s[0] ret1 = %r([#{NAMECHAR}#]).match(start) ? "_" : (%r([#{NAMESTARTCHAR}#]).match(start) ? "_#{start}" : start) ret2 = s[1..-1] || "" ret = (ret1 || "") + ret2.gsub(%r([#{NAMECHAR}#]), "_") ret end