Merge branch 'bullshitium'
This commit is contained in:
commit
f19d262825
8
build.rs
8
build.rs
@ -66,10 +66,6 @@ fn write_test(test_file: &mut File, test: &walkdir::DirEntry) {
|
||||
}
|
||||
|
||||
#[cfg(feature = "compare")]
|
||||
fn is_expect_fail(name: &str) -> Option<&str> {
|
||||
match name {
|
||||
"greater_element_drawer_drawer_with_headline_inside" => Some("Apparently lines with :end: become their own paragraph. This odd behavior needs to be investigated more."),
|
||||
"element_container_priority_footnote_definition_dynamic_block" => Some("Apparently broken begin lines become their own paragraph."),
|
||||
_ => None,
|
||||
}
|
||||
fn is_expect_fail(_name: &str) -> Option<&str> {
|
||||
None
|
||||
}
|
||||
|
@ -0,0 +1,3 @@
|
||||
foo
|
||||
:end:
|
||||
bar
|
@ -0,0 +1,2 @@
|
||||
foo
|
||||
:end:
|
165
src/parser/bullshitium.rs
Normal file
165
src/parser/bullshitium.rs
Normal file
@ -0,0 +1,165 @@
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag_no_case;
|
||||
use nom::character::complete::anychar;
|
||||
use nom::character::complete::space0;
|
||||
use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::paragraph::paragraph;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::util::org_line_ending;
|
||||
use super::util::start_of_line;
|
||||
use super::OrgSource;
|
||||
use crate::context::bind_context;
|
||||
use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::macros::element;
|
||||
use crate::types::AffiliatedKeywords;
|
||||
use crate::types::Object;
|
||||
use crate::types::Paragraph;
|
||||
use crate::types::PlainText;
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
pub(crate) fn bullshitium<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Paragraph<'s>> {
|
||||
alt((
|
||||
bind_context!(broken_end, context),
|
||||
bind_context!(broken_dynamic_block, context),
|
||||
))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
pub(crate) fn detect_bullshitium<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
element!(detect_broken_end, context, input);
|
||||
element!(detect_broken_dynamic_block, context, input);
|
||||
Err(nom::Err::Error(CustomError::Static("No bullshitium.")))
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
pub(crate) fn broken_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Paragraph<'s>> {
|
||||
start_of_line(input)?;
|
||||
let (remaining, _) = space0(input)?;
|
||||
let (remaining, _) = tag_no_case(":end:")(remaining)?;
|
||||
let (lead_in_remaining, _) = tuple((space0, org_line_ending))(remaining)?;
|
||||
if let Ok((remaining, mut paragraph)) =
|
||||
paragraph(std::iter::empty(), lead_in_remaining, context, input)
|
||||
{
|
||||
match paragraph.children.first_mut() {
|
||||
Some(Object::PlainText(plain_text)) => {
|
||||
plain_text.source = input.get_until_end_of_str(plain_text.source).into();
|
||||
}
|
||||
Some(obj) => {
|
||||
panic!("Unhandled first object type inside bullshitium {:?}", obj);
|
||||
}
|
||||
None => {
|
||||
unreachable!("Paragraph must have children.");
|
||||
}
|
||||
};
|
||||
Ok((remaining, paragraph))
|
||||
} else {
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, lead_in_remaining)?;
|
||||
|
||||
Ok((
|
||||
remaining,
|
||||
Paragraph {
|
||||
source: input.get_until(remaining).into(),
|
||||
affiliated_keywords: AffiliatedKeywords::default(),
|
||||
children: vec![Object::PlainText(PlainText {
|
||||
source: input.get_until(lead_in_remaining).into(),
|
||||
})],
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(_context))
|
||||
)]
|
||||
pub(crate) fn detect_broken_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
start_of_line(input)?;
|
||||
let (remaining, _) = space0(input)?;
|
||||
let (remaining, _) = tag_no_case(":end:")(remaining)?;
|
||||
let (_remaining, _) = tuple((space0, org_line_ending))(remaining)?;
|
||||
Ok((input, ()))
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
pub(crate) fn broken_dynamic_block<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Paragraph<'s>> {
|
||||
start_of_line(input)?;
|
||||
let (remaining, _) = space0(input)?;
|
||||
let (remaining, _) = tag_no_case("#+BEGIN:")(remaining)?;
|
||||
let (lead_in_remaining, _) = many_till(anychar, org_line_ending)(remaining)?;
|
||||
if let Ok((remaining, mut paragraph)) =
|
||||
paragraph(std::iter::empty(), lead_in_remaining, context, input)
|
||||
{
|
||||
match paragraph.children.first_mut() {
|
||||
Some(Object::PlainText(plain_text)) => {
|
||||
plain_text.source = input.get_until_end_of_str(plain_text.source).into();
|
||||
}
|
||||
Some(obj) => {
|
||||
panic!("Unhandled first object type inside bullshitium {:?}", obj);
|
||||
}
|
||||
None => {
|
||||
unreachable!("Paragraph must have children.");
|
||||
}
|
||||
};
|
||||
Ok((remaining, paragraph))
|
||||
} else {
|
||||
let (remaining, _trailing_ws) =
|
||||
maybe_consume_trailing_whitespace_if_not_exiting(context, lead_in_remaining)?;
|
||||
|
||||
Ok((
|
||||
remaining,
|
||||
Paragraph {
|
||||
source: input.get_until(remaining).into(),
|
||||
affiliated_keywords: AffiliatedKeywords::default(),
|
||||
children: vec![Object::PlainText(PlainText {
|
||||
source: input.get_until(lead_in_remaining).into(),
|
||||
})],
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(_context))
|
||||
)]
|
||||
pub(crate) fn detect_broken_dynamic_block<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
start_of_line(input)?;
|
||||
let (remaining, _) = space0(input)?;
|
||||
let (_remaining, _) = tag_no_case("#+BEGIN:")(remaining)?;
|
||||
Ok((input, ()))
|
||||
}
|
@ -32,6 +32,8 @@ use crate::event_count::record_event;
|
||||
#[cfg(feature = "event_count")]
|
||||
use crate::event_count::EventType;
|
||||
use crate::parser::affiliated_keyword::affiliated_keywords;
|
||||
use crate::parser::bullshitium::bullshitium;
|
||||
use crate::parser::bullshitium::detect_bullshitium;
|
||||
use crate::parser::macros::ak_element;
|
||||
use crate::parser::macros::element;
|
||||
use crate::parser::table::org_mode_table;
|
||||
@ -242,6 +244,9 @@ fn _element<'b, 'g, 'r, 's>(
|
||||
);
|
||||
|
||||
if can_be_paragraph {
|
||||
// Fake paragraphs
|
||||
element!(bullshitium, context, input, Element::Paragraph);
|
||||
|
||||
// Paragraph without affiliated keyword
|
||||
ak_element!(
|
||||
paragraph,
|
||||
@ -319,6 +324,11 @@ fn _detect_element<'b, 'g, 'r, 's>(
|
||||
input
|
||||
);
|
||||
|
||||
// Fake paragraphs
|
||||
if !can_be_paragraph {
|
||||
element!(detect_bullshitium, context, input);
|
||||
}
|
||||
|
||||
if _element(context, input, can_be_paragraph).is_ok() {
|
||||
return Ok((input, ()));
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
mod affiliated_keyword;
|
||||
mod angle_link;
|
||||
mod babel_call;
|
||||
mod bullshitium;
|
||||
mod citation;
|
||||
mod citation_reference;
|
||||
mod clock;
|
||||
|
@ -82,6 +82,15 @@ impl<'s> OrgSource<'s> {
|
||||
self.slice(..(other.end - self.start))
|
||||
}
|
||||
|
||||
pub(crate) fn get_until_end_of_str(&self, other: &'s str) -> OrgSource<'s> {
|
||||
let full_source_start = self.full_source.as_ptr() as usize;
|
||||
let other_start = other.as_ptr() as usize - full_source_start;
|
||||
let other_end = other_start + other.len();
|
||||
debug_assert!(other_start >= self.start);
|
||||
debug_assert!(other_end <= self.end);
|
||||
self.slice(..(other_end - self.start))
|
||||
}
|
||||
|
||||
pub(crate) fn get_start_of_line(&self) -> OrgSource<'s> {
|
||||
let skipped_text = self.text_since_line_break();
|
||||
let mut bracket_depth = self.bracket_depth;
|
||||
|
Loading…
x
Reference in New Issue
Block a user