diff --git a/flake.lock b/flake.lock index ea9103e..a198397 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1761574448, - "narHash": "sha256-zCRT8xJbC5rYPghC/AVyHh7cPPyyNxx/siyrQhg3u6s=", + "lastModified": 1771495088, + "narHash": "sha256-1M4NAJMJDgdR/IegOhBQbxnJ9Dhj9VSM+JT2yuxiedI=", "owner": "nixos", "repo": "nixpkgs", - "rev": "497f8871b05933590ae58e4b48172320c59f108f", + "rev": "8c1d8f4fa63318fdc8658ca1f28a58b30bdc25cc", "type": "github" }, "original": { diff --git a/src/lib.rs b/src/lib.rs index b74c36b..c5067bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,6 @@ use std::{ cmp::{max, min}, ffi::{CStr, CString, OsStr, c_void}, fs, - hash::Hash, os::unix::ffi::OsStrExt, path::Path, ptr::{self, NonNull}, @@ -12,7 +11,7 @@ use std::{ use ::typst::{ Document, layout::{Abs, FrameItem, Page, Point, Rect}, - model::{Destination, Numbering, NumberingPattern}, + model::{Destination, Numbering}, text::{Glyph, TextItem}, }; use cairo::{Format, ImageSurface}; @@ -21,15 +20,20 @@ use crate::{ typst::FrameItemIterator, zathura::{ GiraraList, ZathuraResult, cairo_t, girara_list_t, zathura_document_get_data, - zathura_document_get_path, zathura_document_s, zathura_document_set_data, - zathura_document_set_number_of_pages, + zathura_document_get_path, zathura_document_information_entry_list_new, + zathura_document_information_entry_new, zathura_document_information_entry_t, + zathura_document_information_type_e_ZATHURA_DOCUMENT_INFORMATION_AUTHOR, + zathura_document_information_type_e_ZATHURA_DOCUMENT_INFORMATION_CREATION_DATE, + zathura_document_information_type_e_ZATHURA_DOCUMENT_INFORMATION_KEYWORDS, + zathura_document_information_type_e_ZATHURA_DOCUMENT_INFORMATION_PRODUCER, + zathura_document_information_type_e_ZATHURA_DOCUMENT_INFORMATION_TITLE, zathura_document_s, + zathura_document_set_data, zathura_document_set_number_of_pages, zathura_link_destination_type_e_ZATHURA_LINK_DESTINATION_UNKNOWN, zathura_link_destination_type_e_ZATHURA_LINK_DESTINATION_XYZ, zathura_link_free, zathura_link_new, zathura_link_target_s, zathura_link_type_e_ZATHURA_LINK_GOTO_DEST, zathura_link_type_e_ZATHURA_LINK_GOTO_REMOTE, zathura_link_type_e_ZATHURA_LINK_URI, zathura_page_get_document, zathura_page_get_index, zathura_page_set_data, - zathura_page_set_height, zathura_page_set_width, zathura_page_t, zathura_plugin_error_e, - zathura_rectangle_s, + zathura_page_set_height, zathura_page_set_width, zathura_page_t, zathura_rectangle_s, }, }; @@ -54,7 +58,7 @@ pub static zathura_plugin_6_7: zathura::zathura_plugin_definition_s = document_save_as: Some(document_save_as), document_attachments_get: None, document_attachment_save: None, - document_get_information: None, // TODO + document_get_information: Some(document_get_information), page_init: Some(page_init), page_clear: Some(page_clear), page_search_text: None, // TODO? @@ -98,6 +102,71 @@ unsafe extern "C" fn document_free(_: *mut zathura_document_s, data: *mut c_void ZathuraResult::OK } +unsafe extern "C" fn document_get_information( + _: *mut zathura_document_s, + doc: *mut c_void, + res: *mut ZathuraResult, +) -> *mut girara_list_t { + let res = if let Some(mut r) = NonNull::new(res) { + unsafe { + r.write(ZathuraResult::Unknown); + r.as_mut() + } + } else { + &mut ZathuraResult::OK + }; + + let doc = unsafe { &mut *(doc as *mut TypstDocument) }; + let i = &doc.doc.info; + let mut lst = unsafe { + GiraraList::::from_raw( + zathura_document_information_entry_list_new(), + ) + }; + [ + ( + zathura_document_information_type_e_ZATHURA_DOCUMENT_INFORMATION_TITLE, + i.title.clone().unwrap_or_default().to_string(), + ), + ( + zathura_document_information_type_e_ZATHURA_DOCUMENT_INFORMATION_AUTHOR, + i.author.join(", "), + ), + ( + zathura_document_information_type_e_ZATHURA_DOCUMENT_INFORMATION_KEYWORDS, + i.keywords.join(", "), + ), + ( + zathura_document_information_type_e_ZATHURA_DOCUMENT_INFORMATION_CREATION_DATE, + i.date.unwrap_or_default().map_or(String::new(), |d| { + d.display(Default::default()) + .expect("Defaults do the right thing") + .to_string() + }), + ), + ( + zathura_document_information_type_e_ZATHURA_DOCUMENT_INFORMATION_PRODUCER, + "Typst (via zathura-plugin-typst)".to_owned(), + ), + ] + .into_iter() + .filter(|(_, st)| !st.is_empty()) + .map(|(ty, st)| { + unsafe extern "C" { + safe fn calloc(n: usize, s: usize) -> *mut c_void; + } + let st_m = calloc(st.len() + 1, 1); + unsafe { slice::from_raw_parts_mut(st_m as *mut u8, st.len()) } + .copy_from_slice(st.as_bytes()); + (ty, st_m as *const i8) + }) + .for_each(|(ty, st)| { + unsafe { lst.append_allocated(zathura_document_information_entry_new(ty, st)) }; + }); + *res = ZathuraResult::OK; + lst.into_raw() +} + unsafe extern "C" fn document_save_as( _: *mut zathura_document_s, data: *mut c_void, diff --git a/src/typst.rs b/src/typst.rs index 0e76015..c89a98f 100644 --- a/src/typst.rs +++ b/src/typst.rs @@ -8,7 +8,7 @@ use codespan_reporting::{ term::{Config, DisplayStyle, emit_to_write_style, termcolor::Ansi}, }; use typst::{ - diag::{FileError, FileResult, SourceDiagnostic, Warned}, foundations::{Bytes, Datetime}, layout::{Frame, FrameItem, GroupItem, Point, Transform}, model::Url, syntax::{FileId, Lines, Source, Span, VirtualPath}, text::{Font, FontBook}, utils::LazyHash, Library, LibraryExt, WorldExt + diag::{FileError, FileResult, SourceDiagnostic, Warned}, foundations::{Bytes, Datetime}, layout::{Frame, FrameItem, GroupItem, Point, Transform}, syntax::{FileId, Lines, Source, Span, VirtualPath}, text::{Font, FontBook}, utils::LazyHash, Library, LibraryExt, WorldExt }; use typst_kit::{ download::{Downloader, ProgressSink}, diff --git a/src/zathura.rs b/src/zathura.rs index 19979ec..714f2c7 100644 --- a/src/zathura.rs +++ b/src/zathura.rs @@ -82,6 +82,10 @@ impl GiraraList { } } + pub unsafe fn from_raw(list: *mut girara_list_t) -> Self { + Self { list, data: PhantomData } + } + pub fn into_raw(self) -> *mut girara_list_t { let s = ManuallyDrop::new(self); s.list