kreuzberg 4.0.0.rc1 → 4.0.0.rc2
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/.gitignore +14 -8
- data/.rspec +3 -3
- data/.rubocop.yaml +1 -534
- data/.rubocop.yml +538 -0
- data/Gemfile +8 -9
- data/Gemfile.lock +9 -109
- data/README.md +426 -421
- data/Rakefile +25 -25
- data/Steepfile +47 -47
- data/examples/async_patterns.rb +341 -340
- data/ext/kreuzberg_rb/extconf.rb +45 -35
- data/ext/kreuzberg_rb/native/Cargo.lock +6535 -0
- data/ext/kreuzberg_rb/native/Cargo.toml +44 -36
- data/ext/kreuzberg_rb/native/README.md +425 -425
- data/ext/kreuzberg_rb/native/build.rs +15 -17
- data/ext/kreuzberg_rb/native/include/ieeefp.h +11 -11
- data/ext/kreuzberg_rb/native/include/msvc_compat/strings.h +14 -14
- data/ext/kreuzberg_rb/native/include/strings.h +20 -20
- data/ext/kreuzberg_rb/native/include/unistd.h +47 -47
- data/ext/kreuzberg_rb/native/src/lib.rs +2998 -2939
- data/extconf.rb +28 -28
- data/kreuzberg.gemspec +148 -105
- data/lib/kreuzberg/api_proxy.rb +142 -142
- data/lib/kreuzberg/cache_api.rb +46 -45
- data/lib/kreuzberg/cli.rb +55 -55
- data/lib/kreuzberg/cli_proxy.rb +127 -127
- data/lib/kreuzberg/config.rb +691 -684
- data/lib/kreuzberg/error_context.rb +32 -0
- data/lib/kreuzberg/errors.rb +118 -50
- data/lib/kreuzberg/extraction_api.rb +85 -84
- data/lib/kreuzberg/mcp_proxy.rb +186 -186
- data/lib/kreuzberg/ocr_backend_protocol.rb +113 -113
- data/lib/kreuzberg/post_processor_protocol.rb +86 -86
- data/lib/kreuzberg/result.rb +216 -216
- data/lib/kreuzberg/setup_lib_path.rb +80 -79
- data/lib/kreuzberg/validator_protocol.rb +89 -89
- data/lib/kreuzberg/version.rb +5 -5
- data/lib/kreuzberg.rb +103 -82
- data/sig/kreuzberg/internal.rbs +184 -184
- data/sig/kreuzberg.rbs +520 -468
- data/spec/binding/cache_spec.rb +227 -227
- data/spec/binding/cli_proxy_spec.rb +85 -87
- data/spec/binding/cli_spec.rb +55 -54
- data/spec/binding/config_spec.rb +345 -345
- data/spec/binding/config_validation_spec.rb +283 -283
- data/spec/binding/error_handling_spec.rb +213 -213
- data/spec/binding/errors_spec.rb +66 -66
- data/spec/binding/plugins/ocr_backend_spec.rb +307 -307
- data/spec/binding/plugins/postprocessor_spec.rb +269 -269
- data/spec/binding/plugins/validator_spec.rb +274 -274
- data/spec/fixtures/config.toml +39 -39
- data/spec/fixtures/config.yaml +41 -42
- data/spec/fixtures/invalid_config.toml +4 -4
- data/spec/smoke/package_spec.rb +178 -178
- data/spec/spec_helper.rb +42 -42
- data/vendor/kreuzberg/Cargo.toml +204 -134
- data/vendor/kreuzberg/README.md +175 -175
- data/vendor/kreuzberg/benches/otel_overhead.rs +48 -0
- data/vendor/kreuzberg/build.rs +474 -460
- data/vendor/kreuzberg/src/api/error.rs +81 -81
- data/vendor/kreuzberg/src/api/handlers.rs +199 -199
- data/vendor/kreuzberg/src/api/mod.rs +79 -79
- data/vendor/kreuzberg/src/api/server.rs +353 -353
- data/vendor/kreuzberg/src/api/types.rs +170 -170
- data/vendor/kreuzberg/src/cache/mod.rs +1167 -1143
- data/vendor/kreuzberg/src/chunking/mod.rs +677 -677
- data/vendor/kreuzberg/src/core/batch_mode.rs +95 -35
- data/vendor/kreuzberg/src/core/config.rs +1032 -1032
- data/vendor/kreuzberg/src/core/extractor.rs +1024 -903
- data/vendor/kreuzberg/src/core/io.rs +329 -327
- data/vendor/kreuzberg/src/core/mime.rs +605 -615
- data/vendor/kreuzberg/src/core/mod.rs +45 -42
- data/vendor/kreuzberg/src/core/pipeline.rs +984 -906
- data/vendor/kreuzberg/src/embeddings.rs +432 -323
- data/vendor/kreuzberg/src/error.rs +431 -431
- data/vendor/kreuzberg/src/extraction/archive.rs +954 -954
- data/vendor/kreuzberg/src/extraction/docx.rs +40 -40
- data/vendor/kreuzberg/src/extraction/email.rs +854 -854
- data/vendor/kreuzberg/src/extraction/excel.rs +688 -688
- data/vendor/kreuzberg/src/extraction/html.rs +553 -553
- data/vendor/kreuzberg/src/extraction/image.rs +368 -368
- data/vendor/kreuzberg/src/extraction/libreoffice.rs +563 -564
- data/vendor/kreuzberg/src/extraction/markdown.rs +213 -0
- data/vendor/kreuzberg/src/extraction/mod.rs +81 -77
- data/vendor/kreuzberg/src/extraction/office_metadata/app_properties.rs +398 -398
- data/vendor/kreuzberg/src/extraction/office_metadata/core_properties.rs +247 -247
- data/vendor/kreuzberg/src/extraction/office_metadata/custom_properties.rs +240 -240
- data/vendor/kreuzberg/src/extraction/office_metadata/mod.rs +130 -128
- data/vendor/kreuzberg/src/extraction/office_metadata/odt_properties.rs +287 -0
- data/vendor/kreuzberg/src/extraction/pptx.rs +3000 -3000
- data/vendor/kreuzberg/src/extraction/structured.rs +490 -490
- data/vendor/kreuzberg/src/extraction/table.rs +328 -328
- data/vendor/kreuzberg/src/extraction/text.rs +269 -269
- data/vendor/kreuzberg/src/extraction/xml.rs +333 -333
- data/vendor/kreuzberg/src/extractors/archive.rs +446 -425
- data/vendor/kreuzberg/src/extractors/bibtex.rs +469 -0
- data/vendor/kreuzberg/src/extractors/docbook.rs +502 -0
- data/vendor/kreuzberg/src/extractors/docx.rs +367 -479
- data/vendor/kreuzberg/src/extractors/email.rs +143 -129
- data/vendor/kreuzberg/src/extractors/epub.rs +707 -0
- data/vendor/kreuzberg/src/extractors/excel.rs +343 -344
- data/vendor/kreuzberg/src/extractors/fictionbook.rs +491 -0
- data/vendor/kreuzberg/src/extractors/fictionbook.rs.backup2 +738 -0
- data/vendor/kreuzberg/src/extractors/html.rs +393 -410
- data/vendor/kreuzberg/src/extractors/image.rs +198 -195
- data/vendor/kreuzberg/src/extractors/jats.rs +1051 -0
- data/vendor/kreuzberg/src/extractors/jupyter.rs +367 -0
- data/vendor/kreuzberg/src/extractors/latex.rs +652 -0
- data/vendor/kreuzberg/src/extractors/markdown.rs +700 -0
- data/vendor/kreuzberg/src/extractors/mod.rs +365 -268
- data/vendor/kreuzberg/src/extractors/odt.rs +628 -0
- data/vendor/kreuzberg/src/extractors/opml.rs +634 -0
- data/vendor/kreuzberg/src/extractors/orgmode.rs +528 -0
- data/vendor/kreuzberg/src/extractors/pdf.rs +493 -496
- data/vendor/kreuzberg/src/extractors/pptx.rs +248 -234
- data/vendor/kreuzberg/src/extractors/rst.rs +576 -0
- data/vendor/kreuzberg/src/extractors/rtf.rs +810 -0
- data/vendor/kreuzberg/src/extractors/security.rs +484 -0
- data/vendor/kreuzberg/src/extractors/security_tests.rs +367 -0
- data/vendor/kreuzberg/src/extractors/structured.rs +140 -126
- data/vendor/kreuzberg/src/extractors/text.rs +260 -242
- data/vendor/kreuzberg/src/extractors/typst.rs +650 -0
- data/vendor/kreuzberg/src/extractors/xml.rs +135 -128
- data/vendor/kreuzberg/src/image/dpi.rs +164 -164
- data/vendor/kreuzberg/src/image/mod.rs +6 -6
- data/vendor/kreuzberg/src/image/preprocessing.rs +417 -417
- data/vendor/kreuzberg/src/image/resize.rs +89 -89
- data/vendor/kreuzberg/src/keywords/config.rs +154 -154
- data/vendor/kreuzberg/src/keywords/mod.rs +237 -237
- data/vendor/kreuzberg/src/keywords/processor.rs +267 -267
- data/vendor/kreuzberg/src/keywords/rake.rs +293 -294
- data/vendor/kreuzberg/src/keywords/types.rs +68 -68
- data/vendor/kreuzberg/src/keywords/yake.rs +163 -163
- data/vendor/kreuzberg/src/language_detection/mod.rs +942 -942
- data/vendor/kreuzberg/src/lib.rs +105 -102
- data/vendor/kreuzberg/src/mcp/mod.rs +32 -32
- data/vendor/kreuzberg/src/mcp/server.rs +1968 -1966
- data/vendor/kreuzberg/src/ocr/cache.rs +469 -469
- data/vendor/kreuzberg/src/ocr/error.rs +37 -37
- data/vendor/kreuzberg/src/ocr/hocr.rs +216 -216
- data/vendor/kreuzberg/src/ocr/mod.rs +58 -58
- data/vendor/kreuzberg/src/ocr/processor.rs +863 -847
- data/vendor/kreuzberg/src/ocr/table/mod.rs +4 -4
- data/vendor/kreuzberg/src/ocr/table/tsv_parser.rs +144 -144
- data/vendor/kreuzberg/src/ocr/tesseract_backend.rs +450 -450
- data/vendor/kreuzberg/src/ocr/types.rs +393 -393
- data/vendor/kreuzberg/src/ocr/utils.rs +47 -47
- data/vendor/kreuzberg/src/ocr/validation.rs +206 -206
- data/vendor/kreuzberg/src/panic_context.rs +154 -0
- data/vendor/kreuzberg/src/pdf/error.rs +122 -122
- data/vendor/kreuzberg/src/pdf/images.rs +139 -139
- data/vendor/kreuzberg/src/pdf/metadata.rs +346 -346
- data/vendor/kreuzberg/src/pdf/mod.rs +50 -50
- data/vendor/kreuzberg/src/pdf/rendering.rs +369 -369
- data/vendor/kreuzberg/src/pdf/table.rs +393 -420
- data/vendor/kreuzberg/src/pdf/text.rs +158 -161
- data/vendor/kreuzberg/src/plugins/extractor.rs +1013 -1010
- data/vendor/kreuzberg/src/plugins/mod.rs +209 -209
- data/vendor/kreuzberg/src/plugins/ocr.rs +620 -629
- data/vendor/kreuzberg/src/plugins/processor.rs +642 -641
- data/vendor/kreuzberg/src/plugins/registry.rs +1337 -1324
- data/vendor/kreuzberg/src/plugins/traits.rs +258 -258
- data/vendor/kreuzberg/src/plugins/validator.rs +956 -955
- data/vendor/kreuzberg/src/stopwords/mod.rs +1470 -1470
- data/vendor/kreuzberg/src/text/mod.rs +19 -19
- data/vendor/kreuzberg/src/text/quality.rs +697 -697
- data/vendor/kreuzberg/src/text/string_utils.rs +217 -217
- data/vendor/kreuzberg/src/text/token_reduction/cjk_utils.rs +164 -164
- data/vendor/kreuzberg/src/text/token_reduction/config.rs +100 -100
- data/vendor/kreuzberg/src/text/token_reduction/core.rs +796 -796
- data/vendor/kreuzberg/src/text/token_reduction/filters.rs +902 -902
- data/vendor/kreuzberg/src/text/token_reduction/mod.rs +160 -160
- data/vendor/kreuzberg/src/text/token_reduction/semantic.rs +619 -619
- data/vendor/kreuzberg/src/text/token_reduction/simd_text.rs +147 -147
- data/vendor/kreuzberg/src/types.rs +903 -873
- data/vendor/kreuzberg/src/utils/mod.rs +17 -17
- data/vendor/kreuzberg/src/utils/quality.rs +959 -959
- data/vendor/kreuzberg/src/utils/string_utils.rs +381 -381
- data/vendor/kreuzberg/stopwords/af_stopwords.json +53 -53
- data/vendor/kreuzberg/stopwords/ar_stopwords.json +482 -482
- data/vendor/kreuzberg/stopwords/bg_stopwords.json +261 -261
- data/vendor/kreuzberg/stopwords/bn_stopwords.json +400 -400
- data/vendor/kreuzberg/stopwords/br_stopwords.json +1205 -1205
- data/vendor/kreuzberg/stopwords/ca_stopwords.json +280 -280
- data/vendor/kreuzberg/stopwords/cs_stopwords.json +425 -425
- data/vendor/kreuzberg/stopwords/da_stopwords.json +172 -172
- data/vendor/kreuzberg/stopwords/de_stopwords.json +622 -622
- data/vendor/kreuzberg/stopwords/el_stopwords.json +849 -849
- data/vendor/kreuzberg/stopwords/en_stopwords.json +1300 -1300
- data/vendor/kreuzberg/stopwords/eo_stopwords.json +175 -175
- data/vendor/kreuzberg/stopwords/es_stopwords.json +734 -734
- data/vendor/kreuzberg/stopwords/et_stopwords.json +37 -37
- data/vendor/kreuzberg/stopwords/eu_stopwords.json +100 -100
- data/vendor/kreuzberg/stopwords/fa_stopwords.json +801 -801
- data/vendor/kreuzberg/stopwords/fi_stopwords.json +849 -849
- data/vendor/kreuzberg/stopwords/fr_stopwords.json +693 -693
- data/vendor/kreuzberg/stopwords/ga_stopwords.json +111 -111
- data/vendor/kreuzberg/stopwords/gl_stopwords.json +162 -162
- data/vendor/kreuzberg/stopwords/gu_stopwords.json +226 -226
- data/vendor/kreuzberg/stopwords/ha_stopwords.json +41 -41
- data/vendor/kreuzberg/stopwords/he_stopwords.json +196 -196
- data/vendor/kreuzberg/stopwords/hi_stopwords.json +227 -227
- data/vendor/kreuzberg/stopwords/hr_stopwords.json +181 -181
- data/vendor/kreuzberg/stopwords/hu_stopwords.json +791 -791
- data/vendor/kreuzberg/stopwords/hy_stopwords.json +47 -47
- data/vendor/kreuzberg/stopwords/id_stopwords.json +760 -760
- data/vendor/kreuzberg/stopwords/it_stopwords.json +634 -634
- data/vendor/kreuzberg/stopwords/ja_stopwords.json +136 -136
- data/vendor/kreuzberg/stopwords/kn_stopwords.json +84 -84
- data/vendor/kreuzberg/stopwords/ko_stopwords.json +681 -681
- data/vendor/kreuzberg/stopwords/ku_stopwords.json +64 -64
- data/vendor/kreuzberg/stopwords/la_stopwords.json +51 -51
- data/vendor/kreuzberg/stopwords/lt_stopwords.json +476 -476
- data/vendor/kreuzberg/stopwords/lv_stopwords.json +163 -163
- data/vendor/kreuzberg/stopwords/ml_stopwords.json +1 -1
- data/vendor/kreuzberg/stopwords/mr_stopwords.json +101 -101
- data/vendor/kreuzberg/stopwords/ms_stopwords.json +477 -477
- data/vendor/kreuzberg/stopwords/ne_stopwords.json +490 -490
- data/vendor/kreuzberg/stopwords/nl_stopwords.json +415 -415
- data/vendor/kreuzberg/stopwords/no_stopwords.json +223 -223
- data/vendor/kreuzberg/stopwords/pl_stopwords.json +331 -331
- data/vendor/kreuzberg/stopwords/pt_stopwords.json +562 -562
- data/vendor/kreuzberg/stopwords/ro_stopwords.json +436 -436
- data/vendor/kreuzberg/stopwords/ru_stopwords.json +561 -561
- data/vendor/kreuzberg/stopwords/si_stopwords.json +193 -193
- data/vendor/kreuzberg/stopwords/sk_stopwords.json +420 -420
- data/vendor/kreuzberg/stopwords/sl_stopwords.json +448 -448
- data/vendor/kreuzberg/stopwords/so_stopwords.json +32 -32
- data/vendor/kreuzberg/stopwords/st_stopwords.json +33 -33
- data/vendor/kreuzberg/stopwords/sv_stopwords.json +420 -420
- data/vendor/kreuzberg/stopwords/sw_stopwords.json +76 -76
- data/vendor/kreuzberg/stopwords/ta_stopwords.json +129 -129
- data/vendor/kreuzberg/stopwords/te_stopwords.json +54 -54
- data/vendor/kreuzberg/stopwords/th_stopwords.json +118 -118
- data/vendor/kreuzberg/stopwords/tl_stopwords.json +149 -149
- data/vendor/kreuzberg/stopwords/tr_stopwords.json +506 -506
- data/vendor/kreuzberg/stopwords/uk_stopwords.json +75 -75
- data/vendor/kreuzberg/stopwords/ur_stopwords.json +519 -519
- data/vendor/kreuzberg/stopwords/vi_stopwords.json +647 -647
- data/vendor/kreuzberg/stopwords/yo_stopwords.json +62 -62
- data/vendor/kreuzberg/stopwords/zh_stopwords.json +796 -796
- data/vendor/kreuzberg/stopwords/zu_stopwords.json +31 -31
- data/vendor/kreuzberg/tests/api_extract_multipart.rs +52 -0
- data/vendor/kreuzberg/tests/api_tests.rs +966 -966
- data/vendor/kreuzberg/tests/archive_integration.rs +543 -543
- data/vendor/kreuzberg/tests/batch_orchestration.rs +556 -542
- data/vendor/kreuzberg/tests/batch_processing.rs +316 -304
- data/vendor/kreuzberg/tests/bibtex_parity_test.rs +421 -0
- data/vendor/kreuzberg/tests/concurrency_stress.rs +525 -509
- data/vendor/kreuzberg/tests/config_features.rs +598 -580
- data/vendor/kreuzberg/tests/config_loading_tests.rs +415 -439
- data/vendor/kreuzberg/tests/core_integration.rs +510 -493
- data/vendor/kreuzberg/tests/csv_integration.rs +414 -424
- data/vendor/kreuzberg/tests/docbook_extractor_tests.rs +498 -0
- data/vendor/kreuzberg/tests/docx_metadata_extraction_test.rs +122 -124
- data/vendor/kreuzberg/tests/docx_vs_pandoc_comparison.rs +370 -0
- data/vendor/kreuzberg/tests/email_integration.rs +325 -325
- data/vendor/kreuzberg/tests/epub_native_extractor_tests.rs +275 -0
- data/vendor/kreuzberg/tests/error_handling.rs +393 -393
- data/vendor/kreuzberg/tests/fictionbook_extractor_tests.rs +228 -0
- data/vendor/kreuzberg/tests/format_integration.rs +159 -159
- data/vendor/kreuzberg/tests/helpers/mod.rs +142 -142
- data/vendor/kreuzberg/tests/html_table_test.rs +551 -0
- data/vendor/kreuzberg/tests/image_integration.rs +253 -253
- data/vendor/kreuzberg/tests/instrumentation_test.rs +139 -0
- data/vendor/kreuzberg/tests/jats_extractor_tests.rs +639 -0
- data/vendor/kreuzberg/tests/jupyter_extractor_tests.rs +704 -0
- data/vendor/kreuzberg/tests/keywords_integration.rs +479 -479
- data/vendor/kreuzberg/tests/keywords_quality.rs +509 -509
- data/vendor/kreuzberg/tests/latex_extractor_tests.rs +496 -0
- data/vendor/kreuzberg/tests/markdown_extractor_tests.rs +490 -0
- data/vendor/kreuzberg/tests/mime_detection.rs +428 -428
- data/vendor/kreuzberg/tests/ocr_configuration.rs +510 -510
- data/vendor/kreuzberg/tests/ocr_errors.rs +676 -676
- data/vendor/kreuzberg/tests/ocr_quality.rs +627 -627
- data/vendor/kreuzberg/tests/ocr_stress.rs +469 -469
- data/vendor/kreuzberg/tests/odt_extractor_tests.rs +695 -0
- data/vendor/kreuzberg/tests/opml_extractor_tests.rs +616 -0
- data/vendor/kreuzberg/tests/orgmode_extractor_tests.rs +822 -0
- data/vendor/kreuzberg/tests/pdf_integration.rs +43 -43
- data/vendor/kreuzberg/tests/pipeline_integration.rs +1411 -1412
- data/vendor/kreuzberg/tests/plugin_ocr_backend_test.rs +771 -771
- data/vendor/kreuzberg/tests/plugin_postprocessor_test.rs +560 -561
- data/vendor/kreuzberg/tests/plugin_system.rs +921 -921
- data/vendor/kreuzberg/tests/plugin_validator_test.rs +783 -783
- data/vendor/kreuzberg/tests/registry_integration_tests.rs +586 -607
- data/vendor/kreuzberg/tests/rst_extractor_tests.rs +692 -0
- data/vendor/kreuzberg/tests/rtf_extractor_tests.rs +776 -0
- data/vendor/kreuzberg/tests/security_validation.rs +415 -404
- data/vendor/kreuzberg/tests/stopwords_integration_test.rs +888 -888
- data/vendor/kreuzberg/tests/test_fastembed.rs +609 -609
- data/vendor/kreuzberg/tests/typst_behavioral_tests.rs +1259 -0
- data/vendor/kreuzberg/tests/typst_extractor_tests.rs +647 -0
- data/vendor/kreuzberg/tests/xlsx_metadata_extraction_test.rs +87 -87
- data/vendor/rb-sys/.cargo-ok +1 -0
- data/vendor/rb-sys/.cargo_vcs_info.json +6 -0
- data/vendor/rb-sys/Cargo.lock +393 -0
- data/vendor/rb-sys/Cargo.toml +70 -0
- data/vendor/rb-sys/Cargo.toml.orig +57 -0
- data/vendor/rb-sys/LICENSE-APACHE +190 -0
- data/vendor/rb-sys/LICENSE-MIT +21 -0
- data/vendor/rb-sys/bin/release.sh +21 -0
- data/vendor/rb-sys/build/features.rs +108 -0
- data/vendor/rb-sys/build/main.rs +246 -0
- data/vendor/rb-sys/build/stable_api_config.rs +153 -0
- data/vendor/rb-sys/build/version.rs +48 -0
- data/vendor/rb-sys/readme.md +36 -0
- data/vendor/rb-sys/src/bindings.rs +21 -0
- data/vendor/rb-sys/src/hidden.rs +11 -0
- data/vendor/rb-sys/src/lib.rs +34 -0
- data/vendor/rb-sys/src/macros.rs +371 -0
- data/vendor/rb-sys/src/memory.rs +53 -0
- data/vendor/rb-sys/src/ruby_abi_version.rs +38 -0
- data/vendor/rb-sys/src/special_consts.rs +31 -0
- data/vendor/rb-sys/src/stable_api/compiled.c +179 -0
- data/vendor/rb-sys/src/stable_api/compiled.rs +257 -0
- data/vendor/rb-sys/src/stable_api/ruby_2_6.rs +316 -0
- data/vendor/rb-sys/src/stable_api/ruby_2_7.rs +316 -0
- data/vendor/rb-sys/src/stable_api/ruby_3_0.rs +324 -0
- data/vendor/rb-sys/src/stable_api/ruby_3_1.rs +317 -0
- data/vendor/rb-sys/src/stable_api/ruby_3_2.rs +315 -0
- data/vendor/rb-sys/src/stable_api/ruby_3_3.rs +326 -0
- data/vendor/rb-sys/src/stable_api/ruby_3_4.rs +327 -0
- data/vendor/rb-sys/src/stable_api.rs +261 -0
- data/vendor/rb-sys/src/symbol.rs +31 -0
- data/vendor/rb-sys/src/tracking_allocator.rs +332 -0
- data/vendor/rb-sys/src/utils.rs +89 -0
- data/vendor/rb-sys/src/value_type.rs +7 -0
- metadata +90 -95
- data/pkg/kreuzberg-4.0.0.rc1.gem +0 -0
- data/spec/examples.txt +0 -104
- data/vendor/kreuzberg/src/bin/profile_extract.rs +0 -455
- data/vendor/kreuzberg/src/extraction/pandoc/batch.rs +0 -275
- data/vendor/kreuzberg/src/extraction/pandoc/mime_types.rs +0 -178
- data/vendor/kreuzberg/src/extraction/pandoc/mod.rs +0 -491
- data/vendor/kreuzberg/src/extraction/pandoc/server.rs +0 -496
- data/vendor/kreuzberg/src/extraction/pandoc/subprocess.rs +0 -1188
- data/vendor/kreuzberg/src/extraction/pandoc/version.rs +0 -162
- data/vendor/kreuzberg/src/extractors/pandoc.rs +0 -201
- data/vendor/kreuzberg/tests/chunking_offset_demo.rs +0 -92
- data/vendor/kreuzberg/tests/pandoc_integration.rs +0 -503
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Kreuzberg
|
|
4
|
-
# PostProcessor protocol interface.
|
|
5
|
-
#
|
|
6
|
-
# This module defines the protocol that all Ruby post-processors must implement
|
|
7
|
-
# to be registered with the Rust core via the FFI bridge.
|
|
8
|
-
#
|
|
9
|
-
# Post-processors enrich extraction results by adding metadata, transforming content,
|
|
10
|
-
# or performing additional analysis. They are called after extraction completes.
|
|
11
|
-
#
|
|
12
|
-
# @example Implementing a simple post-processor
|
|
13
|
-
# class UpcaseProcessor
|
|
14
|
-
# include Kreuzberg::PostProcessorProtocol
|
|
15
|
-
#
|
|
16
|
-
# def call(result)
|
|
17
|
-
# result["content"] = result["content"].upcase
|
|
18
|
-
# result
|
|
19
|
-
# end
|
|
20
|
-
# end
|
|
21
|
-
#
|
|
22
|
-
# Kreuzberg.register_post_processor("upcase", UpcaseProcessor.new)
|
|
23
|
-
#
|
|
24
|
-
# @example Implementing a post-processor that adds metadata
|
|
25
|
-
# class EntityExtractor
|
|
26
|
-
# include Kreuzberg::PostProcessorProtocol
|
|
27
|
-
#
|
|
28
|
-
# def call(result)
|
|
29
|
-
# entities = extract_entities(result["content"])
|
|
30
|
-
# result["metadata"]["entities"] = entities
|
|
31
|
-
# result
|
|
32
|
-
# end
|
|
33
|
-
#
|
|
34
|
-
# private
|
|
35
|
-
#
|
|
36
|
-
# def extract_entities(text)
|
|
37
|
-
# # Extract named entities from text
|
|
38
|
-
# # This is a placeholder - use a real NER library in production
|
|
39
|
-
# text.scan(/[A-Z][a-z]+(?:\s[A-Z][a-z]+)*/)
|
|
40
|
-
# end
|
|
41
|
-
# end
|
|
42
|
-
#
|
|
43
|
-
# Kreuzberg.register_post_processor("entities", EntityExtractor.new)
|
|
44
|
-
#
|
|
45
|
-
# @example Using a Proc as a post-processor
|
|
46
|
-
# Kreuzberg.register_post_processor("word_count", ->(result) {
|
|
47
|
-
# word_count = result["content"].split.length
|
|
48
|
-
# result["metadata"]["word_count"] = word_count
|
|
49
|
-
# result
|
|
50
|
-
# })
|
|
51
|
-
#
|
|
52
|
-
module PostProcessorProtocol
|
|
53
|
-
# Process and enrich an extraction result.
|
|
54
|
-
#
|
|
55
|
-
# This method is called after extraction completes. It receives the extraction result
|
|
56
|
-
# as a hash and must return the modified hash. The processor can:
|
|
57
|
-
# - Add new keys to result["metadata"]
|
|
58
|
-
# - Transform result["content"]
|
|
59
|
-
# - Add entries to result["tables"]
|
|
60
|
-
# - Modify any other result fields
|
|
61
|
-
#
|
|
62
|
-
# Existing metadata keys will not be overwritten by the FFI bridge, so it's safe
|
|
63
|
-
# to add new keys without worrying about conflicts.
|
|
64
|
-
#
|
|
65
|
-
# @param result [Hash] Extraction result with the following structure:
|
|
66
|
-
# - "content" [String] - Extracted text content
|
|
67
|
-
# - "mime_type" [String] - MIME type of the source document
|
|
68
|
-
# - "metadata" [Hash] - Document metadata (title, author, etc.)
|
|
69
|
-
# - "tables" [Array<Hash>] - Extracted tables
|
|
70
|
-
# - "detected_languages" [Array<String>, nil] - Detected language codes
|
|
71
|
-
# - "chunks" [Array<String>, nil] - Content chunks (if chunking enabled)
|
|
72
|
-
#
|
|
73
|
-
# @return [Hash] Modified extraction result with enriched metadata
|
|
74
|
-
#
|
|
75
|
-
# @example
|
|
76
|
-
# def call(result)
|
|
77
|
-
# text = result["content"]
|
|
78
|
-
# entities = extract_entities(text)
|
|
79
|
-
# result["metadata"]["entities"] = entities
|
|
80
|
-
# result
|
|
81
|
-
# end
|
|
82
|
-
def call(result)
|
|
83
|
-
raise NotImplementedError, "#{self.class} must implement #call(result)"
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kreuzberg
|
|
4
|
+
# PostProcessor protocol interface.
|
|
5
|
+
#
|
|
6
|
+
# This module defines the protocol that all Ruby post-processors must implement
|
|
7
|
+
# to be registered with the Rust core via the FFI bridge.
|
|
8
|
+
#
|
|
9
|
+
# Post-processors enrich extraction results by adding metadata, transforming content,
|
|
10
|
+
# or performing additional analysis. They are called after extraction completes.
|
|
11
|
+
#
|
|
12
|
+
# @example Implementing a simple post-processor
|
|
13
|
+
# class UpcaseProcessor
|
|
14
|
+
# include Kreuzberg::PostProcessorProtocol
|
|
15
|
+
#
|
|
16
|
+
# def call(result)
|
|
17
|
+
# result["content"] = result["content"].upcase
|
|
18
|
+
# result
|
|
19
|
+
# end
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# Kreuzberg.register_post_processor("upcase", UpcaseProcessor.new)
|
|
23
|
+
#
|
|
24
|
+
# @example Implementing a post-processor that adds metadata
|
|
25
|
+
# class EntityExtractor
|
|
26
|
+
# include Kreuzberg::PostProcessorProtocol
|
|
27
|
+
#
|
|
28
|
+
# def call(result)
|
|
29
|
+
# entities = extract_entities(result["content"])
|
|
30
|
+
# result["metadata"]["entities"] = entities
|
|
31
|
+
# result
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
# private
|
|
35
|
+
#
|
|
36
|
+
# def extract_entities(text)
|
|
37
|
+
# # Extract named entities from text
|
|
38
|
+
# # This is a placeholder - use a real NER library in production
|
|
39
|
+
# text.scan(/[A-Z][a-z]+(?:\s[A-Z][a-z]+)*/)
|
|
40
|
+
# end
|
|
41
|
+
# end
|
|
42
|
+
#
|
|
43
|
+
# Kreuzberg.register_post_processor("entities", EntityExtractor.new)
|
|
44
|
+
#
|
|
45
|
+
# @example Using a Proc as a post-processor
|
|
46
|
+
# Kreuzberg.register_post_processor("word_count", ->(result) {
|
|
47
|
+
# word_count = result["content"].split.length
|
|
48
|
+
# result["metadata"]["word_count"] = word_count
|
|
49
|
+
# result
|
|
50
|
+
# })
|
|
51
|
+
#
|
|
52
|
+
module PostProcessorProtocol
|
|
53
|
+
# Process and enrich an extraction result.
|
|
54
|
+
#
|
|
55
|
+
# This method is called after extraction completes. It receives the extraction result
|
|
56
|
+
# as a hash and must return the modified hash. The processor can:
|
|
57
|
+
# - Add new keys to result["metadata"]
|
|
58
|
+
# - Transform result["content"]
|
|
59
|
+
# - Add entries to result["tables"]
|
|
60
|
+
# - Modify any other result fields
|
|
61
|
+
#
|
|
62
|
+
# Existing metadata keys will not be overwritten by the FFI bridge, so it's safe
|
|
63
|
+
# to add new keys without worrying about conflicts.
|
|
64
|
+
#
|
|
65
|
+
# @param result [Hash] Extraction result with the following structure:
|
|
66
|
+
# - "content" [String] - Extracted text content
|
|
67
|
+
# - "mime_type" [String] - MIME type of the source document
|
|
68
|
+
# - "metadata" [Hash] - Document metadata (title, author, etc.)
|
|
69
|
+
# - "tables" [Array<Hash>] - Extracted tables
|
|
70
|
+
# - "detected_languages" [Array<String>, nil] - Detected language codes
|
|
71
|
+
# - "chunks" [Array<String>, nil] - Content chunks (if chunking enabled)
|
|
72
|
+
#
|
|
73
|
+
# @return [Hash] Modified extraction result with enriched metadata
|
|
74
|
+
#
|
|
75
|
+
# @example
|
|
76
|
+
# def call(result)
|
|
77
|
+
# text = result["content"]
|
|
78
|
+
# entities = extract_entities(text)
|
|
79
|
+
# result["metadata"]["entities"] = entities
|
|
80
|
+
# result
|
|
81
|
+
# end
|
|
82
|
+
def call(result)
|
|
83
|
+
raise NotImplementedError, "#{self.class} must implement #call(result)"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
data/lib/kreuzberg/result.rb
CHANGED
|
@@ -1,216 +1,216 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
begin
|
|
4
|
-
require 'json'
|
|
5
|
-
rescue LoadError
|
|
6
|
-
require 'json/pure'
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
module Kreuzberg
|
|
10
|
-
# Extraction result wrapper
|
|
11
|
-
#
|
|
12
|
-
# Provides structured access to extraction results from the native extension.
|
|
13
|
-
#
|
|
14
|
-
# @example
|
|
15
|
-
# result = Kreuzberg.extract_file_sync("document.pdf")
|
|
16
|
-
# puts result.content
|
|
17
|
-
# puts "MIME type: #{result.mime_type}"
|
|
18
|
-
# puts "Metadata: #{result.metadata.inspect}"
|
|
19
|
-
# result.tables.each { |table| puts table.inspect }
|
|
20
|
-
#
|
|
21
|
-
# rubocop:disable Metrics/ClassLength
|
|
22
|
-
class Result
|
|
23
|
-
attr_reader :content, :mime_type, :metadata, :metadata_json, :tables,
|
|
24
|
-
:detected_languages, :chunks, :images
|
|
25
|
-
|
|
26
|
-
# Table structure
|
|
27
|
-
#
|
|
28
|
-
# @!attribute [r] cells
|
|
29
|
-
# @return [Array<Array<String>>] Table cells (2D array)
|
|
30
|
-
# @!attribute [r] markdown
|
|
31
|
-
# @return [String] Markdown representation
|
|
32
|
-
# @!attribute [r] page_number
|
|
33
|
-
# @return [Integer] Page number where table was found
|
|
34
|
-
#
|
|
35
|
-
Table = Struct.new(:cells, :markdown, :page_number, keyword_init: true) do
|
|
36
|
-
def to_h
|
|
37
|
-
{ cells: cells, markdown: markdown, page_number: page_number }
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Text chunk
|
|
42
|
-
#
|
|
43
|
-
# @!attribute [r] content
|
|
44
|
-
# @return [String] Chunk content
|
|
45
|
-
# @!attribute [r] char_start
|
|
46
|
-
# @return [Integer] Starting character index
|
|
47
|
-
# @!attribute [r] char_end
|
|
48
|
-
# @return [Integer] Ending character index
|
|
49
|
-
# @!attribute [r] token_count
|
|
50
|
-
# @return [Integer, nil] Approximate token count (may be nil)
|
|
51
|
-
#
|
|
52
|
-
Chunk = Struct.new(
|
|
53
|
-
:content,
|
|
54
|
-
:char_start,
|
|
55
|
-
:char_end,
|
|
56
|
-
:token_count,
|
|
57
|
-
:chunk_index,
|
|
58
|
-
:total_chunks,
|
|
59
|
-
:embedding,
|
|
60
|
-
keyword_init: true
|
|
61
|
-
) do
|
|
62
|
-
def to_h
|
|
63
|
-
{
|
|
64
|
-
content: content,
|
|
65
|
-
char_start: char_start,
|
|
66
|
-
char_end: char_end,
|
|
67
|
-
token_count: token_count,
|
|
68
|
-
chunk_index: chunk_index,
|
|
69
|
-
total_chunks: total_chunks,
|
|
70
|
-
embedding: embedding
|
|
71
|
-
}
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
Image = Struct.new(
|
|
76
|
-
:data,
|
|
77
|
-
:format,
|
|
78
|
-
:image_index,
|
|
79
|
-
:page_number,
|
|
80
|
-
:width,
|
|
81
|
-
:height,
|
|
82
|
-
:colorspace,
|
|
83
|
-
:bits_per_component,
|
|
84
|
-
:is_mask,
|
|
85
|
-
:description,
|
|
86
|
-
:ocr_result,
|
|
87
|
-
keyword_init: true
|
|
88
|
-
) do
|
|
89
|
-
def to_h
|
|
90
|
-
{
|
|
91
|
-
data: data,
|
|
92
|
-
format: format,
|
|
93
|
-
image_index: image_index,
|
|
94
|
-
page_number: page_number,
|
|
95
|
-
width: width,
|
|
96
|
-
height: height,
|
|
97
|
-
colorspace: colorspace,
|
|
98
|
-
bits_per_component: bits_per_component,
|
|
99
|
-
is_mask: is_mask,
|
|
100
|
-
description: description,
|
|
101
|
-
ocr_result: ocr_result&.to_h
|
|
102
|
-
}
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# Initialize from native hash result
|
|
107
|
-
#
|
|
108
|
-
# @param hash [Hash] Hash returned from native extension
|
|
109
|
-
#
|
|
110
|
-
def initialize(hash)
|
|
111
|
-
# Handle both string and symbol keys for flexibility
|
|
112
|
-
@content = get_value(hash, 'content', '')
|
|
113
|
-
@mime_type = get_value(hash, 'mime_type', '')
|
|
114
|
-
@metadata_json = get_value(hash, 'metadata_json', '{}')
|
|
115
|
-
@metadata = parse_metadata(@metadata_json)
|
|
116
|
-
@tables = parse_tables(get_value(hash, 'tables'))
|
|
117
|
-
@detected_languages = parse_detected_languages(get_value(hash, 'detected_languages'))
|
|
118
|
-
@chunks = parse_chunks(get_value(hash, 'chunks'))
|
|
119
|
-
@images = parse_images(get_value(hash, 'images'))
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
# Convert to hash
|
|
123
|
-
#
|
|
124
|
-
# @return [Hash] Hash representation
|
|
125
|
-
#
|
|
126
|
-
def to_h
|
|
127
|
-
{
|
|
128
|
-
content: @content,
|
|
129
|
-
mime_type: @mime_type,
|
|
130
|
-
metadata: @metadata,
|
|
131
|
-
tables: @tables.map(&:to_h),
|
|
132
|
-
detected_languages: @detected_languages,
|
|
133
|
-
chunks: @chunks&.map(&:to_h),
|
|
134
|
-
images: @images&.map(&:to_h)
|
|
135
|
-
}
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# Convert to JSON
|
|
139
|
-
#
|
|
140
|
-
# @return [String] JSON representation
|
|
141
|
-
#
|
|
142
|
-
def to_json(*)
|
|
143
|
-
to_h.to_json(*)
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
private
|
|
147
|
-
|
|
148
|
-
def get_value(hash, key, default = nil)
|
|
149
|
-
hash[key] || hash[key.to_sym] || default
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def parse_metadata(metadata_json)
|
|
153
|
-
JSON.parse(metadata_json)
|
|
154
|
-
rescue JSON::ParserError
|
|
155
|
-
{}
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def parse_tables(tables_data)
|
|
159
|
-
return [] if tables_data.nil? || tables_data.empty?
|
|
160
|
-
|
|
161
|
-
tables_data.map do |table_hash|
|
|
162
|
-
Table.new(
|
|
163
|
-
cells: table_hash['cells'] || [],
|
|
164
|
-
markdown: table_hash['markdown'] || '',
|
|
165
|
-
page_number: table_hash['page_number'] || 0
|
|
166
|
-
)
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def parse_detected_languages(langs_data)
|
|
171
|
-
return nil if langs_data.nil?
|
|
172
|
-
|
|
173
|
-
# Detected languages is now just an array of strings
|
|
174
|
-
langs_data.is_a?(Array) ? langs_data : []
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
def parse_chunks(chunks_data)
|
|
178
|
-
return nil if chunks_data.nil?
|
|
179
|
-
|
|
180
|
-
chunks_data.map do |chunk_hash|
|
|
181
|
-
Chunk.new(
|
|
182
|
-
content: chunk_hash['content'],
|
|
183
|
-
char_start: chunk_hash['char_start'],
|
|
184
|
-
char_end: chunk_hash['char_end'],
|
|
185
|
-
token_count: chunk_hash['token_count'],
|
|
186
|
-
chunk_index: chunk_hash['chunk_index'],
|
|
187
|
-
total_chunks: chunk_hash['total_chunks'],
|
|
188
|
-
embedding: chunk_hash['embedding']
|
|
189
|
-
)
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
def parse_images(images_data)
|
|
194
|
-
return nil if images_data.nil?
|
|
195
|
-
|
|
196
|
-
images_data.map do |image_hash|
|
|
197
|
-
data = image_hash['data']
|
|
198
|
-
data = data.dup.force_encoding(Encoding::BINARY) if data.respond_to?(:force_encoding)
|
|
199
|
-
Image.new(
|
|
200
|
-
data: data,
|
|
201
|
-
format: image_hash['format'],
|
|
202
|
-
image_index: image_hash['image_index'],
|
|
203
|
-
page_number: image_hash['page_number'],
|
|
204
|
-
width: image_hash['width'],
|
|
205
|
-
height: image_hash['height'],
|
|
206
|
-
colorspace: image_hash['colorspace'],
|
|
207
|
-
bits_per_component: image_hash['bits_per_component'],
|
|
208
|
-
is_mask: image_hash['is_mask'],
|
|
209
|
-
description: image_hash['description'],
|
|
210
|
-
ocr_result: image_hash['ocr_result'] ? Result.new(image_hash['ocr_result']) : nil
|
|
211
|
-
)
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
# rubocop:enable Metrics/ClassLength
|
|
216
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'json'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
require 'json/pure'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module Kreuzberg
|
|
10
|
+
# Extraction result wrapper
|
|
11
|
+
#
|
|
12
|
+
# Provides structured access to extraction results from the native extension.
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
# result = Kreuzberg.extract_file_sync("document.pdf")
|
|
16
|
+
# puts result.content
|
|
17
|
+
# puts "MIME type: #{result.mime_type}"
|
|
18
|
+
# puts "Metadata: #{result.metadata.inspect}"
|
|
19
|
+
# result.tables.each { |table| puts table.inspect }
|
|
20
|
+
#
|
|
21
|
+
# rubocop:disable Metrics/ClassLength
|
|
22
|
+
class Result
|
|
23
|
+
attr_reader :content, :mime_type, :metadata, :metadata_json, :tables,
|
|
24
|
+
:detected_languages, :chunks, :images
|
|
25
|
+
|
|
26
|
+
# Table structure
|
|
27
|
+
#
|
|
28
|
+
# @!attribute [r] cells
|
|
29
|
+
# @return [Array<Array<String>>] Table cells (2D array)
|
|
30
|
+
# @!attribute [r] markdown
|
|
31
|
+
# @return [String] Markdown representation
|
|
32
|
+
# @!attribute [r] page_number
|
|
33
|
+
# @return [Integer] Page number where table was found
|
|
34
|
+
#
|
|
35
|
+
Table = Struct.new(:cells, :markdown, :page_number, keyword_init: true) do
|
|
36
|
+
def to_h
|
|
37
|
+
{ cells: cells, markdown: markdown, page_number: page_number }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Text chunk
|
|
42
|
+
#
|
|
43
|
+
# @!attribute [r] content
|
|
44
|
+
# @return [String] Chunk content
|
|
45
|
+
# @!attribute [r] char_start
|
|
46
|
+
# @return [Integer] Starting character index
|
|
47
|
+
# @!attribute [r] char_end
|
|
48
|
+
# @return [Integer] Ending character index
|
|
49
|
+
# @!attribute [r] token_count
|
|
50
|
+
# @return [Integer, nil] Approximate token count (may be nil)
|
|
51
|
+
#
|
|
52
|
+
Chunk = Struct.new(
|
|
53
|
+
:content,
|
|
54
|
+
:char_start,
|
|
55
|
+
:char_end,
|
|
56
|
+
:token_count,
|
|
57
|
+
:chunk_index,
|
|
58
|
+
:total_chunks,
|
|
59
|
+
:embedding,
|
|
60
|
+
keyword_init: true
|
|
61
|
+
) do
|
|
62
|
+
def to_h
|
|
63
|
+
{
|
|
64
|
+
content: content,
|
|
65
|
+
char_start: char_start,
|
|
66
|
+
char_end: char_end,
|
|
67
|
+
token_count: token_count,
|
|
68
|
+
chunk_index: chunk_index,
|
|
69
|
+
total_chunks: total_chunks,
|
|
70
|
+
embedding: embedding
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
Image = Struct.new(
|
|
76
|
+
:data,
|
|
77
|
+
:format,
|
|
78
|
+
:image_index,
|
|
79
|
+
:page_number,
|
|
80
|
+
:width,
|
|
81
|
+
:height,
|
|
82
|
+
:colorspace,
|
|
83
|
+
:bits_per_component,
|
|
84
|
+
:is_mask,
|
|
85
|
+
:description,
|
|
86
|
+
:ocr_result,
|
|
87
|
+
keyword_init: true
|
|
88
|
+
) do
|
|
89
|
+
def to_h
|
|
90
|
+
{
|
|
91
|
+
data: data,
|
|
92
|
+
format: format,
|
|
93
|
+
image_index: image_index,
|
|
94
|
+
page_number: page_number,
|
|
95
|
+
width: width,
|
|
96
|
+
height: height,
|
|
97
|
+
colorspace: colorspace,
|
|
98
|
+
bits_per_component: bits_per_component,
|
|
99
|
+
is_mask: is_mask,
|
|
100
|
+
description: description,
|
|
101
|
+
ocr_result: ocr_result&.to_h
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Initialize from native hash result
|
|
107
|
+
#
|
|
108
|
+
# @param hash [Hash] Hash returned from native extension
|
|
109
|
+
#
|
|
110
|
+
def initialize(hash)
|
|
111
|
+
# Handle both string and symbol keys for flexibility
|
|
112
|
+
@content = get_value(hash, 'content', '')
|
|
113
|
+
@mime_type = get_value(hash, 'mime_type', '')
|
|
114
|
+
@metadata_json = get_value(hash, 'metadata_json', '{}')
|
|
115
|
+
@metadata = parse_metadata(@metadata_json)
|
|
116
|
+
@tables = parse_tables(get_value(hash, 'tables'))
|
|
117
|
+
@detected_languages = parse_detected_languages(get_value(hash, 'detected_languages'))
|
|
118
|
+
@chunks = parse_chunks(get_value(hash, 'chunks'))
|
|
119
|
+
@images = parse_images(get_value(hash, 'images'))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Convert to hash
|
|
123
|
+
#
|
|
124
|
+
# @return [Hash] Hash representation
|
|
125
|
+
#
|
|
126
|
+
def to_h
|
|
127
|
+
{
|
|
128
|
+
content: @content,
|
|
129
|
+
mime_type: @mime_type,
|
|
130
|
+
metadata: @metadata,
|
|
131
|
+
tables: @tables.map(&:to_h),
|
|
132
|
+
detected_languages: @detected_languages,
|
|
133
|
+
chunks: @chunks&.map(&:to_h),
|
|
134
|
+
images: @images&.map(&:to_h)
|
|
135
|
+
}
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Convert to JSON
|
|
139
|
+
#
|
|
140
|
+
# @return [String] JSON representation
|
|
141
|
+
#
|
|
142
|
+
def to_json(*)
|
|
143
|
+
to_h.to_json(*)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
private
|
|
147
|
+
|
|
148
|
+
def get_value(hash, key, default = nil)
|
|
149
|
+
hash[key] || hash[key.to_sym] || default
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def parse_metadata(metadata_json)
|
|
153
|
+
JSON.parse(metadata_json)
|
|
154
|
+
rescue JSON::ParserError
|
|
155
|
+
{}
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def parse_tables(tables_data)
|
|
159
|
+
return [] if tables_data.nil? || tables_data.empty?
|
|
160
|
+
|
|
161
|
+
tables_data.map do |table_hash|
|
|
162
|
+
Table.new(
|
|
163
|
+
cells: table_hash['cells'] || [],
|
|
164
|
+
markdown: table_hash['markdown'] || '',
|
|
165
|
+
page_number: table_hash['page_number'] || 0
|
|
166
|
+
)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def parse_detected_languages(langs_data)
|
|
171
|
+
return nil if langs_data.nil?
|
|
172
|
+
|
|
173
|
+
# Detected languages is now just an array of strings
|
|
174
|
+
langs_data.is_a?(Array) ? langs_data : []
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def parse_chunks(chunks_data)
|
|
178
|
+
return nil if chunks_data.nil?
|
|
179
|
+
|
|
180
|
+
chunks_data.map do |chunk_hash|
|
|
181
|
+
Chunk.new(
|
|
182
|
+
content: chunk_hash['content'],
|
|
183
|
+
char_start: chunk_hash['char_start'],
|
|
184
|
+
char_end: chunk_hash['char_end'],
|
|
185
|
+
token_count: chunk_hash['token_count'],
|
|
186
|
+
chunk_index: chunk_hash['chunk_index'],
|
|
187
|
+
total_chunks: chunk_hash['total_chunks'],
|
|
188
|
+
embedding: chunk_hash['embedding']
|
|
189
|
+
)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def parse_images(images_data)
|
|
194
|
+
return nil if images_data.nil?
|
|
195
|
+
|
|
196
|
+
images_data.map do |image_hash|
|
|
197
|
+
data = image_hash['data']
|
|
198
|
+
data = data.dup.force_encoding(Encoding::BINARY) if data.respond_to?(:force_encoding)
|
|
199
|
+
Image.new(
|
|
200
|
+
data: data,
|
|
201
|
+
format: image_hash['format'],
|
|
202
|
+
image_index: image_hash['image_index'],
|
|
203
|
+
page_number: image_hash['page_number'],
|
|
204
|
+
width: image_hash['width'],
|
|
205
|
+
height: image_hash['height'],
|
|
206
|
+
colorspace: image_hash['colorspace'],
|
|
207
|
+
bits_per_component: image_hash['bits_per_component'],
|
|
208
|
+
is_mask: image_hash['is_mask'],
|
|
209
|
+
description: image_hash['description'],
|
|
210
|
+
ocr_result: image_hash['ocr_result'] ? Result.new(image_hash['ocr_result']) : nil
|
|
211
|
+
)
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
# rubocop:enable Metrics/ClassLength
|
|
216
|
+
end
|