mirror of
https://git.pumpin.online/funkpower/catena.git
synced 2026-10-23 11:17:13 +00:00
citefind: the references in a bibliography, and what could not be read off them
Cuts a reference list into entries — at the note numbers where there are any, at the layout where there are not — and reads each as far as its punctuation allows. Fields that would not parse are named in `unsettled` rather than guessed at, and `--prompt` asks a model about exactly those and no others. Over 202 real reference sections from the corpus: 8,566 references, 95% with a title, 82% with a year, 46% settling every field with no model involved. A title is refused where the entry was never divided, so no record reports its own text back as the work it cites. `ibid.` is flagged and left alone — it points at a work, and the entry does not say which. A rule of dashes is filled in, because the style defines it as the author above. chunkmd gains `note_starts` and `cites_something`: recognising a page of notes and splitting one are the same knowledge, and two copies of that pattern would drift.
This commit is contained in:
@@ -417,6 +417,82 @@ pub unsafe extern "C" fn catena_identify(
|
||||
give_json(&crate::identify(name, bytes))
|
||||
}
|
||||
|
||||
/// Read the references out of a bibliography or a page of notes. Returns a
|
||||
/// JSON array, one object per reference.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `text` must be NUL-terminated UTF-8.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn catena_find_citations(text: *const c_char) -> *mut c_char {
|
||||
clear_error();
|
||||
let Some(text) = (unsafe { borrow(text, "text") }) else {
|
||||
return ptr::null_mut();
|
||||
};
|
||||
give_json(&crate::find_citations(text))
|
||||
}
|
||||
|
||||
/// The question to put to a model about the references that did not parse.
|
||||
/// Takes the JSON array `catena_find_citations` returned. Returns the prompt
|
||||
/// as a JSON string, or NULL when every reference settled — an answer, not an
|
||||
/// error: `catena_last_error` is NULL in that case.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `references` must be NUL-terminated UTF-8 holding a JSON array.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn catena_citation_prompt(references: *const c_char) -> *mut c_char {
|
||||
clear_error();
|
||||
let Some(references) = (unsafe { borrow(references, "references") }) else {
|
||||
return ptr::null_mut();
|
||||
};
|
||||
let references: Vec<citefind::Reference> = match serde_json::from_str(references) {
|
||||
Ok(references) => references,
|
||||
Err(why) => {
|
||||
set_error(why.to_string());
|
||||
return ptr::null_mut();
|
||||
}
|
||||
};
|
||||
match crate::citation_prompt(&references) {
|
||||
Some(prompt) => give_json(&prompt),
|
||||
None => ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill in what did not parse from a model's reply. Returns the JSON array
|
||||
/// with the answer applied, or NULL and an error when the reply is not one
|
||||
/// JSON object.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `references` and `reply` must be NUL-terminated UTF-8.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn catena_merge_citation_reply(
|
||||
references: *const c_char,
|
||||
reply: *const c_char,
|
||||
) -> *mut c_char {
|
||||
clear_error();
|
||||
let (Some(references), Some(reply)) = (unsafe { borrow(references, "references") }, unsafe {
|
||||
borrow(reply, "reply")
|
||||
}) else {
|
||||
return ptr::null_mut();
|
||||
};
|
||||
let references: Vec<citefind::Reference> = match serde_json::from_str(references) {
|
||||
Ok(references) => references,
|
||||
Err(why) => {
|
||||
set_error(why.to_string());
|
||||
return ptr::null_mut();
|
||||
}
|
||||
};
|
||||
match crate::merge_citation_reply(&references, reply) {
|
||||
Ok(merged) => give_json(&merged),
|
||||
Err(why) => {
|
||||
set_error(why);
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The series a title belongs to. Returns a JSON proposal, or NULL when the
|
||||
/// title says nothing about a series — which is most titles, and not an
|
||||
/// error: `catena_last_error` is NULL in that case.
|
||||
|
||||
Reference in New Issue
Block a user