Compare commits
6 Commits
cf383fa394
...
v0.1.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26f41b83aa | ||
|
|
e4c0e32536 | ||
|
|
37e85158ea | ||
|
|
6589a755a6 | ||
|
|
a651b79e77 | ||
|
|
98de5e4ec5 |
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "organic"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
authors = ["Tom Alexander <tom@fizz.buzz>"]
|
||||
description = "An org-mode parser."
|
||||
edition = "2021"
|
||||
|
||||
4
build.rs
4
build.rs
@@ -71,10 +71,6 @@ fn write_header(test_file: &mut File) {
|
||||
test_file,
|
||||
r#"
|
||||
#[feature(exit_status_error)]
|
||||
use organic::compare_document;
|
||||
use organic::parser::parse;
|
||||
use organic::emacs_parse_anonymous_org_document;
|
||||
use organic::parser::sexp::sexp_with_padding;
|
||||
|
||||
"#
|
||||
)
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
#![feature(round_char_boundary)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
|
||||
use ::organic::parser::parse;
|
||||
use organic::compare_document;
|
||||
use organic::emacs_parse_anonymous_org_document;
|
||||
use organic::emacs_parse_file_org_document;
|
||||
use organic::get_emacs_version;
|
||||
use organic::get_org_mode_version;
|
||||
use organic::parser::parse_with_settings;
|
||||
use organic::parser::sexp::sexp_with_padding;
|
||||
use organic::GlobalSettings;
|
||||
use organic::LocalFileAccessInterface;
|
||||
use organic::compare::run_anonymous_compare;
|
||||
use organic::compare::run_compare_on_file;
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
use crate::init_tracing::init_telemetry;
|
||||
@@ -43,10 +34,10 @@ fn main_body() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args = std::env::args().skip(1);
|
||||
if args.is_empty() {
|
||||
let org_contents = read_stdin_to_string()?;
|
||||
run_anonymous_parse(org_contents)
|
||||
run_anonymous_compare(org_contents)
|
||||
} else {
|
||||
for arg in args {
|
||||
run_parse_on_file(arg)?
|
||||
run_compare_on_file(arg)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -59,64 +50,3 @@ fn read_stdin_to_string() -> Result<String, Box<dyn std::error::Error>> {
|
||||
.read_to_string(&mut stdin_contents)?;
|
||||
Ok(stdin_contents)
|
||||
}
|
||||
|
||||
fn run_anonymous_parse<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let org_contents = org_contents.as_ref();
|
||||
eprintln!("Using emacs version: {}", get_emacs_version()?.trim());
|
||||
eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim());
|
||||
let rust_parsed = parse(org_contents)?;
|
||||
let org_sexp = emacs_parse_anonymous_org_document(org_contents)?;
|
||||
let (_remaining, parsed_sexp) =
|
||||
sexp_with_padding(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||
|
||||
println!("{}\n\n\n", org_contents);
|
||||
println!("{}", org_sexp);
|
||||
println!("{:#?}", rust_parsed);
|
||||
|
||||
// We do the diffing after printing out both parsed forms in case the diffing panics
|
||||
let diff_result = compare_document(&parsed_sexp, &rust_parsed)?;
|
||||
diff_result.print(org_contents)?;
|
||||
|
||||
if diff_result.is_bad() {
|
||||
Err("Diff results do not match.")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let org_path = org_path.as_ref();
|
||||
eprintln!("Using emacs version: {}", get_emacs_version()?.trim());
|
||||
eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim());
|
||||
let parent_directory = org_path
|
||||
.parent()
|
||||
.ok_or("Should be contained inside a directory.")?;
|
||||
let org_contents = std::fs::read_to_string(org_path)?;
|
||||
let org_contents = org_contents.as_str();
|
||||
let file_access_interface = LocalFileAccessInterface {
|
||||
working_directory: Some(parent_directory.to_path_buf()),
|
||||
};
|
||||
let global_settings = {
|
||||
let mut global_settings = GlobalSettings::default();
|
||||
global_settings.file_access = &file_access_interface;
|
||||
global_settings
|
||||
};
|
||||
let rust_parsed = parse_with_settings(org_contents, &global_settings)?;
|
||||
let org_sexp = emacs_parse_file_org_document(org_path)?;
|
||||
let (_remaining, parsed_sexp) =
|
||||
sexp_with_padding(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||
|
||||
println!("{}\n\n\n", org_contents);
|
||||
println!("{}", org_sexp);
|
||||
println!("{:#?}", rust_parsed);
|
||||
|
||||
// We do the diffing after printing out both parsed forms in case the diffing panics
|
||||
let diff_result = compare_document(&parsed_sexp, &rust_parsed)?;
|
||||
diff_result.print(org_contents)?;
|
||||
|
||||
if diff_result.is_bad() {
|
||||
Err("Diff results do not match.")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
73
src/compare/compare.rs
Normal file
73
src/compare/compare.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use std::path::Path;
|
||||
|
||||
use crate::compare::diff::compare_document;
|
||||
use crate::compare::parse::emacs_parse_anonymous_org_document;
|
||||
use crate::compare::parse::emacs_parse_file_org_document;
|
||||
use crate::compare::parse::get_emacs_version;
|
||||
use crate::compare::parse::get_org_mode_version;
|
||||
use crate::compare::sexp::sexp;
|
||||
use crate::parser::parse;
|
||||
use crate::parser::parse_with_settings;
|
||||
use crate::GlobalSettings;
|
||||
use crate::LocalFileAccessInterface;
|
||||
|
||||
pub fn run_anonymous_compare<P: AsRef<str>>(
|
||||
org_contents: P,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let org_contents = org_contents.as_ref();
|
||||
eprintln!("Using emacs version: {}", get_emacs_version()?.trim());
|
||||
eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim());
|
||||
let rust_parsed = parse(org_contents)?;
|
||||
let org_sexp = emacs_parse_anonymous_org_document(org_contents)?;
|
||||
let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||
|
||||
println!("{}\n\n\n", org_contents);
|
||||
println!("{}", org_sexp);
|
||||
println!("{:#?}", rust_parsed);
|
||||
|
||||
// We do the diffing after printing out both parsed forms in case the diffing panics
|
||||
let diff_result = compare_document(&parsed_sexp, &rust_parsed)?;
|
||||
diff_result.print(org_contents)?;
|
||||
|
||||
if diff_result.is_bad() {
|
||||
Err("Diff results do not match.")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_compare_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let org_path = org_path.as_ref();
|
||||
eprintln!("Using emacs version: {}", get_emacs_version()?.trim());
|
||||
eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim());
|
||||
let parent_directory = org_path
|
||||
.parent()
|
||||
.ok_or("Should be contained inside a directory.")?;
|
||||
let org_contents = std::fs::read_to_string(org_path)?;
|
||||
let org_contents = org_contents.as_str();
|
||||
let file_access_interface = LocalFileAccessInterface {
|
||||
working_directory: Some(parent_directory.to_path_buf()),
|
||||
};
|
||||
let global_settings = {
|
||||
let mut global_settings = GlobalSettings::default();
|
||||
global_settings.file_access = &file_access_interface;
|
||||
global_settings
|
||||
};
|
||||
let rust_parsed = parse_with_settings(org_contents, &global_settings)?;
|
||||
let org_sexp = emacs_parse_file_org_document(org_path)?;
|
||||
let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||
|
||||
println!("{}\n\n\n", org_contents);
|
||||
println!("{}", org_sexp);
|
||||
println!("{:#?}", rust_parsed);
|
||||
|
||||
// We do the diffing after printing out both parsed forms in case the diffing panics
|
||||
let diff_result = compare_document(&parsed_sexp, &rust_parsed)?;
|
||||
diff_result.print(org_contents)?;
|
||||
|
||||
if diff_result.is_bad() {
|
||||
Err("Diff results do not match.")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::sexp::unquote;
|
||||
use super::sexp::Token;
|
||||
use super::util::assert_bounds;
|
||||
use super::util::assert_name;
|
||||
use super::util::get_property;
|
||||
use crate::parser::sexp::unquote;
|
||||
use crate::parser::sexp::Token;
|
||||
use crate::types::AngleLink;
|
||||
use crate::types::Bold;
|
||||
use crate::types::Citation;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
mod compare;
|
||||
mod diff;
|
||||
mod parse;
|
||||
mod sexp;
|
||||
mod util;
|
||||
pub use diff::compare_document;
|
||||
pub use parse::emacs_parse_anonymous_org_document;
|
||||
pub use parse::emacs_parse_file_org_document;
|
||||
pub use parse::get_emacs_version;
|
||||
pub use parse::get_org_mode_version;
|
||||
pub use compare::run_anonymous_compare;
|
||||
pub use compare::run_compare_on_file;
|
||||
|
||||
@@ -16,9 +16,6 @@ use nom::sequence::delimited;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::org_source::convert_error;
|
||||
use super::org_source::OrgSource;
|
||||
use super::util::get_consumed;
|
||||
use crate::error::Res;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -99,6 +96,25 @@ impl<'s> Token<'s> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the child string slice is a slice of the parent string slice.
|
||||
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;
|
||||
let child_end = child_start + child.len();
|
||||
child_start >= parent_start && child_end <= parent_end
|
||||
}
|
||||
|
||||
/// Get a slice of the string that was consumed in a parser using the original input to the parser and the remaining input after the parser.
|
||||
pub fn get_consumed<'s>(input: &'s str, remaining: &'s str) -> &'s str {
|
||||
assert!(is_slice_of(input, remaining));
|
||||
let source = {
|
||||
let offset = remaining.as_ptr() as usize - input.as_ptr() as usize;
|
||||
&input[..offset]
|
||||
};
|
||||
source.into()
|
||||
}
|
||||
|
||||
pub(crate) fn unquote(text: &str) -> Result<String, Box<dyn std::error::Error>> {
|
||||
let mut out = String::with_capacity(text.len());
|
||||
if !text.starts_with(r#"""#) {
|
||||
@@ -136,29 +152,20 @@ pub(crate) fn unquote(text: &str) -> Result<String, Box<dyn std::error::Error>>
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn sexp_with_padding<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||
pub fn sexp<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||
let (remaining, _) = multispace0(input)?;
|
||||
let remaining = OrgSource::new(remaining);
|
||||
let (remaining, tkn) = token(remaining)
|
||||
.map(|(rem, out)| (Into::<&str>::into(rem), out))
|
||||
.map_err(convert_error)?;
|
||||
let (remaining, tkn) = token(remaining).map(|(rem, out)| (Into::<&str>::into(rem), out))?;
|
||||
let (remaining, _) = multispace0(remaining)?;
|
||||
Ok((remaining, tkn))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn sexp<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
let (remaining, tkn) = token(input)?;
|
||||
Ok((remaining, tkn))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn token<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
fn token<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||
alt((list, vector, atom))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn list<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
fn list<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||
let (remaining, _) = tag("(")(input)?;
|
||||
let (remaining, children) = delimited(
|
||||
multispace0,
|
||||
@@ -170,7 +177,7 @@ fn list<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn vector<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
fn vector<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||
let (remaining, _) = tag("[")(input)?;
|
||||
let (remaining, children) = delimited(
|
||||
multispace0,
|
||||
@@ -182,7 +189,7 @@ fn vector<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
fn atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||
not(peek(one_of(")]")))(input)?;
|
||||
alt((
|
||||
text_with_properties,
|
||||
@@ -193,7 +200,7 @@ fn atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn unquoted_atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
fn unquoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||
let (remaining, body) = take_till1(|c| match c {
|
||||
' ' | '\t' | '\r' | '\n' | ')' | ']' => true,
|
||||
_ => false,
|
||||
@@ -202,7 +209,7 @@ fn unquoted_atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn quoted_atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
fn quoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||
let (remaining, _) = tag(r#"""#)(input)?;
|
||||
let (remaining, _) = escaped(
|
||||
take_till1(|c| match c {
|
||||
@@ -218,7 +225,7 @@ fn quoted_atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn hash_notation<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
fn hash_notation<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||
let (remaining, _) = tag("#<")(input)?;
|
||||
let (remaining, _body) = take_till1(|c| match c {
|
||||
'>' => true,
|
||||
@@ -229,7 +236,7 @@ fn hash_notation<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
Ok((remaining, Token::Atom(source.into())))
|
||||
}
|
||||
|
||||
fn text_with_properties<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
|
||||
fn text_with_properties<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||
let (remaining, _) = tag("#(")(input)?;
|
||||
let (remaining, (text, props)) = delimited(
|
||||
multispace0,
|
||||
@@ -259,7 +266,7 @@ mod tests {
|
||||
#[test]
|
||||
fn simple() {
|
||||
let input = " (foo bar baz ) ";
|
||||
let (remaining, parsed) = sexp_with_padding(input).expect("Parse the input");
|
||||
let (remaining, parsed) = sexp(input).expect("Parse the input");
|
||||
assert_eq!(remaining, "");
|
||||
assert!(match parsed {
|
||||
Token::Atom(_) => false,
|
||||
@@ -272,7 +279,7 @@ mod tests {
|
||||
#[test]
|
||||
fn quoted() {
|
||||
let input = r#" ("foo" bar baz ) "#;
|
||||
let (remaining, parsed) = sexp_with_padding(input).expect("Parse the input");
|
||||
let (remaining, parsed) = sexp(input).expect("Parse the input");
|
||||
assert_eq!(remaining, "");
|
||||
assert!(match parsed {
|
||||
Token::Atom(_) => false,
|
||||
@@ -296,7 +303,7 @@ mod tests {
|
||||
#[test]
|
||||
fn quoted_containing_paren() {
|
||||
let input = r#" (foo "b(a)r" baz ) "#;
|
||||
let (remaining, parsed) = sexp_with_padding(input).expect("Parse the input");
|
||||
let (remaining, parsed) = sexp(input).expect("Parse the input");
|
||||
assert_eq!(remaining, "");
|
||||
assert!(match parsed {
|
||||
Token::List(_) => true,
|
||||
@@ -332,7 +339,7 @@ mod tests {
|
||||
#[test]
|
||||
fn string_containing_escaped_characters() {
|
||||
let input = r#" (foo "\\( x=2 \\)" bar) "#;
|
||||
let (remaining, parsed) = sexp_with_padding(input).expect("Parse the input");
|
||||
let (remaining, parsed) = sexp(input).expect("Parse the input");
|
||||
assert_eq!(remaining, "");
|
||||
assert!(match parsed {
|
||||
Token::Atom(_) => false,
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::parser::sexp::Token;
|
||||
use super::sexp::Token;
|
||||
use crate::types::Source;
|
||||
|
||||
/// Check if the child string slice is a slice of the parent string slice.
|
||||
|
||||
12
src/lib.rs
12
src/lib.rs
@@ -4,17 +4,7 @@
|
||||
// TODO: #![warn(missing_docs)]
|
||||
|
||||
#[cfg(feature = "compare")]
|
||||
mod compare;
|
||||
#[cfg(feature = "compare")]
|
||||
pub use compare::compare_document;
|
||||
#[cfg(feature = "compare")]
|
||||
pub use compare::emacs_parse_anonymous_org_document;
|
||||
#[cfg(feature = "compare")]
|
||||
pub use compare::emacs_parse_file_org_document;
|
||||
#[cfg(feature = "compare")]
|
||||
pub use compare::get_emacs_version;
|
||||
#[cfg(feature = "compare")]
|
||||
pub use compare::get_org_mode_version;
|
||||
pub mod compare;
|
||||
|
||||
mod context;
|
||||
mod error;
|
||||
|
||||
@@ -28,7 +28,7 @@ use crate::types::Object;
|
||||
///
|
||||
/// This is the main entry point for Organic. It will parse the full contents of the input string as an org-mode document.
|
||||
#[allow(dead_code)]
|
||||
pub fn parse<'s>(input: &'s str) -> Result<Document<'s>, String> {
|
||||
pub fn parse<'s>(input: &'s str) -> Result<Document<'s>, Box<dyn std::error::Error>> {
|
||||
parse_with_settings(input, &GlobalSettings::default())
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ pub fn parse<'s>(input: &'s str) -> Result<Document<'s>, String> {
|
||||
pub fn parse_with_settings<'g, 's>(
|
||||
input: &'s str,
|
||||
global_settings: &'g GlobalSettings<'g, 's>,
|
||||
) -> Result<Document<'s>, String> {
|
||||
) -> Result<Document<'s>, Box<dyn std::error::Error>> {
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(global_settings, List::new(&initial_context));
|
||||
let wrapped_input = OrgSource::new(input);
|
||||
@@ -49,7 +49,7 @@ pub fn parse_with_settings<'g, 's>(
|
||||
all_consuming(parser_with_context!(document_org_source)(&initial_context))(wrapped_input)
|
||||
.map_err(|err| err.to_string())
|
||||
.map(|(_remaining, parsed_document)| parsed_document);
|
||||
ret
|
||||
Ok(ret?)
|
||||
}
|
||||
|
||||
/// Parse a full org-mode document.
|
||||
|
||||
@@ -37,8 +37,6 @@ mod property_drawer;
|
||||
mod radio_link;
|
||||
mod regular_link;
|
||||
mod section;
|
||||
#[cfg(feature = "compare")]
|
||||
pub mod sexp;
|
||||
mod statistics_cookie;
|
||||
mod subscript_and_superscript;
|
||||
mod table;
|
||||
|
||||
@@ -64,5 +64,5 @@ pub use object::Target;
|
||||
pub use object::Timestamp;
|
||||
pub use object::Underline;
|
||||
pub use object::Verbatim;
|
||||
pub use source::SetSource;
|
||||
pub(crate) use source::SetSource;
|
||||
pub use source::Source;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pub trait Source<'s> {
|
||||
fn get_source(&'s self) -> &'s str;
|
||||
}
|
||||
pub trait SetSource<'s> {
|
||||
pub(crate) trait SetSource<'s> {
|
||||
fn set_source(&mut self, source: &'s str);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
#[test]
|
||||
fn {name}() {{
|
||||
let todo_org_path = "{path}";
|
||||
let org_contents = std::fs::read_to_string(todo_org_path).expect("Read org file.");
|
||||
println!("{{}}", org_contents);
|
||||
let org_sexp = emacs_parse_anonymous_org_document(org_contents.as_str()).expect("Use emacs to parse org file.");
|
||||
println!("{{}}", org_sexp);
|
||||
let (_remaining, parsed_sexp) = sexp_with_padding(org_sexp.as_str()).expect("Sexp Parse failure");
|
||||
let rust_parsed = parse(org_contents.as_str()).expect("Org Parse failure");
|
||||
println!("{{:#?}}", rust_parsed);
|
||||
let diff_result =
|
||||
compare_document(&parsed_sexp, &rust_parsed).expect("Compare parsed documents.");
|
||||
diff_result
|
||||
.print(org_contents.as_str())
|
||||
.expect("Print document parse tree diff.");
|
||||
assert!(!diff_result.is_bad());
|
||||
fn {name}() -> Result<(), Box<dyn std::error::Error>> {{
|
||||
let org_path = "{path}";
|
||||
let org_contents = std::fs::read_to_string(org_path).expect("Read org file.");
|
||||
organic::compare::run_anonymous_compare(org_contents.as_str())?;
|
||||
Ok(())
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user