diff --git a/src/context/file_access_interface.rs b/src/context/file_access_interface.rs index a31c020..87d7b27 100644 --- a/src/context/file_access_interface.rs +++ b/src/context/file_access_interface.rs @@ -1,14 +1,24 @@ use std::fmt::Debug; +use std::path::PathBuf; pub trait FileAccessInterface: Debug { fn read_file(&self, path: &str) -> Result; } #[derive(Debug, Clone)] -pub struct LocalFileAccessInterface; +pub struct LocalFileAccessInterface { + pub working_directory: Option, +} impl FileAccessInterface for LocalFileAccessInterface { fn read_file(&self, path: &str) -> Result { - 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)?) } } diff --git a/src/context/global_settings.rs b/src/context/global_settings.rs index 4601b24..f1b4d1b 100644 --- a/src/context/global_settings.rs +++ b/src/context/global_settings.rs @@ -14,7 +14,9 @@ impl<'g, 's> GlobalSettings<'g, 's> { pub fn new() -> GlobalSettings<'g, 's> { GlobalSettings { radio_targets: Vec::new(), - file_access: &LocalFileAccessInterface, + file_access: &LocalFileAccessInterface { + working_directory: None, + }, } } } diff --git a/src/lib.rs b/src/lib.rs index c481b7d..d8790d6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,3 +19,6 @@ mod context; mod error; pub mod parser; pub mod types; + +pub use context::GlobalSettings; +pub use context::LocalFileAccessInterface; diff --git a/src/main.rs b/src/main.rs index 14ce151..ece63fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -103,10 +103,18 @@ fn run_parse_on_file>(org_path: P) -> Result<(), Box>(org_path: P) -> Result<(), Box>(org_path: P) -> Result<(), Box> { + use organic::parser::parse_with_settings; + use organic::GlobalSettings; + use organic::LocalFileAccessInterface; + let org_path = org_path.as_ref(); eprintln!( "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 = 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); Ok(()) } diff --git a/src/parser/keyword.rs b/src/parser/keyword.rs index 0d1a11d..886ec70 100644 --- a/src/parser/keyword.rs +++ b/src/parser/keyword.rs @@ -47,14 +47,24 @@ fn _filtered_keyword<'s, F: Matcher>( ) -> Res, Keyword<'s>> { 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. - let (remaining, (consumed_input, (_, _, parsed_key, _, parsed_value, _))) = consumed(tuple(( - space0, - tag("#+"), - key_parser, - tag(":"), - alt((recognize(tuple((space1, is_not("\r\n")))), space0)), - alt((line_ending, eof)), - )))(input)?; + let (remaining, (consumed_input, (_, _, parsed_key, _))) = + consumed(tuple((space0, tag("#+"), key_parser, tag(":"))))(input)?; + match tuple((space0, alt((line_ending, eof))))(remaining) { + Ok((remaining, _)) => { + return Ok(( + remaining, + Keyword { + 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(( remaining, Keyword { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index ebda885..8394ab0 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -46,4 +46,5 @@ mod token; mod util; pub use document::document; pub use document::parse; +pub use document::parse_with_settings; pub use org_source::OrgSource;