prawn-svg 0.23.0 → 0.23.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0455251b1d5e7c430660f51c4843d26adb8d9913
4
- data.tar.gz: caf87db1d427b7b528b5ae09b826b4dddec7a8a0
3
+ metadata.gz: 6f44a25b66d4e198d2f841ad98d277200cec4296
4
+ data.tar.gz: 6ce1562107ec65b0d8453826401c894dac0bb57b
5
5
  SHA512:
6
- metadata.gz: e1068767350107317ce264382ead9432a8ca98118d82301a402ef5fb50f6da65bdc2f547101955911cd24cf291745dd3f7b55f51d2374c96b9442673833df638
7
- data.tar.gz: 47b83cd0def9edaec474ec458fa01831801abefadeebe797840b64bd7b3b2f38ff869e135893bb16a9f23b6a9fea28ab46c9f843775fa1c3f72bcd11964d8b33
6
+ metadata.gz: 5646e98d81e04aabeca34ae15444c7a6f9f210bae25e3217ee411a479c861544f43521fcafe272f3bdcc774a99b19327b5446857de6c633b7605fa86e98e3937
7
+ data.tar.gz: 266cb1f5721dfd3cc363650c9bd27a601e52f76f79f672e2da0d04ca97ed505fb9a03d50f6f3bbfacfd768ca92153b01e49a1062ad748aee9c20b724435e118c
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  An SVG renderer for the Prawn PDF library.
7
7
 
8
- This will take an SVG file as input and render it into your PDF. Find out more about the Prawn PDF library at:
8
+ This will take an SVG document as input and render it into your PDF. Find out more about the Prawn PDF library at:
9
9
 
10
10
  http://github.com/prawnpdf/prawn
11
11
 
data/lib/prawn-svg.rb CHANGED
@@ -3,6 +3,8 @@ require 'rexml/document'
3
3
  require 'prawn'
4
4
  require 'prawn/svg/version'
5
5
 
6
+ require 'css_parser'
7
+
6
8
  require 'prawn/svg/font_registry'
7
9
  require 'prawn/svg/calculators/aspect_ratio'
8
10
  require 'prawn/svg/calculators/document_sizing'
@@ -2,13 +2,6 @@ class Prawn::SVG::Document
2
2
  Error = Class.new(StandardError)
3
3
  InvalidSVGData = Class.new(Error)
4
4
 
5
- begin
6
- require 'css_parser'
7
- CSS_PARSER_LOADED = true
8
- rescue LoadError
9
- CSS_PARSER_LOADED = false
10
- end
11
-
12
5
  DEFAULT_FALLBACK_FONT_NAME = "Times-Roman"
13
6
 
14
7
  # An +Array+ of warnings that occurred while parsing the SVG data.
@@ -22,8 +15,6 @@ class Prawn::SVG::Document
22
15
  :css_parser, :elements_by_id, :gradients
23
16
 
24
17
  def initialize(data, bounds, options, font_registry: nil)
25
- @css_parser = CssParser::Parser.new if CSS_PARSER_LOADED
26
-
27
18
  @root = REXML::Document.new(data).root
28
19
 
29
20
  if @root.nil?
@@ -54,6 +45,8 @@ class Prawn::SVG::Document
54
45
 
55
46
  @axis_to_size = {:x => sizing.viewport_width, :y => sizing.viewport_height}
56
47
 
48
+ @css_parser = CssParser::Parser.new
49
+
57
50
  yield self if block_given?
58
51
  end
59
52
 
@@ -20,7 +20,7 @@ class Prawn::SVG::Font
20
20
  end
21
21
  end
22
22
 
23
- def initialize(name, weight, style, font_registry: font_registry)
23
+ def initialize(name, weight, style, font_registry: nil)
24
24
  name = GENERIC_CSS_FONT_MAPPING.fetch(name, name) # If it's a standard CSS font name, map it to one of the standard PDF fonts.
25
25
 
26
26
  @font_registry = font_registry
@@ -1,8 +1,33 @@
1
+ #
2
+ # Load a file from disk.
3
+ #
4
+ # WINDOWS
5
+ # =======
6
+ # Windows is supported, but must use URLs in the modern structure like:
7
+ # file:///x:/path/to/the/file.png
8
+ # or as a relative path:
9
+ # directory/file.png
10
+ # or as an absolute path from the current drive:
11
+ # /path/to/the/file.png
12
+ #
13
+ # Ruby's URI parser does not like backslashes, nor can it handle filenames as URLs starting
14
+ # with a drive letter as it thinks you're giving it a scheme.
15
+ #
16
+ # URL ENCODING
17
+ # ============
18
+ # This module assumes the URL that is passed in has been URL-encoded. If for some reason
19
+ # you're passing in a filename that hasn't been taken from an XML document's attribute,
20
+ # you will want to URL encode it before you pass it in.
21
+ #
1
22
  module Prawn::SVG::Loaders
