module IsoDoc::Function
module Utils
def date_range(date)
self.class.date_range(date)
end
def ns(xpath)
self.class.ns(xpath)
end
def insert_tab(out, n)
[1..n].each { out << " " }
end
# add namespaces for Word fragments
NOKOHEAD = <<~HERE.freeze
HERE
# block for processing XML document fragments as XHTML,
# to allow for HTMLentities
def noko(&block)
doc = ::Nokogiri::XML.parse(NOKOHEAD)
fragment = doc.fragment("")
::Nokogiri::XML::Builder.with fragment, &block
fragment.to_xml(encoding: "US-ASCII").lines.map do |l|
l.gsub(/\s*\n/, "")
end
end
def attr_code(attributes)
attributes = attributes.reject { |_, val| val.nil? }.map
attributes.map do |k, v|
[k, (v.is_a? String) ? HTMLEntities.new.decode(v) : v]
end.to_h
end
DOCTYPE_HDR = ''.freeze
def to_xhtml(xml)
xml.gsub!(/<\?xml[^>]*>/, "")
/}, " ").sub(/<\/?h[123456][^>]*>/, "")
h1 = to_xhtml_fragment(h.dup)
h1.traverse do |x|
x.replace(" ") if x.name == "span" && /mso-tab-count/.match(x["style"])
x.remove if x.name == "span" && x["class"] == "MsoCommentReference"
x.remove if x.name == "a" && x["epub:type"] == "footnote"
x.remove if x.name == "span" && /mso-bookmark/.match(x["style"])
x.replace(x.children) if x.name == "a"
end
from_xhtml(h1)
end
def liquid(doc)
self.class.liquid(doc)
end
def liquid(doc)
# unescape HTML escapes in doc
doc = doc.split(%r<(\{%|%\})>).each_slice(4).map do |a|
a[2] = a[2].gsub(/\</, "<").gsub(/\>/, ">") if a.size > 2
a.join("")
end.join("")
Liquid::Template.parse(doc)
end
def empty2nil(v)
return nil if !v.nil? && v.is_a?(String) && v.empty?
v
end
def populate_template(docxml, _format)
meta = @meta.get.merge(@labels || {})
template = liquid(docxml)
template.render(meta.map { |k, v| [k.to_s, empty2nil(v)] }.to_h).
gsub('<', '<').gsub('>', '>').gsub('&', '&')
end
def save_dataimage(uri, relative_dir = true)
%r{^data:image/(?[^;]+);base64,(?.+)$} =~ uri
imgtype = "png" unless /^[a-z0-9]+$/.match imgtype
Tempfile.open(["image", ".#{imgtype}"]) do |f|
f.binmode
f.write(Base64.strict_decode64(imgdata))
@tempfile_cache << f #persist to the end
f.path
end
end
def image_localfile(i)
if /^data:image/.match i["src"]
save_dataimage(i["src"], false)
elsif %r{^([A-Z]:)?/}.match i["src"]
i["src"]
else
File.join(@localdir, i["src"])
end
end
def labelled_ancestor(node)
return !node.ancestors("example, requirement, recommendation, permission, "\
"table, figure, sourcecode").empty?
end
end
end