xberg 0.1.0 → 1.0.0.pre.rc.4

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: 4613ff8d41c5a493c91850c6232ad4284e88c7357c00d01280ed5fc6e96037ef
4
- data.tar.gz: f1ce432eae2afeaffd51e295f38662860f08952287104e1e7378f22620590f21
3
+ metadata.gz: 0f60934602c639945ecbda935c02cabe03df8fe8de5bcddcc0899dba68efe646
4
+ data.tar.gz: 82b50843c61556eb6792503bfb42705a5c7fb9e6b56c978a809b2fea0cb88114
5
5
  SHA512:
6
- metadata.gz: efd689846e2edd2d73f6ddaa722a3be3d9ac20aa14c38cfb3ae15c6d3fae081872242a81173de03dffaafba6075370281fe9a51079ea387a53585e4937d4e8b1
7
- data.tar.gz: d654949cb1cd1524a4e7302d8724aa344f056cdec560144ba6f3a496b4086a28ce89a50deb9acb95e7129c2daa75f825ef7cdf9ca9b0fb085553a963903e86a7
6
+ metadata.gz: d68291a01b8624efaaf620858afdcab0f45791da334e2684a0d1717082a0a4e1d46222f88935f99f149490efb9c45129c69b53fc82cc8f1cb90dfe7276db9dfa
7
+ data.tar.gz: 19871a4ca7b01cc2592ab6727ded46818c9a3ffcd19a8e6dacca9447067faa86e9b69f528bd4eca1e42d397d9784bc612894c0b8eddb3631f8499d5676d795e7
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Kreuzberg, Inc.
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 CHANGED
@@ -1,11 +1,476 @@
1
- # xberg
1
+ # Xberg for Ruby
2
2
 
