Add src block properties.
These are largely the same as example blocks but with a :language property.
This commit is contained in:
@@ -176,7 +176,6 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
|
||||
remaining,
|
||||
ExampleBlock {
|
||||
source: source.into(),
|
||||
name: source.into(),
|
||||
switches,
|
||||
number_lines,
|
||||
retain_labels,
|
||||
@@ -233,9 +232,9 @@ pub(crate) fn src_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, SrcBlock<'s>> {
|
||||
let (remaining, name) = lesser_block_begin("src")(context, input)?;
|
||||
let (remaining, _name) = lesser_block_begin("src")(context, input)?;
|
||||
// https://orgmode.org/worg/org-syntax.html#Blocks claims that data is mandatory and must follow the LANGUAGE SWITCHES ARGUMENTS pattern but testing has shown that no data and incorrect data here will still parse to a src block.
|
||||
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
|
||||
let (remaining, parameters) = opt(tuple((space1, src_switches)))(remaining)?;
|
||||
let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
|
||||
let lesser_block_end_specialized = lesser_block_end("src");
|
||||
let contexts = [
|
||||
@@ -254,17 +253,35 @@ pub(crate) fn src_block<'b, 'g, 'r, 's>(
|
||||
None => None,
|
||||
};
|
||||
|
||||
let (remaining, contents) = parser_with_context!(text_until_exit)(&parser_context)(remaining)?;
|
||||
let (remaining, contents) = content(&parser_context, remaining)?;
|
||||
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
||||
|
||||
let source = get_consumed(input, remaining);
|
||||
let (switches, language, number_lines, retain_labels, use_labels, label_format) = {
|
||||
if let Some(parameters) = parameters {
|
||||
(
|
||||
Some(parameters.source),
|
||||
parameters.language,
|
||||
parameters.number_lines,
|
||||
parameters.retain_labels,
|
||||
parameters.use_labels,
|
||||
parameters.label_format,
|
||||
)
|
||||
} else {
|
||||
(None, None, None, RetainLabels::Yes, true, None)
|
||||
}
|
||||
};
|
||||
Ok((
|
||||
remaining,
|
||||
SrcBlock {
|
||||
source: source.into(),
|
||||
name: name.into(),
|
||||
switches: parameters.map(|parameters| Into::<&str>::into(parameters)),
|
||||
contents: contents.into(),
|
||||
switches,
|
||||
language,
|
||||
number_lines,
|
||||
retain_labels,
|
||||
use_labels,
|
||||
label_format,
|
||||
contents,
|
||||
},
|
||||
))
|
||||
}
|
||||
@@ -329,8 +346,9 @@ fn _lesser_block_begin<'b, 'g, 'r, 's, 'c>(
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ExampleSwitches<'s> {
|
||||
struct ExampleSrcSwitches<'s> {
|
||||
source: &'s str,
|
||||
language: Option<&'s str>,
|
||||
number_lines: Option<SwitchNumberLines>,
|
||||
retain_labels: RetainLabels,
|
||||
use_labels: bool,
|
||||
@@ -346,17 +364,50 @@ enum SwitchState {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn example_switches<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ExampleSwitches<'s>> {
|
||||
fn src_switches<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ExampleSrcSwitches<'s>> {
|
||||
example_src_switches(true)(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn example_switches<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ExampleSrcSwitches<'s>> {
|
||||
let (remaining, switches) = example_src_switches(false)(input)?;
|
||||
debug_assert!(switches.language.is_none());
|
||||
Ok((remaining, switches))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn example_src_switches(
|
||||
grab_language: bool,
|
||||
) -> impl for<'s> Fn(OrgSource<'s>) -> Res<OrgSource<'s>, ExampleSrcSwitches<'s>> {
|
||||
move |input| _example_src_switches(input, grab_language)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn _example_src_switches<'s>(
|
||||
input: OrgSource<'s>,
|
||||
grab_language: bool,
|
||||
) -> Res<OrgSource<'s>, ExampleSrcSwitches<'s>> {
|
||||
let mut number_lines = None;
|
||||
let mut retain_labels = RetainLabels::Yes;
|
||||
let mut use_labels = true;
|
||||
let mut label_format = None;
|
||||
let mut saw_r = false;
|
||||
let mut language = None;
|
||||
let (remaining, (source, (words, _))) =
|
||||
consumed(tuple((separated_list1(space1, switch_word), space0)))(input)?;
|
||||
|
||||
let mut words_iter = words.into_iter();
|
||||
if grab_language {
|
||||
match words_iter.next() {
|
||||
Some(l) => {
|
||||
language = Some(Into::<&str>::into(l));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
let mut state = SwitchState::Normal;
|
||||
for word in words {
|
||||
for word in words_iter {
|
||||
let normalized_word = Into::<&str>::into(word);
|
||||
loop {
|
||||
match (&state, normalized_word) {
|
||||
@@ -436,8 +487,9 @@ fn example_switches<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ExampleSwitc
|
||||
|
||||
Ok((
|
||||
remaining,
|
||||
ExampleSwitches {
|
||||
ExampleSrcSwitches {
|
||||
source: Into::<&str>::into(source),
|
||||
language,
|
||||
number_lines,
|
||||
retain_labels,
|
||||
use_labels,
|
||||
|
||||
Reference in New Issue
Block a user