Merge branch 'export_snippet'
Some checks failed
semver Build semver has succeeded
rustfmt Build rustfmt has succeeded
rust-test Build rust-test has failed

This commit is contained in:
Tom Alexander 2023-07-19 00:38:40 -04:00
commit d3c265415c
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
9 changed files with 129 additions and 3 deletions

View File

@ -0,0 +1,9 @@
@@latex:
\documentclass[margin,11pt]{res} % default is 10 pt
@@

View File

@ -0,0 +1,4 @@
@@html:<b>@@This text is only bold for the html exporter@@html:</b>@@
@@latex:
\documentclass[margin,11pt]{res} % default is 10 pt
@@

View File

@ -16,6 +16,7 @@ use crate::parser::Element;
use crate::parser::Entity;
use crate::parser::ExampleBlock;
use crate::parser::ExportBlock;
use crate::parser::ExportSnippet;
use crate::parser::FixedWidthArea;
use crate::parser::FootnoteDefinition;
use crate::parser::GreaterBlock;
@ -158,6 +159,7 @@ fn compare_object<'s>(
Object::OrgMacro(obj) => compare_org_macro(source, emacs, obj),
Object::Entity(obj) => compare_entity(source, emacs, obj),
Object::LatexFragment(obj) => compare_latex_fragment(source, emacs, obj),
Object::ExportSnippet(obj) => compare_export_snippet(source, emacs, obj),
}
}
@ -1288,3 +1290,26 @@ fn compare_latex_fragment<'s>(
children: Vec::new(),
})
}
fn compare_export_snippet<'s>(
source: &'s str,
emacs: &'s Token<'s>,
rust: &'s ExportSnippet<'s>,
) -> Result<DiffResult, Box<dyn std::error::Error>> {
let mut this_status = DiffStatus::Good;
let emacs_name = "export-snippet";
if assert_name(emacs, emacs_name).is_err() {
this_status = DiffStatus::Bad;
}
if assert_bounds(source, emacs, rust).is_err() {
this_status = DiffStatus::Bad;
}
Ok(DiffResult {
status: this_status,
name: emacs_name.to_owned(),
message: None,
children: Vec::new(),
})
}

View File

@ -0,0 +1,61 @@
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete::anychar;
use nom::combinator::opt;
use nom::combinator::peek;
use nom::combinator::recognize;
use nom::combinator::verify;
use nom::multi::many1;
use nom::multi::many_till;
use nom::sequence::tuple;
use super::Context;
use crate::error::Res;
use crate::parser::parser_with_context::parser_with_context;
use crate::parser::util::exit_matcher_parser;
use crate::parser::util::get_consumed;
use crate::parser::ExportSnippet;
#[tracing::instrument(ret, level = "debug")]
pub fn export_snippet<'r, 's>(
context: Context<'r, 's>,
input: &'s str,
) -> Res<&'s str, ExportSnippet<'s>> {
let (remaining, _) = tag("@@")(input)?;
let (remaining, backend_name) = backend(context, remaining)?;
let (remaining, backend_contents) =
opt(tuple((tag(":"), parser_with_context!(contents)(context))))(remaining)?;
let (remaining, _) = tag("@@")(remaining)?;
let source = get_consumed(input, remaining);
Ok((
remaining,
ExportSnippet {
source,
backend: backend_name,
contents: backend_contents.map(|(_colon, backend_contents)| backend_contents),
},
))
}
#[tracing::instrument(ret, level = "debug")]
fn backend<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> {
let (remaining, backend_name) =
recognize(many1(verify(anychar, |c| c.is_alphanumeric() || *c == '-')))(input)?;
Ok((remaining, backend_name))
}
#[tracing::instrument(ret, level = "debug")]
fn contents<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> {
let (remaining, source) = recognize(verify(
many_till(
anychar,
peek(alt((
parser_with_context!(exit_matcher_parser)(context),
tag("@@"),
))),
),
|(children, _exit_contents)| !children.is_empty(),
))(input)?;
Ok((remaining, source))
}

View File

