From d38e19825887e0c63fcc51f6c84797b1c99be84c Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Mon, 4 Sep 2023 17:38:02 -0400 Subject: [PATCH] Add a parse_with_settings function. --- src/parser/document.rs | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/parser/document.rs b/src/parser/document.rs index aaadfbb..5f0d1c0 100644 --- a/src/parser/document.rs +++ b/src/parser/document.rs @@ -51,6 +51,9 @@ use crate::types::Heading; use crate::types::Object; use crate::types::Section; +/// 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. #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[allow(dead_code)] pub fn parse<'s>(input: &'s str) -> Result, String> { @@ -65,6 +68,30 @@ pub fn parse<'s>(input: &'s str) -> Result, String> { ret } +/// 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 will not prevent additional settings from being learned during parsing, for example when encountering a "#+TODO". +#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] +#[allow(dead_code)] +pub fn parse_with_settings<'g, 's>( + input: &'s str, + global_settings: &'g GlobalSettings<'g, 's>, +) -> Result, String> { + let initial_context = ContextElement::document_context(); + let initial_context = Context::new(global_settings, List::new(&initial_context)); + let wrapped_input = OrgSource::new(input); + let ret = + all_consuming(parser_with_context!(document_org_source)(&initial_context))(wrapped_input) + .map_err(|err| err.to_string()) + .map(|(_remaining, parsed_document)| parsed_document); + ret +} + +/// Parse a full org-mode document. +/// +/// Use this entry point when you want to have direct control over the starting context or if you want to use this integrated with other nom parsers. For general-purpose usage, the `parse` and `parse_with_settings` functions are a lot simpler. #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[allow(dead_code)] pub fn document<'b, 'g, 'r, 's>( @@ -91,11 +118,14 @@ fn document_org_source<'b, 'g, 'r, 's>( .map_err(|err| nom::Err::>>::Failure(err.into()))?; let parsed_setup_file = _document(context, setup_file_contents.as_str().into()); if parsed_setup_file.is_err() { - return Err(nom::Err::Error(CustomError::MyError(MyError("Failed to parse the setup file.".into())))); + return Err(nom::Err::Error(CustomError::MyError(MyError( + "Failed to parse the setup file.".into(), + )))); } - let (_remaining, parsed_setup_file) = parsed_setup_file.expect("The if-statement proves this is ok."); + let (_remaining, parsed_setup_file) = + parsed_setup_file.expect("The if-statement proves this is ok."); - println!("TODO: Process setup_file: {}", setup_file); + println!("TODO: Process setup_file: {:#?}", parsed_setup_file); } let (remaining, document) = _document(context, input).map(|(rem, out)| (Into::<&str>::into(rem), out))?;