fulgur 0.5.0-aarch64-linux
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 +7 -0
- data/CHANGELOG.md +27 -0
- data/LICENSE-MIT +21 -0
- data/README.md +234 -0
- data/lib/fulgur/3.1/fulgur.so +0 -0
- data/lib/fulgur/3.2/fulgur.so +0 -0
- data/lib/fulgur/3.3/fulgur.so +0 -0
- data/lib/fulgur/3.4/fulgur.so +0 -0
- data/lib/fulgur/asset_bundle.rb +11 -0
- data/lib/fulgur/margin.rb +36 -0
- data/lib/fulgur/version.rb +5 -0
- data/lib/fulgur.rb +19 -0
- metadata +60 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a59f68ed163b7a1d7dddfdc0481bcbcf7844affea4fa3f32c191e5cbf3e3cb9b
|
|
4
|
+
data.tar.gz: 3abf8a424ad6a25473bdfe87c2ae5d77147bef8c8bc549d3b5d6368b692b6e75
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 40b12fb4eb1c2d2a74b1e9f03f4a7c5c0e972ecc50d1b150f2135ba7d2b365d9e5e9ed61373d23c870fc2f3c518c00d1a724f8d27c272a2447dd7ddaeddbda12
|
|
7
|
+
data.tar.gz: c2fccbabda140f27c3b8c8d94d87f260b40dcce8b47355212af35c3402460db091b37642321ac62cc0bd15127cbe194718b4285edc15a5e0f62e0259e6c5de89
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the `fulgur` gem will be documented here.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [0.0.1] - 2026-04-17
|
|
8
|
+
|
|
9
|
+
Initial Ruby binding for fulgur.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `Fulgur::Engine` (kwargs constructor + builder chain)
|
|
14
|
+
- `Fulgur::EngineBuilder` for reusable engine construction
|
|
15
|
+
- `Fulgur::AssetBundle` with long (`add_*`) and short (`css`, `font_file`, etc.) aliases
|
|
16
|
+
- `Fulgur::PageSize` with `A4` / `LETTER` / `A3` constants and `.custom(w_mm, h_mm)`; accepts `Symbol`, `String`, or class constants as input
|
|
17
|
+
- `Fulgur::Margin` with CSS-style positional args, keyword args, and `.uniform` / `.symmetric` factories
|
|
18
|
+
- `Fulgur::Pdf` result object: `#to_s` (ASCII-8BIT), `#to_base64`, `#to_data_uri`, `#write_to_path`, `#write_to_io` (64 KiB chunked, binmode-guaranteed), `#bytesize`
|
|
19
|
+
- `Engine#render_html` and `Engine#render_html_to_file` release the GVL during the Rust render call
|
|
20
|
+
- Error hierarchy: `Fulgur::Error` / `Fulgur::RenderError` / `Fulgur::AssetError`, plus standard `ArgumentError` / `Errno::ENOENT`
|
|
21
|
+
- Ruby 3.3+ support
|
|
22
|
+
|
|
23
|
+
### Known Limitations
|
|
24
|
+
|
|
25
|
+
- Precompiled gems / RubyGems publish automation are tracked separately (fulgur-qyf) and not yet in place; gems must be built from source for now
|
|
26
|
+
- Streaming renderer: Krilla emits bytes at the end of rendering, so `#write_to_io` chunks a completed buffer rather than streaming during layout
|
|
27
|
+
- No Ractor safety analysis yet
|
data/LICENSE-MIT
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mitsuru Takigahira
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# fulgur
|
|
2
|
+
|
|
3
|
+
Ruby bindings for [fulgur](https://github.com/mitsuru/fulgur) — an offline,
|
|
4
|
+
deterministic HTML/CSS to PDF conversion library written in Rust.
|
|
5
|
+
|
|
6
|
+
## Status
|
|
7
|
+
|
|
8
|
+
**MVP (gem v0.0.1, unreleased).** The core `Engine` / `EngineBuilder` /
|
|
9
|
+
`AssetBundle` / `PageSize` / `Margin` / `Pdf` API is available. Precompiled
|
|
10
|
+
gems, batch rendering, sandboxing, and template-engine wiring are planned
|
|
11
|
+
for later releases.
|
|
12
|
+
|
|
13
|
+
> **Versioning note:** the `fulgur` gem is versioned independently from the
|
|
14
|
+
> underlying `fulgur` Rust crate and the `pyfulgur` PyPI package. This gem
|
|
15
|
+
> starts at `0.0.1` as an MVP and will bump on its own cadence. "v0.5.0"
|
|
16
|
+
> elsewhere in project documents refers to the parent epic that bundles
|
|
17
|
+
> the Rust / Python / Ruby shipping milestones, not this gem's version.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
> **Note:** v0.0.1 is an early MVP. Pre-built gems are not yet published to
|
|
22
|
+
> RubyGems; build from source for now.
|
|
23
|
+
|
|
24
|
+
Requires a Rust toolchain (1.85+) and Ruby 3.3+.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# From a checkout of the fulgur repository
|
|
28
|
+
cd crates/fulgur-ruby
|
|
29
|
+
bundle install
|
|
30
|
+
bundle exec rake compile
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Once pre-built gems ship, installation will be:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
gem install fulgur
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For Bundler:
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
gem "fulgur"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quick start
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
require "fulgur"
|
|
49
|
+
|
|
50
|
+
bundle = Fulgur::AssetBundle.new
|
|
51
|
+
bundle.add_css("body { font-family: sans-serif; }")
|
|
52
|
+
|
|
53
|
+
engine = Fulgur::Engine.new(page_size: :a4, assets: bundle)
|
|
54
|
+
pdf = engine.render_html("<h1>Hello, world!</h1>")
|
|
55
|
+
|
|
56
|
+
pdf.write_to_path("output.pdf")
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Builder style:
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
engine = Fulgur::Engine.builder
|
|
63
|
+
.page_size(Fulgur::PageSize::A4)
|
|
64
|
+
.landscape(false)
|
|
65
|
+
.title("My doc")
|
|
66
|
+
.assets(bundle)
|
|
67
|
+
.build
|
|
68
|
+
|
|
69
|
+
engine.render_html_to_file("<h1>Hi</h1>", "out.pdf")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API surface
|
|
73
|
+
|
|
74
|
+
### `Fulgur::Engine`
|
|
75
|
+
|
|
76
|
+
Keyword-argument constructor:
|
|
77
|
+
|
|
78
|
+
```ruby
|
|
79
|
+
engine = Fulgur::Engine.new(
|
|
80
|
+
page_size: :a4, # Symbol, String, or Fulgur::PageSize
|
|
81
|
+
margin: Fulgur::Margin.uniform(72),
|
|
82
|
+
landscape: false,
|
|
83
|
+
title: "My Document",
|
|
84
|
+
author: "Me",
|
|
85
|
+
lang: "en",
|
|
86
|
+
bookmarks: true,
|
|
87
|
+
assets: bundle, # Fulgur::AssetBundle
|
|
88
|
+
)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Or use the builder:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
engine = Fulgur::Engine.builder
|
|
95
|
+
.page_size(:letter)
|
|
96
|
+
.margin(Fulgur::Margin.new(72, 36, 48, 24))
|
|
97
|
+
.assets(bundle)
|
|
98
|
+
.build
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Rendering
|
|
102
|
+
|
|
103
|
+
```ruby
|
|
104
|
+
pdf = engine.render_html(html_string) # => Fulgur::Pdf
|
|
105
|
+
engine.render_html_to_file(html, "out.pdf") # shortcut
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`render_html` and `render_html_to_file` release the GVL, allowing other
|
|
109
|
+
Ruby threads to run concurrently during rendering.
|
|
110
|
+
|
|
111
|
+
### `Fulgur::Pdf` (render result)
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
pdf.bytesize # => Integer
|
|
115
|
+
pdf.to_s # => String (ASCII-8BIT binary)
|
|
116
|
+
pdf.to_base64 # => String (Base64)
|
|
117
|
+
pdf.to_data_uri # => "data:application/pdf;base64,..."
|
|
118
|
+
pdf.write_to_path("out.pdf") # write raw bytes to file path
|
|
119
|
+
pdf.write_to_io(io) # chunked write to any IO (calls binmode when supported)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The result object keeps bytes on the Rust side. Methods like `to_base64`
|
|
123
|
+
encode directly from the Rust buffer, avoiding an intermediate Ruby binary
|
|
124
|
+
String. For server-side batch workloads rendering many PDFs, this halves
|
|
125
|
+
peak memory compared with `Base64.strict_encode64(bytes)` on the Ruby
|
|
126
|
+
side.
|
|
127
|
+
|
|
128
|
+
### `Fulgur::AssetBundle`
|
|
129
|
+
|
|
130
|
+
Offline-first: all assets must be explicitly registered.
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
bundle = Fulgur::AssetBundle.new
|
|
134
|
+
bundle.add_css("body { font-family: 'Noto Sans' }")
|
|
135
|
+
bundle.add_css_file("style.css")
|
|
136
|
+
bundle.add_font_file("NotoSans-Regular.ttf")
|
|
137
|
+
bundle.add_image("logo", File.binread("logo.png"))
|
|
138
|
+
bundle.add_image_file("icon", "icon.png")
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Short aliases are also available:
|
|
142
|
+
|
|
143
|
+
```ruby
|
|
144
|
+
bundle.css "..."
|
|
145
|
+
bundle.css_file "style.css"
|
|
146
|
+
bundle.font_file "NotoSans.ttf"
|
|
147
|
+
bundle.image "logo", bytes
|
|
148
|
+
bundle.image_file "icon", "icon.png"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `Fulgur::PageSize`
|
|
152
|
+
|
|
153
|
+
```ruby
|
|
154
|
+
Fulgur::PageSize::A4
|
|
155
|
+
Fulgur::PageSize::LETTER
|
|
156
|
+
Fulgur::PageSize::A3
|
|
157
|
+
Fulgur::PageSize.custom(100, 200) # width/height in mm
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Engine kwargs and builder also accept `:a4`, `"A4"`, etc. as shorthand.
|
|
161
|
+
|
|
162
|
+
### `Fulgur::Margin`
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
Fulgur::Margin.new(72) # uniform
|
|
166
|
+
Fulgur::Margin.new(72, 36) # [vertical, horizontal]
|
|
167
|
+
Fulgur::Margin.new(72, 36, 48, 24) # [top, right, bottom, left]
|
|
168
|
+
Fulgur::Margin.new(top: 72, right: 36, bottom: 48, left: 24)
|
|
169
|
+
Fulgur::Margin.uniform(72)
|
|
170
|
+
Fulgur::Margin.symmetric(72, 36)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
All values are in points (pt).
|
|
174
|
+
|
|
175
|
+
## LLM integration
|
|
176
|
+
|
|
177
|
+
`Fulgur::Pdf#to_base64` and `#to_data_uri` are optimized for passing PDFs
|
|
178
|
+
to LLMs as base64-encoded payloads (e.g., Anthropic Claude, OpenAI GPT-4):
|
|
179
|
+
|
|
180
|
+
```ruby
|
|
181
|
+
pdf = engine.render_html(html)
|
|
182
|
+
|
|
183
|
+
anthropic.messages.create(
|
|
184
|
+
model: "claude-opus-4-7",
|
|
185
|
+
messages: [{
|
|
186
|
+
role: "user",
|
|
187
|
+
content: [
|
|
188
|
+
{
|
|
189
|
+
type: "document",
|
|
190
|
+
source: {
|
|
191
|
+
type: "base64",
|
|
192
|
+
media_type: "application/pdf",
|
|
193
|
+
data: pdf.to_base64,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{ type: "text", text: "Summarize this document." },
|
|
197
|
+
],
|
|
198
|
+
}],
|
|
199
|
+
)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Errors
|
|
203
|
+
|
|
204
|
+
```text
|
|
205
|
+
Fulgur::Error # base class (StandardError)
|
|
206
|
+
Fulgur::RenderError # rendering failure (HTML parse, layout, PDF generation, WOFF decode)
|
|
207
|
+
Fulgur::AssetError # asset registration failure (unsupported font format, invalid asset)
|
|
208
|
+
|
|
209
|
+
ArgumentError # invalid arguments (unknown page_size, malformed margin)
|
|
210
|
+
Errno::ENOENT # missing font/image/CSS file
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Development
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
cd crates/fulgur-ruby
|
|
217
|
+
bundle install
|
|
218
|
+
bundle exec rake compile # builds the Rust extension
|
|
219
|
+
bundle exec rspec # runs tests
|
|
220
|
+
bundle exec rake # compile + test
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
The native extension lives under `ext/fulgur/`, the Ruby-side wrappers
|
|
224
|
+
under `lib/`, and Rust sources under `src/`.
|
|
225
|
+
|
|
226
|
+
## Links
|
|
227
|
+
|
|
228
|
+
- [fulgur on GitHub](https://github.com/mitsuru/fulgur)
|
|
229
|
+
- [fulgur on crates.io](https://crates.io/crates/fulgur)
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
Licensed under either of Apache License, Version 2.0 or MIT license at
|
|
234
|
+
your option.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Fulgur
|
|
4
|
+
class AssetBundle
|
|
5
|
+
alias_method :css, :add_css
|
|
6
|
+
alias_method :css_file, :add_css_file
|
|
7
|
+
alias_method :font_file, :add_font_file
|
|
8
|
+
alias_method :image, :add_image
|
|
9
|
+
alias_method :image_file, :add_image_file
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Fulgur
|
|
4
|
+
class Margin
|
|
5
|
+
class << self
|
|
6
|
+
alias_method :__native_new__, :new
|
|
7
|
+
|
|
8
|
+
def new(*args, **kwargs)
|
|
9
|
+
unless kwargs.empty?
|
|
10
|
+
raise ArgumentError, "positional and kwargs are mutually exclusive" unless args.empty?
|
|
11
|
+
|
|
12
|
+
required = %i[top right bottom left]
|
|
13
|
+
missing = required - kwargs.keys
|
|
14
|
+
raise ArgumentError, "missing keys: #{missing.join(", ")}" unless missing.empty?
|
|
15
|
+
|
|
16
|
+
t, r, b, l = kwargs.values_at(*required).map(&:to_f)
|
|
17
|
+
return __build__(t, r, b, l)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
case args.length
|
|
21
|
+
when 1
|
|
22
|
+
v = args[0].to_f
|
|
23
|
+
__build__(v, v, v, v)
|
|
24
|
+
when 2
|
|
25
|
+
vv, hh = args.map(&:to_f)
|
|
26
|
+
__build__(vv, hh, vv, hh)
|
|
27
|
+
when 4
|
|
28
|
+
t, r, b, l = args.map(&:to_f)
|
|
29
|
+
__build__(t, r, b, l)
|
|
30
|
+
else
|
|
31
|
+
raise ArgumentError, "wrong number of arguments (#{args.length} for 1, 2, 4, or kwargs)"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/fulgur.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "fulgur/version"
|
|
4
|
+
|
|
5
|
+
begin
|
|
6
|
+
minor = RUBY_VERSION[/\A\d+\.\d+/]
|
|
7
|
+
require_relative "fulgur/#{minor}/fulgur"
|
|
8
|
+
rescue LoadError
|
|
9
|
+
require_relative "fulgur/fulgur"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module Fulgur
|
|
13
|
+
class Error < StandardError; end
|
|
14
|
+
class RenderError < Error; end
|
|
15
|
+
class AssetError < Error; end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
require_relative "fulgur/margin"
|
|
19
|
+
require_relative "fulgur/asset_bundle"
|
metadata
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: fulgur
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.5.0
|
|
5
|
+
platform: aarch64-linux
|
|
6
|
+
authors:
|
|
7
|
+
- Mitsuru Hayasaka
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-04-18 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Ruby bindings for fulgur, a deterministic HTML/CSS to PDF rendering engine.
|
|
14
|
+
email:
|
|
15
|
+
- hayasaka.mitsuru@gmail.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- CHANGELOG.md
|
|
21
|
+
- LICENSE-MIT
|
|
22
|
+
- README.md
|
|
23
|
+
- lib/fulgur.rb
|
|
24
|
+
- lib/fulgur/3.1/fulgur.so
|
|
25
|
+
- lib/fulgur/3.2/fulgur.so
|
|
26
|
+
- lib/fulgur/3.3/fulgur.so
|
|
27
|
+
- lib/fulgur/3.4/fulgur.so
|
|
28
|
+
- lib/fulgur/asset_bundle.rb
|
|
29
|
+
- lib/fulgur/margin.rb
|
|
30
|
+
- lib/fulgur/version.rb
|
|
31
|
+
homepage: https://github.com/mitsuru/fulgur
|
|
32
|
+
licenses:
|
|
33
|
+
- Apache-2.0
|
|
34
|
+
- MIT
|
|
35
|
+
metadata:
|
|
36
|
+
allowed_push_host: https://rubygems.org
|
|
37
|
+
source_code_uri: https://github.com/mitsuru/fulgur
|
|
38
|
+
post_install_message:
|
|
39
|
+
rdoc_options: []
|
|
40
|
+
require_paths:
|
|
41
|
+
- lib
|
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '3.1'
|
|
47
|
+
- - "<"
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: 3.5.dev
|
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
requirements: []
|
|
56
|
+
rubygems_version: 3.5.23
|
|
57
|
+
signing_key:
|
|
58
|
+
specification_version: 4
|
|
59
|
+
summary: Offline HTML/CSS → PDF conversion
|
|
60
|
+
test_files: []
|