2
23
  class File
3
24
  attr_reader :root_path
4
25
 
5
26
  def initialize(root_path)
27
+ if root_path.empty?
28
+ raise ArgumentError, "An empty string is not a valid root path. Use '.' if you want the current working directory."
29
+ end
30
+
6
31
  @root_path = ::File.expand_path(root_path)
7
32
 
8
33
  raise ArgumentError, "#{root_path} is not a directory" unless Dir.exist?(@root_path)
@@ -12,19 +37,20 @@ module Prawn::SVG::Loaders
12
37
  uri = build_uri(url)
13
38
 
14
39
  if uri && uri.scheme.nil? && uri.path
15
- path = build_absolute_path(uri.path)
16
- load_file(path)
40
+ load_file(uri.path)
17
41
 
18
42
  elsif uri && uri.scheme == 'file'
19
43
  assert_valid_file_uri!(uri)
20
- load_file(uri.path)
44
+ path = windows? ? fix_windows_path(uri.path) : uri.path
45
+ load_file(path)
21
46
  end
22
47
  end
23
48
 
24
49
  private
25
50
 
26
51
  def load_file(path)
27
- path = ::File.expand_path(path)
52
+ path = URI.decode(path)
53
+ path = build_absolute_and_expand_path(path)
28
54
  assert_valid_path!(path)
29
55
  assert_file_exists!(path)
30
56
  IO.read(path)
@@ -38,17 +64,17 @@ module Prawn::SVG::Loaders
38
64
  end
39
65
 
40
66
  def assert_valid_path!(path)
41
- if !path.start_with?("#{root_path}/")
67
+ # TODO : case sensitive comparison, but it's going to be a bit of a headache
68
+ # making it dependent on whether the file system is case sensitive or not.
69
+ # Leaving it like this until it's a problem for someone.
70
+
71
+ if !path.start_with?("#{root_path}#{::File::SEPARATOR}")
42
72
  raise Prawn::SVG::UrlLoader::Error, "file path is not inside the root path of #{root_path}"
43
73
  end
44
74
  end
45
75
 
46
- def build_absolute_path(path)
47
- if path[0] == "/"
48
- path
49
- else
50
- "#{root_path}/#{path}"
51
- end
76
+ def build_absolute_and_expand_path(path)
77
+ ::File.expand_path(path, root_path)
52
78
  end
53
79
 
54
80
  def assert_valid_file_uri!(uri)
@@ -62,5 +88,17 @@ module Prawn::SVG::Loaders
62
88
  raise Prawn::SVG::UrlLoader::Error, "File #{path} does not exist"
63
89
  end
64
90
  end
91
+
92
+ def fix_windows_path(path)
93
+ if matches = path.match(%r(\A/[a-z]:/)i)
94
+ path[1..-1]
95
+ else
96
+ path
97
+ end
98
+ end
99
+
100
+ def windows?
101
+ !!(RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/)
102
+ end
65
103
  end
66
104
  end
@@ -1,5 +1,5 @@
1
1
  module Prawn
2
2
  module SVG
3
- VERSION = '0.23.0'
3
+ VERSION = '0.23.1'
4
4
  end
5
5
  end
@@ -2,8 +2,10 @@ require 'spec_helper'
2
2
 
3
3
  RSpec.describe Prawn::SVG::Loaders::File do
4
4
  let(:root_path) { "." }
5
+ let(:fake_root_path) { "/some" }
5
6
 
6
- subject { Prawn::SVG::Loaders::File.new(root_path).from_url(url) }
7
+ let(:file_loader) { Prawn::SVG::Loaders::File.new(root_path) }
8
+ subject { file_loader.from_url(url) }
7
9
 
8
10
  context "when an invalid path is supplied" do
9
11
  let(:root_path) { "/does/not/exist" }
@@ -14,15 +16,15 @@ RSpec.describe Prawn::SVG::Loaders::File do
14
16
  end
15
17
 
16
18
  context "when a relative path is supplied" do
17
- let(:url) { "some/relative/./path" }
19
+ let(:url) { "relative/./path" }
18
20
 
19
21
  it "loads the file" do
20
- expect(File).to receive(:expand_path).with(".").and_return("/our/root/path")
21
- expect(File).to receive(:expand_path).with("/our/root/path/some/relative/./path").and_return("/our/root/path/some/relative/path")
22
+ expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
23
+ expect(File).to receive(:expand_path).with("relative/./path", fake_root_path).and_return("#{fake_root_path}/relative/path")
22
24
 
23
- expect(Dir).to receive(:exist?).with("/our/root/path").and_return(true)
24
- expect(File).to receive(:exist?).with("/our/root/path/some/relative/path").and_return(true)
25
- expect(IO).to receive(:read).with("/our/root/path/some/relative/path").and_return("data")
25
+ expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
26
+ expect(File).to receive(:exist?).with("#{fake_root_path}/relative/path").and_return(true)
27
+ expect(IO).to receive(:read).with("#{fake_root_path}/relative/path").and_return("data")
26
28
 
