Compare commits
16 Commits
32071ce74d
...
feature_ma
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
678106bb65 | ||
|
|
19432d91ab | ||
|
|
16a107eebb | ||
|
|
77348b560c | ||
|
|
fc79507ef3 | ||
|
|
9c1e6ccc97 | ||
|
|
0dbc8f0925 | ||
|
|
02fe10fba3 | ||
|
|
33d7ae03d1 | ||
|
|
03faa7257f | ||
|
|
ae3510abd5 | ||
|
|
ad3f47864a | ||
|
|
533ef2a9a8 | ||
|
|
cf37bc4111 | ||
|
|
e5224cda63 | ||
|
|
64e3481660 |
@@ -14,10 +14,6 @@ spec:
|
|||||||
- name: path-to-dockerfile
|
- name: path-to-dockerfile
|
||||||
description: The path to the Dockerfile
|
description: The path to the Dockerfile
|
||||||
type: string
|
type: string
|
||||||
- name: command
|
|
||||||
type: array
|
|
||||||
description: Command to run.
|
|
||||||
default: []
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: report-pending
|
- name: report-pending
|
||||||
taskRef:
|
taskRef:
|
||||||
@@ -81,9 +77,19 @@ spec:
|
|||||||
workspace: docker-credentials
|
workspace: docker-credentials
|
||||||
runAfter:
|
runAfter:
|
||||||
- fetch-repository
|
- fetch-repository
|
||||||
- name: run-image-none
|
- name: build-organic
|
||||||
taskRef:
|
taskRef:
|
||||||
name: run-docker-image
|
name: run-docker-image
|
||||||
|
matrix:
|
||||||
|
params:
|
||||||
|
- name: feature-compare
|
||||||
|
value:
|
||||||
|
- "true"
|
||||||
|
- "false"
|
||||||
|
- name: feature-tracing
|
||||||
|
value:
|
||||||
|
- "true"
|
||||||
|
- "false"
|
||||||
workspaces:
|
workspaces:
|
||||||
- name: source
|
- name: source
|
||||||
workspace: git-source
|
workspace: git-source
|
||||||
@@ -93,77 +99,21 @@ spec:
|
|||||||
- build-image
|
- build-image
|
||||||
params:
|
params:
|
||||||
- name: command
|
- name: command
|
||||||
value: ["$(params.command[*])"]
|
value: ["/bin/sh", "-c"]
|
||||||
- name: args
|
- name: args
|
||||||
value: ["--no-default-features"]
|
value:
|
||||||
- name: docker-image
|
- |
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
set -euo pipefail
|
||||||
- name: run-image-tracing
|
IFS=$$'\n\t'
|
||||||
taskRef:
|
features=()
|
||||||
name: run-docker-image
|
if [ $(params.feature-compare) = "true" ]; then features+=(compare); fi
|
||||||
workspaces:
|
if [ $(params.feature-tracing) = "true" ]; then features+=(tracing); fi
|
||||||
- name: source
|
if [ $${#features[@]} -eq 0 ]; then
|
||||||
workspace: git-source
|
exec cargo build --no-default-features
|
||||||
- name: cargo-cache
|
else
|
||||||
workspace: cargo-cache
|
featurelist=$$(IFS="," ; echo "$${features[*]}")
|
||||||
runAfter:
|
exec cargo build --no-default-features --features "$$featurelist"
|
||||||
- run-image-none
|
fi
|
||||||
params:
|
|
||||||
- name: command
|
|
||||||
value: ["$(params.command[*])"]
|
|
||||||
- name: args
|
|
||||||
value: ["--no-default-features", "--features", "tracing"]
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: run-image-compare
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- run-image-tracing
|
|
||||||
params:
|
|
||||||
- name: command
|
|
||||||
value: ["$(params.command[*])"]
|
|
||||||
- name: args
|
|
||||||
value: ["--no-default-features", "--features", "compare"]
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: run-image-default
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- run-image-compare
|
|
||||||
params:
|
|
||||||
- name: command
|
|
||||||
value: ["$(params.command[*])"]
|
|
||||||
- name: args
|
|
||||||
value: []
|
|
||||||
- name: docker-image
|
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
|
||||||
- name: run-image-all
|
|
||||||
taskRef:
|
|
||||||
name: run-docker-image
|
|
||||||
workspaces:
|
|
||||||
- name: source
|
|
||||||
workspace: git-source
|
|
||||||
- name: cargo-cache
|
|
||||||
workspace: cargo-cache
|
|
||||||
runAfter:
|
|
||||||
- run-image-default
|
|
||||||
params:
|
|
||||||
- name: command
|
|
||||||
value: ["$(params.command[*])"]
|
|
||||||
- name: args
|
|
||||||
value: ["--no-default-features", "--features", "tracing,compare"]
|
|
||||||
- name: docker-image
|
- name: docker-image
|
||||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||||
finally:
|
finally:
|
||||||
@@ -256,5 +206,3 @@ spec:
|
|||||||
value: docker/organic_build/
|
value: docker/organic_build/
|
||||||
- name: path-to-dockerfile
|
- name: path-to-dockerfile
|
||||||
value: docker/organic_build/Dockerfile
|
value: docker/organic_build/Dockerfile
|
||||||
- name: command
|
|
||||||
value: [cargo, build]
|
|
||||||
|
|||||||
3
build.rs
3
build.rs
@@ -75,9 +75,6 @@ fn is_expect_fail(name: &str) -> Option<&str> {
|
|||||||
"autogen_greater_element_drawer_drawer_with_headline_inside" => Some("Apparently lines with :end: become their own paragraph. This odd behavior needs to be investigated more."),
|
"autogen_greater_element_drawer_drawer_with_headline_inside" => Some("Apparently lines with :end: become their own paragraph. This odd behavior needs to be investigated more."),
|
||||||
"autogen_element_container_priority_footnote_definition_dynamic_block" => Some("Apparently broken begin lines become their own paragraph."),
|
"autogen_element_container_priority_footnote_definition_dynamic_block" => Some("Apparently broken begin lines become their own paragraph."),
|
||||||
"autogen_lesser_element_paragraphs_paragraph_with_backslash_line_breaks" => Some("The text we're getting out of the parse tree is already processed to remove line breaks, so our comparison needs to take that into account."),
|
"autogen_lesser_element_paragraphs_paragraph_with_backslash_line_breaks" => Some("The text we're getting out of the parse tree is already processed to remove line breaks, so our comparison needs to take that into account."),
|
||||||
"autogen_greater_element_plain_list_trailing_whitespace_ownership_test_case_1" => Some("Seeing odd behavior about whitespace ownership."), // https://list.orgmode.org/9372527e-3852-419e-936a-7b4dd38cc847@app.fastmail.com/
|
|
||||||
"autogen_greater_element_plain_list_trailing_whitespace_ownership_test_case_3" => Some("Seeing odd behavior about whitespace ownership."), // https://list.orgmode.org/9372527e-3852-419e-936a-7b4dd38cc847@app.fastmail.com/
|
|
||||||
"autogen_greater_element_plain_list_trailing_whitespace_ownership_test_case_4" => Some("Seeing odd behavior about whitespace ownership."), // https://list.orgmode.org/9372527e-3852-419e-936a-7b4dd38cc847@app.fastmail.com/
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
FROM alpine:3.17 AS build
|
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
|
||||||
|
|
||||||
|
|
||||||
FROM build AS build-emacs
|
FROM build AS build-emacs
|
||||||
|
ARG EMACS_VERSION=emacs-29.1
|
||||||
RUN git clone --depth 1 --branch emacs-29.1 https://git.savannah.gnu.org/git/emacs.git /root/emacs
|
RUN git clone --depth 1 --branch $EMACS_VERSION https://git.savannah.gnu.org/git/emacs.git /root/emacs
|
||||||
WORKDIR /root/emacs
|
WORKDIR /root/emacs
|
||||||
RUN mkdir /root/dist
|
RUN mkdir /root/dist
|
||||||
RUN ./autogen.sh
|
RUN ./autogen.sh
|
||||||
@@ -15,9 +14,12 @@ RUN make DESTDIR="/root/dist" install
|
|||||||
|
|
||||||
|
|
||||||
FROM build AS build-org-mode
|
FROM build AS build-org-mode
|
||||||
|
ARG ORG_VERSION=7bdec435ff5d86220d13c431e799c5ed44a57da1
|
||||||
COPY --from=build-emacs /root/dist/ /
|
COPY --from=build-emacs /root/dist/ /
|
||||||
RUN mkdir /root/dist
|
RUN mkdir /root/dist
|
||||||
RUN mkdir /root/org-mode && git -C /root/org-mode init --initial-branch=main && git -C /root/org-mode remote add origin https://git.savannah.gnu.org/git/emacs/org-mode.git && git -C /root/org-mode fetch origin 299193bf091a63474fc8036bd31de51800a2555a && git -C /root/org-mode checkout FETCH_HEAD
|
# Savannah does not allow fetching specific revisions, so we're going to have to put unnecessary load on their server by cloning main and then checking out the revision we want.
|
||||||
|
RUN git clone https://git.savannah.gnu.org/git/emacs/org-mode.git /root/org-mode && git -C /root/org-mode checkout $ORG_VERSION
|
||||||
|
# RUN mkdir /root/org-mode && git -C /root/org-mode init --initial-branch=main && git -C /root/org-mode remote add origin https://git.savannah.gnu.org/git/emacs/org-mode.git && git -C /root/org-mode fetch origin $ORG_VERSION && git -C /root/org-mode checkout FETCH_HEAD
|
||||||
WORKDIR /root/org-mode
|
WORKDIR /root/org-mode
|
||||||
RUN make compile
|
RUN make compile
|
||||||
RUN make DESTDIR="/root/dist" install
|
RUN make DESTDIR="/root/dist" install
|
||||||
|
|||||||
@@ -3,3 +3,5 @@ mod parse;
|
|||||||
mod util;
|
mod util;
|
||||||
pub use diff::compare_document;
|
pub use diff::compare_document;
|
||||||
pub use parse::emacs_parse_org_document;
|
pub use parse::emacs_parse_org_document;
|
||||||
|
pub use parse::get_emacs_version;
|
||||||
|
pub use parse::get_org_mode_version;
|
||||||
|
|||||||
@@ -49,3 +49,40 @@ where
|
|||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_emacs_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||||
|
let elisp_script = r#"(progn
|
||||||
|
(message "%s" (version))
|
||||||
|
)"#;
|
||||||
|
let mut cmd = Command::new("emacs");
|
||||||
|
let proc = cmd
|
||||||
|
.arg("-q")
|
||||||
|
.arg("--no-site-file")
|
||||||
|
.arg("--no-splash")
|
||||||
|
.arg("--batch")
|
||||||
|
.arg("--eval")
|
||||||
|
.arg(elisp_script);
|
||||||
|
|
||||||
|
let out = proc.output()?;
|
||||||
|
out.status.exit_ok()?;
|
||||||
|
Ok(String::from_utf8(out.stderr)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_org_mode_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||||
|
let elisp_script = r#"(progn
|
||||||
|
(org-mode)
|
||||||
|
(message "%s" (org-version nil t nil))
|
||||||
|
)"#;
|
||||||
|
let mut cmd = Command::new("emacs");
|
||||||
|
let proc = cmd
|
||||||
|
.arg("-q")
|
||||||
|
.arg("--no-site-file")
|
||||||
|
.arg("--no-splash")
|
||||||
|
.arg("--batch")
|
||||||
|
.arg("--eval")
|
||||||
|
.arg(elisp_script);
|
||||||
|
|
||||||
|
let out = proc.output()?;
|
||||||
|
out.status.exit_ok()?;
|
||||||
|
Ok(String::from_utf8(out.stderr)?)
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,6 +42,39 @@ pub fn assert_bounds<'s, S: Source<'s>>(
|
|||||||
emacs: &'s Token<'s>,
|
emacs: &'s Token<'s>,
|
||||||
rust: &'s S,
|
rust: &'s S,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let standard_properties = get_standard_properties(emacs)?;
|
||||||
|
let (begin, end) = (
|
||||||
|
standard_properties
|
||||||
|
.begin
|
||||||
|
.ok_or("Token should have a begin.")?,
|
||||||
|
standard_properties
|
||||||
|
.end
|
||||||
|
.ok_or("Token should have a begin.")?,
|
||||||
|
);
|
||||||
|
let (rust_begin, rust_end) = get_offsets(source, rust);
|
||||||
|
if (rust_begin + 1) != begin || (rust_end + 1) != end {
|
||||||
|
Err(format!("Rust bounds ({rust_begin}, {rust_end}) do not match emacs bounds ({emacs_begin}, {emacs_end})", rust_begin = rust_begin + 1, rust_end = rust_end + 1, emacs_begin=begin, emacs_end=end))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StandardProperties {
|
||||||
|
begin: Option<usize>,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
post_affiliated: Option<usize>,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
contents_begin: Option<usize>,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
contents_end: Option<usize>,
|
||||||
|
end: Option<usize>,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
post_blank: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_standard_properties<'s>(
|
||||||
|
emacs: &'s Token<'s>,
|
||||||
|
) -> Result<StandardProperties, Box<dyn std::error::Error>> {
|
||||||
let children = emacs.as_list()?;
|
let children = emacs.as_list()?;
|
||||||
let attributes_child = children
|
let attributes_child = children
|
||||||
.iter()
|
.iter()
|
||||||
@@ -49,34 +82,60 @@ pub fn assert_bounds<'s, S: Source<'s>>(
|
|||||||
.ok_or("Should have an attributes child.")?;
|
.ok_or("Should have an attributes child.")?;
|
||||||
let attributes_map = attributes_child.as_map()?;
|
let attributes_map = attributes_child.as_map()?;
|
||||||
let standard_properties = attributes_map.get(":standard-properties");
|
let standard_properties = attributes_map.get(":standard-properties");
|
||||||
let (begin, end) = if standard_properties.is_some() {
|
Ok(if standard_properties.is_some() {
|
||||||
let std_props = standard_properties
|
let mut std_props = standard_properties
|
||||||
.expect("if statement proves its Some")
|
.expect("if statement proves its Some")
|
||||||
.as_vector()?;
|
.as_vector()?
|
||||||
let begin = std_props
|
.into_iter();
|
||||||
.get(0)
|
let begin = maybe_token_to_usize(std_props.next())?;
|
||||||
.ok_or("Missing first element in standard properties")?
|
let post_affiliated = maybe_token_to_usize(std_props.next())?;
|
||||||
.as_atom()?;
|
let contents_begin = maybe_token_to_usize(std_props.next())?;
|
||||||
let end = std_props
|
let contents_end = maybe_token_to_usize(std_props.next())?;
|
||||||
.get(1)
|
let end = maybe_token_to_usize(std_props.next())?;
|
||||||
.ok_or("Missing first element in standard properties")?
|
let post_blank = maybe_token_to_usize(std_props.next())?;
|
||||||
.as_atom()?;
|
StandardProperties {
|
||||||
(begin, end)
|
begin,
|
||||||
|
post_affiliated,
|
||||||
|
contents_begin,
|
||||||
|
contents_end,
|
||||||
|
end,
|
||||||
|
post_blank,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let begin = attributes_map
|
let begin = maybe_token_to_usize(attributes_map.get(":begin").map(|token| *token))?;
|
||||||
.get(":begin")
|
let end = maybe_token_to_usize(attributes_map.get(":end").map(|token| *token))?;
|
||||||
.ok_or("Missing :begin attribute.")?
|
let contents_begin =
|
||||||
.as_atom()?;
|
maybe_token_to_usize(attributes_map.get(":contents-begin").map(|token| *token))?;
|
||||||
let end = attributes_map
|
let contents_end =
|
||||||
.get(":end")
|
maybe_token_to_usize(attributes_map.get(":contents-end").map(|token| *token))?;
|
||||||
.ok_or("Missing :end attribute.")?
|
let post_blank =
|
||||||
.as_atom()?;
|
maybe_token_to_usize(attributes_map.get(":post-blank").map(|token| *token))?;
|
||||||
(begin, end)
|
let post_affiliated =
|
||||||
};
|
maybe_token_to_usize(attributes_map.get(":post-affiliated").map(|token| *token))?;
|
||||||
let (rust_begin, rust_end) = get_offsets(source, rust);
|
StandardProperties {
|
||||||
if (rust_begin + 1).to_string() != begin || (rust_end + 1).to_string() != end {
|
begin,
|
||||||
Err(format!("Rust bounds ({rust_begin}, {rust_end}) do not match emacs bounds ({emacs_begin}, {emacs_end})", rust_begin = rust_begin + 1, rust_end = rust_end + 1, emacs_begin=begin, emacs_end=end))?;
|
post_affiliated,
|
||||||
}
|
contents_begin,
|
||||||
|
contents_end,
|
||||||
Ok(())
|
end,
|
||||||
|
post_blank,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maybe_token_to_usize(
|
||||||
|
token: Option<&Token<'_>>,
|
||||||
|
) -> Result<Option<usize>, Box<dyn std::error::Error>> {
|
||||||
|
Ok(token
|
||||||
|
.map(|token| token.as_atom())
|
||||||
|
.map_or(Ok(None), |r| r.map(Some))?
|
||||||
|
.map(|val| {
|
||||||
|
if val == "nil" {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(val.parse::<usize>())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.flatten() // Outer option is whether or not the param exists, inner option is whether or not it is nil
|
||||||
|
.map_or(Ok(None), |r| r.map(Some))?)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ mod compare;
|
|||||||
pub use compare::compare_document;
|
pub use compare::compare_document;
|
||||||
#[cfg(feature = "compare")]
|
#[cfg(feature = "compare")]
|
||||||
pub use compare::emacs_parse_org_document;
|
pub use compare::emacs_parse_org_document;
|
||||||
|
#[cfg(feature = "compare")]
|
||||||
|
pub use compare::get_emacs_version;
|
||||||
|
#[cfg(feature = "compare")]
|
||||||
|
pub use compare::get_org_mode_version;
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|||||||
18
src/main.rs
18
src/main.rs
@@ -7,6 +7,10 @@ use organic::compare_document;
|
|||||||
#[cfg(feature = "compare")]
|
#[cfg(feature = "compare")]
|
||||||
use organic::emacs_parse_org_document;
|
use organic::emacs_parse_org_document;
|
||||||
#[cfg(feature = "compare")]
|
#[cfg(feature = "compare")]
|
||||||
|
use organic::get_emacs_version;
|
||||||
|
#[cfg(feature = "compare")]
|
||||||
|
use organic::get_org_mode_version;
|
||||||
|
#[cfg(feature = "compare")]
|
||||||
use organic::parser::sexp::sexp_with_padding;
|
use organic::parser::sexp::sexp_with_padding;
|
||||||
|
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
@@ -49,10 +53,14 @@ fn read_stdin_to_string() -> Result<String, Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
#[cfg(feature = "compare")]
|
#[cfg(feature = "compare")]
|
||||||
fn run_compare<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std::error::Error>> {
|
fn run_compare<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let (remaining, rust_parsed) = document(org_contents.as_ref()).expect("Org Parse failure");
|
let emacs_version = get_emacs_version()?;
|
||||||
|
let org_mode_version = get_org_mode_version()?;
|
||||||
|
eprintln!("Using emacs version: {}", emacs_version.trim());
|
||||||
|
eprintln!("Using org-mode version: {}", org_mode_version.trim());
|
||||||
|
let (remaining, rust_parsed) = document(org_contents.as_ref()).map_err(|e| e.to_string())?;
|
||||||
let org_sexp = emacs_parse_org_document(org_contents.as_ref())?;
|
let org_sexp = emacs_parse_org_document(org_contents.as_ref())?;
|
||||||
let (_remaining, parsed_sexp) =
|
let (_remaining, parsed_sexp) =
|
||||||
sexp_with_padding(org_sexp.as_str()).expect("Sexp Parse failure");
|
sexp_with_padding(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
println!("{}\n\n\n", org_contents.as_ref());
|
println!("{}\n\n\n", org_contents.as_ref());
|
||||||
println!("{}", org_sexp);
|
println!("{}", org_sexp);
|
||||||
@@ -74,8 +82,10 @@ fn run_compare<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std::error:
|
|||||||
|
|
||||||
#[cfg(not(feature = "compare"))]
|
#[cfg(not(feature = "compare"))]
|
||||||
fn run_compare<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std::error::Error>> {
|
fn run_compare<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
eprintln!("This program was built with compare disabled. Dumping the AST from rust.");
|
eprintln!(
|
||||||
let (remaining, rust_parsed) = document(org_contents.as_ref()).expect("Org Parse failure");
|
"This program was built with compare disabled. Only parsing with organic, not comparing."
|
||||||
|
);
|
||||||
|
let (remaining, rust_parsed) = document(org_contents.as_ref()).map_err(|e| e.to_string())?;
|
||||||
println!("{:#?}", rust_parsed);
|
println!("{:#?}", rust_parsed);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ fn path_angle<'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &path_angle_end,
|
exit_matcher: &path_angle_end,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ fn path_angle<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn path_angle_end<'r, 's>(
|
fn path_angle_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
tag(">")(input)
|
tag(">")(input)
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ fn global_prefix<'r, 's>(
|
|||||||
depth: 0,
|
depth: 0,
|
||||||
}))
|
}))
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &global_prefix_end,
|
exit_matcher: &global_prefix_end,
|
||||||
}));
|
}));
|
||||||
let (remaining, (children, _exit_contents)) = verify(
|
let (remaining, (children, _exit_contents)) = verify(
|
||||||
@@ -151,7 +151,7 @@ fn global_suffix<'r, 's>(
|
|||||||
depth: 0,
|
depth: 0,
|
||||||
}))
|
}))
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &global_suffix_end,
|
exit_matcher: &global_suffix_end,
|
||||||
}));
|
}));
|
||||||
let (remaining, (children, _exit_contents)) = verify(
|
let (remaining, (children, _exit_contents)) = verify(
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ fn key_prefix<'r, 's>(
|
|||||||
depth: 0,
|
depth: 0,
|
||||||
}))
|
}))
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &key_prefix_end,
|
exit_matcher: &key_prefix_end,
|
||||||
}));
|
}));
|
||||||
let (remaining, (children, _exit_contents)) = verify(
|
let (remaining, (children, _exit_contents)) = verify(
|
||||||
@@ -101,7 +101,7 @@ fn key_suffix<'r, 's>(
|
|||||||
depth: 0,
|
depth: 0,
|
||||||
}))
|
}))
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &key_suffix_end,
|
exit_matcher: &key_suffix_end,
|
||||||
}));
|
}));
|
||||||
let (remaining, (children, _exit_contents)) = verify(
|
let (remaining, (children, _exit_contents)) = verify(
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub fn clock<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Clock<'s>> {
|
) -> Res<OrgSource<'s>, Clock<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _leading_whitespace) = space0(input)?;
|
let (remaining, _leading_whitespace) = space0(input)?;
|
||||||
let (remaining, _clock) = tag_no_case("clock:")(remaining)?;
|
let (remaining, _clock) = tag_no_case("clock:")(remaining)?;
|
||||||
let (remaining, _gap_whitespace) = space1(remaining)?;
|
let (remaining, _gap_whitespace) = space1(remaining)?;
|
||||||
@@ -45,7 +45,7 @@ pub fn clock<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn inactive_timestamp_range_duration<'r, 's>(
|
fn inactive_timestamp_range_duration<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(tuple((
|
recognize(tuple((
|
||||||
@@ -67,7 +67,7 @@ fn inactive_timestamp_range_duration<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn inactive_timestamp<'r, 's>(
|
fn inactive_timestamp<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(tuple((
|
recognize(tuple((
|
||||||
|
|||||||
@@ -52,10 +52,10 @@ pub fn comment<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn comment_line<'r, 's>(
|
fn comment_line<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _indent) = space0(input)?;
|
let (remaining, _indent) = space0(input)?;
|
||||||
let (remaining, (_hash, _leading_whitespace_and_content, _line_ending)) = tuple((
|
let (remaining, (_hash, _leading_whitespace_and_content, _line_ending)) = tuple((
|
||||||
tag("#"),
|
tag("#"),
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ use crate::parser::DiarySexp;
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn diary_sexp<'r, 's>(
|
pub fn diary_sexp<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, DiarySexp<'s>> {
|
) -> Res<OrgSource<'s>, DiarySexp<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _leading_whitespace) = space0(input)?;
|
let (remaining, _leading_whitespace) = space0(input)?;
|
||||||
let (remaining, _clock) = tag("%%")(remaining)?;
|
let (remaining, _clock) = tag("%%")(remaining)?;
|
||||||
let (remaining, _gap_whitespace) = space0(remaining)?;
|
let (remaining, _gap_whitespace) = space0(remaining)?;
|
||||||
|
|||||||
@@ -300,10 +300,9 @@ fn headline<'r, 's>(
|
|||||||
exit_matcher: &headline_end,
|
exit_matcher: &headline_end,
|
||||||
}));
|
}));
|
||||||
let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context);
|
let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context);
|
||||||
let start_of_line_matcher = parser_with_context!(start_of_line)(&parser_context);
|
|
||||||
|
|
||||||
let (remaining, (_sol, star_count, ws, title, _line_ending)) = tuple((
|
let (remaining, (_sol, star_count, ws, title, _line_ending)) = tuple((
|
||||||
start_of_line_matcher,
|
start_of_line,
|
||||||
many1_count(tag("*")),
|
many1_count(tag("*")),
|
||||||
space1,
|
space1,
|
||||||
many1(standard_set_object_matcher),
|
many1(standard_set_object_matcher),
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ pub fn drawer<'r, 's>(
|
|||||||
"Cannot nest objects of the same element".into(),
|
"Cannot nest objects of the same element".into(),
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _leading_whitespace) = space0(input)?;
|
let (remaining, _leading_whitespace) = space0(input)?;
|
||||||
let (remaining, (_open_colon, drawer_name, _close_colon, _new_line)) = tuple((
|
let (remaining, (_open_colon, drawer_name, _close_colon, _new_line)) = tuple((
|
||||||
tag(":"),
|
tag(":"),
|
||||||
@@ -99,10 +99,10 @@ fn name<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn drawer_end<'r, 's>(
|
fn drawer_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
recognize(tuple((
|
recognize(tuple((
|
||||||
space0,
|
space0,
|
||||||
tag_no_case(":end:"),
|
tag_no_case(":end:"),
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub fn dynamic_block<'r, 's>(
|
|||||||
"Cannot nest objects of the same element".into(),
|
"Cannot nest objects of the same element".into(),
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _leading_whitespace) = space0(input)?;
|
let (remaining, _leading_whitespace) = space0(input)?;
|
||||||
let (remaining, (_begin, name, parameters, _ws)) = tuple((
|
let (remaining, (_begin, name, parameters, _ws)) = tuple((
|
||||||
recognize(tuple((tag_no_case("#+begin:"), space1))),
|
recognize(tuple((tag_no_case("#+begin:"), space1))),
|
||||||
@@ -107,10 +107,10 @@ fn parameters<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn dynamic_block_end<'r, 's>(
|
fn dynamic_block_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, source) = recognize(tuple((
|
let (remaining, source) = recognize(tuple((
|
||||||
space0,
|
space0,
|
||||||
tag_no_case("#+end:"),
|
tag_no_case("#+end:"),
|
||||||
|
|||||||
@@ -21,16 +21,19 @@ use super::lesser_block::src_block;
|
|||||||
use super::lesser_block::verse_block;
|
use super::lesser_block::verse_block;
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
use super::paragraph::paragraph;
|
use super::paragraph::paragraph;
|
||||||
|
use super::plain_list::detect_plain_list;
|
||||||
use super::plain_list::plain_list;
|
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::CustomError;
|
||||||
|
use crate::error::MyError;
|
||||||
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;
|
||||||
|
|
||||||
pub fn element(
|
pub const fn element(
|
||||||
can_be_paragraph: bool,
|
can_be_paragraph: bool,
|
||||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, Element<'s>> {
|
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, Element<'s>> {
|
||||||
move |context: Context, input: OrgSource<'_>| _element(context, input, can_be_paragraph)
|
move |context: Context, input: OrgSource<'_>| _element(context, input, can_be_paragraph)
|
||||||
@@ -108,3 +111,26 @@ fn _element<'r, 's>(
|
|||||||
|
|
||||||
Ok((remaining, element))
|
Ok((remaining, element))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn detect_element(
|
||||||
|
can_be_paragraph: bool,
|
||||||
|
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
|
move |context: Context, input: OrgSource<'_>| _detect_element(context, input, can_be_paragraph)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
fn _detect_element<'r, 's>(
|
||||||
|
context: Context<'r, 's>,
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
can_be_paragraph: bool,
|
||||||
|
) -> Res<OrgSource<'s>, ()> {
|
||||||
|
if detect_plain_list(context, input).is_ok() {
|
||||||
|
return Ok((input, ()));
|
||||||
|
}
|
||||||
|
if _element(context, input, can_be_paragraph).is_ok() {
|
||||||
|
return Ok((input, ()));
|
||||||
|
}
|
||||||
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
|
"No element detected.".into(),
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub fn entity<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn name<'r, 's>(
|
fn name<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
// TODO: This should be defined by org-entities and optionally org-entities-user
|
// TODO: This should be defined by org-entities and optionally org-entities-user
|
||||||
@@ -50,7 +50,7 @@ fn name<'r, 's>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn entity_end<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
fn entity_end<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
let (remaining, _) = alt((eof, recognize(satisfy(|c| !c.is_alphabetic()))))(input)?;
|
let (remaining, _) = alt((eof, recognize(satisfy(|c| !c.is_alphabetic()))))(input)?;
|
||||||
|
|
||||||
Ok((remaining, ()))
|
Ok((remaining, ()))
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ pub enum ExitClass {
|
|||||||
|
|
||||||
/// Elements who cede priority to alpha elements when matching.
|
/// Elements who cede priority to alpha elements when matching.
|
||||||
Beta = 300,
|
Beta = 300,
|
||||||
|
|
||||||
|
/// Elements who cede priority to alpha and beta elements when matching.
|
||||||
|
Gamma = 4000,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for ExitClass {
|
impl std::fmt::Display for ExitClass {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ pub fn export_snippet<'r, 's>(
|
|||||||
let (remaining, backend_name) = backend(context, remaining)?;
|
let (remaining, backend_name) = backend(context, remaining)?;
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &export_snippet_end,
|
exit_matcher: &export_snippet_end,
|
||||||
}));
|
}));
|
||||||
let (remaining, backend_contents) = opt(tuple((
|
let (remaining, backend_contents) = opt(tuple((
|
||||||
@@ -48,7 +48,7 @@ pub fn export_snippet<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn backend<'r, 's>(
|
fn backend<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let (remaining, backend_name) =
|
let (remaining, backend_name) =
|
||||||
@@ -71,7 +71,7 @@ fn contents<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn export_snippet_end<'r, 's>(
|
fn export_snippet_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
tag("@@")(input)
|
tag("@@")(input)
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ pub fn fixed_width_area<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn fixed_width_area_line<'r, 's>(
|
fn fixed_width_area_line<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _indent) = space0(input)?;
|
let (remaining, _indent) = space0(input)?;
|
||||||
let (remaining, (_hash, _leading_whitespace_and_content, _line_ending)) = tuple((
|
let (remaining, (_hash, _leading_whitespace_and_content, _line_ending)) = tuple((
|
||||||
tag(":"),
|
tag(":"),
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub fn footnote_definition<'r, 's>(
|
|||||||
"Cannot nest objects of the same element".into(),
|
"Cannot nest objects of the same element".into(),
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
// Cannot be indented.
|
// Cannot be indented.
|
||||||
let (remaining, (_lead_in, lbl, _lead_out, _ws)) =
|
let (remaining, (_lead_in, lbl, _lead_out, _ws)) =
|
||||||
tuple((tag_no_case("[fn:"), label, tag("]"), space0))(input)?;
|
tuple((tag_no_case("[fn:"), label, tag("]"), space0))(input)?;
|
||||||
@@ -80,7 +80,6 @@ fn footnote_definition_end<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let start_of_line_matcher = parser_with_context!(start_of_line)(context);
|
|
||||||
let allow_nesting_context =
|
let allow_nesting_context =
|
||||||
context.with_additional_node(ContextElement::Context("allow nesting footnotes"));
|
context.with_additional_node(ContextElement::Context("allow nesting footnotes"));
|
||||||
let footnote_definition_matcher = parser_with_context!(footnote_definition)(
|
let footnote_definition_matcher = parser_with_context!(footnote_definition)(
|
||||||
@@ -98,7 +97,7 @@ fn footnote_definition_end<'r, 's>(
|
|||||||
footnote_definition_matcher,
|
footnote_definition_matcher,
|
||||||
))),
|
))),
|
||||||
recognize(tuple((
|
recognize(tuple((
|
||||||
start_of_line_matcher,
|
start_of_line,
|
||||||
verify(many1(blank_line), |lines: &Vec<OrgSource<'_>>| {
|
verify(many1(blank_line), |lines: &Vec<OrgSource<'_>>| {
|
||||||
lines.len() >= 2
|
lines.len() >= 2
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ 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::FootnoteReference;
|
use crate::parser::FootnoteReference;
|
||||||
use crate::parser::Object;
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn footnote_reference<'r, 's>(
|
pub fn footnote_reference<'r, 's>(
|
||||||
@@ -116,7 +115,7 @@ fn inline_footnote<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn footnote_reference_only<'r, 's>(
|
fn footnote_reference_only<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, FootnoteReference<'s>> {
|
) -> Res<OrgSource<'s>, FootnoteReference<'s>> {
|
||||||
let (remaining, _) = tag_no_case("[fn:")(input)?;
|
let (remaining, _) = tag_no_case("[fn:")(input)?;
|
||||||
@@ -134,11 +133,6 @@ fn footnote_reference_only<'r, 's>(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
fn definition<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Vec<Object<'s>>> {
|
|
||||||
Ok((input, vec![]))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn footnote_definition_end<'r, 's>(
|
fn footnote_definition_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ pub fn greater_block<'r, 's>(
|
|||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, GreaterBlock<'s>> {
|
) -> Res<OrgSource<'s>, GreaterBlock<'s>> {
|
||||||
// TODO: Do I need to differentiate between different greater block types.
|
// TODO: Do I need to differentiate between different greater block types.
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _leading_whitespace) = space0(input)?;
|
let (remaining, _leading_whitespace) = space0(input)?;
|
||||||
let (remaining, (_begin, name)) = tuple((
|
let (remaining, (_begin, name)) = tuple((
|
||||||
tag_no_case("#+begin_"),
|
tag_no_case("#+begin_"),
|
||||||
@@ -125,7 +125,7 @@ fn greater_block_end<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let current_name: &str = get_context_greater_block_name(context).ok_or(nom::Err::Error(
|
let current_name: &str = get_context_greater_block_name(context).ok_or(nom::Err::Error(
|
||||||
CustomError::MyError(MyError("Not inside a greater block".into())),
|
CustomError::MyError(MyError("Not inside a greater block".into())),
|
||||||
))?;
|
))?;
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ use crate::parser::HorizontalRule;
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn horizontal_rule<'r, 's>(
|
pub fn horizontal_rule<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, HorizontalRule<'s>> {
|
) -> Res<OrgSource<'s>, HorizontalRule<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, rule) = recognize(tuple((
|
let (remaining, rule) = recognize(tuple((
|
||||||
space0,
|
space0,
|
||||||
verify(many1_count(tag("-")), |dashes| *dashes >= 5),
|
verify(many1_count(tag("-")), |dashes| *dashes >= 5),
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ fn name<'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &name_end,
|
exit_matcher: &name_end,
|
||||||
}));
|
}));
|
||||||
let (remaining, name) = recognize(many_till(
|
let (remaining, name) = recognize(many_till(
|
||||||
@@ -61,7 +61,7 @@ fn name<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn name_end<'r, 's>(
|
fn name_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(one_of("[("))(input)
|
recognize(one_of("[("))(input)
|
||||||
@@ -80,7 +80,7 @@ fn header<'r, 's>(
|
|||||||
depth: 0,
|
depth: 0,
|
||||||
}))
|
}))
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &header_end,
|
exit_matcher: &header_end,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ fn argument<'r, 's>(
|
|||||||
depth: 0,
|
depth: 0,
|
||||||
}))
|
}))
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &argument_end,
|
exit_matcher: &argument_end,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ fn lang<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn lang_end<'r, 's>(
|
fn lang_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(one_of("[{"))(input)
|
recognize(one_of("[{"))(input)
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ use crate::parser::Keyword;
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn keyword<'r, 's>(
|
pub fn keyword<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Keyword<'s>> {
|
) -> Res<OrgSource<'s>, Keyword<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
// TODO: When key is a member of org-element-parsed-keywords, value can contain the standard set objects, excluding footnote references.
|
// TODO: When key is a member of org-element-parsed-keywords, value can contain the standard set objects, excluding footnote references.
|
||||||
let (remaining, rule) = recognize(tuple((
|
let (remaining, rule) = recognize(tuple((
|
||||||
space0,
|
space0,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ pub fn latex_environment<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, LatexEnvironment<'s>> {
|
) -> Res<OrgSource<'s>, LatexEnvironment<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _leading_whitespace) = space0(input)?;
|
let (remaining, _leading_whitespace) = space0(input)?;
|
||||||
let (remaining, (_opening, name, _open_close_brace, _ws, _line_ending)) = tuple((
|
let (remaining, (_opening, name, _open_close_brace, _ws, _line_ending)) = tuple((
|
||||||
tag_no_case(r#"\begin{"#),
|
tag_no_case(r#"\begin{"#),
|
||||||
@@ -97,11 +97,11 @@ fn latex_environment_end(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn _latex_environment_end<'r, 's, 'x>(
|
fn _latex_environment_end<'r, 's, 'x>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
current_name_lower: &'x str,
|
current_name_lower: &'x str,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _leading_whitespace) = space0(input)?;
|
let (remaining, _leading_whitespace) = space0(input)?;
|
||||||
let (remaining, (_begin, _name, _close_brace, _ws, _line_ending)) = tuple((
|
let (remaining, (_begin, _name, _close_brace, _ws, _line_ending)) = tuple((
|
||||||
tag_no_case(r#"\end{"#),
|
tag_no_case(r#"\end{"#),
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ fn raw_latex_fragment<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn name<'r, 's>(
|
fn name<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
alpha1(input)
|
alpha1(input)
|
||||||
@@ -173,7 +173,7 @@ fn dollar_char_fragment<'r, 's>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn pre<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
pub fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
let preceding_character = input.get_preceding_character();
|
let preceding_character = input.get_preceding_character();
|
||||||
if let Some('$') = preceding_character {
|
if let Some('$') = preceding_character {
|
||||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
@@ -184,7 +184,7 @@ pub fn pre<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSou
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn post<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
pub fn post<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
// TODO: What about eof? Test to find out.
|
// TODO: What about eof? Test to find out.
|
||||||
|
|
||||||
// TODO: Figure out which punctuation characters should be included.
|
// TODO: Figure out which punctuation characters should be included.
|
||||||
@@ -224,7 +224,7 @@ fn bordered_dollar_fragment<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn open_border<'r, 's>(
|
pub fn open_border<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(verify(none_of(".,;$"), |c| !c.is_whitespace()))(input)
|
recognize(verify(none_of(".,;$"), |c| !c.is_whitespace()))(input)
|
||||||
@@ -232,7 +232,7 @@ pub fn open_border<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn close_border<'r, 's>(
|
pub fn close_border<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, ()> {
|
) -> Res<OrgSource<'s>, ()> {
|
||||||
let preceding_character = input.get_preceding_character();
|
let preceding_character = input.get_preceding_character();
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ pub fn example_block<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, ExampleBlock<'s>> {
|
) -> Res<OrgSource<'s>, ExampleBlock<'s>> {
|
||||||
let (remaining, name) = lesser_block_begin("example")(context, input)?;
|
let (remaining, _name) = lesser_block_begin("example")(context, input)?;
|
||||||
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
|
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
|
||||||
let (remaining, _nl) = line_ending(remaining)?;
|
let (remaining, _nl) = line_ending(remaining)?;
|
||||||
let lesser_block_end_specialized = lesser_block_end("example");
|
let lesser_block_end_specialized = lesser_block_end("example");
|
||||||
@@ -250,11 +250,11 @@ fn lesser_block_end(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn _lesser_block_end<'r, 's, 'x>(
|
fn _lesser_block_end<'r, 's, 'x>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
current_name_lower: &'x str,
|
current_name_lower: &'x str,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _leading_whitespace) = space0(input)?;
|
let (remaining, _leading_whitespace) = space0(input)?;
|
||||||
let (remaining, (_begin, _name, _ws)) = tuple((
|
let (remaining, (_begin, _name, _ws)) = tuple((
|
||||||
tag_no_case("#+end_"),
|
tag_no_case("#+end_"),
|
||||||
@@ -265,22 +265,23 @@ fn _lesser_block_end<'r, 's, 'x>(
|
|||||||
Ok((remaining, source))
|
Ok((remaining, source))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lesser_block_begin(
|
/// Parser for the beginning of a lesser block
|
||||||
current_name: &str,
|
///
|
||||||
|
/// current_name MUST be lowercase. We do not do the conversion ourselves because it is not allowed in a const fn.
|
||||||
|
const fn lesser_block_begin(
|
||||||
|
current_name: &'static str,
|
||||||
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let current_name_lower = current_name.to_lowercase();
|
// TODO: Since this is a const fn, is there ANY way to "generate" functions at compile time?
|
||||||
move |context: Context, input: OrgSource<'_>| {
|
move |context: Context, input: OrgSource<'_>| _lesser_block_begin(context, input, current_name)
|
||||||
_lesser_block_begin(context, input, current_name_lower.as_str())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn _lesser_block_begin<'r, 's, 'x>(
|
fn _lesser_block_begin<'r, 's, 'x>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
current_name_lower: &'x str,
|
current_name_lower: &'x str,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _leading_whitespace) = space0(input)?;
|
let (remaining, _leading_whitespace) = space0(input)?;
|
||||||
let (remaining, (_begin, name)) = tuple((
|
let (remaining, (_begin, name)) = tuple((
|
||||||
tag_no_case("#+begin_"),
|
tag_no_case("#+begin_"),
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ pub fn line_break<'r, 's>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn pre<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
let preceding_character = input.get_preceding_character();
|
let preceding_character = input.get_preceding_character();
|
||||||
match preceding_character {
|
match preceding_character {
|
||||||
// If None, we are at the start of the file
|
// If None, we are at the start of the file
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::combinator::map;
|
use nom::combinator::map;
|
||||||
use nom::combinator::not;
|
|
||||||
|
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
use super::parser_with_context::parser_with_context;
|
use super::parser_with_context::parser_with_context;
|
||||||
@@ -34,8 +33,6 @@ pub fn standard_set_object<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||||
not(|i| context.check_exit_matcher(i))(input)?;
|
|
||||||
|
|
||||||
alt((
|
alt((
|
||||||
map(parser_with_context!(timestamp)(context), Object::Timestamp),
|
map(parser_with_context!(timestamp)(context), Object::Timestamp),
|
||||||
map(parser_with_context!(subscript)(context), Object::Subscript),
|
map(parser_with_context!(subscript)(context), Object::Subscript),
|
||||||
@@ -93,8 +90,6 @@ pub fn minimal_set_object<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||||
not(|i| context.check_exit_matcher(i))(input)?;
|
|
||||||
|
|
||||||
alt((
|
alt((
|
||||||
map(parser_with_context!(subscript)(context), Object::Subscript),
|
map(parser_with_context!(subscript)(context), Object::Subscript),
|
||||||
map(
|
map(
|
||||||
@@ -116,7 +111,6 @@ pub fn any_object_except_plain_text<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Object<'s>> {
|
) -> Res<OrgSource<'s>, Object<'s>> {
|
||||||
// Used for exit matchers so this does not check exit matcher condition.
|
|
||||||
alt((
|
alt((
|
||||||
map(parser_with_context!(timestamp)(context), Object::Timestamp),
|
map(parser_with_context!(timestamp)(context), Object::Timestamp),
|
||||||
map(parser_with_context!(subscript)(context), Object::Subscript),
|
map(parser_with_context!(subscript)(context), Object::Subscript),
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub fn org_macro<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn org_macro_name<'r, 's>(
|
fn org_macro_name<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let (remaining, _) = verify(anychar, |c| c.is_alphabetic())(input)?;
|
let (remaining, _) = verify(anychar, |c| c.is_alphabetic())(input)?;
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ impl<'s> OrgSource<'s> {
|
|||||||
pub fn is_at_start_of_line(&self) -> bool {
|
pub fn is_at_start_of_line(&self) -> bool {
|
||||||
self.start == self.start_of_line
|
self.start == self.start_of_line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_until(&self, other: OrgSource<'s>) -> OrgSource<'s> {
|
||||||
|
assert!(other.start >= self.start);
|
||||||
|
assert!(other.end <= self.end);
|
||||||
|
self.slice(..(other.start - self.start))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> InputTake for OrgSource<'s> {
|
impl<'s> InputTake for OrgSource<'s> {
|
||||||
@@ -118,7 +124,6 @@ where
|
|||||||
.map(|idx| self.start + idx + 1)
|
.map(|idx| self.start + idx + 1)
|
||||||
.unwrap_or(self.start_of_line);
|
.unwrap_or(self.start_of_line);
|
||||||
|
|
||||||
// TODO: calculate updated values for WrappedInput
|
|
||||||
OrgSource {
|
OrgSource {
|
||||||
full_source: self.full_source,
|
full_source: self.full_source,
|
||||||
start: new_start,
|
start: new_start,
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ use nom::multi::many1;
|
|||||||
use nom::multi::many_till;
|
use nom::multi::many_till;
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
|
||||||
|
use super::element_parser::detect_element;
|
||||||
use super::lesser_element::Paragraph;
|
use super::lesser_element::Paragraph;
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
use super::util::blank_line;
|
use super::util::blank_line;
|
||||||
use super::util::get_consumed;
|
use super::util::get_consumed;
|
||||||
use super::Context;
|
use super::Context;
|
||||||
use crate::error::Res;
|
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;
|
||||||
@@ -28,7 +28,7 @@ pub fn paragraph<'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, Paragraph<'s>> {
|
) -> Res<OrgSource<'s>, Paragraph<'s>> {
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: ¶graph_end,
|
exit_matcher: ¶graph_end,
|
||||||
}));
|
}));
|
||||||
let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context);
|
let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context);
|
||||||
@@ -57,10 +57,9 @@ fn paragraph_end<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let non_paragraph_element_matcher = parser_with_context!(element(false))(context);
|
let non_paragraph_element_matcher = parser_with_context!(detect_element(false))(context);
|
||||||
let start_of_line_matcher = parser_with_context!(start_of_line)(&context);
|
|
||||||
alt((
|
alt((
|
||||||
recognize(tuple((start_of_line_matcher, many1(blank_line)))),
|
recognize(tuple((start_of_line, many1(blank_line)))),
|
||||||
recognize(non_paragraph_element_matcher),
|
recognize(non_paragraph_element_matcher),
|
||||||
eof,
|
eof,
|
||||||
))(input)
|
))(input)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ impl<'r, 's> ContextTree<'r, 's> {
|
|||||||
// exit_matcher: ChainBehavior::IgnoreParent(Some(&always_fail)),
|
// exit_matcher: ChainBehavior::IgnoreParent(Some(&always_fail)),
|
||||||
// }));
|
// }));
|
||||||
|
|
||||||
let mut current_class_filter = ExitClass::Beta;
|
let mut current_class_filter = ExitClass::Gamma;
|
||||||
for current_node in self.iter() {
|
for current_node in self.iter() {
|
||||||
let context_element = current_node.get_data();
|
let context_element = current_node.get_data();
|
||||||
match context_element {
|
match context_element {
|
||||||
@@ -112,9 +112,6 @@ pub enum ContextElement<'r, 's> {
|
|||||||
ExitMatcherNode(ExitMatcherNode<'r>),
|
ExitMatcherNode(ExitMatcherNode<'r>),
|
||||||
Context(&'r str),
|
Context(&'r str),
|
||||||
|
|
||||||
/// Stores the indentation level of the current list item.
|
|
||||||
ListItem(usize),
|
|
||||||
|
|
||||||
/// Stores the name of the greater block.
|
/// Stores the name of the greater block.
|
||||||
GreaterBlock(&'s str),
|
GreaterBlock(&'s str),
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ pub fn plain_link<'r, 's>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn pre<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
let preceding_character = input.get_preceding_character();
|
let preceding_character = input.get_preceding_character();
|
||||||
match preceding_character {
|
match preceding_character {
|
||||||
// If None, we are at the start of the file which is fine
|
// If None, we are at the start of the file which is fine
|
||||||
@@ -62,14 +62,14 @@ fn pre<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn post<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
fn post<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
let (remaining, _) = alt((eof, recognize(none_of(WORD_CONSTITUENT_CHARACTERS))))(input)?;
|
let (remaining, _) = alt((eof, recognize(none_of(WORD_CONSTITUENT_CHARACTERS))))(input)?;
|
||||||
Ok((remaining, ()))
|
Ok((remaining, ()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn protocol<'r, 's>(
|
pub fn protocol<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
// TODO: This should be defined by org-link-parameters
|
// TODO: This should be defined by org-link-parameters
|
||||||
@@ -113,7 +113,7 @@ fn path_plain<'r, 's>(
|
|||||||
// TODO: "optionally containing parenthesis-wrapped non-whitespace non-bracket substrings up to a depth of two. The string must end with either a non-punctation non-whitespace character, a forwards slash, or a parenthesis-wrapped substring"
|
// TODO: "optionally containing parenthesis-wrapped non-whitespace non-bracket substrings up to a depth of two. The string must end with either a non-punctation non-whitespace character, a forwards slash, or a parenthesis-wrapped substring"
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &path_plain_end,
|
exit_matcher: &path_plain_end,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ fn path_plain<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn path_plain_end<'r, 's>(
|
fn path_plain_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(one_of(" \t\r\n()[]<>"))(input)
|
recognize(one_of(" \t\r\n()[]<>"))(input)
|
||||||
|
|||||||
@@ -32,6 +32,27 @@ use crate::parser::util::get_consumed;
|
|||||||
use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||||
use crate::parser::util::start_of_line;
|
use crate::parser::util::start_of_line;
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
pub fn detect_plain_list<'r, 's>(
|
||||||
|
_context: Context<'r, 's>,
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, ()> {
|
||||||
|
// TODO: Add support for plain list items that do not have content on the first line.
|
||||||
|
if verify(
|
||||||
|
tuple((start_of_line, space0, bullet, space1)),
|
||||||
|
|(_start, indent, bull, _after_whitespace)| {
|
||||||
|
Into::<&str>::into(bull) != "*" || indent.len() > 0
|
||||||
|
},
|
||||||
|
)(input)
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
return Ok((input, ()));
|
||||||
|
}
|
||||||
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
|
"No element detected.".into(),
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn plain_list<'r, 's>(
|
pub fn plain_list<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
@@ -90,9 +111,6 @@ pub fn plain_list<'r, 's>(
|
|||||||
parser_with_context!(plain_list_item)(&final_item_context)(final_child_start)?;
|
parser_with_context!(plain_list_item)(&final_item_context)(final_child_start)?;
|
||||||
children.push((final_child_start, reparsed_final_item));
|
children.push((final_child_start, reparsed_final_item));
|
||||||
|
|
||||||
let (remaining, _trailing_ws) =
|
|
||||||
maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?;
|
|
||||||
|
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
@@ -108,7 +126,7 @@ pub fn plain_list_item<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, PlainListItem<'s>> {
|
) -> Res<OrgSource<'s>, PlainListItem<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, leading_whitespace) = space0(input)?;
|
let (remaining, leading_whitespace) = space0(input)?;
|
||||||
// It is fine that we get the indent level using the number of bytes rather than the number of characters because nom's space0 only matches space and tab (0x20 and 0x09)
|
// It is fine that we get the indent level using the number of bytes rather than the number of characters because nom's space0 only matches space and tab (0x20 and 0x09)
|
||||||
let indent_level = leading_whitespace.len();
|
let indent_level = leading_whitespace.len();
|
||||||
@@ -116,6 +134,7 @@ pub fn plain_list_item<'r, 's>(
|
|||||||
Into::<&str>::into(bull) != "*" || indent_level > 0
|
Into::<&str>::into(bull) != "*" || indent_level > 0
|
||||||
})(remaining)?;
|
})(remaining)?;
|
||||||
|
|
||||||
|
// TODO: This isn't taking into account items that immediately line break and then have contents
|
||||||
let maybe_contentless_item: Res<OrgSource<'_>, OrgSource<'_>> =
|
let maybe_contentless_item: Res<OrgSource<'_>, OrgSource<'_>> =
|
||||||
alt((eof, line_ending))(remaining);
|
alt((eof, line_ending))(remaining);
|
||||||
match maybe_contentless_item {
|
match maybe_contentless_item {
|
||||||
@@ -135,12 +154,12 @@ pub fn plain_list_item<'r, 's>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (remaining, _ws) = space1(remaining)?;
|
let (remaining, _ws) = space1(remaining)?;
|
||||||
|
let exit_matcher = plain_list_item_end(indent_level);
|
||||||
let parser_context = context
|
let parser_context = context
|
||||||
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
|
||||||
.with_additional_node(ContextElement::ListItem(indent_level))
|
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Beta,
|
||||||
exit_matcher: &plain_list_item_end,
|
exit_matcher: &exit_matcher,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let (remaining, (children, _exit_contents)) = verify(
|
let (remaining, (children, _exit_contents)) = verify(
|
||||||
@@ -183,59 +202,66 @@ fn counter<'s>(i: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn plain_list_end<'r, 's>(
|
fn plain_list_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let start_of_line_matcher = parser_with_context!(start_of_line)(context);
|
|
||||||
recognize(tuple((
|
recognize(tuple((
|
||||||
start_of_line_matcher,
|
start_of_line,
|
||||||
verify(many1(blank_line), |lines: &Vec<OrgSource<'_>>| {
|
verify(many1(blank_line), |lines: &Vec<OrgSource<'_>>| {
|
||||||
lines.len() >= 2
|
lines.len() >= 2
|
||||||
}),
|
}),
|
||||||
)))(input)
|
)))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
const fn plain_list_item_end(
|
||||||
fn plain_list_item_end<'r, 's>(
|
indent_level: usize,
|
||||||
|
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
|
let line_indented_lte_matcher = line_indented_lte(indent_level);
|
||||||
|
move |context: Context, input: OrgSource<'_>| {
|
||||||
|
_plain_list_item_end(context, input, &line_indented_lte_matcher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "tracing",
|
||||||
|
tracing::instrument(ret, level = "debug", skip(line_indented_lte_matcher))
|
||||||
|
)]
|
||||||
|
fn _plain_list_item_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
|
line_indented_lte_matcher: impl for<'rr, 'ss> Fn(
|
||||||
|
Context<'rr, 'ss>,
|
||||||
|
OrgSource<'ss>,
|
||||||
|
) -> Res<OrgSource<'ss>, OrgSource<'ss>>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
recognize(tuple((
|
recognize(tuple((
|
||||||
opt(blank_line),
|
opt(blank_line),
|
||||||
parser_with_context!(line_indented_lte)(context),
|
parser_with_context!(line_indented_lte_matcher)(context),
|
||||||
)))(input)
|
)))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
const fn line_indented_lte(
|
||||||
fn line_indented_lte<'r, 's>(
|
indent_level: usize,
|
||||||
context: Context<'r, 's>,
|
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
input: OrgSource<'s>,
|
move |context: Context, input: OrgSource<'_>| _line_indented_lte(context, input, indent_level)
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
}
|
||||||
let current_item_indent_level: &usize =
|
|
||||||
get_context_item_indent(context).ok_or(nom::Err::Error(CustomError::MyError(MyError(
|
|
||||||
"Not inside a plain list item".into(),
|
|
||||||
))))?;
|
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
fn _line_indented_lte<'r, 's>(
|
||||||
|
_context: Context<'r, 's>,
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
indent_level: usize,
|
||||||
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let matched = recognize(verify(
|
let matched = recognize(verify(
|
||||||
tuple((space0::<OrgSource<'_>, _>, non_whitespace_character)),
|
tuple((space0::<OrgSource<'_>, _>, non_whitespace_character)),
|
||||||
// It is fine that we get the indent level using the number of bytes rather than the number of characters because nom's space0 only matches space and tab (0x20 and 0x09)
|
// It is fine that we get the indent level using the number of bytes rather than the number of characters because nom's space0 only matches space and tab (0x20 and 0x09)
|
||||||
|(_space0, _anychar)| _space0.len() <= *current_item_indent_level,
|
|(_space0, _anychar)| _space0.len() <= indent_level,
|
||||||
))(input)?;
|
))(input)?;
|
||||||
|
|
||||||
Ok(matched)
|
Ok(matched)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_context_item_indent<'r, 's>(context: Context<'r, 's>) -> Option<&'r usize> {
|
|
||||||
for thing in context.iter() {
|
|
||||||
match thing.get_data() {
|
|
||||||
ContextElement::ListItem(depth) => return Some(depth),
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ use crate::parser::util::start_of_line;
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn planning<'r, 's>(
|
pub fn planning<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Planning<'s>> {
|
) -> Res<OrgSource<'s>, Planning<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _leading_whitespace) = space0(input)?;
|
let (remaining, _leading_whitespace) = space0(input)?;
|
||||||
let (remaining, _planning_parameters) = separated_list1(space1, planning_parameter)(remaining)?;
|
let (remaining, _planning_parameters) = separated_list1(space1, planning_parameter)(remaining)?;
|
||||||
let (remaining, _trailing_ws) = tuple((space0, alt((line_ending, eof))))(remaining)?;
|
let (remaining, _trailing_ws) = tuple((space0, alt((line_ending, eof))))(remaining)?;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ pub fn property_drawer<'r, 's>(
|
|||||||
remaining,
|
remaining,
|
||||||
(_start_of_line, _leading_whitespace, _open_tag, _trailing_whitespace, _line_ending),
|
(_start_of_line, _leading_whitespace, _open_tag, _trailing_whitespace, _line_ending),
|
||||||
) = tuple((
|
) = tuple((
|
||||||
parser_with_context!(start_of_line)(context),
|
start_of_line,
|
||||||
space0,
|
space0,
|
||||||
tag_no_case(":PROPERTIES:"),
|
tag_no_case(":PROPERTIES:"),
|
||||||
space0,
|
space0,
|
||||||
@@ -80,11 +80,11 @@ pub fn property_drawer<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn property_drawer_end<'r, 's>(
|
fn property_drawer_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(tuple((
|
recognize(tuple((
|
||||||
parser_with_context!(start_of_line)(context),
|
start_of_line,
|
||||||
space0,
|
space0,
|
||||||
tag_no_case(":end:"),
|
tag_no_case(":end:"),
|
||||||
space0,
|
space0,
|
||||||
@@ -99,7 +99,7 @@ fn node_property<'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, NodeProperty<'s>> {
|
) -> Res<OrgSource<'s>, NodeProperty<'s>> {
|
||||||
let (remaining, (_start_of_line, _leading_whitespace, _open_colon, _name, _close_colon)) =
|
let (remaining, (_start_of_line, _leading_whitespace, _open_colon, _name, _close_colon)) =
|
||||||
tuple((
|
tuple((
|
||||||
parser_with_context!(start_of_line)(context),
|
start_of_line,
|
||||||
space0,
|
space0,
|
||||||
tag(":"),
|
tag(":"),
|
||||||
parser_with_context!(node_property_name)(context),
|
parser_with_context!(node_property_name)(context),
|
||||||
@@ -157,7 +157,7 @@ fn node_property_name<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn node_property_name_end<'r, 's>(
|
fn node_property_name_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
alt((tag("+:"), tag(":")))(input)
|
alt((tag("+:"), tag(":")))(input)
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ pub fn radio_target<'r, 's>(
|
|||||||
let (remaining, _opening) = tag("<<<")(input)?;
|
let (remaining, _opening) = tag("<<<")(input)?;
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &radio_target_end,
|
exit_matcher: &radio_target_end,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ pub fn radio_target<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn radio_target_end<'r, 's>(
|
fn radio_target_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
alt((tag("<"), tag(">"), line_ending))(input)
|
alt((tag("<"), tag(">"), line_ending))(input)
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ pub fn regular_link_with_description<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn pathreg<'r, 's>(
|
pub fn pathreg<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let (remaining, path) = escaped(
|
let (remaining, path) = escaped(
|
||||||
@@ -108,7 +108,7 @@ pub fn description<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn description_end<'r, 's>(
|
fn description_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
tag("]]")(input)
|
tag("]]")(input)
|
||||||
|
|||||||
@@ -137,7 +137,9 @@ impl<'s> Token<'s> {
|
|||||||
pub fn sexp_with_padding<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
pub fn sexp_with_padding<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
|
||||||
let (remaining, _) = multispace0(input)?;
|
let (remaining, _) = multispace0(input)?;
|
||||||
let remaining = OrgSource::new(remaining);
|
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))
|
||||||
|
.map_err(convert_error)?;
|
||||||
let (remaining, _) = multispace0(remaining)?;
|
let (remaining, _) = multispace0(remaining)?;
|
||||||
Ok((remaining, tkn))
|
Ok((remaining, tkn))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ pub fn statistics_cookie<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn percent_statistics_cookie<'r, 's>(
|
pub fn percent_statistics_cookie<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, StatisticsCookie<'s>> {
|
) -> Res<OrgSource<'s>, StatisticsCookie<'s>> {
|
||||||
let (remaining, source) =
|
let (remaining, source) =
|
||||||
@@ -39,7 +39,7 @@ pub fn percent_statistics_cookie<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn fraction_statistics_cookie<'r, 's>(
|
pub fn fraction_statistics_cookie<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, StatisticsCookie<'s>> {
|
) -> Res<OrgSource<'s>, StatisticsCookie<'s>> {
|
||||||
let (remaining, source) = recognize(tuple((
|
let (remaining, source) = recognize(tuple((
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ pub fn superscript<'r, 's>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn pre<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
let preceding_character = input.get_preceding_character();
|
let preceding_character = input.get_preceding_character();
|
||||||
match preceding_character {
|
match preceding_character {
|
||||||
Some(c) if !c.is_whitespace() => {}
|
Some(c) if !c.is_whitespace() => {}
|
||||||
@@ -106,7 +106,7 @@ fn script_body<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn script_asterisk<'r, 's>(
|
fn script_asterisk<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
tag("*")(input)
|
tag("*")(input)
|
||||||
@@ -128,7 +128,7 @@ fn script_alphanum<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn script_alphanum_character<'r, 's>(
|
fn script_alphanum_character<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(verify(anychar, |c| {
|
recognize(verify(anychar, |c| {
|
||||||
@@ -162,7 +162,7 @@ fn script_with_braces<'r, 's>(
|
|||||||
},
|
},
|
||||||
))
|
))
|
||||||
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &script_with_braces_end,
|
exit_matcher: &script_with_braces_end,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub fn org_mode_table<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Table<'s>> {
|
) -> Res<OrgSource<'s>, Table<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
peek(tuple((space0, tag("|"))))(input)?;
|
peek(tuple((space0, tag("|"))))(input)?;
|
||||||
|
|
||||||
let parser_context = context
|
let parser_context = context
|
||||||
@@ -67,10 +67,10 @@ pub fn org_mode_table<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn table_end<'r, 's>(
|
fn table_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
recognize(tuple((space0, not(tag("|")))))(input)
|
recognize(tuple((space0, not(tag("|")))))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,10 +87,10 @@ pub fn org_mode_table_row<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn org_mode_table_row_rule<'r, 's>(
|
pub fn org_mode_table_row_rule<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, TableRow<'s>> {
|
) -> Res<OrgSource<'s>, TableRow<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _) = tuple((space0, tag("|-"), is_not("\r\n"), line_ending))(input)?;
|
let (remaining, _) = tuple((space0, tag("|-"), is_not("\r\n"), line_ending))(input)?;
|
||||||
let source = get_consumed(input, remaining);
|
let source = get_consumed(input, remaining);
|
||||||
Ok((
|
Ok((
|
||||||
@@ -107,7 +107,7 @@ pub fn org_mode_table_row_regular<'r, 's>(
|
|||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, TableRow<'s>> {
|
) -> Res<OrgSource<'s>, TableRow<'s>> {
|
||||||
start_of_line(context, input)?;
|
start_of_line(input)?;
|
||||||
let (remaining, _) = tuple((space0, tag("|")))(input)?;
|
let (remaining, _) = tuple((space0, tag("|")))(input)?;
|
||||||
let (remaining, children) =
|
let (remaining, children) =
|
||||||
many1(parser_with_context!(org_mode_table_cell)(context))(remaining)?;
|
many1(parser_with_context!(org_mode_table_cell)(context))(remaining)?;
|
||||||
@@ -157,7 +157,7 @@ pub fn org_mode_table_cell<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn org_mode_table_cell_end<'r, 's>(
|
fn org_mode_table_cell_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(tuple((space0, alt((tag("|"), peek(line_ending))))))(input)
|
recognize(tuple((space0, alt((tag("|"), peek(line_ending))))))(input)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ pub fn target<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn target_end<'r, 's>(
|
fn target_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(one_of("<>\n"))(input)
|
recognize(one_of("<>\n"))(input)
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ fn _text_markup_object<'r, 's, 'x>(
|
|||||||
let text_markup_end_specialized = text_markup_end(open.into());
|
let text_markup_end_specialized = text_markup_end(open.into());
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &text_markup_end_specialized,
|
exit_matcher: &text_markup_end_specialized,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@ fn _text_markup_string<'r, 's, 'x>(
|
|||||||
let text_markup_end_specialized = text_markup_end(open.into());
|
let text_markup_end_specialized = text_markup_end(open.into());
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &text_markup_end_specialized,
|
exit_matcher: &text_markup_end_specialized,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ fn _text_markup_string<'r, 's, 'x>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn pre<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
pub fn pre<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
let preceding_character = input.get_preceding_character();
|
let preceding_character = input.get_preceding_character();
|
||||||
match preceding_character {
|
match preceding_character {
|
||||||
// If None, we are at the start of the file which is technically the beginning of a line.
|
// If None, we are at the start of the file which is technically the beginning of a line.
|
||||||
@@ -276,7 +276,7 @@ pub fn pre<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSou
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn post<'r, 's>(context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
pub fn post<'r, 's>(_context: Context<'r, 's>, input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
let (remaining, _) = alt((recognize(one_of(" \r\n\t-.,;:!?')}[\">")), line_ending))(input)?;
|
let (remaining, _) = alt((recognize(one_of(" \r\n\t-.,;:!?')}[\">")), line_ending))(input)?;
|
||||||
Ok((remaining, ()))
|
Ok((remaining, ()))
|
||||||
}
|
}
|
||||||
@@ -296,7 +296,7 @@ fn _text_markup_end<'r, 's, 'x>(
|
|||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
marker_symbol: &'x str,
|
marker_symbol: &'x str,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
not(parser_with_context!(preceded_by_whitespace)(context))(input)?;
|
not(preceded_by_whitespace)(input)?;
|
||||||
let (remaining, _marker) = terminated(
|
let (remaining, _marker) = terminated(
|
||||||
tag(marker_symbol),
|
tag(marker_symbol),
|
||||||
peek(parser_with_context!(post)(context)),
|
peek(parser_with_context!(post)(context)),
|
||||||
@@ -338,7 +338,7 @@ fn _rematch_text_markup_object<'r, 's, 'x>(
|
|||||||
let text_markup_end_specialized = text_markup_end(open.into());
|
let text_markup_end_specialized = text_markup_end(open.into());
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &text_markup_end_specialized,
|
exit_matcher: &text_markup_end_specialized,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ fn sexp<'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &sexp_end,
|
exit_matcher: &sexp_end,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ fn sexp<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn sexp_end<'r, 's>(
|
fn sexp_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
alt((tag(")>"), recognize(one_of(">\n"))))(input)
|
alt((tag(")>"), recognize(one_of(">\n"))))(input)
|
||||||
@@ -99,7 +99,7 @@ fn active_timestamp<'r, 's>(
|
|||||||
let (remaining, _date) = date(context, remaining)?;
|
let (remaining, _date) = date(context, remaining)?;
|
||||||
let time_context =
|
let time_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &active_time_rest_end,
|
exit_matcher: &active_time_rest_end,
|
||||||
}));
|
}));
|
||||||
let (remaining, _time) =
|
let (remaining, _time) =
|
||||||
@@ -132,7 +132,7 @@ fn inactive_timestamp<'r, 's>(
|
|||||||
let (remaining, _date) = date(context, remaining)?;
|
let (remaining, _date) = date(context, remaining)?;
|
||||||
let time_context =
|
let time_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &inactive_time_rest_end,
|
exit_matcher: &inactive_time_rest_end,
|
||||||
}));
|
}));
|
||||||
let (remaining, _time) =
|
let (remaining, _time) =
|
||||||
@@ -186,12 +186,12 @@ fn active_time_range_timestamp<'r, 's>(
|
|||||||
let (remaining, _date) = date(context, remaining)?;
|
let (remaining, _date) = date(context, remaining)?;
|
||||||
let time_context =
|
let time_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &active_time_rest_end,
|
exit_matcher: &active_time_rest_end,
|
||||||
}));
|
}));
|
||||||
let first_time_context =
|
let first_time_context =
|
||||||
time_context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
time_context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &time_range_rest_end,
|
exit_matcher: &time_range_rest_end,
|
||||||
}));
|
}));
|
||||||
let (remaining, _first_time) =
|
let (remaining, _first_time) =
|
||||||
@@ -247,12 +247,12 @@ fn inactive_time_range_timestamp<'r, 's>(
|
|||||||
let (remaining, _date) = date(context, remaining)?;
|
let (remaining, _date) = date(context, remaining)?;
|
||||||
let time_context =
|
let time_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &inactive_time_rest_end,
|
exit_matcher: &inactive_time_rest_end,
|
||||||
}));
|
}));
|
||||||
let first_time_context =
|
let first_time_context =
|
||||||
time_context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
time_context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &time_range_rest_end,
|
exit_matcher: &time_range_rest_end,
|
||||||
}));
|
}));
|
||||||
let (remaining, _first_time) =
|
let (remaining, _first_time) =
|
||||||
@@ -303,7 +303,7 @@ fn dayname<'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let parser_context =
|
let parser_context =
|
||||||
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Gamma,
|
||||||
exit_matcher: &dayname_end,
|
exit_matcher: &dayname_end,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -320,7 +320,7 @@ fn dayname<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn dayname_end<'r, 's>(
|
fn dayname_end<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
recognize(verify(anychar, |c| {
|
recognize(verify(anychar, |c| {
|
||||||
@@ -402,7 +402,7 @@ fn time_range_rest_end<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn repeater<'r, 's>(
|
fn repeater<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
// + for cumulative type
|
// + for cumulative type
|
||||||
@@ -418,7 +418,7 @@ fn repeater<'r, 's>(
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn warning_delay<'r, 's>(
|
fn warning_delay<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
_context: Context<'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
// - for all type
|
// - for all type
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::character::complete::anychar;
|
use nom::character::complete::anychar;
|
||||||
use nom::character::complete::line_ending;
|
use nom::character::complete::line_ending;
|
||||||
use nom::character::complete::multispace0;
|
|
||||||
use nom::character::complete::none_of;
|
use nom::character::complete::none_of;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
@@ -49,26 +48,9 @@ pub fn immediate_in_section<'r, 's, 'x>(context: Context<'r, 's>, section_name:
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
/// 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: OrgSource<'s>, remaining: OrgSource<'s>) -> OrgSource<'s> {
|
pub fn get_consumed<'s>(input: OrgSource<'s>, remaining: OrgSource<'s>) -> OrgSource<'s> {
|
||||||
// TODO: This should be replaced with new logic now that we are wrapping the input type.
|
input.get_until(remaining)
|
||||||
let input = Into::<&str>::into(&input);
|
|
||||||
let remaining = Into::<&str>::into(&remaining);
|
|
||||||
assert!(is_slice_of(input, remaining));
|
|
||||||
let source = {
|
|
||||||
let offset = remaining.as_ptr() as usize - input.as_ptr() as usize;
|
|
||||||
&input[..offset]
|
|
||||||
};
|
|
||||||
source.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A line containing only whitespace and then a line break
|
/// A line containing only whitespace and then a line break
|
||||||
@@ -81,11 +63,8 @@ pub fn blank_line(input: OrgSource<'_>) -> Res<OrgSource<'_>, OrgSource<'_>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn element_trailing_whitespace<'r, 's>(
|
pub fn element_trailing_whitespace<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
context: Context<'r, 's>,
|
start_of_line(input)?;
|
||||||
input: OrgSource<'s>,
|
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|
||||||
start_of_line(context, input)?;
|
|
||||||
alt((eof, recognize(many0(blank_line))))(input)
|
alt((eof, recognize(many0(blank_line))))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,9 +75,7 @@ pub fn maybe_consume_trailing_whitespace_if_not_exiting<'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
||||||
if context.should_consume_trailing_whitespace() && exit_matcher_parser(context, input).is_err()
|
if context.should_consume_trailing_whitespace() && exit_matcher_parser(context, input).is_err()
|
||||||
{
|
{
|
||||||
Ok(opt(parser_with_context!(element_trailing_whitespace)(
|
Ok(opt(element_trailing_whitespace)(input)?)
|
||||||
context,
|
|
||||||
))(input)?)
|
|
||||||
} else {
|
} else {
|
||||||
Ok((input, None))
|
Ok((input, None))
|
||||||
}
|
}
|
||||||
@@ -110,25 +87,15 @@ pub fn maybe_consume_trailing_whitespace<'r, 's>(
|
|||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
||||||
if context.should_consume_trailing_whitespace() {
|
if context.should_consume_trailing_whitespace() {
|
||||||
Ok(opt(parser_with_context!(element_trailing_whitespace)(
|
Ok(opt(element_trailing_whitespace)(input)?)
|
||||||
context,
|
|
||||||
))(input)?)
|
|
||||||
} else {
|
} else {
|
||||||
Ok((input, None))
|
Ok((input, None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
pub fn trailing_whitespace(input: OrgSource<'_>) -> Res<OrgSource<'_>, OrgSource<'_>> {
|
|
||||||
alt((eof, recognize(tuple((line_ending, many0(blank_line))))))(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that we are at the start of a line
|
/// Check that we are at the start of a line
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn start_of_line<'r, 's>(
|
pub fn start_of_line<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
context: Context<'r, 's>,
|
|
||||||
input: OrgSource<'s>,
|
|
||||||
) -> Res<OrgSource<'s>, ()> {
|
|
||||||
if input.is_at_start_of_line() {
|
if input.is_at_start_of_line() {
|
||||||
Ok((input, ()))
|
Ok((input, ()))
|
||||||
} else {
|
} else {
|
||||||
@@ -140,10 +107,7 @@ pub fn start_of_line<'r, 's>(
|
|||||||
|
|
||||||
/// Check that we are at the start of a line
|
/// Check that we are at the start of a line
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn preceded_by_whitespace<'r, 's>(
|
pub fn preceded_by_whitespace<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
|
||||||
context: Context<'r, 's>,
|
|
||||||
input: OrgSource<'s>,
|
|
||||||
) -> Res<OrgSource<'s>, ()> {
|
|
||||||
let preceding_character = input.get_preceding_character();
|
let preceding_character = input.get_preceding_character();
|
||||||
match preceding_character {
|
match preceding_character {
|
||||||
Some('\n') | Some('\r') | Some(' ') | Some('\t') => {}
|
Some('\n') | Some('\r') | Some(' ') | Some('\t') => {}
|
||||||
@@ -174,21 +138,6 @@ pub fn exit_matcher_parser<'r, 's>(
|
|||||||
peek(|i| context.check_exit_matcher(i))(input)
|
peek(|i| context.check_exit_matcher(i))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
pub fn always_fail<'r, 's>(
|
|
||||||
_context: Context<'r, 's>,
|
|
||||||
input: OrgSource<'s>,
|
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|
||||||
Err(nom::Err::Error(CustomError::MyError(MyError(
|
|
||||||
"Always fail".into(),
|
|
||||||
))))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
pub fn whitespace_eof(input: OrgSource<'_>) -> Res<OrgSource<'_>, OrgSource<'_>> {
|
|
||||||
recognize(tuple((multispace0, eof)))(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub fn text_until_exit<'r, 's>(
|
pub fn text_until_exit<'r, 's>(
|
||||||
context: Context<'r, 's>,
|
context: Context<'r, 's>,
|
||||||
|
|||||||
Reference in New Issue
Block a user