mupdf 0.3.0 → 1.0.0

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
  SHA256:
3
- metadata.gz: 025aace876d1fc5f6ba89c7e94fb7a618b645c5011d1eb7d3923252ca1643693
4
- data.tar.gz: 9cc27d161818550e2b3290933652be4c1b8474f550f7c6f71a59eda5af4f02cc
3
+ metadata.gz: 75c0956dd50c089d4cea76952bdc5c4244a946c674d4e648edc71d749bd1faca
4
+ data.tar.gz: c5fe14cf7c06739d4e03480c894ab938c4e0fa68b897bdcf4b49e0f078f33bf5
5
5
  SHA512:
6
- metadata.gz: baf0ad502de63e12d938481d8944a96091a74f85e5d42189bcac9b7b0afb5b262f133e70eae434ac3f129349105262ececeff6e3feadbc037f4be14fd7127502
7
- data.tar.gz: 90a9bedd5984280f820b76bbbcab596bea290bdb79c6e699cf029898569cc006e23e7c26ea1877a95d8406a025e2dd70f2faec675f8aab0af2b143d9fa76352f
6
+ metadata.gz: 842db6317559209c6f2a6b0205adc8e2792c395be8fc61c0b5b23a6d750d86daf8a9642b656661efea26981cbbe6e8b64c83cd9448b470941bedc7c8011df04c
7
+ data.tar.gz: e3e79b6054b2f4f32947d62b64ca421d71efe1c949d544e99e0464503a22dde8472d4cb5da7e8cf9770d464dd7bd0f8e5b2a95d8351ab7c9347edd88405b32b9
data/Gemfile CHANGED
@@ -11,4 +11,5 @@ gem 'rubocop'
11
11
  gem 'rubocop-rake'
12
12
  gem 'rubocop-rspec'
13
13
  gem 'simplecov'
14
+ gem 'tempfile'
14
15
  gem 'yard'
data/README.md CHANGED
@@ -12,11 +12,29 @@
12
12
  gem install mupdf
13
13
  ```
14
14
 
15
+ _This project requires `mutool` be installed on your system. To verify ensure the following works:_
16
+
17
+ ```bash
18
+ mutool
19
+ ```
20
+
21
+ To install `mutool` on MacOS use:
22
+
23
+ ```bash
24
+ brew install mupdf
25
+ ```
26
+
27
+ To install `mutool` on Ubuntu use:
28
+
29
+ ```bash
30
+ apt-get install mupdf
31
+ ```
32
+
15
33
  ## Usage
16
34
 
17
35
  ### Document
18
36
 
19
- A `MuPDF::Document` wraps for a file:
37
+ A `MuPDF::Document` wraps a PDF file:
20
38
 
21
39
  ```ruby
22
40
  document = MuPDF::Document.new('./file.pdf')
@@ -24,9 +42,33 @@ document = MuPDF::Document.new('./file.pdf')
24
42
 
25
43
  #### Info
26
44
 
27
- The `info` command displays information about a document such as the number of pages:
45
+ The `info` command displays information about the document such as the number of pages:
28
46
 
29
47
  ```ruby
30
48
  info = document.info
31
49
  info.pages # e.g. 2
32
50
  ```
51
+
52
+ #### Pages
53
+
54
+ The `pages` command finds sizing information about the pages within a document:
55
+
56
+ ```ruby
57
+ pages = document.pages
58
+ pages.count # e.g. 2
59
+ pages.each do |page|
60
+ page.number # e.g. 1, 2, ...
61
+ page.width # 612
62
+ page.height # 792
63
+ end
64
+ ```
65
+
66
+ #### Draw
67
+
68
+ The `draw` command is useful for converting a document between formats:
69
+
70
+ ```ruby
71
+ document.pages.each do |page|
72
+ document.draw(page: page.number, format: "png", path: "./file-#{page.number}.png")
73
+ end
74
+ ```
data/lib/mupdf/box.rb ADDED
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MuPDF
4
+ # A bounding box for a PDF (e.g. media / crop / bleed / trim).
5
+ class Box
6
+ REGEX = /l="(?<l>\d+)" b="(?<b>\d+)" r="(?<r>\d+)" t="(?<t>\d+)"/
7
+
8
+ # @!attribute l
9
+ # @return [String] The left coordinate.
10
+ attr_reader :l
11
+
12
+ # @!attribute b
13
+ # @return [String] The bottom coordinate.
14
+ attr_reader :b
15
+
16
+ # @!attribute r
17
+ # @return [String] The right coordinate.
18
+ attr_reader :r
19
+
20
+ # @!attribute t
21
+ # @return [String] The top coordinate.
22
+ attr_reader :t
23
+
24
+ # @!attribute kind
25
+ # @return [Symbol] The kind of box.
26
+ attr_reader :kind
27
+
28
+ # @param text [String]
29
+ # @param kind [Symbol]
30
+ #
31
+ # @return [MuPDF::Box]
32
+ def self.parse(text, kind:)
33
+ match = text.match(REGEX)
34
+
35
+ new(
36
+ l: Integer(match[:l]),
37
+ b: Integer(match[:b]),
38
+ r: Integer(match[:r]),
39
+ t: Integer(match[:t]),
40
+ kind:
41
+ )
42
+ end
43
+
44
+ # @param l [Integer]
45
+ # @param b [Integer]
46
+ # @param r [Integer]
47
+ # @param t [Integer]
48
+ # @param kind [Symbol] optional
49
+ def initialize(l:, b:, r:, t:, kind: nil)
50
+ @l = l
51
+ @b = b
52
+ @r = r
53
+ @t = t
54
+ @kind = kind
55
+ end
56
+
57
+ # @return [String]
58
+ def inspect
59
+ "#<#{self.class.name} l=#{l} b=#{b} r=#{r} t=#{t} kind=#{kind}>"
60
+ end
61
+
62
+ # @return [Integer]
63
+ def width
64
+ @r - @l
65
+ end
66
+
67
+ # @return [Integer]
68
+ def height
69
+ @t - @b
70
+ end
71
+ end
72
+ end
@@ -8,6 +8,14 @@ module MuPDF
8
8
  @pathname = pathname