27
29
  expect(subject).to eq 'data'
28
30
  end
@@ -32,10 +34,10 @@ RSpec.describe Prawn::SVG::Loaders::File do
32
34
  let(:url) { "/some/absolute/./path" }
33
35
 
34
36
  it "loads the file" do
35
- expect(File).to receive(:expand_path).with(".").and_return("/some")
36
- expect(File).to receive(:expand_path).with(url).and_return("/some/absolute/path")
37
+ expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
38
+ expect(File).to receive(:expand_path).with(url, fake_root_path).and_return("/some/absolute/path")
37
39
 
38
- expect(Dir).to receive(:exist?).with("/some").and_return(true)
40
+ expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
39
41
  expect(File).to receive(:exist?).with("/some/absolute/path").and_return(true)
40
42
  expect(IO).to receive(:read).with("/some/absolute/path").and_return("data")
41
43
 
@@ -44,28 +46,28 @@ RSpec.describe Prawn::SVG::Loaders::File do
44
46
  end
45
47
 
46
48
  context "when an absolute path with file scheme is supplied" do
47
- let(:url) { "file:///some/absolute/./path" }
49
+ let(:url) { "file:///some/absolute/./path%20name" }
48
50
 
49
51
  it "loads the file" do
50
- expect(File).to receive(:expand_path).with(".").and_return("/some")
51
- expect(File).to receive(:expand_path).with("/some/absolute/./path").and_return("/some/absolute/path")
52
+ expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
53
+ expect(File).to receive(:expand_path).with("/some/absolute/./path name", fake_root_path).and_return("/some/absolute/path name")
52
54
 
53
- expect(Dir).to receive(:exist?).with("/some").and_return(true)
54
- expect(File).to receive(:exist?).with("/some/absolute/path").and_return(true)
55
- expect(IO).to receive(:read).with("/some/absolute/path").and_return("data")
55
+ expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
56
+ expect(File).to receive(:exist?).with("/some/absolute/path name").and_return(true)
57
+ expect(IO).to receive(:read).with("/some/absolute/path name").and_return("data")
56
58
 
57
59
  expect(subject).to eq 'data'
58
60
  end
59
61
  end
60
62
 
61
63
  context "when a path outside of our root is specified" do
62
- let(:url) { "/some/absolute/./path" }
64
+ let(:url) { "/other/absolute/./path" }
63
65
 
64
66
  it "raises" do
65
- expect(File).to receive(:expand_path).with(".").and_return("/other")
66
- expect(File).to receive(:expand_path).with(url).and_return("/some/absolute/path")
67
+ expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
68
+ expect(File).to receive(:expand_path).with(url, fake_root_path).and_return("/other/absolute/path")
67
69
 
68
- expect(Dir).to receive(:exist?).with("/other").and_return(true)
70
+ expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
69
71
 
70
72
  expect { subject }.to raise_error Prawn::SVG::UrlLoader::Error, /not inside the root path/
71
73
  end
@@ -75,10 +77,27 @@ RSpec.describe Prawn::SVG::Loaders::File do
75
77
  let(:url) { "file://somewhere/somefile" }
76
78
 
77
79
  it "raises" do
78
- expect(File).to receive(:expand_path).with(".").and_return("/other")
79
- expect(Dir).to receive(:exist?).with("/other").and_return(true)
80
+ expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
81
+ expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
80
82
 
81
83
  expect { subject }.to raise_error Prawn::SVG::UrlLoader::Error, /with a host/
82
84
  end
83
85
  end
86
+
87
+ context "when we're running on Windows" do
88
+ let(:url) { "file:///c:/path/to/file.png" }
89
+ let(:fake_root_path) { "c:/full" }
90
+
91
+ it "automatically fixes up URI's misparsing of Windows file paths and loads the file" do
92
+ expect(File).to receive(:expand_path).with(".").and_return(fake_root_path)
93
+ expect(File).to receive(:expand_path).with("c:/path/to/file.png", fake_root_path).and_return("c:/full/path/to/file.png")
94
+
95
+ expect(Dir).to receive(:exist?).with(fake_root_path).and_return(true)
96
+ expect(File).to receive(:exist?).with("c:/full/path/to/file.png").and_return(true)
97
+ expect(IO).to receive(:read).with("c:/full/path/to/file.png").and_return("data")
98
+
99
+ allow(file_loader).to receive(:windows?).and_return true
100
+ expect(subject).to eq 'data'
101
+ end
102
+ end
84
103
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prawn-svg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.0
4
+ version: 0.23.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roger Nesbitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-24 00:00:00.000000000 Z
11
+ date: 2016-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: prawn