Module: Asciidoctor::Diagram::SVG

Defined in:
lib/asciidoctor-diagram/util/svg.rb

Class Method Summary collapse

Class Method Details

.post_process_image(data, optimise) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/asciidoctor-diagram/util/svg.rb', line 8

def self.post_process_image(data, optimise)
  svg = REXML::Document.new(data)

  root = svg.root

  unless root.attributes['xmlns']
    root.add_attribute('xmlns', 'http://www.w3.org/2000/svg')
  end

  unless root.attributes['preserveAspectRatio']
    root.add_attribute('preserveAspectRatio', 'xMidYMid meet')
  end

  width = nil
  height = nil

  if (w = WIDTH_HEIGHT_REGEX.match(root.attributes['width'])) && (h = WIDTH_HEIGHT_REGEX.match(root.attributes['height']))
    width = to_numeric(w[:value]) * to_px_factor(w[:unit])
    height = to_numeric(h[:value]) * to_px_factor(h[:unit])
  end

  viewbox = root.attributes['viewBox']
  if (v = VIEWBOX_REGEX.match(viewbox)) && width.nil? && height.nil?
    min_x = to_numeric(v[:min_x])
    min_y = to_numeric(v[:min_y])
    width ||= to_numeric(v[:width]) - min_x
    height ||= to_numeric(v[:height]) - min_y
  end

  if viewbox.nil? && width && height
    root.add_attribute('viewBox', "0 0 #{width.to_s} #{height.to_s}")
  end

  indent = 2
  if optimise
    remove_comments(svg)
    indent = -1
  end

  patched_svg = ""
  svg.write(:output => patched_svg, :indent => indent, :transitive => true)

  [patched_svg, width, height]
end

.remove_comments(parent) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/asciidoctor-diagram/util/svg.rb', line 55

def self.remove_comments(parent)
  comments = []

  parent.each do |child|
    case child
      when REXML::Comment
        comments << child
      when REXML::Parent
        remove_comments(child)
    end
  end

  comments.each do |c|
    c.remove
  end
end

.to_numeric(text) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/asciidoctor-diagram/util/svg.rb', line 72

def self.to_numeric(text)
  if text.include? '.'
    text.to_f
  else
    text.to_i
  end
end

.to_px_factor(unit) ⇒ Object



83
84
85
86
87
88
89
90
# File 'lib/asciidoctor-diagram/util/svg.rb', line 83

def self.to_px_factor(unit)
  case unit
    when 'pt'
      1.33
    else
      1
  end
end