9
9
  end
10
10
 
11
+ # @return [String]
12
+ def inspect
13
+ "#<#{self.class.name} pathname=#{@pathname}>"
14
+ end
15
+
16
+ # @usage
17
+ # document.info #=> #<MuPDF::Info ...>
18
+ #
11
19
  # @raise [MuPDF::CommandError]
12
20
  #
13
21
  # @return [MuPDF::Info]
@@ -17,5 +25,46 @@ module MuPDF
17
25
  MuPDF::Info.parse(result)
18
26
  end
19
27
  end
28
+
29
+ # @usage
30
+ # pages = document.pages #=> [#<MuPDF::Page ...>, ...]
31
+ # pages.each do |page|
32
+ # puts page.number # e.g. 1, 2, 3, ...
33
+ # puts page.width # e.g. 612
34
+ # puts page.height # e.g. 792
35
+ # end
36
+ #
37
+ # @raise [MuPDF::CommandError]
38
+ #
39
+ # @return [Array<MuPDF::Page>]
40
+ def pages
41
+ @pages ||= begin
42
+ result = MuPDF.mutool('pages', String(@pathname))
43
+ MuPDF::Page.parse(result)
44
+ end
45
+ end
46
+
47
+ # @usage
48
+ # Tempfile.open(['mupdf', '.png']) do |tempfile|
49
+ # document.draw(path: tempfile.path, page: 2, format: 'png')
50
+ # end
51
+ #
52
+ # @param path [String] the path where the conversion is saved
53
+ # @param format [String] "png", "svg", "txt", etc
54
+ # @param page [Integer] the page
55
+ # @param resultion [Integer] optional (default: 72)
56
+ # @param width [Integer] optional
57
+ # @param height [Integer] optional
58
+ #
59
+ # @raise [MuPDF::CommandError]
60
+ def draw(path:, page:, format: 'png', width: nil, height: nil, resolution: nil)
61
+ args = ['draw', '-o', path, '-F', format, String(@pathname), String(page)]
62
+
63
+ args << '-w' << width if width
64
+ args << '-h' << height if height
65
+ args << '-r' << resolution if resolution
66
+
67
+ MuPDF.mutool(*args)
68
+ end
20
69
  end
21
70
  end
