Handle escaping the characters in org macro arguments.
This commit is contained in:
parent
a32cea8139
commit
a6adeee40b
7
org_mode_samples/object/macro/escape.org
Normal file
7
org_mode_samples/object/macro/escape.org
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{{{foo}}}
|
||||||
|
|
||||||
|
{{{fo\o}}}
|
||||||
|
|
||||||
|
{{{foo(b\ar)}}}
|
||||||
|
|
||||||
|
{{{foo(b\,r)}}}
|
@ -149,8 +149,8 @@ pub(crate) fn compare_property_list_of_quoted_string<
|
|||||||
if e != r {
|
if e != r {
|
||||||
let this_status = DiffStatus::Bad;
|
let this_status = DiffStatus::Bad;
|
||||||
let message = Some(format!(
|
let message = Some(format!(
|
||||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
"{} mismatch (emacs != rust) {:?} != {:?}. Full list: {:?} != {:?}",
|
||||||
emacs_field, value, rust_value
|
emacs_field, e, r, value, rust_value
|
||||||
));
|
));
|
||||||
return Ok(Some((this_status, message)));
|
return Ok(Some((this_status, message)));
|
||||||
}
|
}
|
||||||
|
@ -243,3 +243,149 @@ enum CoalesceWhitespace {
|
|||||||
Normal,
|
Normal,
|
||||||
HasWhitespace { in_whitespace: bool, ret: String },
|
HasWhitespace { in_whitespace: bool, ret: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes all whitespace from a string and handle escaping characters.
|
||||||
|
///
|
||||||
|
/// Example: "foo bar" => "foobar" and "foo \n bar" => "foobar" but if the escape character is backslash and comma is an escapable character than "foo\,bar" becomes "foo,bar".
|
||||||
|
pub(crate) fn coalesce_whitespace_escaped<'c, C: Fn(char) -> bool>(
|
||||||
|
escape_character: char,
|
||||||
|
escapable_characters: C,
|
||||||
|
) -> impl for<'s> Fn(&'s str) -> Cow<'s, str> {
|
||||||
|
move |input| impl_coalesce_whitespace_escaped(input, escape_character, &escapable_characters)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn impl_coalesce_whitespace_escaped<'s, C: Fn(char) -> bool>(
|
||||||
|
input: &'s str,
|
||||||
|
escape_character: char,
|
||||||
|
escapable_characters: C,
|
||||||
|
) -> Cow<'s, str> {
|
||||||
|
let mut state = CoalesceWhitespaceEscaped::Normal;
|
||||||
|
for (offset, c) in input.char_indices() {
|
||||||
|
state = match (state, c) {
|
||||||
|
(CoalesceWhitespaceEscaped::Normal, c) if c == escape_character => {
|
||||||
|
CoalesceWhitespaceEscaped::NormalEscaping {
|
||||||
|
escape_offset: offset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(CoalesceWhitespaceEscaped::Normal, ' ' | '\t' | '\r' | '\n') => {
|
||||||
|
let mut ret = String::with_capacity(input.len());
|
||||||
|
ret.push_str(&input[..offset]);
|
||||||
|
ret.push(' ');
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
in_whitespace: true,
|
||||||
|
ret,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(CoalesceWhitespaceEscaped::Normal, _) => CoalesceWhitespaceEscaped::Normal,
|
||||||
|
(CoalesceWhitespaceEscaped::NormalEscaping { escape_offset }, c)
|
||||||
|
if escapable_characters(c) =>
|
||||||
|
{
|
||||||
|
// We escaped a character so we need mutation
|
||||||
|
let mut ret = String::with_capacity(input.len());
|
||||||
|
ret.push_str(&input[..escape_offset]);
|
||||||
|
ret.push(c);
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
in_whitespace: false,
|
||||||
|
ret,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
CoalesceWhitespaceEscaped::NormalEscaping { escape_offset: _ },
|
||||||
|
' ' | '\t' | '\r' | '\n',
|
||||||
|
) => {
|
||||||
|
// We didn't escape the character but we hit whitespace anyway.
|
||||||
|
let mut ret = String::with_capacity(input.len());
|
||||||
|
ret.push_str(&input[..offset]);
|
||||||
|
ret.push(' ');
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
in_whitespace: true,
|
||||||
|
ret,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(CoalesceWhitespaceEscaped::NormalEscaping { escape_offset: _ }, _) => {
|
||||||
|
// We didn't escape the character so continue as normal.
|
||||||
|
CoalesceWhitespaceEscaped::Normal
|
||||||
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
in_whitespace: _,
|
||||||
|
ret,
|
||||||
|
},
|
||||||
|
c,
|
||||||
|
) if c == escape_character => {
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutationEscaping { ret }
|
||||||
|
}
|
||||||
|
(
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
mut in_whitespace,
|
||||||
|
mut ret,
|
||||||
|
},
|
||||||
|
' ' | '\t' | '\r' | '\n',
|
||||||
|
) => {
|
||||||
|
if !in_whitespace {
|
||||||
|
in_whitespace = true;
|
||||||
|
ret.push(' ');
|
||||||
|
}
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation { in_whitespace, ret }
|
||||||
|
}
|
||||||
|
(
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
in_whitespace,
|
||||||
|
mut ret,
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
) => {
|
||||||
|
ret.push(c);
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
in_whitespace: false,
|
||||||
|
ret,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(CoalesceWhitespaceEscaped::RequiresMutationEscaping { mut ret }, c)
|
||||||
|
if escapable_characters(c) =>
|
||||||
|
{
|
||||||
|
ret.push(c);
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
in_whitespace: false,
|
||||||
|
ret,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutationEscaping { mut ret },
|
||||||
|
' ' | '\t' | '\r' | '\n',
|
||||||
|
) => {
|
||||||
|
ret.push(' ');
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
in_whitespace: true,
|
||||||
|
ret,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(CoalesceWhitespaceEscaped::RequiresMutationEscaping { mut ret }, c) => {
|
||||||
|
ret.push(escape_character);
|
||||||
|
ret.push(c);
|
||||||
|
// TODO
|
||||||
|
CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
in_whitespace: false,
|
||||||
|
ret,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// match state {
|
||||||
|
// CoalesceWhitespaceEscaped::Normal => Cow::Borrowed(input),
|
||||||
|
// CoalesceWhitespaceEscaped::RequiresMutation {
|
||||||
|
// in_whitespace: _,
|
||||||
|
// ret,
|
||||||
|
// } => Cow::Owned(ret),
|
||||||
|
// }
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CoalesceWhitespaceEscaped {
|
||||||
|
Normal,
|
||||||
|
NormalEscaping { escape_offset: usize },
|
||||||
|
RequiresMutation { in_whitespace: bool, ret: String },
|
||||||
|
RequiresMutationEscaping { ret: String },
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user