Files
wordcraft/crates/engine/src/cmd/citations.rs
T

99 lines
5.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! References: citations and bibliography (APA, MLA, Chicago, IEEE, Harvard, ISO 690, Turabian,
//! GB/T 7714, GOST, SIST02), source manager, index, table of figures, cross-references, table
//! of authorities, footnote options.
use serde_json::{Value, json};
use wordcraft_doc::collate::{SortKey, heading_letter, sort_key};
use wordcraft_doc::para::InlineObject;
use wordcraft_doc::props::{CharProps, TabAlign, TabLeader, TabStop};
use wordcraft_doc::{Block, Document, Paragraph, Path, Pos, Source, StoryRef};
use super::references::FieldCode;
use super::{delete_selection, sel_result};
use crate::{CmdError, CmdResult, CommandSpec, Selection, Session, p};
mod cross_refs;
mod generated;
mod render;
mod sources;
mod styles;
use cross_refs::cross_ref;
pub use cross_refs::{caption_labels, ref_targets};
#[cfg(test)]
use generated::ENTRY_STYLE;
pub(crate) use generated::generated_list;
use generated::table_of_figures;
pub use generated::{figures_instr, update_generated};
pub use render::{cite, entry};
pub use sources::update_citations;
use sources::{citation, sources};
pub use styles::{Cite, CiteStyle, Name, Names, Order, STYLES, find_style, style};
pub fn specs() -> Vec<CommandSpec> {
vec![
CommandSpec::new("references.sources", "Manage Sources", "References › Citations & Bibliography", sources)
.params(r#"{"add"?: Source, "remove"?: tag, "import"?: path (a Word bibliography file, `b:Sources` / `Sources.xml`)} → list"#),
CommandSpec::new("references.citation", "Insert Citation", "References › Citations & Bibliography", citation).params(r#"{"tag"?: string, "source"?: Source (added if new), "pages"?: string}"#),
CommandSpec::new("references.citationStyle", "Style", "References › Citations & Bibliography", |s, v| {
let st = p::str(v, "style").unwrap_or("APA");
let st = find_style(st).ok_or_else(|| {
CmdError::Params(format!("style must be one of {:?}", STYLES.iter().map(|x| x.name).collect::<Vec<_>>()))
})?;
s.bib_style = st.name.to_string();
// Recorded in the document too, so a save keeps it.
s.doc.settings.bib_style = Some(st.name.to_string());
update_citations(s)?;
Ok(json!({"style": s.bib_style}))
})
.params(
r#"{"style": "APA|Chicago|GB/T 7714|GOST (name sort)|GOST (title sort)|Harvard (Anglia)|IEEE|ISO 690 (author-date)|ISO 690 (numerical)|MLA|SIST02|Turabian" (Word's style names work too)}"#,
),
CommandSpec::new("references.bibliography", "Bibliography", "References › Citations & Bibliography", |s, v| {
let title = p::str(v, "title").unwrap_or(style(&s.bib_style).bib_title).to_string();
generated_list(s, "BIBLIOGRAPHY", &title)?;
sel_result(s)
})
.params(r#"{"title"?: string}"#),
CommandSpec::new("references.tableOfFigures", "Insert Table of Figures", "References › Captions", table_of_figures).params(
r#"{"label"?: "Figure|Table|Equation" or a caption label of your own, "includeLabel"?: bool, "pageNumbers"?: bool, "rightAlign"?: bool, "tabLeader"?: "dot|hyphen|underscore|none"}"#,
),
CommandSpec::new("references.updateFigures", "Update Table", "References › Captions", |s, _| {
update_generated(s)?;
sel_result(s)
}),
CommandSpec::new("references.markCitation", "Mark Citation", "References › Table of Authorities", |s, v| {
let entry = p::str(v, "entry").map(str::to_string).unwrap_or_else(|| s.selected_text().trim().to_string());
if entry.is_empty() {
return Err(CmdError::Params("select a citation or give `entry`".into()));
}
let (_, b) = s.sel.ordered();
s.doc.insert_object(&b, InlineObject::Field { instr: format!("TA \\l \"{}\"", entry.replace('"', "")), result: String::new(), locked: false, dirty: false, code: false, form: String::new() }, &CharProps { hidden: Some(true), ..Default::default() })?;
Ok(json!({"entry": entry}))
})
.params(r#"{"entry"?: string}"#)
.key(super::non_mac("Alt+Shift+I")),
CommandSpec::new("references.tableOfAuthorities", "Insert Table of Authorities", "References › Table of Authorities", |s, _| {
generated_list(s, "TOA", "Table of Authorities")?;
sel_result(s)
}),
CommandSpec::new("references.updateAuthorities", "Update Table", "References › Table of Authorities", |s, _| {
update_generated(s)?;
sel_result(s)
}),
CommandSpec::new("insert.crossReference", "Cross-reference", "Insert › Links", cross_ref)
.params(r#"{"to": "heading|bookmark|figure|table|equation|label:<Name> (a caption label of your own)", "target": string (text / name / number), "show"?: "text|page|number|aboveBelow"} or {} to list targets"#),
CommandSpec::new("references.noteOptions", "Footnote and Endnote", "References › Footnotes", super::references::note_options).params(
r#"{"kind"?: "footnote|endnote", "pos"?: "pageBottom|beneathText" (footnotes) | "sectEnd|docEnd" (endnotes), "numFmt"?: "decimal|lowerRoman|upperRoman|lowerLetter|upperLetter|…", "numStart"?: 1-32767, "numRestart"?: "continuous|eachSect|eachPage" (each page: footnotes only), "scope"?: "document|section", "footnoteFormat"?: …, "endnoteFormat"?: …} — no settings: the options in effect at the caret"#,
),
CommandSpec::new("references.researcher", "Researcher", "References › Research", |s, _| {
s.status = "Researcher needs an online service; WordCraft keeps your documents offline.".into();
Ok(json!({"available": false}))
})
.pure(),
]
}
#[cfg(test)]
mod tests;