Module: Metanorma::Utils

Defined in:
lib/utils/log.rb,
lib/utils/main.rb,
lib/utils/version.rb

Defined Under Namespace

Classes: Log, Namespace

Constant Summary collapse

NAMECHAR =
"\u0000-\u0022\u0024\u002c\u002f\u003a-\u0040\\u005b-\u005e"\
"\u0060\u007b-\u00b6\u00b8-\u00bf\u00d7\u00f7\u037e\u2000-\u200b"\
"\u200e-\u203e\u2041-\u206f\u2190-\u2bff\u2ff0-\u3000".freeze
NAMESTARTCHAR =

“ud800-uf8ffufdd0-ufdefufffe-uffff”.freeze

"\\u002d\u002e\u0030-\u0039\u00b7\u0300-\u036f"\
"\u203f-\u2040".freeze
VERSION =
"1.0.5".freeze

Class Method Summary collapse

Class Method Details

.anchor_or_uuid(node = nil) ⇒ Object



28
29
30
31
# File 'lib/utils/main.rb', line 28

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(x) ⇒ Object



33
34
35
36
37
38
39
# File 'lib/utils/main.rb', line 33

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

.datauri(uri, localdir = ".") ⇒ Object

FIXME: nested uri path error(

sources/plantuml/plantuml20200524-90467-1iqek5i.png ->
sources/sources/plantuml/plantuml20200524-90467-1iqek5i.png)


169
170
171
172
173
174
175
176
177
# File 'lib/utils/main.rb', line 169

def datauri(uri, localdir = ".")
  return uri if /^data:/.match(uri)
  path = %r{^([A-Z]:)?/}.match?(uri) ? uri : File.join(localdir, uri)
  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) ⇒ Object



179
180
181
182
183
184
185
186
187
# File 'lib/utils/main.rb', line 179

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) ⇒ Object



189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/utils/main.rb', line 189

def datauri2mime1(file, imgdata)
  type = nil
  begin
    file.binmode
    file.write(Base64.strict_decode64(imgdata))
    file.rewind
    type = MimeMagic.by_magic(file)
  ensure
    file.close!
  end
  type
end

.endash_date(elem) ⇒ Object



52
53
54
55
56
# File 'lib/utils/main.rb', line 52

def endash_date(elem)
  elem.traverse do |n|
    n.text? and n.replace(n.text.gsub(/\s+--?\s+/, "&#8211;").gsub(/--/, "&#8211;"))
  end
end

.flatten_rawtext(node) ⇒ Object

not currently used if node contains blocks, flatten them into a single line; and extract only raw text



152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/utils/main.rb', line 152

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) ⇒ Object

not currently used



137
138
139
140
141
142
143
144
145
146
147
# File 'lib/utils/main.rb', line 137

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(/</, "&lt;").gsub(/>/, "&gt;")
    else
      # strip not only HTML <tag>, and Asciidoc xrefs <<xref>>
      result << x.gsub(/<[^>]*>+/, "")
    end
  end
  result
end

.localdir(node) ⇒ Object



41
42
43
44
# File 'lib/utils/main.rb', line 41

def localdir(node)
  docfile = node.attr("docfile")
  docfile.nil? ? './' : Pathname.new(docfile).parent.to_s + '/'
end

.save_dataimage(uri) ⇒ Object



99
100
101
102
103
104
105
106
107
108
# File 'lib/utils/main.rb', line 99

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) ⇒ Object

Set hash value using keys path mod from stackoverflow.com/a/42425884



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/utils/main.rb', line 60

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

.smartformat(n) ⇒ Object

TODO needs internationalisation



47
48
49
50
# File 'lib/utils/main.rb', line 47

def smartformat(n)
  n.gsub(/ --? /, "&#8201;&#8212;&#8201;").
    gsub(/--/, "&#8212;").smart_format.gsub(/</, "&lt;").gsub(/>/, "&gt;")
end

.svgmap_rewrite(xmldoc, localdir = "") ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/utils/main.rb', line 110

def svgmap_rewrite(xmldoc, localdir = "")
  n = Namespace.new(xmldoc)
  xmldoc.xpath(n.ns("//svgmap")).each do |s|
    next unless i = s.at(n.ns(".//image")) and src = i["src"]
    path = /^data:/.match(src) ? save_dataimage(src) : 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, n)
    /^data:/.match(src) and i["src"] = datauri(path)
    next if s.at(n.ns("./target/eref"))
    s.replace(s.at(n.ns("./figure")))
  end
end

.svgmap_rewrite1(s, svg, path, n) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
# File 'lib/utils/main.rb', line 124

def svgmap_rewrite1(s, svg, path, n)
  targets = s.xpath(n.ns("./target")).each_with_object({}) do |t, m|
    x = t.at(n.ns("./xref")) and m[t["href"]] = "##{x['target']}"
    x = t.at(n.ns("./link")) and m[t["href"]] = x['target']
    t.remove if t.at(n.ns("./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

.to_ncname(s) ⇒ Object



19
20
21
22
23
24
25
26
# File 'lib/utils/main.rb', line 19

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