prawn-svg 0.23.0 → 0.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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