Take into account the source directory when parsing org-mode in Organic.

Previously only the emacs code was doing this.
This commit is contained in:
Tom Alexander 2023-09-04 21:46:40 -04:00
parent 275b4b53d1
commit d3c733c5ad
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
6 changed files with 61 additions and 15 deletions

View File

@ -1,14 +1,24 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::path::PathBuf;
pub trait FileAccessInterface: Debug { pub trait FileAccessInterface: Debug {
fn read_file(&self, path: &str) -> Result<String, std::io::Error>; fn read_file(&self, path: &str) -> Result<String, std::io::Error>;
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct LocalFileAccessInterface; pub struct LocalFileAccessInterface {
pub working_directory: Option<PathBuf>,
}
impl FileAccessInterface for LocalFileAccessInterface { impl FileAccessInterface for LocalFileAccessInterface {
fn read_file(&self, path: &str) -> Result<String, std::io::Error> { fn read_file(&self, path: &str) -> Result<String, std::io::Error> {
Ok(std::fs::read_to_string(path)?) let final_path = self
.working_directory
.as_ref()
.map(PathBuf::as_path)
.map(|pb| pb.join(path))
.unwrap_or_else(|| PathBuf::from(path));
eprintln!("Reading file: {}", final_path.display());
Ok(std::fs::read_to_string(final_path)?)
} }
} }

View File

@ -14,7 +14,9 @@ impl<'g, 's> GlobalSettings<'g, 's> {
pub fn new() -> GlobalSettings<'g, 's> { pub fn new() -> GlobalSettings<'g, 's> {
GlobalSettings { GlobalSettings {
radio_targets: Vec::new(), radio_targets: Vec::new(),
file_access: &LocalFileAccessInterface, file_access: &LocalFileAccessInterface {
working_directory: None,
},
} }
} }
} }

View File

@ -19,3 +19,6 @@ mod context;
mod error; mod error;
pub mod parser; pub mod parser;
pub mod types; pub mod types;
pub use context::GlobalSettings;
pub use context::LocalFileAccessInterface;

View File

@ -103,10 +103,18 @@ fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::err
let org_path = org_path.as_ref(); let org_path = org_path.as_ref();
eprintln!("Using emacs version: {}", get_emacs_version()?.trim()); eprintln!("Using emacs version: {}", get_emacs_version()?.trim());
eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim()); eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim());
// TODO: This should take into account the original file path when parsing in Organic, not just in emacs. let parent_directory = org_path
.parent()
.ok_or("Should be contained inside a directory.")?;
let org_contents = std::fs::read_to_string(org_path)?; let org_contents = std::fs::read_to_string(org_path)?;
let org_contents = org_contents.as_str(); let org_contents = org_contents.as_str();
let rust_parsed = parse(org_contents)?; let global_settings = GlobalSettings {
radio_targets: Vec::new(),
file_access: &LocalFileAccessInterface {
working_directory: Some(parent_directory.to_path_buf()),
},
};
let rust_parsed = parse_with_settings(org_contents, &global_settings)?;
let org_sexp = emacs_parse_file_org_document(org_path)?; let org_sexp = emacs_parse_file_org_document(org_path)?;
let (_remaining, parsed_sexp) = let (_remaining, parsed_sexp) =
sexp_with_padding(org_sexp.as_str()).map_err(|e| e.to_string())?; sexp_with_padding(org_sexp.as_str()).map_err(|e| e.to_string())?;
@ -128,14 +136,26 @@ fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::err
#[cfg(not(feature = "compare"))] #[cfg(not(feature = "compare"))]
fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::error::Error>> { fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::error::Error>> {
use organic::parser::parse_with_settings;
use organic::GlobalSettings;
use organic::LocalFileAccessInterface;
let org_path = org_path.as_ref(); let org_path = org_path.as_ref();
eprintln!( eprintln!(
"This program was built with compare disabled. Only parsing with organic, not comparing." "This program was built with compare disabled. Only parsing with organic, not comparing."
); );
// TODO: This should take into account the original file path when parsing let parent_directory = org_path
.parent()
.ok_or("Should be contained inside a directory.")?;
let org_contents = std::fs::read_to_string(org_path)?; let org_contents = std::fs::read_to_string(org_path)?;
let org_contents = org_contents.as_str(); let org_contents = org_contents.as_str();
let rust_parsed = parse(org_contents)?; let global_settings = GlobalSettings {
radio_targets: Vec::new(),
file_access: &LocalFileAccessInterface {
working_directory: Some(parent_directory.to_path_buf()),
},
};
let rust_parsed = parse_with_settings(org_contents, &global_settings)?;
println!("{:#?}", rust_parsed); println!("{:#?}", rust_parsed);
Ok(()) Ok(())
} }

View File

@ -47,14 +47,24 @@ fn _filtered_keyword<'s, F: Matcher>(
) -> Res<OrgSource<'s>, Keyword<'s>> { ) -> Res<OrgSource<'s>, Keyword<'s>> {
start_of_line(input)?; start_of_line(input)?;
// TODO: When key is a member of org-element-parsed-keywords, value can contain the standard set objects, excluding footnote references. // TODO: When key is a member of org-element-parsed-keywords, value can contain the standard set objects, excluding footnote references.
let (remaining, (consumed_input, (_, _, parsed_key, _, parsed_value, _))) = consumed(tuple(( let (remaining, (consumed_input, (_, _, parsed_key, _))) =
space0, consumed(tuple((space0, tag("#+"), key_parser, tag(":"))))(input)?;
tag("#+"), match tuple((space0, alt((line_ending, eof))))(remaining) {
key_parser, Ok((remaining, _)) => {
tag(":"), return Ok((
alt((recognize(tuple((space1, is_not("\r\n")))), space0)), remaining,
alt((line_ending, eof)), Keyword {
)))(input)?; source: consumed_input.into(),
key: parsed_key.into(),
value: "".into(),
},
));
}
err @ Err(_) => err?,
};
let (remaining, _ws) = space1(remaining)?;
let (remaining, parsed_value) = is_not("\r\n")(remaining)?;
let (remaining, _ws) = tuple((space0, alt((line_ending, eof))))(remaining)?;
Ok(( Ok((
remaining, remaining,
Keyword { Keyword {

View File

@ -46,4 +46,5 @@ mod token;
mod util; mod util;
pub use document::document; pub use document::document;
pub use document::parse; pub use document::parse;
pub use document::parse_with_settings;
pub use org_source::OrgSource; pub use org_source::OrgSource;