Compare commits
12 Commits
31406fd520
...
3fb7cb82cd
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3fb7cb82cd | ||
![]() |
e0ec5c115f | ||
![]() |
f0868ba3ed | ||
![]() |
425bc12353 | ||
![]() |
03754be71e | ||
![]() |
70002800c2 | ||
![]() |
281c35677b | ||
![]() |
92d15c3d91 | ||
![]() |
b1773ac90e | ||
![]() |
645d9abf9c | ||
![]() |
d2f2bdf88d | ||
![]() |
90ba17b68c |
@ -100,20 +100,26 @@ fn assert_bounds<'b, 's, S: StandardProperties<'s> + ?Sized>(
|
||||
|
||||
// Check contents-begin/contents-end
|
||||
{
|
||||
let (begin, end) = (
|
||||
standard_properties
|
||||
.contents_begin
|
||||
.ok_or("Token should have a begin.")?,
|
||||
standard_properties
|
||||
.contents_end
|
||||
.ok_or("Token should have an end.")?,
|
||||
);
|
||||
let (rust_begin, rust_end) = get_rust_byte_offsets(original_document, rust.get_contents()); // 0-based
|
||||
let rust_begin_char_offset = original_document[..rust_begin].chars().count() + 1; // 1-based
|
||||
let rust_end_char_offset =
|
||||
rust_begin_char_offset + original_document[rust_begin..rust_end].chars().count(); // 1-based
|
||||
if rust_begin_char_offset != begin || rust_end_char_offset != end {
|
||||
Err(format!("Rust contents bounds (in chars) ({rust_begin}, {rust_end}) do not match emacs contents bounds ({emacs_begin}, {emacs_end})", rust_begin = rust_begin_char_offset, rust_end = rust_end_char_offset, emacs_begin=begin, emacs_end=end))?;
|
||||
if let Some(rust_contents) = rust.get_contents() {
|
||||
let (begin, end) = (
|
||||
standard_properties
|
||||
.contents_begin
|
||||
.ok_or("Token should have a contents-begin.")?,
|
||||
standard_properties
|
||||
.contents_end
|
||||
.ok_or("Token should have an contents-end.")?,
|
||||
);
|
||||
let (rust_begin, rust_end) = get_rust_byte_offsets(original_document, rust_contents); // 0-based
|
||||
let rust_begin_char_offset = original_document[..rust_begin].chars().count() + 1; // 1-based
|
||||
let rust_end_char_offset =
|
||||
rust_begin_char_offset + original_document[rust_begin..rust_end].chars().count(); // 1-based
|
||||
if rust_begin_char_offset != begin || rust_end_char_offset != end {
|
||||
Err(format!("Rust contents bounds (in chars) ({rust_begin}, {rust_end}) do not match emacs contents bounds ({emacs_begin}, {emacs_end})", rust_begin = rust_begin_char_offset, rust_end = rust_end_char_offset, emacs_begin=begin, emacs_end=end))?;
|
||||
}
|
||||
} else if standard_properties.contents_begin.is_some()
|
||||
|| standard_properties.contents_end.is_some()
|
||||
{
|
||||
Err(format!("Rust contents is None but emacs contents bounds are ({emacs_begin:?}, {emacs_end:?})", emacs_begin=standard_properties.contents_begin, emacs_end=standard_properties.contents_end))?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,11 +134,11 @@ fn assert_post_blank<'b, 's, S: StandardProperties<'s> + ?Sized>(
|
||||
rust: &'b S,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let standard_properties = get_emacs_standard_properties(emacs)?; // 1-based
|
||||
let rust_post_blank = rust.get_post_blank().chars().count();
|
||||
let rust_post_blank = rust.get_post_blank();
|
||||
let emacs_post_blank = standard_properties
|
||||
.post_blank
|
||||
.ok_or("Token should have a post-blank.")?;
|
||||
if rust_post_blank != emacs_post_blank {
|
||||
if rust_post_blank as usize != emacs_post_blank {
|
||||
Err(format!("Rust post-blank (in chars) {rust_post_blank} does not match emacs post-blank ({emacs_post_blank})", rust_post_blank = rust_post_blank, emacs_post_blank = emacs_post_blank))?;
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,7 @@ where
|
||||
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||
let element_matcher = parser_with_context!(element(true))(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
let before_contents = remaining;
|
||||
let (mut remaining, (mut children, _exit_contents)) =
|
||||
many_till(include_input(element_matcher), exit_matcher)(remaining)?;
|
||||
|
||||
@ -90,13 +91,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
let contents = get_consumed(before_contents, remaining);
|
||||
let (remaining, post_blank) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
FootnoteDefinition {
|
||||
source: source.into(),
|
||||
contents: Some(contents.into()),
|
||||
post_blank: post_blank.map(Into::<&str>::into),
|
||||
affiliated_keywords: parse_affiliated_keywords(
|
||||
context.get_global_settings(),
|
||||
affiliated_keywords,
|
||||
|
@ -2,6 +2,7 @@ use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::complete::tag_no_case;
|
||||
use nom::combinator::all_consuming;
|
||||
use nom::combinator::consumed;
|
||||
use nom::combinator::map_parser;
|
||||
use nom::combinator::verify;
|
||||
use nom::multi::many1;
|
||||
@ -59,7 +60,7 @@ fn anonymous_footnote<'b, 'g, 'r, 's>(
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(context.get_global_settings(), List::new(&initial_context));
|
||||
|
||||
let (remaining, children) = map_parser(
|
||||
let (remaining, (contents, children)) = consumed(map_parser(
|
||||
verify(
|
||||
parser_with_context!(text_until_exit)(&parser_context),
|
||||
|text| text.len() > 0,
|
||||
@ -69,17 +70,19 @@ fn anonymous_footnote<'b, 'g, 'r, 's>(
|
||||
&initial_context,
|
||||
)))(i)
|
||||
}),
|
||||
)(remaining)?;
|
||||
))(remaining)?;
|
||||
|
||||
let (remaining, _) = tag("]")(remaining)?;
|
||||
|
||||
let (remaining, _trailing_whitespace) =
|
||||
let (remaining, post_blank) =
|
||||
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
FootnoteReference {
|
||||
source: source.into(),
|
||||
contents: Some(contents.into()),
|
||||
post_blank: post_blank.map(Into::<&str>::into),
|
||||
label: None,
|
||||
definition: children,
|
||||
},
|
||||
@ -106,7 +109,7 @@ fn inline_footnote<'b, 'g, 'r, 's>(
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(context.get_global_settings(), List::new(&initial_context));
|
||||
|
||||
let (remaining, children) = map_parser(
|
||||
let (remaining, (contents, children)) = consumed(map_parser(
|
||||
verify(
|
||||
parser_with_context!(text_until_exit)(&parser_context),
|
||||
|text| text.len() > 0,
|
||||
@ -116,17 +119,19 @@ fn inline_footnote<'b, 'g, 'r, 's>(
|
||||
&initial_context,
|
||||
)))(i)
|
||||
}),
|
||||
)(remaining)?;
|
||||
))(remaining)?;
|
||||
|
||||
let (remaining, _) = tag("]")(remaining)?;
|
||||
|
||||
let (remaining, _trailing_whitespace) =
|
||||
let (remaining, post_blank) =
|
||||
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
FootnoteReference {
|
||||
source: source.into(),
|
||||
contents: Some(contents.into()),
|
||||
post_blank: post_blank.map(Into::<&str>::into),
|
||||
label: Some(label_contents.into()),
|
||||
definition: children,
|
||||
},
|
||||
@ -144,13 +149,15 @@ fn footnote_reference_only<'b, 'g, 'r, 's>(
|
||||
let (remaining, _) = tag_no_case("[fn:")(input)?;
|
||||
let (remaining, label_contents) = label(remaining)?;
|
||||
let (remaining, _) = tag("]")(remaining)?;
|
||||
let (remaining, _trailing_whitespace) =
|
||||
let (remaining, post_blank) =
|
||||
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((
|
||||
remaining,
|
||||
FootnoteReference {
|
||||
source: source.into(),
|
||||
contents: None,
|
||||
post_blank: post_blank.map(Into::<&str>::into),
|
||||
label: Some(label_contents.into()),
|
||||
definition: Vec::with_capacity(0),
|
||||
},
|
||||
|
@ -1,4 +1,5 @@
|
||||
use nom::branch::alt;
|
||||
use nom::combinator::consumed;
|
||||
use nom::combinator::eof;
|
||||
use nom::combinator::recognize;
|
||||
use nom::combinator::verify;
|
||||
@ -45,14 +46,14 @@ where
|
||||
let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context);
|
||||
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
|
||||
|
||||
let (remaining, (children, _exit_contents)) = verify(
|
||||
let (remaining, (contents, (children, _exit_contents))) = consumed(verify(
|
||||
many_till(standard_set_object_matcher, exit_matcher),
|
||||
|(children, _exit_contents)| !children.is_empty(),
|
||||
)(remaining)?;
|
||||
))(remaining)?;
|
||||
|
||||
// Not checking parent exit matcher because if there are any children matched then we have a valid paragraph.
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
let (remaining, post_blank) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
|
||||
@ -60,6 +61,8 @@ where
|
||||
remaining,
|
||||
Paragraph {
|
||||
source: source.into(),
|
||||
contents: Some(contents.into()),
|
||||
post_blank: post_blank.map(Into::<&str>::into),
|
||||
affiliated_keywords: parse_affiliated_keywords(
|
||||
context.get_global_settings(),
|
||||
affiliated_keywords,
|
||||
|
@ -1,3 +1,4 @@
|
||||
use nom::combinator::consumed;
|
||||
use nom::combinator::opt;
|
||||
use nom::combinator::recognize;
|
||||
use nom::combinator::verify;
|
||||
@ -58,12 +59,12 @@ pub(crate) fn zeroth_section<'b, 'g, 'r, 's>(
|
||||
many0(blank_line),
|
||||
)))(input)?;
|
||||
|
||||
let (remaining, (mut children, _exit_contents)) = verify(
|
||||
let (remaining, (contents, (mut children, _exit_contents))) = consumed(verify(
|
||||
many_till(element_matcher, exit_matcher),
|
||||
|(children, _exit_contents)| {
|
||||
!children.is_empty() || comment_and_property_drawer_element.is_some()
|
||||
},
|
||||
)(remaining)?;
|
||||
))(remaining)?;
|
||||
|
||||
if let Some((comment, property_drawer, _ws)) = comment_and_property_drawer_element {
|
||||
children.insert(0, Element::PropertyDrawer(property_drawer));
|
||||
@ -72,7 +73,7 @@ pub(crate) fn zeroth_section<'b, 'g, 'r, 's>(
|
||||
}
|
||||
}
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
let (remaining, post_blank) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
|
||||
let source = get_consumed(input, remaining);
|
||||
@ -80,6 +81,8 @@ pub(crate) fn zeroth_section<'b, 'g, 'r, 's>(
|
||||
remaining,
|
||||
Section {
|
||||
source: source.into(),
|
||||
contents: Some(contents.into()),
|
||||
post_blank: post_blank.map(Into::<&str>::into),
|
||||
children,
|
||||
},
|
||||
))
|
||||
@ -115,12 +118,12 @@ pub(crate) fn section<'b, 'g, 'r, 's>(
|
||||
remaining = remain;
|
||||
input = remain;
|
||||
}
|
||||
let (remaining, (mut children, _exit_contents)) = verify(
|
||||
let (remaining, (contents, (mut children, _exit_contents))) = consumed(verify(
|
||||
many_till(element_matcher, exit_matcher),
|
||||
|(children, _exit_contents)| {
|
||||
!children.is_empty() || property_drawer_element.is_some() || planning_element.is_some()
|
||||
},
|
||||
)(remaining)?;
|
||||
))(remaining)?;
|
||||
if let Some(ele) = property_drawer_element.map(Element::PropertyDrawer) {
|
||||
children.insert(0, ele);
|
||||
}
|
||||
@ -128,7 +131,7 @@ pub(crate) fn section<'b, 'g, 'r, 's>(
|
||||
children.insert(0, ele)
|
||||
}
|
||||
|
||||
let (remaining, _trailing_ws) =
|
||||
let (remaining, post_blank) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
|
||||
let source = get_consumed(input, remaining);
|
||||
@ -136,6 +139,8 @@ pub(crate) fn section<'b, 'g, 'r, 's>(
|
||||
remaining,
|
||||
Section {
|
||||
source: source.into(),
|
||||
contents: Some(contents.into()),
|
||||
post_blank: post_blank.map(Into::<&str>::into),
|
||||
children,
|
||||
},
|
||||
))
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::macros::to_ast_node;
|
||||
use super::CenterBlock;
|
||||
use super::PostBlank;
|
||||
use super::QuoteBlock;
|
||||
use super::SpecialBlock;
|
||||
use super::StandardProperties;
|
||||
@ -323,7 +324,7 @@ impl<'r, 's> StandardProperties<'s> for AstNode<'r, 's> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
match self {
|
||||
AstNode::Document(inner) => inner.get_contents(),
|
||||
AstNode::Heading(inner) => inner.get_contents(),
|
||||
@ -386,7 +387,7 @@ impl<'r, 's> StandardProperties<'s> for AstNode<'r, 's> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
match self {
|
||||
AstNode::Document(inner) => inner.get_post_blank(),
|
||||
AstNode::Heading(inner) => inner.get_post_blank(),
|
||||
|
@ -1,8 +1,10 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::remove_trailing::RemoveTrailing;
|
||||
use super::Element;
|
||||
use super::NodeProperty;
|
||||
use super::Object;
|
||||
use super::PostBlank;
|
||||
use super::StandardProperties;
|
||||
use super::Timestamp;
|
||||
|
||||
@ -38,6 +40,8 @@ pub struct Heading<'s> {
|
||||
#[derive(Debug)]
|
||||
pub struct Section<'s> {
|
||||
pub source: &'s str,
|
||||
pub contents: Option<&'s str>,
|
||||
pub post_blank: Option<&'s str>,
|
||||
pub children: Vec<Element<'s>>,
|
||||
}
|
||||
|
||||
@ -58,12 +62,36 @@ impl<'s> StandardProperties<'s> for Document<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
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<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
self.into_iter()
|
||||
.last()
|
||||
.map(|child| child.get_post_blank())
|
||||
.unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,12 +100,16 @@ impl<'s> StandardProperties<'s> for Section<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
self.contents
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
self.post_blank
|
||||
.map(|text| text.lines().count())
|
||||
.unwrap_or(0)
|
||||
.try_into()
|
||||
.expect("Too much post-blank to fit into a PostBlank.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,12 +118,40 @@ impl<'s> StandardProperties<'s> for Heading<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
let first_child = self.children.first();
|
||||
let last_child = self.children.last();
|
||||
match (first_child, last_child) {
|
||||
(None, None) => None,
|
||||
(None, Some(_)) | (Some(_), None) => unreachable!(),
|
||||
(Some(first_child), Some(last_child)) => {
|
||||
let first_child_offset = first_child.get_source().as_ptr() as usize;
|
||||
let last_child_offset = {
|
||||
let last_child_source = last_child.get_source();
|
||||
last_child_source.as_ptr() as usize + last_child_source.len()
|
||||
};
|
||||
let source_offset = self.source.as_ptr() as usize;
|
||||
debug_assert!(super::lesser_element::is_slice_of(
|
||||
self.source,
|
||||
first_child.get_source()
|
||||
));
|
||||
debug_assert!(super::lesser_element::is_slice_of(
|
||||
self.source,
|
||||
last_child.get_source()
|
||||
));
|
||||
Some(
|
||||
&self.source[(first_child_offset - source_offset)
|
||||
..(last_child_offset - first_child_offset)],
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
self.children
|
||||
.last()
|
||||
.map(|child| child.get_post_blank())
|
||||
.unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,14 +211,14 @@ impl<'s> StandardProperties<'s> for DocumentElement<'s> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
match self {
|
||||
DocumentElement::Heading(inner) => inner.get_contents(),
|
||||
DocumentElement::Section(inner) => inner.get_contents(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
match self {
|
||||
DocumentElement::Heading(inner) => inner.get_post_blank(),
|
||||
DocumentElement::Section(inner) => inner.get_post_blank(),
|
||||
|
@ -20,6 +20,7 @@ use super::lesser_element::SrcBlock;
|
||||
use super::lesser_element::VerseBlock;
|
||||
use super::CenterBlock;
|
||||
use super::Drawer;
|
||||
use super::PostBlank;
|
||||
use super::QuoteBlock;
|
||||
use super::SpecialBlock;
|
||||
use super::StandardProperties;
|
||||
@ -83,7 +84,7 @@ impl<'s> StandardProperties<'s> for Element<'s> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
match self {
|
||||
Element::Paragraph(inner) => inner.get_contents(),
|
||||
Element::PlainList(inner) => inner.get_contents(),
|
||||
@ -112,7 +113,7 @@ impl<'s> StandardProperties<'s> for Element<'s> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
match self {
|
||||
Element::Paragraph(inner) => inner.get_post_blank(),
|
||||
Element::PlainList(inner) => inner.get_post_blank(),
|
||||
|
@ -4,6 +4,7 @@ use super::lesser_element::TableCell;
|
||||
use super::AffiliatedKeywords;
|
||||
use super::Keyword;
|
||||
use super::Object;
|
||||
use super::PostBlank;
|
||||
use super::StandardProperties;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -81,6 +82,8 @@ pub struct DynamicBlock<'s> {
|
||||
#[derive(Debug)]
|
||||
pub struct FootnoteDefinition<'s> {
|
||||
pub source: &'s str,
|
||||
pub contents: Option<&'s str>,
|
||||
pub post_blank: Option<&'s str>,
|
||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||
pub label: &'s str,
|
||||
pub children: Vec<Element<'s>>,
|
||||
@ -132,11 +135,11 @@ impl<'s> StandardProperties<'s> for PlainList<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -146,11 +149,11 @@ impl<'s> StandardProperties<'s> for PlainListItem<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -160,11 +163,11 @@ impl<'s> StandardProperties<'s> for CenterBlock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -174,11 +177,11 @@ impl<'s> StandardProperties<'s> for QuoteBlock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -188,11 +191,11 @@ impl<'s> StandardProperties<'s> for SpecialBlock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -202,11 +205,11 @@ impl<'s> StandardProperties<'s> for DynamicBlock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -216,12 +219,16 @@ impl<'s> StandardProperties<'s> for FootnoteDefinition<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
self.contents
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
self.post_blank
|
||||
.map(|text| text.lines().count())
|
||||
.unwrap_or(0)
|
||||
.try_into()
|
||||
.expect("Too much post-blank to fit into a PostBlank.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,11 +237,11 @@ impl<'s> StandardProperties<'s> for Drawer<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -244,11 +251,11 @@ impl<'s> StandardProperties<'s> for PropertyDrawer<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -258,11 +265,11 @@ impl<'s> StandardProperties<'s> for NodeProperty<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -272,11 +279,11 @@ impl<'s> StandardProperties<'s> for Table<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -286,11 +293,11 @@ impl<'s> StandardProperties<'s> for TableRow<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use super::object::Object;
|
||||
use super::AffiliatedKeywords;
|
||||
use super::GetAffiliatedKeywords;
|
||||
use super::PlainText;
|
||||
use super::PostBlank;
|
||||
use super::StandardProperties;
|
||||
use super::Timestamp;
|
||||
use crate::error::CustomError;
|
||||
@ -24,6 +25,8 @@ use crate::error::Res;
|
||||
#[derive(Debug)]
|
||||
pub struct Paragraph<'s> {
|
||||
pub source: &'s str,
|
||||
pub contents: Option<&'s str>,
|
||||
pub post_blank: Option<&'s str>,
|
||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||
pub children: Vec<Object<'s>>,
|
||||
}
|
||||
@ -188,6 +191,8 @@ impl<'s> Paragraph<'s> {
|
||||
pub(crate) fn of_text(source: &'s str, body: &'s str) -> Self {
|
||||
Paragraph {
|
||||
source,
|
||||
contents: None, // TODO
|
||||
post_blank: None, // TODO
|
||||
affiliated_keywords: AffiliatedKeywords::default(),
|
||||
children: vec![Object::PlainText(PlainText { source: body })],
|
||||
}
|
||||
@ -199,12 +204,16 @@ impl<'s> StandardProperties<'s> for Paragraph<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
self.contents
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
self.post_blank
|
||||
.map(|text| text.lines().count())
|
||||
.unwrap_or(0)
|
||||
.try_into()
|
||||
.expect("Too much post-blank to fit into a PostBlank.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,11 +222,11 @@ impl<'s> StandardProperties<'s> for TableCell<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -227,11 +236,11 @@ impl<'s> StandardProperties<'s> for Comment<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -241,11 +250,11 @@ impl<'s> StandardProperties<'s> for VerseBlock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -254,11 +263,11 @@ impl<'s> StandardProperties<'s> for CommentBlock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -267,11 +276,11 @@ impl<'s> StandardProperties<'s> for ExampleBlock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -280,11 +289,11 @@ impl<'s> StandardProperties<'s> for ExportBlock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -293,11 +302,11 @@ impl<'s> StandardProperties<'s> for SrcBlock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -307,11 +316,11 @@ impl<'s> StandardProperties<'s> for Clock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -321,11 +330,11 @@ impl<'s> StandardProperties<'s> for DiarySexp<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -335,11 +344,11 @@ impl<'s> StandardProperties<'s> for Planning<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -349,11 +358,11 @@ impl<'s> StandardProperties<'s> for FixedWidthArea<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -363,11 +372,11 @@ impl<'s> StandardProperties<'s> for HorizontalRule<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -377,11 +386,11 @@ impl<'s> StandardProperties<'s> for Keyword<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -391,11 +400,11 @@ impl<'s> StandardProperties<'s> for BabelCall<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -405,11 +414,11 @@ impl<'s> StandardProperties<'s> for LatexEnvironment<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -601,7 +610,7 @@ fn content_line<'s>(input: &'s str) -> Res<&'s str, (Option<&'s str>, &'s str)>
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
/// Check if the child string slice is a slice of the parent string slice.
|
||||
fn is_slice_of(parent: &str, child: &str) -> bool {
|
||||
pub(crate) fn is_slice_of(parent: &str, child: &str) -> bool {
|
||||
let parent_start = parent.as_ptr() as usize;
|
||||
let parent_end = parent_start + parent.len();
|
||||
let child_start = child.as_ptr() as usize;
|
||||
|
@ -6,6 +6,7 @@ mod greater_element;
|
||||
mod lesser_element;
|
||||
mod macros;
|
||||
mod object;
|
||||
mod remove_trailing;
|
||||
mod standard_properties;
|
||||
mod util;
|
||||
pub use affiliated_keyword::AffiliatedKeyword;
|
||||
@ -110,4 +111,5 @@ pub use object::WarningDelay;
|
||||
pub use object::WarningDelayType;
|
||||
pub use object::Year;
|
||||
pub use object::YearInner;
|
||||
pub use standard_properties::PostBlank;
|
||||
pub use standard_properties::StandardProperties;
|
||||
|
@ -6,6 +6,7 @@ use super::util::coalesce_whitespace_if_line_break;
|
||||
use super::util::remove_line_break;
|
||||
use super::util::remove_whitespace_if_line_break;
|
||||
use super::util::to_lowercase;
|
||||
use super::PostBlank;
|
||||
use super::StandardProperties;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -191,6 +192,8 @@ pub struct ExportSnippet<'s> {
|
||||
#[derive(Debug)]
|
||||
pub struct FootnoteReference<'s> {
|
||||
pub source: &'s str,
|
||||
pub contents: Option<&'s str>,
|
||||
pub post_blank: Option<&'s str>,
|
||||
pub label: Option<&'s str>,
|
||||
pub definition: Vec<Object<'s>>,
|
||||
}
|
||||
@ -519,11 +522,11 @@ impl<'s> StandardProperties<'s> for Bold<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -533,11 +536,11 @@ impl<'s> StandardProperties<'s> for Italic<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -547,11 +550,11 @@ impl<'s> StandardProperties<'s> for Underline<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -561,11 +564,11 @@ impl<'s> StandardProperties<'s> for StrikeThrough<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -575,11 +578,11 @@ impl<'s> StandardProperties<'s> for Code<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -589,11 +592,11 @@ impl<'s> StandardProperties<'s> for Verbatim<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -603,11 +606,11 @@ impl<'s> StandardProperties<'s> for RegularLink<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -617,11 +620,11 @@ impl<'s> StandardProperties<'s> for RadioLink<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -631,11 +634,11 @@ impl<'s> StandardProperties<'s> for RadioTarget<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -645,11 +648,11 @@ impl<'s> StandardProperties<'s> for PlainLink<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -659,11 +662,11 @@ impl<'s> StandardProperties<'s> for AngleLink<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -673,11 +676,11 @@ impl<'s> StandardProperties<'s> for OrgMacro<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -687,11 +690,11 @@ impl<'s> StandardProperties<'s> for Entity<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -701,11 +704,11 @@ impl<'s> StandardProperties<'s> for LatexFragment<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -715,11 +718,11 @@ impl<'s> StandardProperties<'s> for ExportSnippet<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -729,12 +732,16 @@ impl<'s> StandardProperties<'s> for FootnoteReference<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
self.contents
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
todo!()
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
self.post_blank
|
||||
.map(|text| text.chars().count())
|
||||
.unwrap_or(0)
|
||||
.try_into()
|
||||
.expect("Too much post-blank to fit into a PostBlank.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -743,11 +750,11 @@ impl<'s> StandardProperties<'s> for Citation<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -757,11 +764,11 @@ impl<'s> StandardProperties<'s> for CitationReference<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -771,11 +778,11 @@ impl<'s> StandardProperties<'s> for InlineBabelCall<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -785,11 +792,11 @@ impl<'s> StandardProperties<'s> for InlineSourceBlock<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -799,11 +806,11 @@ impl<'s> StandardProperties<'s> for LineBreak<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -813,11 +820,11 @@ impl<'s> StandardProperties<'s> for Target<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -827,11 +834,11 @@ impl<'s> StandardProperties<'s> for StatisticsCookie<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -841,11 +848,11 @@ impl<'s> StandardProperties<'s> for Subscript<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -855,11 +862,11 @@ impl<'s> StandardProperties<'s> for Superscript<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -869,11 +876,11 @@ impl<'s> StandardProperties<'s> for Timestamp<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -883,11 +890,11 @@ impl<'s> StandardProperties<'s> for PlainText<'s> {
|
||||
self.source
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -1016,7 +1023,7 @@ impl<'s> StandardProperties<'s> for Object<'s> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_contents<'b>(&'b self) -> &'s str {
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str> {
|
||||
match self {
|
||||
Object::Bold(inner) => inner.get_contents(),
|
||||
Object::Italic(inner) => inner.get_contents(),
|
||||
@ -1048,7 +1055,7 @@ impl<'s> StandardProperties<'s> for Object<'s> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str {
|
||||
fn get_post_blank(&self) -> PostBlank {
|
||||
match self {
|
||||
Object::Bold(inner) => inner.get_post_blank(),
|
||||
Object::Italic(inner) => inner.get_post_blank(),
|
||||
|
56
src/types/remove_trailing.rs
Normal file
56
src/types/remove_trailing.rs
Normal file
@ -0,0 +1,56 @@
|
||||
pub(crate) trait RemoveTrailing: Iterator + Sized {
|
||||
fn remove_trailing<R: Into<usize>>(self, amount_to_remove: R) -> RemoveTrailingIter<Self>;
|
||||
}
|
||||
|
||||
impl<I> RemoveTrailing for I
|
||||
where
|
||||
I: Iterator,
|
||||
{
|
||||
fn remove_trailing<R: Into<usize>>(self, amount_to_remove: R) -> RemoveTrailingIter<Self> {
|
||||
RemoveTrailingIter {
|
||||
inner: self,
|
||||
buffer: Vec::new(),
|
||||
next_to_pop: 0,
|
||||
amount_to_remove: amount_to_remove.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct RemoveTrailingIter<I: Iterator> {
|
||||
inner: I,
|
||||
buffer: Vec<I::Item>,
|
||||
next_to_pop: usize,
|
||||
amount_to_remove: usize,
|
||||
}
|
||||
|
||||
impl<I: Iterator> Iterator for RemoveTrailingIter<I> {
|
||||
type Item = I::Item;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.buffer.len() < self.amount_to_remove {
|
||||
self.buffer.reserve_exact(self.amount_to_remove);
|
||||
}
|
||||
while self.buffer.len() < self.amount_to_remove {
|
||||
if let Some(elem) = self.inner.next() {
|
||||
self.buffer.push(elem);
|
||||
} else {
|
||||
// The inner was smaller than amount_to_remove, so never return anything.
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
let new_value = self.inner.next();
|
||||
if self.amount_to_remove == 0 {
|
||||
return new_value;
|
||||
}
|
||||
|
||||
if let Some(new_value) = new_value {
|
||||
let ret = std::mem::replace(&mut self.buffer[self.next_to_pop], new_value);
|
||||
self.next_to_pop = (self.next_to_pop + 1) % self.amount_to_remove;
|
||||
Some(ret)
|
||||
} else {
|
||||
// We have exactly the amount in the buffer than we wanted to cut off, so stop returning values.
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
@ -8,12 +8,12 @@ pub trait StandardProperties<'s> {
|
||||
/// Get the slice of the AST node's contents.
|
||||
///
|
||||
/// This corresponds to :contents-begin to :contents-end
|
||||
fn get_contents<'b>(&'b self) -> &'s str;
|
||||
fn get_contents<'b>(&'b self) -> Option<&'s str>;
|
||||
|
||||
/// Get the slice of the AST node's post-blank text.
|
||||
/// Get the ast node's post-blank.
|
||||
///
|
||||
/// This is optional whitespace following the node.
|
||||
fn get_post_blank<'b>(&'b self) -> &'s str;
|
||||
/// For objects this is a count of the characters of whitespace after the object. For elements this is a count of the line breaks following an element.
|
||||
fn get_post_blank(&self) -> PostBlank;
|
||||
}
|
||||
|
||||
// TODO: Write some debugging code to alert when any of the unknown fields below are non-nil in our test data so we can see what these fields represent.
|
||||
@ -61,3 +61,5 @@ pub trait StandardProperties<'s> {
|
||||
// X :parent - Some weird numeric reference to the containing object. Since we output a tree structure, I do not see any value in including this, especially considering the back-references would be a nightmare in rust.
|
||||
|
||||
// Special case: Plain text. Plain text counts :begin and :end from the start of the text (so :begin is always 0 AFAICT) and instead of including the full set of standard properties, it only includes :begin, :end, and :parent.
|
||||
|
||||
pub type PostBlank = u8;
|
||||
|
Loading…
x
Reference in New Issue
Block a user