mupdf 0.3.0 → 1.0.0

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
  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: []