module Metanorma::Utils
Constants
- NAMECHAR
- NAMESTARTCHAR
- SVG_NS
- VERSION
Public Class Methods
anchor_or_uuid(node = nil)
click to toggle source
# File lib/utils/main.rb, line 29 def anchor_or_uuid(node = nil) uuid = UUIDTools::UUID.random_create node.nil? || node.id.nil? || node.id.empty? ? "_#{uuid}" : node.id end
asciidoc_sub(text, flavour = :standoc)
click to toggle source
# File lib/utils/main.rb, line 34 def asciidoc_sub(text, flavour = :standoc) return nil if text.nil? return "" if text.empty? d = Asciidoctor::Document.new( text.lines.entries, { header_footer: false, backend: flavour }, ) b = d.parse.blocks.first b.apply_subs(b.source) end
datauri(uri, localdirectory = ".")
click to toggle source
sources/plantuml/plantuml20200524-90467-1iqek5i.png already includes localdir
# File lib/utils/image.rb, line 127 def datauri(uri, localdirectory = ".") return uri if /^data:/.match?(uri) path = datauri_path(uri, localdirectory) return path unless File.exist?(path) types = MIME::Types.type_for(path) type = types ? types.first.to_s : 'text/plain; charset="utf-8"' bin = File.open(path, "rb", &:read) data = Base64.strict_encode64(bin) "data:#{type};base64,#{data}" end
datauri2mime(uri)
click to toggle source
# File lib/utils/image.rb, line 152 def datauri2mime(uri) %r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri type = nil imgtype = "png" unless /^[a-z0-9]+$/.match? imgtype ::Tempfile.open(["imageuri", ".#{imgtype}"]) do |file| type = datauri2mime1(file, imgdata) end [type] end
datauri2mime1(file, imgdata)
click to toggle source
# File lib/utils/image.rb, line 162 def datauri2mime1(file, imgdata) type = nil begin file.binmode file.write(Base64.strict_decode64(imgdata)) file.rewind type = Marcel::MimeType.for file ensure file.close! end type end
datauri_path(uri, localdirectory)
click to toggle source
# File lib/utils/image.rb, line 140 def datauri_path(uri, localdirectory) path = if %r{^([A-Z]:)?/}.match?(uri) then uri else File.exist?(uri) ? uri : File.join(localdirectory, uri) end unless File.exist?(path) warn "image at #{path} not found" return uri end path end
endash_date(elem)
click to toggle source
# File lib/utils/main.rb, line 58 def endash_date(elem) elem.traverse do |n| next unless n.text? n.replace(n.text.gsub(/\s+--?\s+/, "–").gsub(/--/, "–")) end end
flatten_rawtext(node)
click to toggle source
not currently used if node contains blocks, flatten them into a single line; and extract only raw text
# File lib/utils/main.rb, line 127 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
flatten_rawtext_lines(node, result)
click to toggle source
not currently used
# File lib/utils/main.rb, line 111 def flatten_rawtext_lines(node, result) node.lines.each do |x| result << if node.respond_to?(:context) && (node.context == :literal || node.context == :listing) x.gsub(/</, "<").gsub(/>/, ">") else # strip not only HTML <tag>, and Asciidoc xrefs <<xref>> x.gsub(/<[^>]*>+/, "") end end result end
localdir(node)
click to toggle source
# File lib/utils/main.rb, line 46 def localdir(node) docfile = node.attr("docfile") docfile.nil? ? "./" : "#{Pathname.new(docfile).parent}/" end
save_dataimage(uri)
click to toggle source
# File lib/utils/image.rb, line 25 def save_dataimage(uri) %r{^data:(image|application)/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri imgtype.sub!(/\+[a-z0-9]+$/, "") # svg+xml imgtype = "png" unless /^[a-z0-9]+$/.match? imgtype Tempfile.open(["image", ".#{imgtype}"]) do |f| f.binmode f.write(Base64.strict_decode64(imgdata)) f.path end end
set_nested_value(hash, keys, new_val)
click to toggle source
Set hash value using keys path mod from stackoverflow.com/a/42425884
# File lib/utils/main.rb, line 68 def set_nested_value(hash, keys, new_val) key = keys[0] if keys.length == 1 hash[key] = if hash[key].is_a?(Array) (hash[key] << new_val) else hash[key].nil? ? new_val : [hash[key], new_val] end elsif 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 hash end
smartformat(text)
click to toggle source
TODO needs internationalisation
# File lib/utils/main.rb, line 52 def smartformat(text) text.gsub(/ --? /, " — ") .gsub(/--/, "—").smart_format.gsub(/</, "<") .gsub(/>/, ">") end
strict_capitalize_first(str)
click to toggle source
# File lib/utils/main.rb, line 102 def strict_capitalize_first(str) str.split(/ /).each_with_index.map do |w, i| letters = w.chars letters.first.upcase! if i.zero? letters.join end.join(" ") end
strict_capitalize_phrase(str)
click to toggle source
# File lib/utils/main.rb, line 94 def strict_capitalize_phrase(str) str.split(/ /).map do |w| letters = w.chars letters.first.upcase! letters.join end.join(" ") end
svg_update_href(svgmap, svg, namespace)
click to toggle source
# File lib/utils/image.rb, line 77 def svg_update_href(svgmap, svg, namespace) targ = svgmap_rewrite1_targets(svgmap, namespace) svg.xpath(".//m:a", "m" => SVG_NS).each do |a| ["xlink:href", "href"].each do |p| a[p] and x = targ[File.expand_path(a[p])] and a[p] = x end end end
svg_update_ids(svg, idx)
click to toggle source
# File lib/utils/image.rb, line 97 def svg_update_ids(svg, idx) ids = svg.xpath("./@id | .//@id") .each_with_object([]) { |i, m| m << i.value } return if ids.empty? svg_update_ids_attrs(svg, ids, idx) svg_update_ids_css(svg, ids, idx) end
svg_update_ids_attrs(svg, ids, idx)
click to toggle source
# File lib/utils/image.rb, line 106 def svg_update_ids_attrs(svg, ids, idx) svg.xpath(". | .//*[@*]").each do |a| a.attribute_nodes.each do |x| ids.include?(x.value) and x.value += sprintf("_%09d", idx) end end end
svg_update_ids_css(svg, ids, idx)
click to toggle source
# File lib/utils/image.rb, line 114 def svg_update_ids_css(svg, ids, idx) svg.xpath("//m:style", "m" => SVG_NS).each do |s| c = s.children.to_xml ids.each do |i| c = c.gsub(%r[##{i}\b], sprintf("#%s_%09d", i, idx)) .gsub(%r(\[id\s*=\s*['"]?#{i}['"]?\]), sprintf("[id='%s_%09d']", i, idx)) end s.children = c end end
svgmap_rewrite(xmldoc, localdirectory = "")
click to toggle source
# File lib/utils/image.rb, line 38 def svgmap_rewrite(xmldoc, localdirectory = "") n = Namespace.new(xmldoc) xmldoc.xpath(n.ns("//svgmap")).each_with_index do |s, i| next unless svgmap_rewrite0(s, n, localdirectory, i) next if s.at(n.ns("./target/eref")) s.replace(s.at(n.ns("./figure"))) end end
svgmap_rewrite0(svgmap, namespace, localdirectory, idx)
click to toggle source
# File lib/utils/image.rb, line 48 def svgmap_rewrite0(svgmap, namespace, localdirectory, idx) if (i = svgmap.at(namespace.ns(".//image"))) && (src = i["src"]) path = svgmap_rewrite0_path(src, localdirectory) File.file?(path) or return false svg = Nokogiri::XML(File.read(path, encoding: "utf-8")) i.replace(svgmap_rewrite1(svgmap, svg.root, namespace, idx)) /^data:/.match(src) and i["src"] = datauri(path) elsif i = svgmap.at(".//m:svg", "m" => SVG_NS) i.replace(svgmap_rewrite1(svgmap, i, namespace, idx)) else return false end true end
svgmap_rewrite0_path(src, localdirectory)
click to toggle source
# File lib/utils/image.rb, line 62 def svgmap_rewrite0_path(src, localdirectory) if /^data:/.match?(src) save_dataimage(src) else File.file?(src) ? src : localdirectory + src end end
svgmap_rewrite1(svgmap, svg, namespace, idx)
click to toggle source
# File lib/utils/image.rb, line 70 def svgmap_rewrite1(svgmap, svg, namespace, idx) svg_update_href(svgmap, svg, namespace) svg_update_ids(svg, idx) svg.xpath("processing-instruction()|.//processing-instruction()").remove svg.to_xml end
svgmap_rewrite1_targets(svgmap, namespace)
click to toggle source
# File lib/utils/image.rb, line 86 def svgmap_rewrite1_targets(svgmap, namespace) svgmap.xpath(namespace.ns("./target")) .each_with_object({}) do |t, m| x = t.at(namespace.ns("./xref")) and m[File.expand_path(t["href"])] = "##{x['target']}" x = t.at(namespace.ns("./link")) and m[File.expand_path(t["href"])] = x["target"] t.remove if t.at(namespace.ns("./xref | ./link")) end end
to_ncname(tag, asciionly: true)
click to toggle source
# File lib/utils/main.rb, line 17 def to_ncname(tag, asciionly: true) asciionly and tag = HTMLEntities.new.encode(tag, :basic, :hexadecimal) start = tag[0] ret1 = if %r([#{NAMECHAR}#])o.match?(start) "_" else (%r([#{NAMESTARTCHAR}#])o.match?(start) ? "_#{start}" : start) end ret2 = tag[1..-1] || "" (ret1 || "") + ret2.gsub(%r([#{NAMECHAR}#])o, "_") end