@ -6,10 +6,10 @@ use nom::character::complete::line_ending;
use nom::character::complete::none_of;
use nom::character::complete::one_of;
use nom::character::complete::space0;
use nom::combinator::opt;
use nom::combinator::peek;
use nom::combinator::recognize;
use nom::combinator::verify;
use nom::multi::many0;
use nom::multi::many_till;
use nom::sequence::tuple;
@ -45,7 +45,7 @@ pub fn latex_fragment<'r, 's>(
fn raw_latex_fragment<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> {
let (remaining, _) = tag("\\")(input)?;
let (remaining, _) = name(context, remaining)?;
let (remaining, _) = opt(parser_with_context!(brackets)(context))(remaining)?;
let (remaining, _) = many0(parser_with_context!(brackets)(context))(remaining)?;
let source = get_consumed(input, remaining);
Ok((remaining, source))

View File

@ -9,6 +9,7 @@ mod element;
mod element_parser;
mod entity;
mod exiting;
mod export_snippet;
mod fixed_width_area;
mod footnote_definition;
mod greater_block;
@ -73,6 +74,7 @@ pub use object::AngleLink;
pub use object::Bold;
pub use object::Code;
pub use object::Entity;
pub use object::ExportSnippet;
pub use object::Italic;
pub use object::LatexFragment;
pub use object::Object;

View File

@ -17,6 +17,7 @@ pub enum Object<'s> {
OrgMacro(OrgMacro<'s>),
Entity(Entity<'s>),
LatexFragment(LatexFragment<'s>),
ExportSnippet(ExportSnippet<'s>),
}
#[derive(Debug, PartialEq)]
@ -109,6 +110,13 @@ pub struct LatexFragment<'s> {
pub source: &'s str,
}
#[derive(Debug, PartialEq)]
pub struct ExportSnippet<'s> {
pub source: &'s str,
pub backend: &'s str,
pub contents: Option<&'s str>,
}
impl<'s> Source<'s> for Object<'s> {
fn get_source(&'s self) -> &'s str {
match self {
@ -127,6 +135,7 @@ impl<'s> Source<'s> for Object<'s> {
Object::OrgMacro(obj) => obj.source,
Object::Entity(obj) => obj.source,
Object::LatexFragment(obj) => obj.source,
Object::ExportSnippet(obj) => obj.source,
}
}
}
@ -214,3 +223,9 @@ impl<'s> Source<'s> for LatexFragment<'s> {
self.source
}
}
impl<'s> Source<'s> for ExportSnippet<'s> {
fn get_source(&'s self) -> &'s str {
self.source
}
}

View File

@ -9,6 +9,7 @@ use super::Context;
use crate::error::Res;
use crate::parser::angle_link::angle_link;
use crate::parser::entity::entity;
use crate::parser::export_snippet::export_snippet;
use crate::parser::latex_fragment::latex_fragment;
use crate::parser::object::Object;
use crate::parser::org_macro::org_macro;
@ -22,10 +23,14 @@ pub fn standard_set_object<'r, 's>(
context: Context<'r, 's>,
input: &'s str,
) -> Res<&'s str, Object<'s>> {
// TODO: export snippets, footnote references, citations (NOT citation references), inline babel calls, inline source blocks, line breaks, links, macros, targets and radio targets, statistics cookies, subscript and superscript, timestamps, and text markup.
// TODO: footnote references, citations (NOT citation references), inline babel calls, inline source blocks, line breaks, links, macros, targets and radio targets, statistics cookies, subscript and superscript, timestamps, and text markup.
not(|i| context.check_exit_matcher(i))(input)?;
alt((
map(
parser_with_context!(export_snippet)(context),
Object::ExportSnippet,
),
map(parser_with_context!(entity)(context), Object::Entity),
map(
parser_with_context!(latex_fragment)(context),
@ -74,6 +79,10 @@ pub fn any_object_except_plain_text<'r, 's>(
) -> Res<&'s str, Object<'s>> {
// Used for exit matchers so this does not check exit matcher condition.
alt((
map(
parser_with_context!(export_snippet)(context),
Object::ExportSnippet,
),
map(parser_with_context!(entity)(context), Object::Entity),
map(
parser_with_context!(latex_fragment)(context),

View File

@ -54,6 +54,7 @@ impl<'r, 's> Token<'r, 's> {
Object::OrgMacro(_) => Box::new(std::iter::empty()),
Object::Entity(_) => Box::new(std::iter::empty()),
Object::LatexFragment(_) => Box::new(std::iter::empty()),
Object::ExportSnippet(_) => Box::new(std::iter::empty()),
},
Token::Element(elem) => match elem {
Element::Paragraph(inner) => Box::new(inner.children.iter().map(Token::Object)),