Simulate trailing whitespace in empty greater blocks just like drawers.

This commit is contained in:
Tom Alexander 2023-04-22 21:45:18 -04:00
parent 4d4d30c597
commit 0ca6ce504f
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
18 changed files with 107 additions and 106 deletions

View File

@ -2,6 +2,7 @@ use std::env;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use std::path::Path; use std::path::Path;
use walkdir::WalkDir; use walkdir::WalkDir;
fn main() { fn main() {

View File

@ -1,7 +1,8 @@
#![feature(round_char_boundary)] #![feature(round_char_boundary)]
use ::organic::parser::document;
use crate::init_tracing::init_telemetry; use crate::init_tracing::init_telemetry;
use crate::init_tracing::shutdown_telemetry; use crate::init_tracing::shutdown_telemetry;
use ::organic::parser::document;
mod init_tracing; mod init_tracing;
const TEST_DOC: &'static str = include_str!("../toy_language.txt"); const TEST_DOC: &'static str = include_str!("../toy_language.txt");

View File

@ -15,7 +15,6 @@ use super::Context;
use crate::error::Res; use crate::error::Res;
use crate::parser::parser_with_context::parser_with_context; use crate::parser::parser_with_context::parser_with_context;
use crate::parser::util::get_consumed; use crate::parser::util::get_consumed;
use crate::parser::util::start_of_line; use crate::parser::util::start_of_line;
use crate::parser::Clock; use crate::parser::Clock;

View File

@ -1,6 +1,3 @@
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res;
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::is_not; use nom::bytes::complete::is_not;
use nom::bytes::complete::tag; use nom::bytes::complete::tag;
@ -16,11 +13,13 @@ use nom::sequence::tuple;
use super::util::get_consumed; use super::util::get_consumed;
use super::Context; use super::Context;
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res;
use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ContextElement;
use crate::parser::parser_with_context::parser_with_context; use crate::parser::parser_with_context::parser_with_context;
use crate::parser::util::exit_matcher_parser; use crate::parser::util::exit_matcher_parser;
use crate::parser::util::immediate_in_section; use crate::parser::util::immediate_in_section;
use crate::parser::util::start_of_line; use crate::parser::util::start_of_line;
use crate::parser::Comment; use crate::parser::Comment;
@ -57,12 +56,11 @@ fn comment_line<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ContextElement;
use crate::parser::parser_context::ContextTree; use crate::parser::parser_context::ContextTree;
use crate::parser::parser_with_context::parser_with_context; use crate::parser::parser_with_context::parser_with_context;
use super::*;
#[test] #[test]
fn require_space_after_hash() { fn require_space_after_hash() {
let input = "# Comment line let input = "# Comment line

View File

@ -10,7 +10,6 @@ use super::sexp::sexp;
use super::Context; use super::Context;
use crate::error::Res; use crate::error::Res;
use crate::parser::util::get_consumed; use crate::parser::util::get_consumed;
use crate::parser::util::start_of_line; use crate::parser::util::start_of_line;
use crate::parser::DiarySexp; use crate::parser::DiarySexp;

View File

@ -1,15 +1,3 @@
use crate::error::Res;
use crate::parser::comment::comment;
use crate::parser::element_parser::element;
use crate::parser::exiting::ExitClass;
use crate::parser::object_parser::standard_set_object;
use crate::parser::parser_context::ContextElement;
use crate::parser::parser_context::ContextTree;
use crate::parser::parser_context::ExitMatcherNode;
use crate::parser::planning::planning;
use crate::parser::property_drawer::property_drawer;
use crate::parser::util::blank_line;
use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting;
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::tag; use nom::bytes::complete::tag;
use nom::character::complete::line_ending; use nom::character::complete::line_ending;
@ -34,6 +22,18 @@ use super::util::exit_matcher_parser;
use super::util::get_consumed; use super::util::get_consumed;
use super::util::start_of_line; use super::util::start_of_line;
use super::Context; use super::Context;
use crate::error::Res;
use crate::parser::comment::comment;
use crate::parser::element_parser::element;
use crate::parser::exiting::ExitClass;
use crate::parser::object_parser::standard_set_object;
use crate::parser::parser_context::ContextElement;
use crate::parser::parser_context::ContextTree;
use crate::parser::parser_context::ExitMatcherNode;
use crate::parser::planning::planning;
use crate::parser::property_drawer::property_drawer;
use crate::parser::util::blank_line;
use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting;
#[derive(Debug)] #[derive(Debug)]
pub struct Document<'s> { pub struct Document<'s> {

View File

@ -1,3 +1,7 @@
use nom::branch::alt;
use nom::combinator::map;
use nom::multi::many0;
use super::clock::clock; use super::clock::clock;
use super::comment::comment; use super::comment::comment;
use super::diary_sexp::diary_sexp; use super::diary_sexp::diary_sexp;
@ -20,15 +24,10 @@ use super::plain_list::plain_list;
use super::source::SetSource; use super::source::SetSource;
use super::util::get_consumed; use super::util::get_consumed;
use super::util::maybe_consume_trailing_whitespace_if_not_exiting; use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
use super::Context; use super::Context;
use crate::error::Res; use crate::error::Res;
use crate::parser::parser_with_context::parser_with_context; use crate::parser::parser_with_context::parser_with_context;
use crate::parser::table::org_mode_table; use crate::parser::table::org_mode_table;
use nom::branch::alt;
use nom::combinator::map;
use nom::multi::many0;
pub fn element( pub fn element(
can_be_paragraph: bool, can_be_paragraph: bool,

View File

@ -16,7 +16,6 @@ use crate::error::Res;
use crate::parser::parser_with_context::parser_with_context; use crate::parser::parser_with_context::parser_with_context;
use crate::parser::util::exit_matcher_parser; use crate::parser::util::exit_matcher_parser;
use crate::parser::util::get_consumed; use crate::parser::util::get_consumed;
use crate::parser::util::start_of_line; use crate::parser::util::start_of_line;
use crate::parser::FixedWidthArea; use crate::parser::FixedWidthArea;

View File

@ -1,3 +1,15 @@
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::bytes::complete::tag_no_case;
use nom::bytes::complete::take_while;
use nom::character::complete::digit1;
use nom::character::complete::space0;
use nom::combinator::recognize;
use nom::combinator::verify;
use nom::multi::many1;
use nom::multi::many_till;
use nom::sequence::tuple;
use super::util::WORD_CONSTITUENT_CHARACTERS; use super::util::WORD_CONSTITUENT_CHARACTERS;
use super::Context; use super::Context;
use crate::error::CustomError; use crate::error::CustomError;
@ -14,19 +26,7 @@ use crate::parser::util::exit_matcher_parser;
use crate::parser::util::get_consumed; use crate::parser::util::get_consumed;
use crate::parser::util::immediate_in_section; use crate::parser::util::immediate_in_section;
use crate::parser::util::maybe_consume_trailing_whitespace; use crate::parser::util::maybe_consume_trailing_whitespace;
use crate::parser::util::start_of_line; use crate::parser::util::start_of_line;
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::bytes::complete::tag_no_case;
use nom::bytes::complete::take_while;
use nom::character::complete::digit1;
use nom::character::complete::space0;
use nom::combinator::recognize;
use nom::combinator::verify;
use nom::multi::many1;
use nom::multi::many_till;
use nom::sequence::tuple;
#[tracing::instrument(ret, level = "debug")] #[tracing::instrument(ret, level = "debug")]
pub fn footnote_definition<'r, 's>( pub fn footnote_definition<'r, 's>(
@ -107,13 +107,12 @@ fn footnote_definition_end<'r, 's>(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ContextElement;
use crate::parser::parser_context::ContextTree; use crate::parser::parser_context::ContextTree;
use crate::parser::parser_with_context::parser_with_context; use crate::parser::parser_with_context::parser_with_context;
use crate::parser::Source; use crate::parser::Source;
use super::*;
#[test] #[test]
fn two_paragraphs() { fn two_paragraphs() {
let input = "[fn:1] A footnote. let input = "[fn:1] A footnote.

View File

@ -1,3 +1,17 @@
use nom::branch::alt;
use nom::bytes::complete::is_not;
use nom::bytes::complete::tag_no_case;
use nom::character::complete::line_ending;
use nom::character::complete::space0;
use nom::character::complete::space1;
use nom::combinator::consumed;
use nom::combinator::eof;
use nom::combinator::not;
use nom::combinator::opt;
use nom::combinator::verify;
use nom::multi::many_till;
use nom::sequence::tuple;
use super::Context; use super::Context;
use crate::error::CustomError; use crate::error::CustomError;
use crate::error::MyError; use crate::error::MyError;
@ -8,26 +22,14 @@ use crate::parser::greater_element::GreaterBlock;
use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ContextElement;
use crate::parser::parser_context::ExitMatcherNode; use crate::parser::parser_context::ExitMatcherNode;
use crate::parser::parser_with_context::parser_with_context; use crate::parser::parser_with_context::parser_with_context;
use crate::parser::source::SetSource;
use crate::parser::util::blank_line; use crate::parser::util::blank_line;
use crate::parser::util::exit_matcher_parser; use crate::parser::util::exit_matcher_parser;
use crate::parser::util::get_consumed; use crate::parser::util::get_consumed;
use crate::parser::util::immediate_in_section; use crate::parser::util::immediate_in_section;
use crate::parser::util::start_of_line; use crate::parser::util::start_of_line;
use crate::parser::Element; use crate::parser::Element;
use crate::parser::Paragraph; use crate::parser::Paragraph;
use nom::branch::alt;
use nom::bytes::complete::is_not;
use nom::bytes::complete::tag_no_case;
use nom::character::complete::line_ending;
use nom::character::complete::space0;
use nom::character::complete::space1;
use nom::combinator::consumed;
use nom::combinator::eof;
use nom::combinator::opt;
use nom::combinator::verify;
use nom::multi::many_till;
use nom::sequence::tuple;
#[tracing::instrument(ret, level = "debug")] #[tracing::instrument(ret, level = "debug")]
pub fn greater_block<'r, 's>( pub fn greater_block<'r, 's>(
@ -72,11 +74,18 @@ pub fn greater_block<'r, 's>(
let element_matcher = parser_with_context!(element(true))(&parser_context); let element_matcher = parser_with_context!(element(true))(&parser_context);
let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context);
// Check for a completely empty block // Check for a completely empty block
let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) { let (remaining, children) = match tuple((
Ok((remaining, (whitespace, (_children, _exit_contents)))) => ( not(exit_matcher),
remaining, blank_line,
vec![Element::Paragraph(Paragraph::of_text(whitespace))], many_till(blank_line, exit_matcher),
), ))(remaining)
{
Ok((remain, (_not_immediate_exit, first_line, (_trailing_whitespace, _exit_contents)))) => {
let mut element = Element::Paragraph(Paragraph::of_text(first_line));
let source = get_consumed(remaining, remain);
element.set_source(source);
(remain, vec![element])
}
Err(_) => { Err(_) => {
let (remaining, (children, _exit_contents)) = let (remaining, (children, _exit_contents)) =
many_till(element_matcher, exit_matcher)(remaining)?; many_till(element_matcher, exit_matcher)(remaining)?;

View File

@ -1,4 +1,3 @@
use crate::error::Res;
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::is_not; use nom::bytes::complete::is_not;
use nom::bytes::complete::tag_no_case; use nom::bytes::complete::tag_no_case;
@ -14,6 +13,7 @@ use nom::multi::many_till;
use nom::sequence::tuple; use nom::sequence::tuple;
use super::Context; use super::Context;
use crate::error::Res;
use crate::parser::exiting::ExitClass; use crate::parser::exiting::ExitClass;
use crate::parser::lesser_element::CommentBlock; use crate::parser::lesser_element::CommentBlock;
use crate::parser::lesser_element::ExampleBlock; use crate::parser::lesser_element::ExampleBlock;
@ -30,7 +30,6 @@ use crate::parser::plain_text::plain_text;
use crate::parser::util::blank_line; use crate::parser::util::blank_line;
use crate::parser::util::exit_matcher_parser; use crate::parser::util::exit_matcher_parser;
use crate::parser::util::get_consumed; use crate::parser::util::get_consumed;
use crate::parser::util::start_of_line; use crate::parser::util::start_of_line;
#[tracing::instrument(ret, level = "debug")] #[tracing::instrument(ret, level = "debug")]

View File

@ -1,5 +1,3 @@
use crate::error::Res;
use crate::parser::element_parser::element;
use nom::branch::alt; use nom::branch::alt;
use nom::combinator::eof; use nom::combinator::eof;
use nom::combinator::recognize; use nom::combinator::recognize;
@ -8,20 +6,20 @@ use nom::multi::many1;
use nom::multi::many_till; use nom::multi::many_till;
use nom::sequence::tuple; use nom::sequence::tuple;
use super::lesser_element::Paragraph;
use super::util::blank_line;
use super::util::get_consumed;
use super::Context;
use crate::error::Res;
use crate::parser::element_parser::element;
use crate::parser::exiting::ExitClass; use crate::parser::exiting::ExitClass;
use crate::parser::object_parser::standard_set_object; use crate::parser::object_parser::standard_set_object;
use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ContextElement;
use crate::parser::parser_context::ExitMatcherNode; use crate::parser::parser_context::ExitMatcherNode;
use crate::parser::parser_with_context::parser_with_context; use crate::parser::parser_with_context::parser_with_context;
use crate::parser::util::exit_matcher_parser; use crate::parser::util::exit_matcher_parser;
use crate::parser::util::start_of_line; use crate::parser::util::start_of_line;
use super::lesser_element::Paragraph;
use super::util::blank_line;
use super::util::get_consumed;
use super::Context;
#[tracing::instrument(ret, level = "debug")] #[tracing::instrument(ret, level = "debug")]
pub fn paragraph<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, Paragraph<'s>> { pub fn paragraph<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, Paragraph<'s>> {
let parser_context = let parser_context =

View File

@ -1,14 +1,15 @@
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res;
use std::rc::Rc; use std::rc::Rc;
use nom::combinator::eof;
use nom::IResult;
use super::list::List; use super::list::List;
use super::list::Node; use super::list::Node;
use super::Context; use super::Context;
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res;
use crate::parser::exiting::ExitClass; use crate::parser::exiting::ExitClass;
use nom::combinator::eof;
use nom::IResult;
type Matcher = dyn for<'r, 's> Fn(Context<'r, 's>, &'s str) -> Res<&'s str, &'s str>; type Matcher = dyn for<'r, 's> Fn(Context<'r, 's>, &'s str) -> Res<&'s str, &'s str>;

View File

@ -1,20 +1,3 @@
use super::greater_element::PlainList;
use super::greater_element::PlainListItem;
use super::parser_with_context::parser_with_context;
use super::util::non_whitespace_character;
use super::Context;
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res;
use crate::parser::element_parser::element;
use crate::parser::exiting::ExitClass;
use crate::parser::parser_context::ContextElement;
use crate::parser::parser_context::ExitMatcherNode;
use crate::parser::util::blank_line;
use crate::parser::util::exit_matcher_parser;
use crate::parser::util::get_consumed;
use crate::parser::util::start_of_line;
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::tag; use nom::bytes::complete::tag;
use nom::character::complete::digit1; use nom::character::complete::digit1;
@ -33,6 +16,23 @@ use nom::sequence::terminated;
use nom::sequence::tuple; use nom::sequence::tuple;
use tracing::span; use tracing::span;
use super::greater_element::PlainList;
use super::greater_element::PlainListItem;
use super::parser_with_context::parser_with_context;
use super::util::non_whitespace_character;
use super::Context;
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res;
use crate::parser::element_parser::element;
use crate::parser::exiting::ExitClass;
use crate::parser::parser_context::ContextElement;
use crate::parser::parser_context::ExitMatcherNode;
use crate::parser::util::blank_line;
use crate::parser::util::exit_matcher_parser;
use crate::parser::util::get_consumed;
use crate::parser::util::start_of_line;
#[tracing::instrument(ret, level = "debug")] #[tracing::instrument(ret, level = "debug")]
pub fn plain_list<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, PlainList<'s>> { pub fn plain_list<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, PlainList<'s>> {
let parser_context = context let parser_context = context
@ -278,13 +278,12 @@ fn get_context_item_indent<'r, 's>(context: Context<'r, 's>) -> Option<&'r usize
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ContextElement;
use crate::parser::parser_context::ContextTree; use crate::parser::parser_context::ContextTree;
use crate::parser::parser_with_context::parser_with_context; use crate::parser::parser_with_context::parser_with_context;
use crate::parser::Source; use crate::parser::Source;
use super::*;
#[test] #[test]
fn plain_list_item_empty() { fn plain_list_item_empty() {
let input = "1."; let input = "1.";

View File

@ -1,6 +1,3 @@
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res;
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::is_not; use nom::bytes::complete::is_not;
use nom::bytes::complete::tag; use nom::bytes::complete::tag;
@ -16,6 +13,9 @@ use nom::multi::many_till;
use nom::sequence::tuple; use nom::sequence::tuple;
use super::Context; use super::Context;
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res;
use crate::parser::exiting::ExitClass; use crate::parser::exiting::ExitClass;
use crate::parser::greater_element::NodeProperty; use crate::parser::greater_element::NodeProperty;
use crate::parser::greater_element::PropertyDrawer; use crate::parser::greater_element::PropertyDrawer;

View File

@ -1,4 +1,3 @@
use crate::error::Res;
use std::collections::HashMap; use std::collections::HashMap;
use nom::branch::alt; use nom::branch::alt;
@ -17,6 +16,8 @@ use nom::sequence::delimited;
use nom::sequence::preceded; use nom::sequence::preceded;
use nom::sequence::tuple; use nom::sequence::tuple;
use crate::error::Res;
#[derive(Debug)] #[derive(Debug)]
pub enum Token<'s> { pub enum Token<'s> {
Atom(&'s str), Atom(&'s str),

View File

@ -1,4 +1,3 @@
use crate::error::Res;
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::is_not; use nom::bytes::complete::is_not;
use nom::bytes::complete::tag; use nom::bytes::complete::tag;
@ -14,6 +13,7 @@ use nom::multi::many_till;
use nom::sequence::tuple; use nom::sequence::tuple;
use super::Context; use super::Context;
use crate::error::Res;
use crate::parser::exiting::ExitClass; use crate::parser::exiting::ExitClass;
use crate::parser::greater_element::TableRow; use crate::parser::greater_element::TableRow;
use crate::parser::lesser_element::TableCell; use crate::parser::lesser_element::TableCell;
@ -24,7 +24,6 @@ use crate::parser::parser_context::ExitMatcherNode;
use crate::parser::parser_with_context::parser_with_context; use crate::parser::parser_with_context::parser_with_context;
use crate::parser::util::exit_matcher_parser; use crate::parser::util::exit_matcher_parser;
use crate::parser::util::get_consumed; use crate::parser::util::get_consumed;
use crate::parser::util::start_of_line; use crate::parser::util::start_of_line;
use crate::parser::Table; use crate::parser::Table;

View File

@ -1,10 +1,3 @@
use crate::parser::parser_with_context::parser_with_context;
use super::parser_context::ContextElement;
use super::Context;
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res;
use nom::branch::alt; use nom::branch::alt;
use nom::character::complete::line_ending; use nom::character::complete::line_ending;
use nom::character::complete::multispace0; use nom::character::complete::multispace0;
@ -18,6 +11,13 @@ use nom::combinator::recognize;
use nom::multi::many0; use nom::multi::many0;
use nom::sequence::tuple; use nom::sequence::tuple;
use super::parser_context::ContextElement;
use super::Context;
use crate::error::CustomError;
use crate::error::MyError;
use crate::error::Res;
use crate::parser::parser_with_context::parser_with_context;
pub const WORD_CONSTITUENT_CHARACTERS: &str = pub const WORD_CONSTITUENT_CHARACTERS: &str =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";