diff --git a/docker/organic_test/Dockerfile b/docker/organic_test/Dockerfile index 01002337..86f3a405 100644 --- a/docker/organic_test/Dockerfile +++ b/docker/organic_test/Dockerfile @@ -1,5 +1,5 @@ FROM alpine:3.17 AS build -RUN apk add --no-cache build-base musl-dev git autoconf make texinfo gnutls-dev ncurses-dev gawk +RUN apk add --no-cache build-base musl-dev git autoconf make texinfo gnutls-dev ncurses-dev gawk libgccjit-dev FROM build AS build-emacs @@ -8,7 +8,7 @@ RUN git clone --depth 1 --branch $EMACS_VERSION https://git.savannah.gnu.org/git WORKDIR /root/emacs RUN mkdir /root/dist RUN ./autogen.sh -RUN ./configure --prefix /usr --without-x --without-sound +RUN ./configure --prefix /usr --without-x --without-sound --with-native-compilation=aot RUN make RUN make DESTDIR="/root/dist" install @@ -27,7 +27,7 @@ RUN make DESTDIR="/root/dist" install FROM rustlang/rust:nightly-alpine3.17 AS tester ENV LANG=en_US.UTF-8 -RUN apk add --no-cache musl-dev ncurses gnutls +RUN apk add --no-cache musl-dev ncurses gnutls libgccjit RUN cargo install --locked --no-default-features --features ci-autoclean cargo-cache COPY --from=build-emacs /root/dist/ / COPY --from=build-org-mode /root/dist/ / diff --git a/org_mode_samples/greater_element/dynamic_block/no_closing_colon.org b/org_mode_samples/greater_element/dynamic_block/no_closing_colon.org new file mode 100644 index 00000000..c6073d9f --- /dev/null +++ b/org_mode_samples/greater_element/dynamic_block/no_closing_colon.org @@ -0,0 +1,3 @@ +#+BEGIN: timestamp :format "%Y-%m-%d %H:%M" + +#+END diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 1aab5789..a135a981 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -894,6 +894,8 @@ fn compare_dynamic_block<'s>( Ok(_) => {} }; + // TODO: Compare :block-name :arguments + for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { child_status.push(compare_element(source, emacs_child, rust_child)?); } diff --git a/src/parser/dynamic_block.rs b/src/parser/dynamic_block.rs index d3683855..b2c5559f 100644 --- a/src/parser/dynamic_block.rs +++ b/src/parser/dynamic_block.rs @@ -1,14 +1,18 @@ use nom::branch::alt; use nom::bytes::complete::is_not; +use nom::bytes::complete::tag; 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::recognize; +use nom::multi::many0; use nom::multi::many_till; +use nom::sequence::preceded; use nom::sequence::tuple; use super::org_source::OrgSource; @@ -67,24 +71,23 @@ pub(crate) fn dynamic_block<'b, 'g, 'r, 's>( }; let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); - let (remaining, children) = match tuple(( - not(exit_matcher), + not(exit_matcher)(remaining)?; + let (remaining, leading_blank_lines) = opt(consumed(tuple(( blank_line, - many_till(blank_line, exit_matcher), - ))(remaining) - { - Ok((remain, (_not_immediate_exit, first_line, (_trailing_whitespace, _exit_contents)))) => { + many0(preceded(not(exit_matcher), blank_line)), + ))))(remaining)?; + let leading_blank_lines = + leading_blank_lines.map(|(source, (first_line, _remaining_lines))| { let mut element = Element::Paragraph(Paragraph::of_text(first_line.into())); - let source = get_consumed(remaining, remain); element.set_source(source.into()); - (remain, vec![element]) - } - Err(_) => { - let (remaining, (children, _exit_contents)) = - many_till(element_matcher, exit_matcher)(remaining)?; - (remaining, children) - } - }; + element + }); + let (remaining, (mut children, _exit_contents)) = + many_till(element_matcher, exit_matcher)(remaining)?; + if let Some(lines) = leading_blank_lines { + children.insert(0, lines); + } + let (remaining, _end) = dynamic_block_end(&parser_context, remaining)?; let source = get_consumed(input, remaining); @@ -117,7 +120,8 @@ fn dynamic_block_end<'b, 'g, 'r, 's>( start_of_line(input)?; let (remaining, source) = recognize(tuple(( space0, - tag_no_case("#+end:"), + tag_no_case("#+end"), + opt(tag(":")), alt((eof, line_ending)), )))(input)?; Ok((remaining, source))