Compare commits
No commits in common. "7a4dc20dc9d03d68f2646c67f509d2d4aa09ccfb" and "e47901a67f71c03870e37ce5049db20bc821aca0" have entirely different histories.
7a4dc20dc9
...
e47901a67f
@ -73,18 +73,14 @@ pub(crate) fn broken_end<'b, 'g, 'r, 's>(
|
|||||||
};
|
};
|
||||||
Ok((remaining, paragraph))
|
Ok((remaining, paragraph))
|
||||||
} else {
|
} else {
|
||||||
let (remaining, post_blank) =
|
let (remaining, _trailing_ws) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, lead_in_remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, lead_in_remaining)?;
|
||||||
|
|
||||||
let body = Into::<&str>::into(input.get_until(lead_in_remaining));
|
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
Paragraph::of_text_full(
|
Paragraph::of_text(
|
||||||
input.get_until(remaining).into(),
|
input.get_until(remaining).into(),
|
||||||
body,
|
input.get_until(lead_in_remaining).into(),
|
||||||
if body.len() > 0 { Some(body) } else { None },
|
|
||||||
post_blank.map(Into::<&str>::into),
|
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -181,10 +181,8 @@ fn _document<'b, 'g, 'r, 's>(
|
|||||||
let zeroth_section_matcher = parser_with_context!(zeroth_section)(context);
|
let zeroth_section_matcher = parser_with_context!(zeroth_section)(context);
|
||||||
let heading_matcher = parser_with_context!(heading(0))(context);
|
let heading_matcher = parser_with_context!(heading(0))(context);
|
||||||
let (remaining, _blank_lines) = many0(blank_line)(input)?;
|
let (remaining, _blank_lines) = many0(blank_line)(input)?;
|
||||||
let contents_begin = remaining;
|
|
||||||
let (remaining, zeroth_section) = opt(zeroth_section_matcher)(remaining)?;
|
let (remaining, zeroth_section) = opt(zeroth_section_matcher)(remaining)?;
|
||||||
let (remaining, children) = many0(heading_matcher)(remaining)?;
|
let (remaining, children) = many0(heading_matcher)(remaining)?;
|
||||||
let contents = get_consumed(contents_begin, remaining);
|
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
@ -194,11 +192,6 @@ fn _document<'b, 'g, 'r, 's>(
|
|||||||
path: None,
|
path: None,
|
||||||
zeroth_section,
|
zeroth_section,
|
||||||
children,
|
children,
|
||||||
contents: if contents.len() > 0 {
|
|
||||||
Some(Into::<&str>::into(contents))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ fn _heading<'b, 'g, 'r, 's>(
|
|||||||
let (remaining, pre_headline) = headline(context, input, parent_star_count)?;
|
let (remaining, pre_headline) = headline(context, input, parent_star_count)?;
|
||||||
let section_matcher = bind_context!(section, context);
|
let section_matcher = bind_context!(section, context);
|
||||||
let heading_matcher = bind_context!(heading(pre_headline.star_count), context);
|
let heading_matcher = bind_context!(heading(pre_headline.star_count), context);
|
||||||
let (contents_begin, _) = opt(many0(blank_line))(remaining)?;
|
let contents_begin = remaining;
|
||||||
let (remaining, maybe_section) =
|
let (remaining, maybe_section) =
|
||||||
opt(map(section_matcher, DocumentElement::Section))(remaining)?;
|
opt(map(section_matcher, DocumentElement::Section))(remaining)?;
|
||||||
let (remaining, _ws) = opt(tuple((start_of_line, many0(blank_line))))(remaining)?;
|
let (remaining, _ws) = opt(tuple((start_of_line, many0(blank_line))))(remaining)?;
|
||||||
|
@ -7,7 +7,6 @@ use nom::character::complete::multispace1;
|
|||||||
use nom::character::complete::one_of;
|
use nom::character::complete::one_of;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
use nom::character::complete::space1;
|
use nom::character::complete::space1;
|
||||||
use nom::combinator::consumed;
|
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
use nom::combinator::map;
|
use nom::combinator::map;
|
||||||
use nom::combinator::not;
|
use nom::combinator::not;
|
||||||
@ -153,7 +152,6 @@ where
|
|||||||
let mut children = Vec::new();
|
let mut children = Vec::new();
|
||||||
let mut first_item_indentation: Option<IndentationLevel> = None;
|
let mut first_item_indentation: Option<IndentationLevel> = None;
|
||||||
let mut first_item_list_type: Option<PlainListType> = None;
|
let mut first_item_list_type: Option<PlainListType> = None;
|
||||||
let contents_begin = remaining;
|
|
||||||
let mut remaining = remaining;
|
let mut remaining = remaining;
|
||||||
|
|
||||||
// The final list item does not consume trailing blank lines (which instead get consumed by the list). We have three options here:
|
// The final list item does not consume trailing blank lines (which instead get consumed by the list). We have three options here:
|
||||||
@ -197,8 +195,7 @@ where
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let contents = get_consumed(contents_begin, remaining);
|
let (remaining, _trailing_ws) =
|
||||||
let (remaining, post_blank) =
|
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@ -211,8 +208,6 @@ where
|
|||||||
),
|
),
|
||||||
list_type: first_item_list_type.expect("Plain lists require at least one element."),
|
list_type: first_item_list_type.expect("Plain lists require at least one element."),
|
||||||
children: children.into_iter().map(|(_start, item)| item).collect(),
|
children: children.into_iter().map(|(_start, item)| item).collect(),
|
||||||
contents: Some(Into::<&str>::into(contents)),
|
|
||||||
post_blank: post_blank.map(Into::<&str>::into),
|
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -270,7 +265,7 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
|||||||
let maybe_contentless_item: Res<OrgSource<'_>, ()> =
|
let maybe_contentless_item: Res<OrgSource<'_>, ()> =
|
||||||
detect_contentless_item_contents(&parser_context, remaining);
|
detect_contentless_item_contents(&parser_context, remaining);
|
||||||
if let Ok((_rem, _ws)) = maybe_contentless_item {
|
if let Ok((_rem, _ws)) = maybe_contentless_item {
|
||||||
let (remaining, post_blank) = if tuple((
|
let (remaining, _trailing_ws) = if tuple((
|
||||||
blank_line,
|
blank_line,
|
||||||
bind_context!(final_item_whitespace_cutoff, context),
|
bind_context!(final_item_whitespace_cutoff, context),
|
||||||
))(remaining)
|
))(remaining)
|
||||||
@ -296,12 +291,6 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
|||||||
.unwrap_or(Vec::new()),
|
.unwrap_or(Vec::new()),
|
||||||
pre_blank: 0,
|
pre_blank: 0,
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
contents: None,
|
|
||||||
post_blank: if post_blank.len() > 0 {
|
|
||||||
Some(Into::<&str>::into(post_blank))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@ -312,13 +301,13 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
|||||||
.filter(|b| *b == b'\n')
|
.filter(|b| *b == b'\n')
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
let (remaining, (contents, (children, _exit_contents))) = consumed(many_till(
|
let (remaining, (children, _exit_contents)) = many_till(
|
||||||
include_input(bind_context!(element(true), &parser_context)),
|
include_input(bind_context!(element(true), &parser_context)),
|
||||||
bind_context!(exit_matcher_parser, &parser_context),
|
bind_context!(exit_matcher_parser, &parser_context),
|
||||||
))(remaining)?;
|
)(remaining)?;
|
||||||
|
|
||||||
// We have to use the parser_context here to include the whitespace cut-off
|
// We have to use the parser_context here to include the whitespace cut-off
|
||||||
let (remaining, post_blank) =
|
let (remaining, _trailing_ws) =
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(&final_whitespace_context, remaining)?;
|
maybe_consume_trailing_whitespace_if_not_exiting(&final_whitespace_context, remaining)?;
|
||||||
|
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
@ -340,12 +329,6 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
|||||||
pre_blank: PlainListItemPreBlank::try_from(pre_blank)
|
pre_blank: PlainListItemPreBlank::try_from(pre_blank)
|
||||||
.expect("pre-blank cannot be larger than 2."),
|
.expect("pre-blank cannot be larger than 2."),
|
||||||
children: children.into_iter().map(|(_start, item)| item).collect(),
|
children: children.into_iter().map(|(_start, item)| item).collect(),
|
||||||
contents: if contents.len() > 0 {
|
|
||||||
Some(contents.into())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
post_blank: post_blank.map(Into::<&str>::into),
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use super::remove_trailing::RemoveTrailing;
|
||||||
use super::Element;
|
use super::Element;
|
||||||
use super::NodeProperty;
|
use super::NodeProperty;
|
||||||
use super::Object;
|
use super::Object;
|
||||||
@ -17,7 +18,6 @@ pub struct Document<'s> {
|
|||||||
pub path: Option<PathBuf>,
|
pub path: Option<PathBuf>,
|
||||||
pub zeroth_section: Option<Section<'s>>,
|
pub zeroth_section: Option<Section<'s>>,
|
||||||
pub children: Vec<Heading<'s>>,
|
pub children: Vec<Heading<'s>>,
|
||||||
pub contents: Option<&'s str>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -63,7 +63,28 @@ impl<'s> StandardProperties<'s> for Document<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
self.contents
|
let post_blank = self.get_post_blank();
|
||||||
|
let mut content_lines = self
|
||||||
|
.source
|
||||||
|
.split_inclusive('\n')
|
||||||
|
.remove_trailing(post_blank);
|
||||||
|
let first_line = content_lines.next();
|
||||||
|
let last_line = content_lines.last().or(first_line);
|
||||||
|
match (first_line, last_line) {
|
||||||
|
(None, None) => None,
|
||||||
|
(None, Some(_)) | (Some(_), None) => unreachable!(),
|
||||||
|
(Some(first_line), Some(last_line)) => {
|
||||||
|
let first_line_offset = first_line.as_ptr() as usize;
|
||||||
|
let last_line_offset = last_line.as_ptr() as usize + last_line.len();
|
||||||
|
let source_offset = self.source.as_ptr() as usize;
|
||||||
|
debug_assert!(super::lesser_element::is_slice_of(self.source, first_line));
|
||||||
|
debug_assert!(super::lesser_element::is_slice_of(self.source, last_line));
|
||||||
|
Some(
|
||||||
|
&self.source[(first_line_offset - source_offset)
|
||||||
|
..(last_line_offset - first_line_offset)],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
|
@ -13,8 +13,6 @@ pub struct PlainList<'s> {
|
|||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub list_type: PlainListType,
|
pub list_type: PlainListType,
|
||||||
pub children: Vec<PlainListItem<'s>>,
|
pub children: Vec<PlainListItem<'s>>,
|
||||||
pub contents: Option<&'s str>, // TODO: Can contents ever be None?
|
|
||||||
pub post_blank: Option<&'s str>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
@ -37,8 +35,6 @@ pub struct PlainListItem<'s> {
|
|||||||
pub tag: Vec<Object<'s>>,
|
pub tag: Vec<Object<'s>>,
|
||||||
pub pre_blank: PlainListItemPreBlank,
|
pub pre_blank: PlainListItemPreBlank,
|
||||||
pub children: Vec<Element<'s>>,
|
pub children: Vec<Element<'s>>,
|
||||||
pub contents: Option<&'s str>,
|
|
||||||
pub post_blank: Option<&'s str>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PlainListItemCounter = u16;
|
pub type PlainListItemCounter = u16;
|
||||||
@ -144,15 +140,11 @@ impl<'s> StandardProperties<'s> for PlainList<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
self.contents
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
self.post_blank
|
todo!()
|
||||||
.map(|text| text.lines().count())
|
|
||||||
.unwrap_or(0)
|
|
||||||
.try_into()
|
|
||||||
.expect("Too much post-blank to fit into a PostBlank.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,15 +154,11 @@ impl<'s> StandardProperties<'s> for PlainListItem<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||||
self.contents
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_post_blank(&self) -> PostBlank {
|
fn get_post_blank(&self) -> PostBlank {
|
||||||
self.post_blank
|
todo!()
|
||||||
.map(|text| text.lines().count())
|
|
||||||
.unwrap_or(0)
|
|
||||||
.try_into()
|
|
||||||
.expect("Too much post-blank to fit into a PostBlank.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user