data/lib/mupdf/page.rb ADDED
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MuPDF
4
+ # A wrapper for a PDF page within a PDF document.
5
+ class Page
6
+ REGEX = %r{<page pagenum="(?<pagenum>\d+)">(?<content>.*?)</page>}m
7
+ MEDIA_BOX_REGEX = %r{<MediaBox (?<content>.*?) />}
8
+ CROP_BOX_REGEX = %r{<CropBox (?<content>.*?) />}
9
+ ART_BOX_REGEX = %r{<ArtBox (?<content>.*?) />}
10
+ BLEED_BOX_REGEX = %r{<BleedBox (?<content>.*?) />}
11
+ TRIM_BOX_REGEX = %r{<TrimBox (?<content>.*?) />}
12
+
13
+ # @param text [String]
14
+ #
15
+ # @return [Array<MuPDF::Page>]
16
+ def self.parse(text)
17
+ text.scan(REGEX).map do |number, content|
18
+ new(
19
+ media_box: parse_media_box(content),
20
+ crop_box: parse_crop_box(content),
21
+ art_box: parse_art_box(content),
22
+ bleed_box: parse_bleed_box(content),
23
+ trim_box: parse_trim_box(content),
24
+ number: Integer(number)
25
+ )
26
+ end
27
+ end
28
+
29
+ # @param text [String]
30
+ #
31
+ # @return [MuPDF::Box]
32
+ def self.parse_media_box(text)
33
+ match = MEDIA_BOX_REGEX.match(text)
34
+ MuPDF::Box.parse(match[:content], kind: :media)
35
+ end
36
+
37
+ # @param text [String]
38
+ #
39
+ # @return [MuPDF::Box]
40
+ def self.parse_crop_box(text)
41
+ match = CROP_BOX_REGEX.match(text)
42
+ MuPDF::Box.parse(match[:content], kind: :crop)
43
+ end
44
+
45
+ # @param text [String]
46
+ #
47
+ # @return [MuPDF::Box]
48
+ def self.parse_art_box(text)
49
+ match = ART_BOX_REGEX.match(text)
50
+ MuPDF::Box.parse(match[:content], kind: :art)
51
+ end
52
+
53
+ # @param text [String]
54
+ #
55
+ # @return [MuPDF::Box]
56
+ def self.parse_bleed_box(text)
57
+ match = BLEED_BOX_REGEX.match(text)
58
+ MuPDF::Box.parse(match[:content], kind: :bleed)
59
+ end
60
+
61
+ # @param text [String]
62
+ #
63
+ # @return [MuPDF::Box]
64
+ def self.parse_trim_box(text)
65
+ match = TRIM_BOX_REGEX.match(text)
66
+ MuPDF::Box.parse(match[:content], kind: :trim)
67
+ end
68
+
69
+ # @!attribute media_box
70
+ # @return [MuPDFBox]
71
+ attr_accessor :media_box
72
+
73
+ # @!attribute crop_box
74
+ # @return [MuPDFBox]
75
+ attr_accessor :crop_box
76
+
77
+ # @!attribute art_box
78
+ # @return [MuPDFBox]
79
+ attr_accessor :art_box
80
+
81
+ # @!attribute bleed_box
82
+ # @return [MuPDFBox]
83
+ attr_accessor :bleed_box
84
+
85
+ # @!attribute trim_box
86
+ # @return [MuPDFBox]
87
+ attr_accessor :trim_box
88
+
89
+ # @!attribute pagenum
90
+ # @return [Integer]
91
+ attr_accessor :pagenum
92
+
93
+ # @param media_box [MuPDF::Box]
94
+ # @param crop_box [MuPDF::Box]
95
+ # @param art_box [MuPDF::Box]
96
+ # @param bleed_box [MuPDF::Box]
97
+ # @param trim_box [MuPDF::Box]
98
+ # @param number [Integer]
99
+ def initialize(media_box:, crop_box:, art_box:, bleed_box:, trim_box:, number:)
100
+ @media_box = media_box
101
+ @crop_box = crop_box
102
+ @art_box = art_box
103
+ @bleed_box = bleed_box
104
+ @trim_box = trim_box
105
+ @number = number
106
+ end
107
+
108
+ # @return [String]
109
+ def inspect
110
+ "#<#{self.class.name} number=#{@number}>"
111
+ end
112
+
113
+ # @return [Integer]
114
+ def width
115
+ @media_box.width
116
+ end
117
+
118
+ # @return [Integer]
119
+ def height
120
+ @media_box.height
121
+ end
122
+ end
123
+ end
data/lib/mupdf/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MuPDF
4
- VERSION = '0.3.0'
4
+ VERSION = '1.0.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mupdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Sylvestre
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-02 00:00:00.000000000 Z
11
+ date: 2025-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: open3
@@ -50,9 +50,11 @@ files:
50
50
  - bin/console
51
51
  - bin/setup
52
52
  - lib/mupdf.rb
53
+ - lib/mupdf/box.rb
53
54
  - lib/mupdf/command_error.rb
54
55
  - lib/mupdf/document.rb
55
56
  - lib/mupdf/info.rb
57
+ - lib/mupdf/page.rb
56
58
  - lib/mupdf/version.rb
57
59
  homepage: https://github.com/ksylvest/mupdf
58
60
  licenses:
@@ -60,8 +62,8 @@ licenses:
60
62
  metadata:
61
63
  rubygems_mfa_required: 'true'
62
64
  homepage_uri: https://github.com/ksylvest/mupdf
63
- source_code_uri: https://github.com/ksylvest/mupdf/tree/v0.3.0
64
- changelog_uri: https://github.com/ksylvest/mupdf/releases/tag/v0.3.0
65
+ source_code_uri: https://github.com/ksylvest/mupdf/tree/v1.0.0
66
+ changelog_uri: https://github.com/ksylvest/mupdf/releases/tag/v1.0.0
65
67
  documentation_uri: https://mupdf.ksylvest.com/
66
68
  post_install_message:
67
69
  rdoc_options: []