diff --git a/Cargo.lock b/Cargo.lock
index 2febb7e..998004b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -127,6 +127,17 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
+[[package]]
+name = "aes"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8"
+dependencies = [
+ "cipher",
+ "cpubits",
+ "cpufeatures",
+]
+
[[package]]
name = "ahash"
version = "0.8.12"
@@ -167,6 +178,21 @@ dependencies = [
"equator",
]
+[[package]]
+name = "alloc-no-stdlib"
+version = "2.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
+
+[[package]]
+name = "alloc-stdlib"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
+dependencies = [
+ "alloc-no-stdlib",
+]
+
[[package]]
name = "allocator-api2"
version = "0.2.21"
@@ -207,6 +233,56 @@ dependencies = [
"libc",
]
+[[package]]
+name = "anstream"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
+
+[[package]]
+name = "anstyle-parse"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
+dependencies = [
+ "anstyle",
+ "once_cell_polyfill",
+ "windows-sys 0.61.2",
+]
+
[[package]]
name = "anyhow"
version = "1.0.102"
@@ -417,6 +493,16 @@ dependencies = [
"syn",
]
+[[package]]
+name = "atoi_simd"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3cdb3708a128e559a30fb830e8a77a5022ee6902806925c216658652b452a44"
+dependencies = [
+ "debug_unsafe",
+ "rustversion",
+]
+
[[package]]
name = "atomic-waker"
version = "1.1.2"
@@ -509,6 +595,12 @@ dependencies = [
"arrayvec",
]
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
[[package]]
name = "bit-set"
version = "0.9.1"
@@ -551,6 +643,24 @@ dependencies = [
"no_std_io2",
]
+[[package]]
+name = "block-buffer"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be"
+dependencies = [
+ "hybrid-array",
+]
+
+[[package]]
+name = "block-padding"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "710f1dd022ef4e93f8a438b4ba958de7f64308434fa6a87104481645cc30068b"
+dependencies = [
+ "hybrid-array",
+]
+
[[package]]
name = "block2"
version = "0.5.1"
@@ -582,6 +692,27 @@ dependencies = [
"piper",
]
+[[package]]
+name = "brotli"
+version = "8.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560"
+dependencies = [
+ "alloc-no-stdlib",
+ "alloc-stdlib",
+ "brotli-decompressor",
+]
+
+[[package]]
+name = "brotli-decompressor"
+version = "5.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
+dependencies = [
+ "alloc-no-stdlib",
+ "alloc-stdlib",
+]
+
[[package]]
name = "bstr"
version = "1.12.1"
@@ -625,6 +756,12 @@ dependencies = [
"syn",
]
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
[[package]]
name = "byteorder-lite"
version = "0.1.0"
@@ -688,6 +825,15 @@ dependencies = [
"wayland-client",
]
+[[package]]
+name = "cbc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98db6aeaef0eeef2c1e3ce9a27b739218825dae116076352ac3777076aa22225"
+dependencies = [
+ "cipher",
+]
+
[[package]]
name = "cc"
version = "1.2.62"
@@ -734,6 +880,16 @@ dependencies = [
"windows-link",
]
+[[package]]
+name = "cipher"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea"
+dependencies = [
+ "crypto-common",
+ "inout",
+]
+
[[package]]
name = "clipboard-win"
version = "5.4.1"
@@ -769,6 +925,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
+[[package]]
+name = "colorchoice"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
+
[[package]]
name = "combine"
version = "4.6.7"
@@ -788,6 +950,12 @@ dependencies = [
"crossbeam-utils",
]
+[[package]]
+name = "const-oid"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
+
[[package]]
name = "core-foundation"
version = "0.9.4"
@@ -838,6 +1006,21 @@ dependencies = [
"libc",
]
+[[package]]
+name = "cpubits"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae"
+
+[[package]]
+name = "cpufeatures"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "crc32fast"
version = "1.5.0"
@@ -878,12 +1061,27 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
+[[package]]
+name = "crypto-common"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710"
+dependencies = [
+ "hybrid-array",
+]
+
[[package]]
name = "cursor-icon"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f"
+[[package]]
+name = "debug_unsafe"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7eed2c4702fa172d1ce21078faa7c5203e69f5394d48cc436d25928394a867a2"
+
[[package]]
name = "deranged"
version = "0.5.8"
@@ -893,6 +1091,17 @@ dependencies = [
"powerfmt",
]
+[[package]]
+name = "digest"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
+dependencies = [
+ "block-buffer",
+ "const-oid",
+ "crypto-common",
+]
+
[[package]]
name = "dispatch"
version = "0.2.0"
@@ -1169,6 +1378,29 @@ dependencies = [
"syn",
]
+[[package]]
+name = "env_filter"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef"
+dependencies = [
+ "log",
+ "regex",
+]
+
+[[package]]
+name = "env_logger"
+version = "0.11.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "env_filter",
+ "jiff",
+ "log",
+]
+
[[package]]
name = "epaint"
version = "0.34.2"
@@ -1180,13 +1412,13 @@ dependencies = [
"ecolor",
"emath",
"epaint_default_fonts",
- "font-types",
+ "font-types 0.11.3",
"log",
"nohash-hasher",
"parking_lot",
"profiling",
"self_cell",
- "skrifa",
+ "skrifa 0.40.0",
"smallvec",
"vello_cpu",
]
@@ -1284,6 +1516,12 @@ dependencies = [
"zune-inflate",
]
+[[package]]
+name = "fast-float2"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8eb564c5c7423d25c886fb561d1e4ee69f72354d16918afa32c08811f6b6a55"
+
[[package]]
name = "fastrand"
version = "2.4.1"
@@ -1328,6 +1566,7 @@ checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
dependencies = [
"crc32fast",
"miniz_oxide",
+ "zlib-rs",
]
[[package]]
@@ -1342,6 +1581,15 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
+[[package]]
+name = "font-types"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39a654f404bbcbd48ea58c617c2993ee91d1cb63727a37bf2323a4edeed1b8c5"
+dependencies = [
+ "bytemuck",
+]
+
[[package]]
name = "font-types"
version = "0.11.3"
@@ -1471,10 +1719,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
dependencies = [
"cfg-if",
+ "js-sys",
"libc",
"r-efi 6.0.0",
"wasip2",
"wasip3",
+ "wasm-bindgen",
]
[[package]]
@@ -1702,6 +1952,12 @@ dependencies = [
"memmap2",
]
+[[package]]
+name = "grid"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b40ca9252762c466af32d0b1002e91e4e1bc5398f77455e55474deb466355ff5"
+
[[package]]
name = "half"
version = "2.7.1"
@@ -1764,6 +2020,15 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
+[[package]]
+name = "hybrid-array"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da"
+dependencies = [
+ "typenum",
+]
+
[[package]]
name = "iana-time-zone"
version = "0.1.65"
@@ -1965,6 +2230,16 @@ dependencies = [
"serde_core",
]
+[[package]]
+name = "inout"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7"
+dependencies = [
+ "block-padding",
+ "hybrid-array",
+]
+
[[package]]
name = "interpolate_name"
version = "0.2.4"
@@ -1995,6 +2270,12 @@ dependencies = [
"once_cell",
]
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
+
[[package]]
name = "itertools"
version = "0.14.0"
@@ -2010,6 +2291,30 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+[[package]]
+name = "jiff"
+version = "0.2.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d"
+dependencies = [
+ "jiff-static",
+ "log",
+ "portable-atomic",
+ "portable-atomic-util",
+ "serde_core",
+]
+
+[[package]]
+name = "jiff-static"
+version = "0.2.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "jni"
version = "0.22.4"
@@ -2078,6 +2383,15 @@ dependencies = [
"libc",
]
+[[package]]
+name = "jpeg-decoder"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07"
+dependencies = [
+ "rayon",
+]
+
[[package]]
name = "js-sys"
version = "0.3.98"
@@ -2107,6 +2421,17 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
+[[package]]
+name = "kurbo"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce9729cc38c18d86123ab736fd2e7151763ba226ac2490ec092d1dd148825e32"
+dependencies = [
+ "arrayvec",
+ "euclid",
+ "smallvec",
+]
+
[[package]]
name = "kurbo"
version = "0.13.0"
@@ -2132,7 +2457,7 @@ checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8"
[[package]]
name = "lexi"
-version = "0.1.0"
+version = "0.2.0"
dependencies = [
"anyhow",
"chrono",
@@ -2143,7 +2468,9 @@ dependencies = [
"ignore",
"image",
"log",
+ "office_oxide",
"open",
+ "pdf_oxide",
"quoted_printable",
"regex",
"rfd",
@@ -2260,6 +2587,16 @@ dependencies = [
"rayon",
]
+[[package]]
+name = "md-5"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98"
+dependencies = [
+ "cfg-if",
+ "digest",
+]
+
[[package]]
name = "memchr"
version = "2.8.0"
@@ -2812,12 +3149,36 @@ dependencies = [
"objc2-foundation 0.2.2",
]
+[[package]]
+name = "office_oxide"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "866a8fa5e1a756f8cc9f9f614031ad7e33adc7f6972eab74a35b0c799fe08da5"
+dependencies = [
+ "atoi_simd",
+ "encoding_rs",
+ "fast-float2",
+ "libc",
+ "log",
+ "quick-xml 0.40.1",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+ "zip",
+]
+
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
+[[package]]
+name = "once_cell_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
+
[[package]]
name = "open"
version = "5.3.5"
@@ -2914,6 +3275,52 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
+[[package]]
+name = "pdf_oxide"
+version = "0.3.50"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c512f3d7e8feac18e94ee08995d5c12d0fb86375ff4b03f931a11c808276eff4"
+dependencies = [
+ "aes",
+ "base64",
+ "bitflags 2.11.1",
+ "brotli",
+ "byteorder",
+ "bytes",
+ "cbc",
+ "chrono",
+ "encoding_rs",
+ "env_logger",
+ "fax",
+ "flate2",
+ "getrandom 0.4.2",
+ "image",
+ "jpeg-decoder",
+ "libc",
+ "log",
+ "md-5",
+ "memchr",
+ "nom",
+ "office_oxide",
+ "phf 0.13.1",
+ "qcms",
+ "quick-xml 0.39.4",
+ "regex",
+ "serde",
+ "serde_json",
+ "sha2",
+ "smallvec",
+ "stringprep",
+ "subsetter",
+ "taffy",
+ "thiserror 2.0.18",
+ "ttf-parser",
+ "unicode-bidi",
+ "unicode-linebreak",
+ "uuid",
+ "weezl",
+]
+
[[package]]
name = "peniko"
version = "0.6.0"
@@ -2922,7 +3329,7 @@ checksum = "9a2b6aadb221872732e87d465213e9be5af2849b0e8cc5300a8ba98fffa2e00a"
dependencies = [
"bytemuck",
"color",
- "kurbo",
+ "kurbo 0.13.0",
"linebender_resource_handle",
"smallvec",
]
@@ -3200,6 +3607,12 @@ version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f"
+[[package]]
+name = "qcms"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edecfcd5d755a5e5d98e24cf43113e7cdaec5a070edd0f6b250c03a573da30fa"
+
[[package]]
name = "qoi"
version = "0.4.1"
@@ -3225,6 +3638,16 @@ dependencies = [
"serde",
]
+[[package]]
+name = "quick-xml"
+version = "0.40.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2474bd2e5029e7ccb6abb2ba48cf2383a333851dedf495901544281590c7da7f"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
[[package]]
name = "quote"
version = "1.0.45"
@@ -3390,6 +3813,16 @@ dependencies = [
"crossbeam-utils",
]
+[[package]]
+name = "read-fonts"
+version = "0.35.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358"
+dependencies = [
+ "bytemuck",
+ "font-types 0.10.1",
+]
+
[[package]]
name = "read-fonts"
version = "0.37.0"
@@ -3397,7 +3830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b634fabf032fab15307ffd272149b622260f55974d9fad689292a5d33df02e5"
dependencies = [
"bytemuck",
- "font-types",
+ "font-types 0.11.3",
]
[[package]]
@@ -3657,6 +4090,17 @@ dependencies = [
"serde_core",
]
+[[package]]
+name = "sha2"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
[[package]]
name = "shlex"
version = "1.3.0"
@@ -3721,6 +4165,16 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
+[[package]]
+name = "skrifa"
+version = "0.37.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841"
+dependencies = [
+ "bytemuck",
+ "read-fonts 0.35.0",
+]
+
[[package]]
name = "skrifa"
version = "0.40.0"
@@ -3728,7 +4182,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fbdfe3d2475fbd7ddd1f3e5cf8288a30eb3e5f95832829570cd88115a7434ac"
dependencies = [
"bytemuck",
- "read-fonts",
+ "read-fonts 0.37.0",
]
[[package]]
@@ -3851,6 +4305,29 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
+[[package]]
+name = "stringprep"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+ "unicode-properties",
+]
+
+[[package]]
+name = "subsetter"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb6895a12ac5599bb6057362f00e8a3cf1daab4df33f553a55690a44e4fed8d0"
+dependencies = [
+ "kurbo 0.12.0",
+ "rustc-hash 2.1.2",
+ "skrifa 0.37.0",
+ "write-fonts",
+]
+
[[package]]
name = "syn"
version = "2.0.117"
@@ -3873,6 +4350,18 @@ dependencies = [
"syn",
]
+[[package]]
+name = "taffy"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aea22054047c16c3f34d3ac473a2170be1424b1115b2a3adcf28cfb067c88859"
+dependencies = [
+ "arrayvec",
+ "grid",
+ "serde",
+ "slotmap",
+]
+
[[package]]
name = "tempfile"
version = "3.27.0"
@@ -4017,6 +4506,21 @@ dependencies = [
"zerovec",
]
+[[package]]
+name = "tinyvec"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
[[package]]
name = "toml"
version = "1.1.2+spec-1.1.0"
@@ -4115,6 +4619,18 @@ dependencies = [
"rustc-hash 2.1.2",
]
+[[package]]
+name = "typed-path"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e"
+
+[[package]]
+name = "typenum"
+version = "1.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
+
[[package]]
name = "uds_windows"
version = "1.2.1"
@@ -4132,12 +4648,39 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
+[[package]]
+name = "unicode-bidi"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
+
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+[[package]]
+name = "unicode-linebreak"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-properties"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d"
+
[[package]]
name = "unicode-segmentation"
version = "1.13.2"
@@ -4174,12 +4717,19 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
[[package]]
name = "uuid"
version = "1.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
dependencies = [
+ "getrandom 0.4.2",
"js-sys",
"serde_core",
"wasm-bindgen",
@@ -4207,7 +4757,7 @@ dependencies = [
"hashbrown 0.16.1",
"log",
"peniko",
- "skrifa",
+ "skrifa 0.40.0",
"smallvec",
]
@@ -4464,7 +5014,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a"
dependencies = [
"proc-macro2",
- "quick-xml",
+ "quick-xml 0.39.4",
"quote",
]
@@ -5149,6 +5699,19 @@ dependencies = [
"wasmparser",
]
+[[package]]
+name = "write-fonts"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "886614b5ce857341226aa091f3c285e450683894acaaa7887f366c361efef79d"
+dependencies = [
+ "font-types 0.10.1",
+ "indexmap",
+ "kurbo 0.12.0",
+ "log",
+ "read-fonts 0.35.0",
+]
+
[[package]]
name = "writeable"
version = "0.6.3"
@@ -5338,7 +5901,7 @@ version = "5.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8067892e940ed1727dea64690378601603b31d62dfde019a5335fbb7c0e0ed9"
dependencies = [
- "quick-xml",
+ "quick-xml 0.39.4",
"serde",
"zbus_names",
"zvariant",
@@ -5418,12 +5981,44 @@ dependencies = [
"syn",
]
+[[package]]
+name = "zip"
+version = "8.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d04a6b5381502aa6087c94c669499eb1602eb9c5e8198e534de571f7154809b"
+dependencies = [
+ "crc32fast",
+ "flate2",
+ "indexmap",
+ "memchr",
+ "typed-path",
+ "zopfli",
+]
+
+[[package]]
+name = "zlib-rs"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513"
+
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+[[package]]
+name = "zopfli"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249"
+dependencies = [
+ "bumpalo",
+ "crc32fast",
+ "log",
+ "simd-adler32",
+]
+
[[package]]
name = "zune-core"
version = "0.5.1"
diff --git a/Cargo.toml b/Cargo.toml
index 444d463..f9cbd18 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "lexi"
-version = "0.1.0"
+version = "0.2.0"
edition = "2024"
[dependencies]
@@ -18,6 +18,8 @@ rfd = "0.17"
quoted_printable = "0.5"
log = "0.4"
simplelog = "0.12"
+pdf_oxide = "0.3.50"
+office_oxide = "0.1.2"
[dev-dependencies]
tempfile = "3.10"
diff --git a/README.md b/README.md
index 5543712..81a1b56 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
# Lexi
윈도우 기본 검색 쓰다가 답답해서 직접 만든 파일 검색기
-
+
diff --git a/src/app.rs b/src/app.rs
index 647742e..6cafc57 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -486,10 +486,24 @@ impl SearchApp {
input_changed = true;
}
if ui
- .checkbox(&mut tab.config.file_name_only, "파일명만 검색")
+ .checkbox(&mut tab.config.file_name_only, "파일명만")
+ .on_hover_text("파일명만 검색합니다.")
.changed()
{
input_changed = true;
+ if tab.config.file_name_only {
+ tab.config.search_doc_content = false;
+ }
+ }
+ if ui
+ .checkbox(&mut tab.config.search_doc_content, "문서내용도")
+ .on_hover_text("pdf, docx, pptx, xlsx 내용도 검색합니다.")
+ .changed()
+ {
+ input_changed = true;
+ if tab.config.search_doc_content {
+ tab.config.file_name_only = false;
+ }
}
});
@@ -573,7 +587,7 @@ impl SearchApp {
.column(Column::remainder().clip(true))
.header(20.0, |mut header| {
header.col(|ui| {
- ui.label("파일");
+ ui.label("파일명");
});
header.col(|ui| {
ui.label("라인");
diff --git a/src/search.rs b/src/search.rs
index de917a4..1cd3b77 100644
--- a/src/search.rs
+++ b/src/search.rs
@@ -208,16 +208,18 @@ pub struct SearchConfig {
pub patterns: String,
pub queries: Vec,
pub file_name_only: bool,
+ pub search_doc_content: bool,
}
impl SearchConfig {
- // Creates a new search config with the given paths and patterns.
+ /// Creates a new search config with the given paths and patterns.
pub fn new(paths: Vec, patterns: String) -> Self {
Self {
paths,
patterns,
queries: vec![SearchQuery::new()],
file_name_only: false,
+ search_doc_content: false,
}
}
@@ -273,6 +275,7 @@ pub fn spawn_search(config: &SearchConfig) -> Result {
// Create variables for the search configuration.
let matcher = config.create_matcher()?;
let file_name_only = config.file_name_only;
+ let search_doc_content = config.search_doc_content;
let paths = config.paths();
if paths.is_empty() {
bail!("No search paths provided");
@@ -339,18 +342,69 @@ pub fn spawn_search(config: &SearchConfig) -> Result {
// Second pass: scan file content (unless "File name only" mode is on).
if !file_name_only {
let mut handled = false;
- // Korean .eml files often use Quoted-Printable encoding for the body.
- if path.extension().is_some_and(|ext| ext == "eml")
- && let Ok(content) = std::fs::read(path)
- && let Ok(decoded) =
- quoted_printable::decode(&content, quoted_printable::ParseMode::Robust)
- {
- let mut sink = SearchSink {
- results: &mut entries,
- matcher: &matcher,
- };
- let _ = searcher.search_slice(&*matcher, &decoded, &mut sink);
- handled = true;
+ let extension = path
+ .extension()
+ .and_then(|ext| ext.to_str())
+ .unwrap_or("")
+ .to_lowercase();
+
+ if search_doc_content {
+ match extension.as_str() {
+ "docx" | "pptx" | "xlsx" | "doc" | "ppt" | "xls" => {
+ if let Ok(text) = office_oxide::extract_text(path) {
+ let mut sink = SearchSink {
+ results: &mut entries,
+ matcher: &matcher,
+ };
+ let _ = searcher.search_slice(
+ &*matcher,
+ text.as_bytes(),
+ &mut sink,
+ );
+ handled = true;
+ }
+ }
+ "pdf" => {
+ if let Ok(doc) = pdf_oxide::PdfDocument::open(path) {
+ let mut full_pdf_text = String::new();
+ let mut page = 0;
+ while let Ok(page_text) = doc.extract_text(page) {
+ full_pdf_text.push_str(&page_text);
+ full_pdf_text.push('\n');
+ page += 1;
+ }
+ if !full_pdf_text.is_empty() {
+ let mut sink = SearchSink {
+ results: &mut entries,
+ matcher: &matcher,
+ };
+ let _ = searcher.search_slice(
+ &*matcher,
+ full_pdf_text.as_bytes(),
+ &mut sink,
+ );
+ handled = true;
+ }
+ }
+ }
+ "eml" => {
+ // Korean .eml files often use Quoted-Printable encoding for the body.
+ if let Ok(content) = std::fs::read(path)
+ && let Ok(decoded) = quoted_printable::decode(
+ &content,
+ quoted_printable::ParseMode::Robust,
+ )
+ {
+ let mut sink = SearchSink {
+ results: &mut entries,
+ matcher: &matcher,
+ };
+ let _ = searcher.search_slice(&*matcher, &decoded, &mut sink);
+ handled = true;
+ }
+ }
+ _ => {}
+ }
}
if !handled {
diff --git a/tests/search_tests.rs b/tests/search_tests.rs
index 165aaab..a85de84 100644
--- a/tests/search_tests.rs
+++ b/tests/search_tests.rs
@@ -155,6 +155,7 @@ fn test_search_korean_qp_eml() {
vec![dir.path().to_string_lossy().to_string()],
"".to_string(),
);
+ config.search_doc_content = true;
config.queries[0].query = "안녕".to_string();
let pending = spawn_search(&config).unwrap();