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 +4 -4
- data/Gemfile +1 -0
- data/README.md +44 -2
- data/lib/mupdf/box.rb +72 -0
- data/lib/mupdf/document.rb +49 -0
- data/lib/mupdf/page.rb +123 -0
- data/lib/mupdf/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75c0956dd50c089d4cea76952bdc5c4244a946c674d4e648edc71d749bd1faca
|
4
|
+
data.tar.gz: c5fe14cf7c06739d4e03480c894ab938c4e0fa68b897bdcf4b49e0f078f33bf5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 842db6317559209c6f2a6b0205adc8e2792c395be8fc61c0b5b23a6d750d86daf8a9642b656661efea26981cbbe6e8b64c83cd9448b470941bedc7c8011df04c
|
7
|
+
data.tar.gz: e3e79b6054b2f4f32947d62b64ca421d71efe1c949d544e99e0464503a22dde8472d4cb5da7e8cf9770d464dd7bd0f8e5b2a95d8351ab7c9347edd88405b32b9
|
data/Gemfile
CHANGED
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
|
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
|
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
|
data/lib/mupdf/document.rb
CHANGED
@@ -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
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.
|
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-
|
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/
|
64
|
-
changelog_uri: https://github.com/ksylvest/mupdf/releases/tag/
|
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: []
|