Set Document path and category based on file path.

This commit is contained in:
Tom Alexander 2023-09-29 21:46:52 -04:00
parent f1e35e317b
commit fc7d4bd949
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
5 changed files with 61 additions and 10 deletions

View File

@ -8,6 +8,7 @@ use crate::compare::parse::get_org_mode_version;
use crate::compare::sexp::sexp; use crate::compare::sexp::sexp;
use crate::context::GlobalSettings; use crate::context::GlobalSettings;
use crate::context::LocalFileAccessInterface; use crate::context::LocalFileAccessInterface;
use crate::parser::parse_file_with_settings;
use crate::parser::parse_with_settings; use crate::parser::parse_with_settings;
pub fn run_anonymous_compare<P: AsRef<str>>( pub fn run_anonymous_compare<P: AsRef<str>>(
@ -70,7 +71,7 @@ pub fn run_compare_on_file_with_settings<P: AsRef<Path>>(
global_settings.file_access = &file_access_interface; global_settings.file_access = &file_access_interface;
global_settings global_settings
}; };
let rust_parsed = parse_with_settings(org_contents, &global_settings)?; let rust_parsed = parse_file_with_settings(org_contents, &global_settings, Some(org_path))?;
let org_sexp = emacs_parse_file_org_document(org_path, &global_settings)?; let org_sexp = emacs_parse_file_org_document(org_path, &global_settings)?;
let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?; let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;

View File

@ -76,11 +76,17 @@ where
r#"(progn r#"(progn
(require 'org) (require 'org)
(defun org-table-align () t) (defun org-table-align () t)
(setq vc-handled-backends nil)
{global_settings} {global_settings}
(find-file-read-only "{file_path}")
(org-mode) (org-mode)
(message "%s" (pp-to-string (org-element-parse-buffer))) (message "%s" (pp-to-string (org-element-parse-buffer)))
)"#, )"#,
global_settings = global_settings_elisp(global_settings) global_settings = global_settings_elisp(global_settings),
file_path = file_path
.as_os_str()
.to_str()
.expect("File name should be valid utf-8.")
); );
let mut cmd = Command::new("emacs"); let mut cmd = Command::new("emacs");
let cmd = cmd let cmd = cmd
@ -89,8 +95,6 @@ where
.arg("--no-site-file") .arg("--no-site-file")
.arg("--no-splash") .arg("--no-splash")
.arg("--batch") .arg("--batch")
.arg("--insert")
.arg(file_path.as_os_str())
.arg("--eval") .arg("--eval")
.arg(elisp_script); .arg(elisp_script);
let out = cmd.output()?; let out = cmd.output()?;

View File

@ -1,5 +1,6 @@
#![feature(exit_status_error)] #![feature(exit_status_error)]
#![feature(trait_alias)] #![feature(trait_alias)]
#![feature(path_file_prefix)]
// TODO: #![warn(missing_docs)] // TODO: #![warn(missing_docs)]
#[cfg(feature = "compare")] #[cfg(feature = "compare")]

View File