3
- `xberg` is the Xberg package alias for
4
- [Kreuzberg](https://rubygems.org/gems/kreuzberg).
3
+ <div align="center" style="display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 20px 0;">
4
+ <a href="https://github.com/xberg-io/alef">
5
+ <img src="https://img.shields.io/badge/Bindings-alef%20%D7%90-007ec6" alt="Bindings">
6
+ </a>
7
+ <!-- Language Bindings -->
8
+ <a href="https://crates.io/crates/xberg">
9
+ <img src="https://img.shields.io/crates/v/xberg?label=Rust&color=007ec6" alt="Rust">
10
+ </a>
11
+ <a href="https://pypi.org/project/xberg/">
12
+ <img src="https://img.shields.io/pypi/v/xberg?label=Python&color=007ec6" alt="Python">
13
+ </a>
14
+ <a href="https://www.npmjs.com/package/@xberg-io/xberg">
15
+ <img src="https://img.shields.io/npm/v/@xberg-io/xberg?label=Node.js&color=007ec6" alt="Node.js">
16
+ </a>
17
+ <a href="https://www.npmjs.com/package/@xberg-io/xberg-wasm">
18
+ <img src="https://img.shields.io/npm/v/@xberg-io/xberg-wasm?label=WASM&color=007ec6" alt="WASM">
19
+ </a>
20
+ <a href="https://central.sonatype.com/artifact/io.xberg/xberg">
21
+ <img src="https://img.shields.io/maven-central/v/io.xberg/xberg?label=Java&color=007ec6" alt="Java">
22
+ </a>
23
+ <a href="https://github.com/xberg-io/xberg/tree/main/packages/go">
24
+ <img src="https://img.shields.io/github/v/tag/xberg-io/xberg?label=Go&color=007ec6&filter=v1*" alt="Go">
25
+ </a>
26
+ <a href="https://www.nuget.org/packages/Xberg/">
27
+ <img src="https://img.shields.io/nuget/v/Xberg?label=C%23&color=007ec6" alt="C#">
28
+ </a>
29
+ <a href="https://packagist.org/packages/xberg-io/xberg">
30
+ <img src="https://img.shields.io/packagist/v/xberg-io/xberg?label=PHP&color=007ec6" alt="PHP">
31
+ </a>
32
+ <a href="https://rubygems.org/gems/xberg">
33
+ <img src="https://img.shields.io/gem/v/xberg?label=Ruby&color=007ec6" alt="Ruby">
34
+ </a>
35
+ <a href="https://hex.pm/packages/xberg">
36
+ <img src="https://img.shields.io/hexpm/v/xberg?label=Elixir&color=007ec6" alt="Elixir">
37
+ </a>
38
+ <a href="https://pub.dev/packages/xberg">
39
+ <img src="https://img.shields.io/pub/v/xberg?label=Dart&color=007ec6" alt="Dart">
40
+ </a>
41
+ <a href="https://central.sonatype.com/artifact/io.xberg/xberg-android">
42
+ <img src="https://img.shields.io/maven-central/v/io.xberg/xberg-android?label=Kotlin&color=007ec6" alt="Kotlin">
43
+ </a>
44
+ <a href="https://github.com/xberg-io/xberg/tree/main/packages/swift">
45
+ <img src="https://img.shields.io/badge/Swift-SPM-007ec6" alt="Swift">
46
+ </a>
47
+ <a href="https://github.com/xberg-io/xberg/tree/main/packages/zig">
48
+ <img src="https://img.shields.io/badge/Zig-package-007ec6" alt="Zig">
49
+ </a>
50
+ <a href="https://github.com/xberg-io/xberg/releases">
51
+ <img src="https://img.shields.io/badge/C-FFI-007ec6" alt="C FFI">
52
+ </a>
53
+ <a href="https://github.com/xberg-io/xberg/pkgs/container/xberg">
54
+ <img src="https://img.shields.io/badge/Docker-ghcr.io-007ec6?logo=docker&logoColor=white" alt="Docker">
55
+ </a>
56
+ <!-- Project Info -->
57
+ <a href="https://github.com/xberg-io/xberg/blob/main/LICENSE">
58
+ <img src="https://img.shields.io/badge/License-MIT-007ec6" alt="License">
59
+ </a>
60
+ <a href="https://docs.xberg.io">
61
+ <img src="https://img.shields.io/badge/Docs-xberg-007ec6" alt="Documentation">
62
+ </a>
63
+ <a href="https://huggingface.co/xberg-io">
64
+ <img src="https://img.shields.io/badge/Hugging%20Face-Xberg-007ec6" alt="Hugging Face">
65
+ </a>
66
+ </div>
5
67
 
6
- The canonical Ruby gem remains `kreuzberg` today. This gem reserves the Xberg
7
- namespace and loads the same API.
68
+ <div align="center" style="display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin: 28px 0 24px;">
69
+ <a href="https://discord.gg/xt9WY3GnKR">
70
+ <img height="22" src="https://img.shields.io/badge/Discord-Chat-007ec6?logo=discord&logoColor=white" alt="Join Discord">
71
+ </a>
72
+ <a href="https://docs.xberg.io/demo.html">
73
+ <img height="22" src="https://img.shields.io/badge/Live%20Demo-Open-007ec6?logo=webassembly&logoColor=white" alt="Live Demo">
74
+ </a>
75
+ <a href="https://github.com/xberg-io/xberg/stargazers">
76
+ <img height="22" src="https://img.shields.io/github/stars/xberg-io/xberg?style=social" alt="GitHub Stars">
77
+ </a>
78
+ </div>
79
+
80
+ Extract text, tables, images, metadata, and code intelligence from 96 file formats and 306 programming languages including PDF, Office documents, images, and audio/video transcripts where native transcription is available. Ruby bindings with idiomatic Ruby API and native performance.
81
+
82
+ ## What This Package Provides
83
+
84
+ - **Ruby-native extraction** — idiomatic Ruby objects over the shared Rust document engine.
85
+ - **Structured results** — an `ExtractionResult` envelope with `ExtractedDocument` items, errors, and summary counts.
86
+ - **OCR support** — Tesseract and PaddleOCR through the same configuration model as other bindings.
87
+ - **Cross-binding parity** — output matches the Python, Node.js, Go, Java, .NET, PHP, Elixir, Dart, Swift, Zig, WASM, and C FFI packages.
88
+
89
+ ## Installation
90
+
91
+ Add to your Gemfile:
92
+
93
+ ```ruby
94
+ gem 'xberg'
95
+ ```
96
+
97
+ Then execute:
98
+
99
+ ```bash
100
+ bundle install
101
+ ```
102
+
103
+ Or install it directly:
104
+
105
+ ```bash
106
+ gem install xberg
107
+ ```
108
+
109
+ ## Quick Start
110
+
111
+ ### Basic Usage
112
+
113
+ ```ruby
114
+ require 'xberg'
115
+
116
+ input = Xberg::ExtractInput.new(kind: "uri", uri: "document.pdf")
117
+ output = Xberg.extract(input, Xberg::ExtractionConfig.new)
118
+ document = output.results.first
119
+
120
+ puts document.content
121
+ puts "Results: #{output.summary.results}"
122
+ ```
123
+
124
+ ### Batch Processing
125
+
126
+ ```ruby
127
+ require 'xberg'
128
+
129
+ bytes = File.binread("doc3.txt")
130
+ inputs = [
131
+ Xberg::ExtractInput.new(kind: "uri", uri: "doc1.pdf"),
132
+ Xberg::ExtractInput.new(kind: "uri", uri: "doc2.docx"),
133
+ Xberg::ExtractInput.new(
134
+ kind: "bytes",
135
+ bytes: bytes,
136
+ mime_type: "text/plain",
137
+ filename: "doc3.txt"
138
+ ),
139
+ ]
140
+
141
+ output = Xberg.extract_batch(inputs, Xberg::ExtractionConfig.new)
142
+
143
+ output.results.each do |document|
144
+ puts "Content length: #{document.content.length}"
145
+ end
146
+ ```
147
+
148
+ ## Configuration
149
+
150
+ ```ruby
151
+ require 'xberg'
152
+
153
+ config = Xberg::ExtractionConfig.new(
154
+ use_cache: true,
155
+ enable_quality_processing: true,
156
+ ocr: Xberg::OcrConfig.new(
157
+ backend: 'tesseract',
158
+ language: 'eng'
159
+ )
160
+ )
161
+
162
+ input = Xberg::ExtractInput.new(kind: "uri", uri: "document.pdf")
163
+ output = Xberg.extract(input, config)
164
+ document = output.results.first
165
+
166
+ puts document.content
167
+ ```
168
+
169
+ ## OCR Support
170
+
171
+ ### Tesseract Configuration
172
+
173
+ ```ruby
174
+ require 'xberg'
175
+
176
+ config = Xberg::ExtractionConfig.new(
177
+ ocr: Xberg::OcrConfig.new(
178
+ backend: 'tesseract',
179
+ language: 'eng',
180
+ tesseract_config: Xberg::TesseractConfig.new(
181
+ psm: 6,
182
+ enable_table_detection: true
183
+ )
184
+ )
185
+ )
186
+
187
+ input = Xberg::ExtractInput.new(kind: "uri", uri: "scanned.pdf")
188
+ output = Xberg.extract(input, config)
189
+ document = output.results.first
190
+
191
+ puts document.content
192
+ ```
193
+
194
+ ## Table Extraction
195
+
196
+ ```ruby
197
+ require 'xberg'
198
+
199
+ config = Xberg::ExtractionConfig.new(
200
+ ocr: Xberg::OcrConfig.new(
201
+ backend: 'tesseract',
202
+ tesseract_config: Xberg::TesseractConfig.new(
203
+ enable_table_detection: true
204
+ )
205
+ )
206
+ )
207
+
208
+ input = Xberg::ExtractInput.new(kind: "uri", uri: "invoice.pdf")
209
+ output = Xberg.extract(input, config)
210
+ document = output.results.first
211
+
212
+ document.tables.each_with_index do |table, index|
213
+ puts "Table #{index}:"
214
+ puts table.markdown
215
+ end
216
+ ```
217
+
218
+ ## Metadata Extraction
219
+
220
+ ```ruby
221
+ require 'xberg'
222
+
223
+ input = Xberg::ExtractInput.new(kind: "uri", uri: "document.pdf")
224
+ output = Xberg.extract(input, Xberg::ExtractionConfig.new)
225
+ document = output.results.first
226
+
227
+ metadata = document.metadata
228
+ puts "Title: #{metadata.title}" if metadata&.title
229
+ if metadata&.authors
230
+ puts "Authors: #{metadata.authors.join(', ')}"
231
+ end
232
+
233
+ puts "Languages: #{document.detected_languages}"
234
+
235
+ if document.images
236
+ puts "Images found: #{document.images.count}"
237
+ end
238
+ ```
239
+
240
+ ## Text Chunking
241
+
242
+ ```ruby
243
+ require 'xberg'
244
+
245
+ config = Xberg::ExtractionConfig.new(
246
+ chunking: Xberg::ChunkingConfig.new(
247
+ max_chars: 1000,
248
+ max_overlap: 200
249
+ )
250
+ )
251
+
252
+ input = Xberg::ExtractInput.new(kind: "uri", uri: "long_document.pdf")
253
+ output = Xberg.extract(input, config)
254
+ document = output.results.first
255
+
256
+ document.chunks.each_with_index do |chunk, index|
257
+ puts "Chunk #{index}: #{chunk.content.length} characters"
258
+ end
259
+ ```
260
+
261
+ ## Password-Protected PDFs
8
262
 
9
263
  ```ruby
10
- require "xberg"
264
+ require 'xberg'
265
+
266
+ config = Xberg::ExtractionConfig.new(
267
+ pdf_options: Xberg::PdfConfig.new(
268
+ passwords: ["password1", "password2"]
269
+ )
270
+ )
271
+
272
+ input = Xberg::ExtractInput.new(kind: "uri", uri: "protected.pdf")
273
+ output = Xberg.extract(input, config)
274
+ document = output.results.first
275
+
276
+ puts document.content
11
277
  ```
278
+
279
+ ## Language Detection
280
+
281
+ ```ruby
282
+ require 'xberg'
283
+
284
+ config = Xberg::ExtractionConfig.new(
285
+ language_detection: Xberg::LanguageDetectionConfig.new(
286
+ enabled: true
287
+ )
288
+ )
289
+
290
+ input = Xberg::ExtractInput.new(kind: "uri", uri: "multilingual.pdf")
291
+ output = Xberg.extract(input, config)
292
+ document = output.results.first
293
+
294
+ puts "Detected languages: #{document.detected_languages}"
295
+ ```
296
+
297
+ ## API Reference
298
+
299
+ ### Main Methods
300
+
301
+ - `Xberg.extract(input, config)` – Extract one URI or bytes input.
302
+ - `Xberg.extract_batch(inputs, config)` – Extract multiple URI or bytes inputs.
303
+ - `Xberg::ExtractInput.new(kind: "uri", uri: "document.pdf")` – Local path, `file://`, or HTTP(S) URI input.
304
+ - `Xberg::ExtractInput.new(kind: "bytes", bytes: data, mime_type: "application/pdf")` – In-memory bytes input.
305
+
306
+ ### Configuration Classes
307
+
308
+ - `ExtractionConfig` – Main configuration
309
+ - `OcrConfig` – OCR settings
310
+ - `TesseractConfig` – Tesseract-specific options
311
+ - `ChunkingConfig` – Text chunking settings
312
+ - `PdfConfig` – PDF-specific options
313
+ - `LanguageDetectionConfig` – Language detection settings
314
+
315
+ ### Result Types
316
+
317
+ - `ExtractionResult` – Envelope with `results`, `errors`, and `summary`.
318
+ - `ExtractedDocument` – Per-document item at `output.results.first` with content, metadata, tables, and chunks.
319
+ - `Table` – Table with `cells`, `markdown`, and `page_number`.
320
+ - `Metadata` – Typed document metadata.
321
+
322
+ ## System Requirements
323
+
324
+ ### Ruby Version
325
+
326
+ - **Ruby 3.2.0 or higher** (including Ruby 4.x)
327
+ - Ruby 4.0+ is fully supported with no code changes required
328
+ - Magnus bindings compile successfully on all supported Ruby versions
329
+
330
+ ### Required
331
+
332
+ - Rust toolchain (for native extension compilation)
333
+
334
+ ### Optional
335
+
336
+ ```bash
337
+ # Tesseract OCR
338
+ brew install tesseract # macOS
339
+ sudo apt-get install tesseract-ocr # Ubuntu/Debian
340
+ ```
341
+
342
+ ### Ruby 4.0 Compatibility
343
+
344
+ Xberg is fully compatible with Ruby 4.0 (released December 25, 2025) and later. Key Ruby 4.0 features that work seamlessly:
345
+
346
+ - **Ruby Box** - Improved memory efficiency and performance
347
+ - **ZJIT Compiler** - Enhanced JIT compilation for faster execution
348
+ - **Ractor Improvements** - Better multi-threaded document processing
349
+ - **Set Promoted to Core** - No changes needed for Xberg
350
+
351
+ All tests pass with Ruby 4.0.1 with 100% compatibility. The gem compiles without any breaking changes.
352
+
353
+ ## Development
354
+
355
+ Clone and setup:
356
+
357
+ ```bash
358
+ git clone https://github.com/xberg-io/xberg.git
359
+ cd xberg
360
+ bundle install
361
+ ```
362
+
363
+ Run tests:
364
+
365
+ ```bash
366
+ rake test
367
+ ```
368
+
369
+ ## Troubleshooting
370
+
371
+ ### Native extension compilation error
372
+
373
+ Ensure build tools are installed:
374
+
375
+ ```bash
376
+ # macOS
377
+ xcode-select --install
378
+
379
+ # Ubuntu/Debian
380
+ sudo apt-get install build-essential ruby-dev
381
+
382
+ # Windows (via RubyInstaller)
383
+ ridk install
384
+ ```
385
+
386
+ ### "Could not find Xberg"
387
+
388
+ Reinstall the gem:
389
+
390
+ ```bash
391
+ gem uninstall xberg
392
+ gem install xberg --no-document
393
+ ```
394
+
395
+ ### OCR not working
396
+
397
+ Verify Tesseract is installed:
398
+
399
+ ```bash
400
+ tesseract --version
401
+ ```
402
+
403
+ ## Examples
404
+
405
+ ### Process Directory of PDFs
406
+
407
+ ```ruby
408
+ require 'xberg'
409
+ require 'pathname'
410
+
411
+ Dir.glob("documents/*.pdf").each do |file|
412
+ puts "Processing: #{file}"
413
+ input = Xberg::ExtractInput.new(kind: "uri", uri: file)
414
+ output = Xberg.extract(input, Xberg::ExtractionConfig.new)
415
+ document = output.results.first
416
+
417
+ puts " Content length: #{document.content.length}"
418
+ puts " Language: #{document.detected_languages}"
419
+ end
420
+ ```
421
+
422
+ ### Extract and Parse Structured Data
423
+
424
+ ```ruby
425
+ require 'xberg'
426
+ require 'json'
427
+
428
+ input = Xberg::ExtractInput.new(kind: "uri", uri: "data.pdf")
429
+ output = Xberg.extract(input, Xberg::ExtractionConfig.new)
430
+ document = output.results.first
431
+
432
+ # Parse content as JSON (if applicable)
433
+ begin
434
+ data = JSON.parse(document.content)
435
+ puts "Parsed data: #{data}"
436
+ rescue JSON::ParserError
437
+ puts "Content is not JSON"
438
+ end
439
+ ```
440
+
441
+ ### Save Extracted Images
442
+
443
+ ```ruby
444
+ require 'xberg'
445
+
446
+ config = Xberg::ExtractionConfig.new(
447
+ images: Xberg::ImageExtractionConfig.new(
448
+ extract_images: true
449
+ )
450
+ )
451
+
452
+ input = Xberg::ExtractInput.new(kind: "uri", uri: "document.pdf")
453
+ output = Xberg.extract(input, config)
454
+ document = output.results.first
455
+
456
+ document.images&.each_with_index do |image, index|
457
+ File.write("image_#{index}.png", image.data)
458
+ end
459
+ ```
460
+
461
+ ## Documentation
462
+
463
+ For comprehensive documentation, visit [https://xberg.io](https://xberg.io)
464
+
465
+ ## Part of Xberg.dev
466
+
467
+ - [crawlberg](https://github.com/xberg-io/crawlberg) — web crawling and scraping with HTML→Markdown and headless-Chrome fallback.
468
+ - [html-to-markdown](https://github.com/xberg-io/html-to-markdown) — fast, lossless HTML→Markdown engine.
469
+ - [liter-llm](https://github.com/xberg-io/liter-llm) — universal LLM API client with native bindings for 14 languages and 143 providers.
470
+ - [tree-sitter-language-pack](https://github.com/xberg-io/tree-sitter-language-pack) — tree-sitter grammars and code-intelligence primitives.
471
+ - [alef](https://github.com/xberg-io/alef) — the polyglot binding generator that produces this README and all per-language bindings.
472
+ - [Discord](https://discord.gg/xt9WY3GnKR) — community, roadmap, announcements.
473
+
474
+ ## License
475
+
476
+ MIT License - see [LICENSE](../../LICENSE) for details.
data/Steepfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ target :lib do
4
+ signature "sig"
5
+ check "lib"
6
+ # The generated `lib/xberg/native.rb` carries inline Sorbet
7
+ # `sig { ... }` blocks on tagged-enum variant Data classes. Sorbet's runtime
8
+ # provides those via `extend T::Sig`, but Steep does not understand the
9
+ # extension (it relies on RBS, not Sorbet sigs) and reports
10
+ # `Type `self` does not have method `sig`` on every block. RBS coverage
11
+ # for the same surface lives in `sig/types.rbs`, so we steer Steep to the
12
+ # RBS file by ignoring the .rb.
13
+ ignore "lib/xberg/native.rb"
14
+ end