diff --git a/org_mode_samples/object/target/simple.org b/org_mode_samples/object/target/simple.org deleted file mode 100644 index 695ff63..0000000 --- a/org_mode_samples/object/target/simple.org +++ /dev/null @@ -1,3 +0,0 @@ -foo <> baz - -lorem << ipsum >> dolar diff --git a/src/compare/diff.rs b/src/compare/diff.rs index e6a6506..e9da204 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -1576,7 +1576,7 @@ fn compare_example_block<'b, 's>( [], ( EmacsField::Required(":value"), - |r| Some(r.contents.as_str()), + |r| Some(&r.contents), compare_property_quoted_string ), ( @@ -1654,7 +1654,7 @@ fn compare_export_block<'b, 's>( ), ( EmacsField::Required(":value"), - |r| Some(r.contents.as_str()), + |r| Some(&r.contents), compare_property_quoted_string ) ) { @@ -1702,7 +1702,7 @@ fn compare_src_block<'b, 's>( ), ( EmacsField::Required(":value"), - |r| Some(r.contents.as_str()), + |r| Some(&r.contents), compare_property_quoted_string ), ( diff --git a/src/parser/lesser_block.rs b/src/parser/lesser_block.rs index 9f99289..bc2a9b6 100644 --- a/src/parser/lesser_block.rs +++ b/src/parser/lesser_block.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use nom::branch::alt; use nom::bytes::complete::is_not; use nom::bytes::complete::tag; @@ -651,6 +653,11 @@ fn switch_word<'s>(input: OrgSource<'s>) -> Res, OrgSource<'s>> { ))(input) } +enum ContentState { + Normal, + Modified(String), +} + #[cfg_attr( feature = "tracing", tracing::instrument(ret, level = "debug", skip(context)) @@ -658,8 +665,8 @@ fn switch_word<'s>(input: OrgSource<'s>) -> Res, OrgSource<'s>> { pub(crate) fn content<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, -) -> Res, String> { - let mut ret = String::new(); +) -> Res, Cow<'s, str>> { + let mut state = ContentState::Normal; let mut remaining = input; let exit_matcher_parser = parser_with_context!(exit_matcher_parser)(context); loop { @@ -669,13 +676,28 @@ pub(crate) fn content<'b, 'g, 'r, 's>( let (remain, (pre_escape_whitespace, line)) = content_line(remaining)?; if let Some(val) = pre_escape_whitespace { - ret.push_str(Into::<&str>::into(val)); + if let ContentState::Modified(ref mut ret) = state { + ret.push_str(Into::<&str>::into(val)); + } else { + let mut ret = String::new(); + ret.push_str(Into::<&str>::into(input.get_until(remaining))); + ret.push_str(Into::<&str>::into(val)); + state = ContentState::Modified(ret); + } + } + if let ContentState::Modified(ref mut ret) = state { + ret.push_str(line.into()); } - ret.push_str(line.into()); remaining = remain; } - Ok((remaining, ret)) + match state { + ContentState::Normal => Ok(( + remaining, + Cow::Borrowed(Into::<&str>::into(input.get_until(remaining))), + )), + ContentState::Modified(ret) => Ok((remaining, Cow::Owned(ret))), + } } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] diff --git a/src/types/lesser_element.rs b/src/types/lesser_element.rs index 5eea3b5..868c175 100644 --- a/src/types/lesser_element.rs +++ b/src/types/lesser_element.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use super::object::Object; use super::AffiliatedKeywords; use super::GetAffiliatedKeywords; @@ -59,7 +61,7 @@ pub struct ExampleBlock<'s> { pub retain_labels: RetainLabels, pub use_labels: bool, pub label_format: Option<&'s str>, - pub contents: String, + pub contents: Cow<'s, str>, } #[derive(Debug)] @@ -68,7 +70,7 @@ pub struct ExportBlock<'s> { pub affiliated_keywords: AffiliatedKeywords<'s>, pub export_type: Option<&'s str>, pub data: Option<&'s str>, - pub contents: String, + pub contents: Cow<'s, str>, } #[derive(Debug)] @@ -83,7 +85,7 @@ pub struct SrcBlock<'s> { pub retain_labels: RetainLabels, pub use_labels: bool, pub label_format: Option<&'s str>, - pub contents: String, + pub contents: Cow<'s, str>, } #[derive(Debug)]