imprimatur 0.5.0 → 0.6.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 +4 -4
- data/CHANGELOG.md +21 -0
- data/Cargo.lock +472 -5
- data/Cargo.toml +16 -1
- data/README.md +52 -7
- data/ext/imprimatur_native/cli/Cargo.toml +1 -1
- data/ext/imprimatur_native/cli/src/app.rs +3 -1
- data/ext/imprimatur_native/core/Cargo.toml +29 -13
- data/ext/imprimatur_native/core/README.md +13 -1
- data/ext/imprimatur_native/core/src/bin/imprimatur-render-worker.rs +10 -0
- data/ext/imprimatur_native/core/src/bytes.rs +16 -0
- data/ext/imprimatur_native/core/src/doc/picture.rs +3 -7
- data/ext/imprimatur_native/core/src/doc/size.rs +14 -0
- data/ext/imprimatur_native/core/src/doc/symbol.rs +3 -5
- data/ext/imprimatur_native/core/src/doc.rs +24 -0
- data/ext/imprimatur_native/core/src/docx.rs +6 -5
- data/ext/imprimatur_native/core/src/error.rs +6 -0
- data/ext/imprimatur_native/core/src/font.rs +12 -0
- data/ext/imprimatur_native/core/src/lib.rs +6 -0
- data/ext/imprimatur_native/core/src/pdf/layout.rs +13 -5
- data/ext/imprimatur_native/core/src/pdf/objects.rs +1 -1
- data/ext/imprimatur_native/core/src/pdf/truetype/descriptor.rs +1 -0
- data/ext/imprimatur_native/core/src/read/budget.rs +10 -5
- data/ext/imprimatur_native/core/src/read/content.rs +16 -0
- data/ext/imprimatur_native/core/src/read/image/dimensions.rs +2 -2
- data/ext/imprimatur_native/core/src/read/ole.rs +1 -8
- data/ext/imprimatur_native/core/src/read/pdf/bounded.rs +190 -0
- data/ext/imprimatur_native/core/src/read/pdf/content/state.rs +50 -0
- data/ext/imprimatur_native/core/src/read/pdf/content.rs +43 -54
- data/ext/imprimatur_native/core/src/read/pdf/document/pages.rs +140 -0
- data/ext/imprimatur_native/core/src/read/pdf/document.rs +20 -110
- data/ext/imprimatur_native/core/src/read/pdf/filter.rs +25 -13
- data/ext/imprimatur_native/core/src/read/pdf/font.rs +4 -3
- data/ext/imprimatur_native/core/src/read/pdf/isolation/protocol.rs +155 -0
- data/ext/imprimatur_native/core/src/read/pdf/isolation/system.rs +71 -0
- data/ext/imprimatur_native/core/src/read/pdf/isolation/worker.rs +43 -0
- data/ext/imprimatur_native/core/src/read/pdf/isolation.rs +166 -0
- data/ext/imprimatur_native/core/src/read/pdf/render.rs +206 -0
- data/ext/imprimatur_native/core/src/read/pdf.rs +16 -8
- data/ext/imprimatur_native/core/src/read/xls/strings.rs +2 -1
- data/ext/imprimatur_native/core/src/read/xls.rs +1 -8
- data/ext/imprimatur_native/core/src/read.rs +6 -5
- data/ext/imprimatur_native/core/src/test_support/font.rs +37 -0
- data/ext/imprimatur_native/core/src/xlsx/validation.rs +28 -18
- data/ext/imprimatur_native/core/src/zip/reader.rs +1 -8
- data/ext/imprimatur_native/extconf.rb +18 -0
- data/ext/imprimatur_native/ffi/Cargo.toml +2 -2
- data/ext/imprimatur_native/ffi/src/document.rs +6 -0
- data/ext/imprimatur_native/ffi/src/lib.rs +7 -0
- data/ext/imprimatur_native/ffi/src/pdf.rs +73 -0
- data/ext/imprimatur_native/ffi/src/read.rs +18 -12
- data/lib/imprimatur/document.rb +4 -2
- data/lib/imprimatur/native.rb +7 -0
- data/lib/imprimatur/pdf_reader.rb +27 -0
- data/lib/imprimatur/version.rb +1 -1
- data/lib/imprimatur.rb +26 -2
- metadata +19 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "imprimatur_native"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.6.0"
|
|
4
4
|
description = "Ruby bindings for the imprimatur crate"
|
|
5
5
|
publish = false
|
|
6
6
|
edition.workspace = true
|
|
@@ -16,7 +16,7 @@ workspace = true
|
|
|
16
16
|
|
|
17
17
|
[dependencies]
|
|
18
18
|
# Gems ship precompiled, so they carry every feature of the crate.
|
|
19
|
-
imprimatur = { workspace = true, features = ["archive", "fonts", "json"] }
|
|
19
|
+
imprimatur = { workspace = true, features = ["archive", "fonts", "json", "isolation"] }
|
|
20
20
|
serde_json.workspace = true
|
|
21
21
|
magnus.workspace = true
|
|
22
22
|
rb-sys.workspace = true
|
|
@@ -66,6 +66,11 @@ impl NativeDocument {
|
|
|
66
66
|
Ok(())
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
fn set_font_size(ruby: &Ruby, rb_self: &Self, points: f64) -> Result<(), Error> {
|
|
70
|
+
borrow(ruby, &rb_self.0, "document")?.set_font_size(points).or_raise(ruby)?;
|
|
71
|
+
Ok(())
|
|
72
|
+
}
|
|
73
|
+
|
|
69
74
|
/// A PNG or JPEG from its bytes, `width` and `height` in points.
|
|
70
75
|
fn picture(
|
|
71
76
|
ruby: &Ruby,
|
|
@@ -201,6 +206,7 @@ pub fn define(ruby: &Ruby, native: RModule) -> Result<(), Error> {
|
|
|
201
206
|
class.define_method("set_page", method!(NativeDocument::set_page, 2))?;
|
|
202
207
|
class.define_method("set_page_points", method!(NativeDocument::set_page_points, 3))?;
|
|
203
208
|
class.define_method("set_margin", method!(NativeDocument::set_margin, 1))?;
|
|
209
|
+
class.define_method("set_font_size", method!(NativeDocument::set_font_size, 1))?;
|
|
204
210
|
class.define_method("picture", method!(NativeDocument::picture, 4))?;
|
|
205
211
|
class.define_method("barcode", method!(NativeDocument::barcode, 4))?;
|
|
206
212
|
class.define_method("heading", method!(NativeDocument::heading, 2))?;
|
|
@@ -8,6 +8,7 @@ mod barcode;
|
|
|
8
8
|
mod blocking;
|
|
9
9
|
mod convert;
|
|
10
10
|
mod document;
|
|
11
|
+
mod pdf;
|
|
11
12
|
mod read;
|
|
12
13
|
mod sheets;
|
|
13
14
|
mod style;
|
|
@@ -277,6 +278,9 @@ fn argument_error(ruby: &Ruby, message: impl Into<std::borrow::Cow<'static, str>
|
|
|
277
278
|
/// Raises `Imprimatur::Error`, or the subclass of it the error has, all
|
|
278
279
|
/// defined in `lib/imprimatur/error.rb`.
|
|
279
280
|
fn domain_error(ruby: &Ruby, error: &imprimatur::Error) -> Error {
|
|
281
|
+
if let imprimatur::Error::InvalidPdfOption(message) = error {
|
|
282
|
+
return argument_error(ruby, *message);
|
|
283
|
+
}
|
|
280
284
|
let name = match error {
|
|
281
285
|
imprimatur::Error::NoTextLayer => "NoTextLayer",
|
|
282
286
|
imprimatur::Error::PasswordRequired => "PasswordRequired",
|
|
@@ -322,6 +326,9 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
322
326
|
native.define_singleton_method("markdown", function!(read::markdown_native, 4))?;
|
|
323
327
|
native.define_singleton_method("content", function!(read::content_native, 5))?;
|
|
324
328
|
native.define_singleton_method("images", function!(read::images_native, 4))?;
|
|
329
|
+
native.define_singleton_method("pdf_info", function!(pdf::info, 2))?;
|
|
330
|
+
native.define_singleton_method("pdf_pages", function!(pdf::pages, 3))?;
|
|
331
|
+
native.define_singleton_method("render_pdf_page", function!(pdf::render, 5))?;
|
|
325
332
|
native.define_singleton_method("sheets", function!(sheets::sheets_native, 5))?;
|
|
326
333
|
let zip_writer = native.define_class("ZipWriter", ruby.class_object())?;
|
|
327
334
|
zip_writer.define_singleton_method("new", function!(archive::ZipWriter::new, 1))?;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//! PDF-specific entry points; all document work stays in the Rust core.
|
|
2
|
+
|
|
3
|
+
use imprimatur::read::{Limits, pdf};
|
|
4
|
+
use magnus::{Error, RString, Ruby};
|
|
5
|
+
use serde_json::json;
|
|
6
|
+
use std::path::PathBuf;
|
|
7
|
+
|
|
8
|
+
use crate::read::without_gvl;
|
|
9
|
+
|
|
10
|
+
type Keywords = (Option<usize>, Option<u64>, Option<f64>);
|
|
11
|
+
|
|
12
|
+
pub fn info(ruby: &Ruby, document: RString, keywords: Keywords) -> Result<RString, Error> {
|
|
13
|
+
let value = without_gvl(ruby, document, keywords, |data, limits| {
|
|
14
|
+
let info = pdf::info(data, limits)?;
|
|
15
|
+
Ok(json!({ "page_count": info.page_count, "encrypted": info.encrypted }).to_string())
|
|
16
|
+
})?;
|
|
17
|
+
Ok(ruby.str_new(&value))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
pub fn pages(
|
|
21
|
+
ruby: &Ruby,
|
|
22
|
+
document: RString,
|
|
23
|
+
keywords: Keywords,
|
|
24
|
+
options: (u32, u32, usize, usize, usize),
|
|
25
|
+
) -> Result<RString, Error> {
|
|
26
|
+
let (first_page, last_page, max_pages, max_page_bytes, max_output_bytes) = options;
|
|
27
|
+
let options =
|
|
28
|
+
pdf::ReadOptions { first_page, last_page, max_pages, max_page_bytes, max_output_bytes };
|
|
29
|
+
let value = without_gvl(ruby, document, keywords, |data, limits| {
|
|
30
|
+
let result = pdf::pages(data, &options, limits)?;
|
|
31
|
+
let pages: Vec<_> = result
|
|
32
|
+
.pages
|
|
33
|
+
.into_iter()
|
|
34
|
+
.map(|page| {
|
|
35
|
+
json!({
|
|
36
|
+
"page": page.number,
|
|
37
|
+
"status": page.status.as_str(),
|
|
38
|
+
"text": page.text,
|
|
39
|
+
"images": page.images,
|
|
40
|
+
"truncated": page.truncated,
|
|
41
|
+
"reason": page.reason,
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
.collect();
|
|
45
|
+
Ok(json!({
|
|
46
|
+
"page_count": result.info.page_count,
|
|
47
|
+
"encrypted": result.info.encrypted,
|
|
48
|
+
"pages": pages,
|
|
49
|
+
})
|
|
50
|
+
.to_string())
|
|
51
|
+
})?;
|
|
52
|
+
Ok(ruby.str_new(&value))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
pub fn render(
|
|
56
|
+
ruby: &Ruby,
|
|
57
|
+
document: RString,
|
|
58
|
+
keywords: Keywords,
|
|
59
|
+
options: (u32, u16, u64, usize, bool),
|
|
60
|
+
worker: String,
|
|
61
|
+
memory_bytes: u64,
|
|
62
|
+
) -> Result<RString, Error> {
|
|
63
|
+
let (page, max_side, max_pixels, max_output_bytes, grayscale) = options;
|
|
64
|
+
let worker = PathBuf::from(worker);
|
|
65
|
+
let options = pdf::RenderOptions { max_side, max_pixels, max_output_bytes, grayscale };
|
|
66
|
+
let process =
|
|
67
|
+
pdf::isolation::ProcessLimits { memory_bytes, ..pdf::isolation::ProcessLimits::default() };
|
|
68
|
+
let data = without_gvl(ruby, document, keywords, |data: &[u8], limits: &Limits| {
|
|
69
|
+
pdf::isolation::render_page_isolated(&worker, data, page, &options, limits, &process)
|
|
70
|
+
.map(|image| image.data)
|
|
71
|
+
})?;
|
|
72
|
+
Ok(ruby.str_from_slice(&data))
|
|
73
|
+
}
|
|
@@ -16,14 +16,11 @@ use serde_json::Value as Json;
|
|
|
16
16
|
use crate::blocking::MAX_ATTEMPTS;
|
|
17
17
|
use crate::{argument_error, domain_error};
|
|
18
18
|
|
|
19
|
-
/// A read of a document's bytes within limits, run without the GVL.
|
|
20
|
-
pub type Job<T> = fn(&[u8], &Limits) -> imprimatur::Result<T>;
|
|
21
|
-
|
|
22
19
|
/// What crosses into the thread without the GVL, and comes back.
|
|
23
|
-
struct Read<T> {
|
|
20
|
+
struct Read<T, F> {
|
|
24
21
|
document: Vec<u8>,
|
|
25
22
|
limits: Limits,
|
|
26
|
-
job:
|
|
23
|
+
job: F,
|
|
27
24
|
result: Option<imprimatur::Result<T>>,
|
|
28
25
|
}
|
|
29
26
|
|
|
@@ -107,17 +104,20 @@ fn limits(
|
|
|
107
104
|
}
|
|
108
105
|
|
|
109
106
|
/// Runs `job` on the document's bytes on this thread, the GVL released.
|
|
110
|
-
pub fn without_gvl<T>(
|
|
107
|
+
pub fn without_gvl<T, F>(
|
|
111
108
|
ruby: &Ruby,
|
|
112
109
|
document: RString,
|
|
113
110
|
keywords: (Option<usize>, Option<u64>, Option<f64>),
|
|
114
|
-
job:
|
|
115
|
-
) -> Result<T, Error>
|
|
111
|
+
job: F,
|
|
112
|
+
) -> Result<T, Error>
|
|
113
|
+
where
|
|
114
|
+
F: Fn(&[u8], &Limits) -> imprimatur::Result<T>,
|
|
115
|
+
{
|
|
116
116
|
let document = crate::bytes(document);
|
|
117
117
|
let cancel = Arc::new(AtomicBool::new(false));
|
|
118
118
|
let limits = limits(ruby, &cancel, keywords)?;
|
|
119
119
|
let mut read = Read { document, limits, job, result: None };
|
|
120
|
-
let read_pointer: *mut Read<T> = &raw mut read;
|
|
120
|
+
let read_pointer: *mut Read<T, F> = &raw mut read;
|
|
121
121
|
let flag_pointer = Arc::as_ptr(&cancel).cast_mut();
|
|
122
122
|
for _ in 0..MAX_ATTEMPTS {
|
|
123
123
|
// SAFETY: `read` and `cancel` outlive the call, which returns only
|
|
@@ -127,12 +127,15 @@ pub fn without_gvl<T>(
|
|
|
127
127
|
#[allow(unsafe_code)]
|
|
128
128
|
unsafe {
|
|
129
129
|
rb_sys::rb_thread_call_without_gvl2(
|
|
130
|
-
Some(run::<T>),
|
|
130
|
+
Some(run::<T, F>),
|
|
131
131
|
read_pointer.cast(),
|
|
132
132
|
Some(stop),
|
|
133
133
|
flag_pointer.cast(),
|
|
134
134
|
);
|
|
135
135
|
}
|
|
136
|
+
// In particular, SIGCHLD wakes an isolated render on normal completion.
|
|
137
|
+
// Deliver real Ruby interrupts even when the native job succeeded.
|
|
138
|
+
ruby.thread_check_ints()?;
|
|
136
139
|
match read.result.take() {
|
|
137
140
|
Some(Ok(value)) => return Ok(value),
|
|
138
141
|
// Cut short by Ruby: raise what Ruby has to raise (Thread#raise,
|
|
@@ -153,10 +156,13 @@ pub fn without_gvl<T>(
|
|
|
153
156
|
/// The read itself, on the thread without the GVL. A panic would abort
|
|
154
157
|
/// the process at this C boundary; it becomes an error instead.
|
|
155
158
|
#[allow(unsafe_code)]
|
|
156
|
-
unsafe extern "C" fn run<T>(data: *mut c_void) -> *mut c_void
|
|
159
|
+
unsafe extern "C" fn run<T, F>(data: *mut c_void) -> *mut c_void
|
|
160
|
+
where
|
|
161
|
+
F: Fn(&[u8], &Limits) -> imprimatur::Result<T>,
|
|
162
|
+
{
|
|
157
163
|
// SAFETY: `data` is the `Read<T>` without_gvl passed, alive and not
|
|
158
164
|
// otherwise borrowed until this returns.
|
|
159
|
-
let read = unsafe { &mut *data.cast::<Read<T>>() };
|
|
165
|
+
let read = unsafe { &mut *data.cast::<Read<T, F>>() };
|
|
160
166
|
let result = catch_unwind(AssertUnwindSafe(|| (read.job)(&read.document, &read.limits)));
|
|
161
167
|
read.result = Some(result.unwrap_or_else(|_| {
|
|
162
168
|
Err(imprimatur::Error::Malformed {
|
data/lib/imprimatur/document.rb
CHANGED
|
@@ -21,10 +21,11 @@ module Imprimatur
|
|
|
21
21
|
# @param page_size [:a4, :letter, Array(Numeric, Numeric)] or its width
|
|
22
22
|
# and height in points, 36 to 1584 a side
|
|
23
23
|
# @param margin [Numeric, nil] points on every side, one inch (72) unless set
|
|
24
|
+
# @param font_size [Numeric, nil] body text in points, 1 to 1638 in steps of 0.5; 11 unless set
|
|
24
25
|
# @param page_numbers [Boolean] number pages "1 / N" in the footer
|
|
25
26
|
# @raise [ArgumentError] an unknown page size
|
|
26
|
-
# @raise [Imprimatur::Error] a page size or
|
|
27
|
-
def initialize(page_size: :a4, margin: nil, page_numbers: false)
|
|
27
|
+
# @raise [Imprimatur::Error] a page size, margin or font size out of range
|
|
28
|
+
def initialize(page_size: :a4, margin: nil, font_size: nil, page_numbers: false)
|
|
28
29
|
@native = Native::Document.new
|
|
29
30
|
numbers = page_numbers ? true : false
|
|
30
31
|
if page_size.is_a?(Array)
|
|
@@ -34,6 +35,7 @@ module Imprimatur
|
|
|
34
35
|
@native.set_page(page_size.to_s, numbers)
|
|
35
36
|
end
|
|
36
37
|
@native.set_margin(Float(margin)) if margin
|
|
38
|
+
@native.set_font_size(Float(font_size)) if font_size
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
# A PNG or JPEG in the flow, at +width+ or +height+ points (the other
|
data/lib/imprimatur/native.rb
CHANGED
|
@@ -15,3 +15,10 @@ rescue LoadError => e
|
|
|
15
15
|
raise LoadError, "imprimatur: the native extension did not load (#{e.message}). " \
|
|
16
16
|
'Install a platform gem, or build it with `rake compile` (toolchain: https://rustup.rs).'
|
|
17
17
|
end
|
|
18
|
+
|
|
19
|
+
module Imprimatur
|
|
20
|
+
# Always use the companion of the loaded extension, never PATH.
|
|
21
|
+
RENDER_WORKER = File.join(File.dirname($LOADED_FEATURES.find do |path|
|
|
22
|
+
path.end_with?("/imprimatur_native.#{RbConfig::CONFIG['DLEXT']}")
|
|
23
|
+
end), 'imprimatur-render-worker').freeze
|
|
24
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Imprimatur
|
|
4
|
+
# Keyword handling only; parsing, limits and rendering live in the native core.
|
|
5
|
+
module PdfReader
|
|
6
|
+
def self.info(document, max_bytes: nil, **limits)
|
|
7
|
+
JSON.parse(Native.pdf_info(Reader.read(document, max_bytes), Reader.limits(max_bytes:, **limits)),
|
|
8
|
+
symbolize_names: true)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.pages(document, first_page: 1, last_page: 0xFFFFFFFF, max_pages: 500,
|
|
12
|
+
max_page_bytes: 256 * 1024, max_output_bytes: 8 * 1024 * 1024,
|
|
13
|
+
max_bytes: nil, **limits)
|
|
14
|
+
options = [first_page, last_page, max_pages, max_page_bytes, max_output_bytes]
|
|
15
|
+
JSON.parse(Native.pdf_pages(Reader.read(document, max_bytes), Reader.limits(max_bytes:, **limits), options),
|
|
16
|
+
symbolize_names: true)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.render(document, page:, max_side: 1568, max_pixels: 4_000_000,
|
|
20
|
+
max_output_bytes: 8 * 1024 * 1024, grayscale: true,
|
|
21
|
+
memory_bytes: 1024 * 1024 * 1024, max_bytes: nil, **limits)
|
|
22
|
+
Native.render_pdf_page(Reader.read(document, max_bytes), Reader.limits(max_bytes:, **limits),
|
|
23
|
+
[page, max_side, max_pixels, max_output_bytes, grayscale],
|
|
24
|
+
RENDER_WORKER, memory_bytes)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/imprimatur/version.rb
CHANGED
data/lib/imprimatur.rb
CHANGED
|
@@ -10,6 +10,7 @@ require_relative 'imprimatur/barcode'
|
|
|
10
10
|
require_relative 'imprimatur/xlsx'
|
|
11
11
|
require_relative 'imprimatur/document'
|
|
12
12
|
require_relative 'imprimatur/reader'
|
|
13
|
+
require_relative 'imprimatur/pdf_reader'
|
|
13
14
|
require_relative 'imprimatur/spreadsheet'
|
|
14
15
|
require_relative 'imprimatur/zip'
|
|
15
16
|
|
|
@@ -45,7 +46,7 @@ module Imprimatur
|
|
|
45
46
|
# Builds a {Document} and renders it as PDF. With a path, saves it there
|
|
46
47
|
# and returns the path; without, returns the bytes.
|
|
47
48
|
#
|
|
48
|
-
# @param options [Hash] +page_size:+ and +page_numbers:+, see {Document#initialize}
|
|
49
|
+
# @param options [Hash] +page_size:+, +margin:+, +font_size:+ and +page_numbers:+, see {Document#initialize}
|
|
49
50
|
# @yieldparam document [Document]
|
|
50
51
|
def pdf(path = nil, **options, &) = Document.build(:pdf, path, **options, &)
|
|
51
52
|
|
|
@@ -92,7 +93,11 @@ module Imprimatur
|
|
|
92
93
|
# sheet = Imprimatur.content('sales.xlsx')[:sheets].first
|
|
93
94
|
# sheet[:rows][1][:cells] # => [{cell: "A2", type: "text", value: "North"}, ...]
|
|
94
95
|
#
|
|
95
|
-
#
|
|
96
|
+
# Unlike {.markdown}, a PDF without text still returns every page, with
|
|
97
|
+
# empty +:blocks+ and its image count, rather than raising {NoTextLayer}.
|
|
98
|
+
# This keeps scanned and blank pages visible to OCR callers.
|
|
99
|
+
#
|
|
100
|
+
# Takes the arguments of {.markdown}, and raises as it does otherwise. With
|
|
96
101
|
# +styles: true+ each sheet also lists its formatted cells' +:styles+:
|
|
97
102
|
# font, size, bold, italic, underline, ARGB color and fill, alignment,
|
|
98
103
|
# wrap, border and number format.
|
|
@@ -100,6 +105,25 @@ module Imprimatur
|
|
|
100
105
|
# @return [Hash] with symbol keys; +:format+ is +"pdf"+, +"xlsx"+ or +"docx"+
|
|
101
106
|
def content(document, ...) = Reader.content(document, ...)
|
|
102
107
|
|
|
108
|
+
# PDF metadata without reading page content.
|
|
109
|
+
# @return [Hash] +page_count:+ and +encrypted:+
|
|
110
|
+
def pdf_info(document, ...) = PdfReader.info(document, ...)
|
|
111
|
+
|
|
112
|
+
# A bounded, one-based page selection. Each page has its status, text,
|
|
113
|
+
# image count (nil when unknown), truncation flag and failure reason.
|
|
114
|
+
# Takes +first_page:+, +last_page:+, +max_pages:+ (500),
|
|
115
|
+
# +max_page_bytes:+ (256 KiB), +max_output_bytes:+ (8 MiB), and read limits.
|
|
116
|
+
# @return [Hash] +page_count:+, +encrypted:+ and +pages:+
|
|
117
|
+
def pdf_pages(document, ...) = PdfReader.pages(document, ...)
|
|
118
|
+
|
|
119
|
+
# A full page as an opaque PNG, not just its embedded images.
|
|
120
|
+
# Takes +page:+ (one-based), +max_side:+ (1568), +max_pixels:+ (4 million),
|
|
121
|
+
# +max_output_bytes:+ (8 MiB), +grayscale:+ (true), and read limits.
|
|
122
|
+
# Rendering checks time/cancellation before and after Hayro, not during it.
|
|
123
|
+
# Untrusted documents still need an externally limited worker process.
|
|
124
|
+
# @return [String] PNG bytes
|
|
125
|
+
def render_pdf_page(document, ...) = PdfReader.render(document, ...)
|
|
126
|
+
|
|
103
127
|
# A workbook's sheets and their values, read from the same documents
|
|
104
128
|
# {.markdown} takes (+.xlsx+, +.xls+, +.ods+); see {Spreadsheet}.
|
|
105
129
|
#
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: imprimatur
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Abdelkader Boudih
|
|
@@ -24,9 +24,10 @@ dependencies:
|
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: 0.9.130
|
|
26
26
|
description: 'A Ruby DSL over a native core that writes Excel workbooks, and PDF and
|
|
27
|
-
Word documents from one model, with its own XML, zip and PDF
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
Word documents from one model, with its own XML, zip and PDF readers and writers.
|
|
28
|
+
It reads PDF, XLSX, XLS, ODS and DOCX back: as Markdown, as typed structure, and
|
|
29
|
+
their images. Full-page PDF rendering uses the pure-Rust Hayro renderer. Precompiled
|
|
30
|
+
for Linux, macOS and FreeBSD; CRuby only.'
|
|
30
31
|
email:
|
|
31
32
|
- terminale@gmail.com
|
|
32
33
|
executables: []
|
|
@@ -58,9 +59,12 @@ files:
|
|
|
58
59
|
- ext/imprimatur_native/core/src/barcode/ean.rs
|
|
59
60
|
- ext/imprimatur_native/core/src/barcode/gs1.rs
|
|
60
61
|
- ext/imprimatur_native/core/src/barcode/matrix.rs
|
|
62
|
+
- ext/imprimatur_native/core/src/bin/imprimatur-render-worker.rs
|
|
63
|
+
- ext/imprimatur_native/core/src/bytes.rs
|
|
61
64
|
- ext/imprimatur_native/core/src/doc.rs
|
|
62
65
|
- ext/imprimatur_native/core/src/doc/paragraph.rs
|
|
63
66
|
- ext/imprimatur_native/core/src/doc/picture.rs
|
|
67
|
+
- ext/imprimatur_native/core/src/doc/size.rs
|
|
64
68
|
- ext/imprimatur_native/core/src/doc/symbol.rs
|
|
65
69
|
- ext/imprimatur_native/core/src/doc/table.rs
|
|
66
70
|
- ext/imprimatur_native/core/src/docx.rs
|
|
@@ -94,22 +98,30 @@ files:
|
|
|
94
98
|
- ext/imprimatur_native/core/src/read/ole.rs
|
|
95
99
|
- ext/imprimatur_native/core/src/read/package.rs
|
|
96
100
|
- ext/imprimatur_native/core/src/read/pdf.rs
|
|
101
|
+
- ext/imprimatur_native/core/src/read/pdf/bounded.rs
|
|
97
102
|
- ext/imprimatur_native/core/src/read/pdf/cmap.rs
|
|
98
103
|
- ext/imprimatur_native/core/src/read/pdf/content.rs
|
|
99
104
|
- ext/imprimatur_native/core/src/read/pdf/content/geometry.rs
|
|
100
105
|
- ext/imprimatur_native/core/src/read/pdf/content/operands.rs
|
|
106
|
+
- ext/imprimatur_native/core/src/read/pdf/content/state.rs
|
|
101
107
|
- ext/imprimatur_native/core/src/read/pdf/crypt.rs
|
|
102
108
|
- ext/imprimatur_native/core/src/read/pdf/document.rs
|
|
109
|
+
- ext/imprimatur_native/core/src/read/pdf/document/pages.rs
|
|
103
110
|
- ext/imprimatur_native/core/src/read/pdf/filter.rs
|
|
104
111
|
- ext/imprimatur_native/core/src/read/pdf/font.rs
|
|
105
112
|
- ext/imprimatur_native/core/src/read/pdf/glyphs.rs
|
|
106
113
|
- ext/imprimatur_native/core/src/read/pdf/glyphs.txt
|
|
107
114
|
- ext/imprimatur_native/core/src/read/pdf/images.rs
|
|
115
|
+
- ext/imprimatur_native/core/src/read/pdf/isolation.rs
|
|
116
|
+
- ext/imprimatur_native/core/src/read/pdf/isolation/protocol.rs
|
|
117
|
+
- ext/imprimatur_native/core/src/read/pdf/isolation/system.rs
|
|
118
|
+
- ext/imprimatur_native/core/src/read/pdf/isolation/worker.rs
|
|
108
119
|
- ext/imprimatur_native/core/src/read/pdf/layout.rs
|
|
109
120
|
- ext/imprimatur_native/core/src/read/pdf/layout/bidi.rs
|
|
110
121
|
- ext/imprimatur_native/core/src/read/pdf/lexer.rs
|
|
111
122
|
- ext/imprimatur_native/core/src/read/pdf/object.rs
|
|
112
123
|
- ext/imprimatur_native/core/src/read/pdf/object/name.rs
|
|
124
|
+
- ext/imprimatur_native/core/src/read/pdf/render.rs
|
|
113
125
|
- ext/imprimatur_native/core/src/read/pdf/xref.rs
|
|
114
126
|
- ext/imprimatur_native/core/src/read/span.rs
|
|
115
127
|
- ext/imprimatur_native/core/src/read/xls.rs
|
|
@@ -118,6 +130,7 @@ files:
|
|
|
118
130
|
- ext/imprimatur_native/core/src/read/xlsx/formats.rs
|
|
119
131
|
- ext/imprimatur_native/core/src/script.rs
|
|
120
132
|
- ext/imprimatur_native/core/src/style.rs
|
|
133
|
+
- ext/imprimatur_native/core/src/test_support/font.rs
|
|
121
134
|
- ext/imprimatur_native/core/src/xlsx.rs
|
|
122
135
|
- ext/imprimatur_native/core/src/xlsx/autofit.rs
|
|
123
136
|
- ext/imprimatur_native/core/src/xlsx/cell.rs
|
|
@@ -142,6 +155,7 @@ files:
|
|
|
142
155
|
- ext/imprimatur_native/ffi/src/convert.rs
|
|
143
156
|
- ext/imprimatur_native/ffi/src/document.rs
|
|
144
157
|
- ext/imprimatur_native/ffi/src/lib.rs
|
|
158
|
+
- ext/imprimatur_native/ffi/src/pdf.rs
|
|
145
159
|
- ext/imprimatur_native/ffi/src/read.rs
|
|
146
160
|
- ext/imprimatur_native/ffi/src/sheets.rs
|
|
147
161
|
- ext/imprimatur_native/ffi/src/style.rs
|
|
@@ -152,6 +166,7 @@ files:
|
|
|
152
166
|
- lib/imprimatur/error.rb
|
|
153
167
|
- lib/imprimatur/formula.rb
|
|
154
168
|
- lib/imprimatur/native.rb
|
|
169
|
+
- lib/imprimatur/pdf_reader.rb
|
|
155
170
|
- lib/imprimatur/reader.rb
|
|
156
171
|
- lib/imprimatur/spreadsheet.rb
|
|
157
172
|
- lib/imprimatur/style.rb
|