@ -1,3 +1,5 @@
use std::path::Path;
use nom::combinator::all_consuming; use nom::combinator::all_consuming;
use nom::combinator::opt; use nom::combinator::opt;
use nom::multi::many0; use nom::multi::many0;
@ -25,30 +27,71 @@ use crate::types::Object;
/// Parse a full org-mode document. /// Parse a full org-mode document.
/// ///
/// This is the main entry point for Organic. It will parse the full contents of the input string as an org-mode document. /// This is a main entry point for Organic. It will parse the full contents of the input string as an org-mode document without an underlying file attached.
#[allow(dead_code)] #[allow(dead_code)]
pub fn parse<'s>(input: &'s str) -> Result<Document<'s>, Box<dyn std::error::Error>> { pub fn parse<'s>(input: &'s str) -> Result<Document<'s>, Box<dyn std::error::Error>> {
parse_with_settings(input, &GlobalSettings::default()) parse_file_with_settings::<&Path>(input, &GlobalSettings::default(), None)
}
/// Parse a full org-mode document.
///
/// This is a main entry point for Organic. It will parse the full contents of the input string as an org-mode document at the file_path.
///
/// file_path is not used for reading the file contents. It is only used for determining the document category and filling in the path attribute on the Document.
#[allow(dead_code)]
pub fn parse_file<'s, P: AsRef<Path>>(
input: &'s str,
file_path: Option<P>,
) -> Result<Document<'s>, Box<dyn std::error::Error>> {
parse_file_with_settings(input, &GlobalSettings::default(), file_path)
} }
/// Parse a full org-mode document with starting settings. /// Parse a full org-mode document with starting settings.
/// ///
/// This is the secondary entry point for Organic. It will parse the full contents of the input string as an org-mode document starting with the settings you supplied. /// This is a secondary entry point for Organic. It will parse the full contents of the input string as an org-mode document starting with the settings you supplied without an underlying file attached.
/// ///
/// This will not prevent additional settings from being learned during parsing, for example when encountering a "#+TODO". /// This will not prevent additional settings from being learned during parsing, for example when encountering a "#+TODO".
#[allow(dead_code)] #[allow(dead_code)]
pub fn parse_with_settings<'g, 's>( pub fn parse_with_settings<'g, 's>(
input: &'s str, input: &'s str,
global_settings: &'g GlobalSettings<'g, 's>, global_settings: &'g GlobalSettings<'g, 's>,
) -> Result<Document<'s>, Box<dyn std::error::Error>> {
parse_file_with_settings::<&Path>(input, global_settings, None)
}
/// Parse a full org-mode document with starting settings.
///
/// This is the secondary entry point for Organic. It will parse the full contents of the input string as an org-mode document at the file_path starting with the settings you supplied.
///
/// This will not prevent additional settings from being learned during parsing, for example when encountering a "#+TODO".
///
/// file_path is not used for reading the file contents. It is only used for determining the document category and filling in the path attribute on the Document.
#[allow(dead_code)]
pub fn parse_file_with_settings<'g, 's, P: AsRef<Path>>(
input: &'s str,
global_settings: &'g GlobalSettings<'g, 's>,
file_path: Option<P>,
) -> Result<Document<'s>, Box<dyn std::error::Error>> { ) -> Result<Document<'s>, Box<dyn std::error::Error>> {
let initial_context = ContextElement::document_context(); let initial_context = ContextElement::document_context();
let initial_context = Context::new(global_settings, List::new(&initial_context)); let initial_context = Context::new(global_settings, List::new(&initial_context));
let wrapped_input = OrgSource::new(input); let wrapped_input = OrgSource::new(input);
let ret = let mut doc =
all_consuming(parser_with_context!(document_org_source)(&initial_context))(wrapped_input) all_consuming(parser_with_context!(document_org_source)(&initial_context))(wrapped_input)
.map_err(|err| err.to_string()) .map_err(|err| err.to_string())
.map(|(_remaining, parsed_document)| parsed_document); .map(|(_remaining, parsed_document)| parsed_document)?;
Ok(ret?) if let Some(file_path) = file_path {
let full_path = file_path.as_ref().canonicalize()?;
if doc.category.is_none() {
let category = full_path
.file_prefix()
.expect("File should have a name.")
.to_str()
.expect("File name should be valid utf-8.");
doc.category = Some(category.to_owned());
}
doc.path = Some(full_path);
}
Ok(doc)
} }
/// Parse a full org-mode document. /// Parse a full org-mode document.

View File

@ -45,5 +45,7 @@ mod text_markup;
mod timestamp; mod timestamp;
mod util; mod util;
pub use document::parse; pub use document::parse;
pub use document::parse_file;
pub use document::parse_file_with_settings;
pub use document::parse_with_settings; pub use document::parse_with_settings;
pub(crate) use org_source::OrgSource; pub(crate) use org_source::OrgSource;