Module tpnote_lib::workflow
source · Expand description
Tp-Note’s high level API.
How to integrate this in your text editor code?
First, call create_new_note_or_synchronize_filename()
with the first positional command line parameter <path>
.
Then open the new text file with the returned path in your
text editor. After modifying the text, saving it and closing your
text editor, call synchronize_filename()
.
The returned path points to the possibly renamed note file.
Tp-Note is customizable at runtime by modifying its configuration stored in
crate::config::LIB_CFG
before executing the functions in this
module (see type definition and documentation in crate::config::LibCfg
).
All functions in this API are stateless.
Example with TemplateKind::New
use tpnote_lib::content::Content;
use tpnote_lib::content::ContentString;
use tpnote_lib::workflow::synchronize_filename;
use tpnote_lib::workflow::create_new_note_or_synchronize_filename;
use std::env::temp_dir;
use std::fs;
use std::path::Path;
// Prepare test.
let notedir = temp_dir();
let clipboard = ContentString::default();
let stdin = ContentString::default();
// This is the condition to choose: `TemplateKind::New`:
assert!(clipboard.is_empty() || stdin.is_empty());
// There are no inhibitor rules to change the `TemplateKind`.
let template_kind_filter = |tk|tk;
// Start test.
// You can plug in your own type (must impl. `Content`).
let n = create_new_note_or_synchronize_filename::<ContentString, _>(
¬edir, &clipboard, &stdin, template_kind_filter,
&None, None).unwrap();
// Check result.
assert!(n.as_os_str().to_str().unwrap()
.contains("--Note"));
assert!(n.is_file());
let raw_note = fs::read_to_string(n).unwrap();
#[cfg(not(target_family = "windows"))]
assert!(raw_note.starts_with("\u{feff}---\ntitle:"));
#[cfg(target_family = "windows")]
assert!(raw_note.starts_with("\u{feff}---\r\ntitle:"));
The internal data storage for the note’s content is ContentString
which implements the Content
trait. Now we modify slightly
the above example to showcase, how to overwrite
one of the trait’s methods.
use std::path::Path;
use tpnote_lib::content::Content;
use tpnote_lib::content::ContentString;
use tpnote_lib::workflow::create_new_note_or_synchronize_filename;
use std::env::temp_dir;
use std::path::PathBuf;
use std::fs;
use std::fs::OpenOptions;
use std::io::Write;
use std::ops::Deref;
#[derive(Default, Debug, Eq, PartialEq)]
// We need a newtype because of the orphan rule.
pub struct MyContentString(ContentString);
impl From<String> for MyContentString {
fn from(input: String) -> Self {
MyContentString(ContentString::from(input))
}
}
impl AsRef<str> for MyContentString {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl Content for MyContentString {
// Now we overwrite one method to show how to plugin custom code.
fn save_as(&self, new_file_path: &Path) -> Result<(), std::io::Error> {
let mut outfile = OpenOptions::new()
.write(true)
.create(true)
.open(&new_file_path)?;
// We do not save the content to disk, we write intstead:
write!(outfile, "Simulation")?;
Ok(())
}
fn header(&self) -> &str {
self.0.header()
}
fn body(&self) -> &str {
self.0.header()
}
}
// Prepare test.
let notedir = temp_dir();
let clipboard = MyContentString::default();
let stdin = MyContentString::default();
// This is the condition to choose: `TemplateKind::New`:
assert!(clipboard.is_empty() || stdin.is_empty());
// There are no inhibitor rules to change the `TemplateKind`.
let template_kind_filter = |tk|tk;
// Start test.
// Here we plugin our own type (must implement `Content`).
let n = create_new_note_or_synchronize_filename::<MyContentString, _>(
¬edir, &clipboard, &stdin, template_kind_filter,
&None, None).unwrap();
// Check result.
assert!(n.as_os_str().to_str().unwrap()
.contains("--Note"));
assert!(n.is_file());
let raw_note = fs::read_to_string(n).unwrap();
assert_eq!(raw_note, "Simulation");
Functions
- Create a new note by inserting
Tp-Note
’s environment in a template. If the note to be created exists already, append a so calledcopy_counter
to the filename and try to save it again. In case this does not succeed either, increment thecopy_counter
until a free filename is found. The returned path points to the (new) note file on disk. Depending on the context, Tp-Note chooses oneTemplateKind
to operate (c.f.tpnote_lib::template::TemplateKind::from()
). Thetk-filter
allows to overwrite this choice, e.g. you may setTemplateKind::None
under certain circumstances. This way the caller can inject command line parameters like--no-filename-sync
. Ifhtml_export = Some((dir, local_link_kind))
, the function acts like like described above, but in addition it renders the note’s content into HTML and saves the.html
file in the directorydir
. This optional HTML rendition is performed just before returning and does not affect any above described operation.force_lang
disables the automatic language detection and usesforce_lang
instead; or, if-
use the environment variableTPNOTE_LANG
or, - if not defined - use the user’s default language as reported from the operating system. - When the header can not be deserialized, the file located in
context.path
is rendered as “Error HTML page”. The erroneous content is rendered to html withparse_hyperlinks::renderer::text_rawlinks2html
and inserted in theTMPL_HTML_VIEWER_ERROR
template (can be replace at runtime). This template expects the template variablesTMPL_VAR_PATH
andTMPL_HTML_VAR_NOTE_JS
andTMPL_HTML_VAR_NOTE_ERROR
incontext
to be set. NB: The value ofTMPL_VAR_PATH
equalscontext.path
. - Returns the HTML rendition of the note file located in
context.path
with the templateTMPL_HTML_VIEWER
. This function is stateless. - Returns the HTML rendition of the note file located in
context.path
with the templateTMPL_HTML_VIEWER
(can be replaced at runtime). This function is stateless. - Open the note file
path
on disk and read its YAML front matter. Then calculate from the front matter how the filename should be to be in sync. If it is different, rename the note on disk. Returns the note’s new or existing filename. Repeated calls, will reload the environment variables, but not the configuration file. This function is stateless.