Compare commits
16 Commits
v0.1.12
...
93cfa71df2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93cfa71df2 | ||
|
|
78320d3265 | ||
|
|
9e908935f8 | ||
|
|
b18a703529 | ||
|
|
ea52dc60be | ||
|
|
f5699ce830 | ||
|
|
10aa0956ee | ||
|
|
816c164996 | ||
|
|
ee201e1336 | ||
|
|
4897952330 | ||
|
|
e1d85c6dc2 | ||
|
|
c420ccd029 | ||
|
|
a880629831 | ||
|
|
5e2dea1f28 | ||
|
|
f47d688be4 | ||
|
|
acfc5e5e68 |
4
Makefile
4
Makefile
@@ -45,10 +45,6 @@ dockerclippy:
|
|||||||
clippy:
|
clippy:
|
||||||
> cargo clippy --no-deps --all-targets --all-features -- -D warnings
|
> cargo clippy --no-deps --all-targets --all-features -- -D warnings
|
||||||
|
|
||||||
.PHONY: clippyfix
|
|
||||||
clippyfix:
|
|
||||||
> cargo clippy --fix --lib -p organic --all-features
|
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
> cargo test --no-default-features --features compare --no-fail-fast --lib --test test_loader -- --test-threads $(TESTJOBS)
|
> cargo test --no-default-features --features compare --no-fail-fast --lib --test test_loader -- --test-threads $(TESTJOBS)
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ ifdef REMOTE_REPO
|
|||||||
else
|
else
|
||||||
@echo "REMOTE_REPO not defined, not removing from remote repo."
|
@echo "REMOTE_REPO not defined, not removing from remote repo."
|
||||||
endif
|
endif
|
||||||
docker volume rm cargo-cache
|
docker volume rm rust-cache cargo-cache
|
||||||
|
|
||||||
# NOTE: This target will write to folders underneath the git-root
|
# NOTE: This target will write to folders underneath the git-root
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run: build
|
run: build
|
||||||
docker run --rm --init --read-only --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry $(IMAGE_NAME)
|
docker run --rm --init --read-only --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source:ro" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target $(IMAGE_NAME)
|
||||||
|
|
||||||
.PHONY: shell
|
.PHONY: shell
|
||||||
shell: build
|
shell: build
|
||||||
docker run --rm -i -t --entrypoint /bin/sh --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry $(IMAGE_NAME)
|
docker run --rm -i -t --entrypoint /bin/sh --mount type=tmpfs,destination=/tmp -v "$$(readlink -f ../../):/source:ro" --workdir=/source --mount source=cargo-cache,target=/usr/local/cargo/registry --mount source=rust-cache,target=/target --env CARGO_TARGET_DIR=/target $(IMAGE_NAME)
|
||||||
|
|||||||
@@ -93,6 +93,12 @@ ARG WORG_PATH=/foreign_documents/worg
|
|||||||
ARG WORG_REPO=https://git.sr.ht/~bzg/worg
|
ARG WORG_REPO=https://git.sr.ht/~bzg/worg
|
||||||
RUN mkdir -p $WORG_PATH && git -C $WORG_PATH init --initial-branch=main && git -C $WORG_PATH remote add origin $WORG_REPO && git -C $WORG_PATH fetch origin $WORG_VERSION && git -C $WORG_PATH checkout FETCH_HEAD
|
RUN mkdir -p $WORG_PATH && git -C $WORG_PATH init --initial-branch=main && git -C $WORG_PATH remote add origin $WORG_REPO && git -C $WORG_PATH fetch origin $WORG_VERSION && git -C $WORG_PATH checkout FETCH_HEAD
|
||||||
|
|
||||||
|
ARG LITERATE_BUILD_EMACS_VERSION=e3ac1afe1e40af601be7af12c1d13d96308ab209
|
||||||
|
ARG LITERATE_BUILD_EMACS_PATH=/foreign_documents/literate_build_emacs
|
||||||
|
ARG LITERATE_BUILD_EMACS_REPO=https://gitlab.com/spudlyo/orgdemo2.git
|
||||||
|
RUN mkdir -p $LITERATE_BUILD_EMACS_PATH && git -C $LITERATE_BUILD_EMACS_PATH init --initial-branch=main && git -C $LITERATE_BUILD_EMACS_PATH remote add origin $LITERATE_BUILD_EMACS_REPO && git -C $LITERATE_BUILD_EMACS_PATH fetch origin $LITERATE_BUILD_EMACS_VERSION && git -C $LITERATE_BUILD_EMACS_PATH checkout FETCH_HEAD
|
||||||
|
# unused/aws.org contains invalid paths for setupfile which causes both upstream org-mode and Organic to error out.
|
||||||
|
RUN rm $LITERATE_BUILD_EMACS_PATH/unused/aws.org
|
||||||
|
|
||||||
FROM tester as foreign-document-test
|
FROM tester as foreign-document-test
|
||||||
RUN apk add --no-cache bash coreutils
|
RUN apk add --no-cache bash coreutils
|
||||||
@@ -100,6 +106,7 @@ RUN mkdir /foreign_documents
|
|||||||
COPY --from=foreign-document-gather /foreign_documents/howardabrams /foreign_documents/howardabrams
|
COPY --from=foreign-document-gather /foreign_documents/howardabrams /foreign_documents/howardabrams
|
||||||
COPY --from=foreign-document-gather /foreign_documents/doomemacs /foreign_documents/doomemacs
|
COPY --from=foreign-document-gather /foreign_documents/doomemacs /foreign_documents/doomemacs
|
||||||
COPY --from=foreign-document-gather /foreign_documents/worg /foreign_documents/worg
|
COPY --from=foreign-document-gather /foreign_documents/worg /foreign_documents/worg
|
||||||
|
COPY --from=foreign-document-gather /foreign_documents/literate_build_emacs /foreign_documents/literate_build_emacs
|
||||||
COPY --from=build-org-mode /root/org-mode /foreign_documents/org-mode
|
COPY --from=build-org-mode /root/org-mode /foreign_documents/org-mode
|
||||||
COPY --from=build-emacs /root/emacs /foreign_documents/emacs
|
COPY --from=build-emacs /root/emacs /foreign_documents/emacs
|
||||||
ENTRYPOINT ["cargo", "run", "--bin", "foreign_document_test", "--features", "compare,foreign_document_test", "--profile", "release-lto"]
|
ENTRYPOINT ["cargo", "run", "--bin", "foreign_document_test", "--features", "compare,foreign_document_test", "--profile", "release-lto"]
|
||||||
|
|||||||
5
org_mode_samples/affiliated_keyword/empty_caption.org
Normal file
5
org_mode_samples/affiliated_keyword/empty_caption.org
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#+caption:
|
||||||
|
#+caption: *foo*
|
||||||
|
#+caption[bar]:
|
||||||
|
#+begin_src bash
|
||||||
|
#+end_src
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
foo <<bar>> baz
|
|
||||||
|
|
||||||
lorem << ipsum >> dolar
|
|
||||||
@@ -53,6 +53,9 @@ async fn main_body() -> Result<ExitCode, Box<dyn std::error::Error>> {
|
|||||||
let layer = layer.chain(compare_group("doomemacs", || {
|
let layer = layer.chain(compare_group("doomemacs", || {
|
||||||
compare_all_org_document("/foreign_documents/doomemacs")
|
compare_all_org_document("/foreign_documents/doomemacs")
|
||||||
}));
|
}));
|
||||||
|
let layer = layer.chain(compare_group("literate_build_emacs", || {
|
||||||
|
compare_all_org_document("/foreign_documents/literate_build_emacs")
|
||||||
|
}));
|
||||||
|
|
||||||
let running_tests: Vec<_> = layer.map(|c| tokio::spawn(c.run_test())).collect();
|
let running_tests: Vec<_> = layer.map(|c| tokio::spawn(c.run_test())).collect();
|
||||||
let mut any_failed = false;
|
let mut any_failed = false;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::borrow::Borrow;
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@@ -262,11 +264,11 @@ pub(crate) fn compare_property_set_of_quoted_string<
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|e| e.as_atom())
|
.map(|e| e.as_atom())
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let value: Vec<String> = value
|
let value: Vec<Cow<'_, str>> = value
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(unquote)
|
.map(unquote)
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let value: BTreeSet<&str> = value.iter().map(|e| e.as_str()).collect();
|
let value: BTreeSet<&str> = value.iter().map(|e| e.borrow()).collect();
|
||||||
let mismatched: Vec<_> = value.symmetric_difference(&rust_value).copied().collect();
|
let mismatched: Vec<_> = value.symmetric_difference(&rust_value).copied().collect();
|
||||||
if !mismatched.is_empty() {
|
if !mismatched.is_empty() {
|
||||||
let this_status = DiffStatus::Bad;
|
let this_status = DiffStatus::Bad;
|
||||||
@@ -546,6 +548,21 @@ where
|
|||||||
let mut full_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(outer_rust_list.len());
|
let mut full_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(outer_rust_list.len());
|
||||||
|
|
||||||
for (kw_e, kw_r) in outer_emacs_list.iter().zip(outer_rust_list) {
|
for (kw_e, kw_r) in outer_emacs_list.iter().zip(outer_rust_list) {
|
||||||
|
match (kw_e.as_atom(), kw_r) {
|
||||||
|
(Ok("nil"), (None, mandatory_value)) if mandatory_value.is_empty() => {
|
||||||
|
// If its an empty keyword then it becomes nil in the elisp.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
(Ok("nil"), _) => {
|
||||||
|
let this_status = DiffStatus::Bad;
|
||||||
|
let message = Some(format!(
|
||||||
|
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||||
|
emacs_field, kw_e, kw_r
|
||||||
|
));
|
||||||
|
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
let kw_e = kw_e.as_list()?;
|
let kw_e = kw_e.as_list()?;
|
||||||
let child_status_length = kw_r.1.len() + kw_r.0.as_ref().map(|opt| opt.len()).unwrap_or(0);
|
let child_status_length = kw_r.1.len() + kw_r.0.as_ref().map(|opt| opt.len()).unwrap_or(0);
|
||||||
let mut child_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(child_status_length);
|
let mut child_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(child_status_length);
|
||||||
@@ -554,18 +571,31 @@ where
|
|||||||
let mut kw_e = kw_e.iter();
|
let mut kw_e = kw_e.iter();
|
||||||
// First element is a list representing the mandatory value.
|
// First element is a list representing the mandatory value.
|
||||||
if let Some(val_e) = kw_e.next() {
|
if let Some(val_e) = kw_e.next() {
|
||||||
let el = val_e.as_list()?;
|
match (val_e.as_atom(), kw_r) {
|
||||||
if el.len() != kw_r.1.len() {
|
(Ok("nil"), (_, mandatory_value)) if mandatory_value.is_empty() => {}
|
||||||
let this_status = DiffStatus::Bad;
|
(Ok("nil"), _) => {
|
||||||
let message = Some(format!(
|
let this_status = DiffStatus::Bad;
|
||||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
let message = Some(format!(
|
||||||
emacs_field, kw_e, kw_r
|
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||||
));
|
emacs_field, kw_e, kw_r
|
||||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
));
|
||||||
}
|
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||||
for (e, r) in el.iter().zip(kw_r.1.iter()) {
|
}
|
||||||
child_status.push(compare_ast_node(source, e, r.into())?);
|
_ => {
|
||||||
}
|
let el = val_e.as_list()?;
|
||||||
|
if el.len() != kw_r.1.len() {
|
||||||
|
let this_status = DiffStatus::Bad;
|
||||||
|
let message = Some(format!(
|
||||||
|
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||||
|
emacs_field, kw_e, kw_r
|
||||||
|
));
|
||||||
|
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||||
|
}
|
||||||
|
for (e, r) in el.iter().zip(kw_r.1.iter()) {
|
||||||
|
child_status.push(compare_ast_node(source, e, r.into())?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
let this_status = DiffStatus::Bad;
|
let this_status = DiffStatus::Bad;
|
||||||
let message = Some(format!(
|
let message = Some(format!(
|
||||||
@@ -653,7 +683,7 @@ pub(crate) fn compare_property_number_lines<
|
|||||||
(Some(number_lines), Some(rust_number_lines)) => {
|
(Some(number_lines), Some(rust_number_lines)) => {
|
||||||
let token_list = number_lines.as_list()?;
|
let token_list = number_lines.as_list()?;
|
||||||
let number_type = token_list
|
let number_type = token_list
|
||||||
.get(0)
|
.first()
|
||||||
.map(Token::as_atom)
|
.map(Token::as_atom)
|
||||||
.map_or(Ok(None), |r| r.map(Some))?
|
.map_or(Ok(None), |r| r.map(Some))?
|
||||||
.ok_or(":number-lines should have a type.")?;
|
.ok_or(":number-lines should have a type.")?;
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ pub struct DiffResult<'b, 's> {
|
|||||||
emacs_token: &'b Token<'s>,
|
emacs_token: &'b Token<'s>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum DiffStatus {
|
pub(crate) enum DiffStatus {
|
||||||
Good,
|
Good,
|
||||||
Bad,
|
Bad,
|
||||||
@@ -164,7 +164,7 @@ impl<'b, 's> DiffEntry<'b, 's> {
|
|||||||
|
|
||||||
fn is_immediately_bad(&self) -> bool {
|
fn is_immediately_bad(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
DiffEntry::DiffResult(diff) => diff.status == DiffStatus::Bad,
|
DiffEntry::DiffResult(diff) => matches!(diff.status, DiffStatus::Bad),
|
||||||
DiffEntry::DiffLayer(_) => false,
|
DiffEntry::DiffLayer(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1576,7 +1576,7 @@ fn compare_example_block<'b, 's>(
|
|||||||
[],
|
[],
|
||||||
(
|
(
|
||||||
EmacsField::Required(":value"),
|
EmacsField::Required(":value"),
|
||||||
|r| Some(r.contents.as_str()),
|
|r| Some(&r.contents),
|
||||||
compare_property_quoted_string
|
compare_property_quoted_string
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -1654,7 +1654,7 @@ fn compare_export_block<'b, 's>(
|
|||||||
),
|
),
|
||||||
(
|
(
|
||||||
EmacsField::Required(":value"),
|
EmacsField::Required(":value"),
|
||||||
|r| Some(r.contents.as_str()),
|
|r| Some(&r.contents),
|
||||||
compare_property_quoted_string
|
compare_property_quoted_string
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@@ -1702,7 +1702,7 @@ fn compare_src_block<'b, 's>(
|
|||||||
),
|
),
|
||||||
(
|
(
|
||||||
EmacsField::Required(":value"),
|
EmacsField::Required(":value"),
|
||||||
|r| Some(r.contents.as_str()),
|
|r| Some(&r.contents),
|
||||||
compare_property_quoted_string
|
compare_property_quoted_string
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -2153,7 +2153,7 @@ fn compare_plain_text<'b, 's>(
|
|||||||
let text = emacs.as_text()?;
|
let text = emacs.as_text()?;
|
||||||
let start_ind: usize = text
|
let start_ind: usize = text
|
||||||
.properties
|
.properties
|
||||||
.get(0)
|
.first()
|
||||||
.expect("Should have start index.")
|
.expect("Should have start index.")
|
||||||
.as_atom()?
|
.as_atom()?
|
||||||
.parse()?;
|
.parse()?;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
@@ -36,12 +37,6 @@ pub struct TextWithProperties<'s> {
|
|||||||
pub(crate) properties: Vec<Token<'s>>,
|
pub(crate) properties: Vec<Token<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ParseState {
|
|
||||||
Normal,
|
|
||||||
Escape,
|
|
||||||
Octal(Vec<u8>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'s> Token<'s> {
|
impl<'s> Token<'s> {
|
||||||
pub(crate) fn as_vector<'p>(
|
pub(crate) fn as_vector<'p>(
|
||||||
&'p self,
|
&'p self,
|
||||||
@@ -117,8 +112,27 @@ fn get_consumed<'s>(input: &'s str, remaining: &'s str) -> &'s str {
|
|||||||
&input[..offset]
|
&input[..offset]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn unquote(text: &str) -> Result<String, Box<dyn std::error::Error>> {
|
#[derive(Debug)]
|
||||||
let mut out: Vec<u8> = Vec::with_capacity(text.len());
|
enum UnquoteState {
|
||||||
|
Normal,
|
||||||
|
Escape,
|
||||||
|
HasEscape {
|
||||||
|
out: Vec<u8>,
|
||||||
|
},
|
||||||
|
HasEscapeEscape {
|
||||||
|
out: Vec<u8>,
|
||||||
|
},
|
||||||
|
Octal {
|
||||||
|
octal_begin_offset: usize,
|
||||||
|
octal: Vec<u8>,
|
||||||
|
},
|
||||||
|
HasEscapeOctal {
|
||||||
|
out: Vec<u8>,
|
||||||
|
octal: Vec<u8>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn unquote(text: &str) -> Result<Cow<'_, str>, Box<dyn std::error::Error>> {
|
||||||
if !text.starts_with('"') {
|
if !text.starts_with('"') {
|
||||||
return Err("Quoted text does not start with quote.".into());
|
return Err("Quoted text does not start with quote.".into());
|
||||||
}
|
}
|
||||||
@@ -126,54 +140,143 @@ pub(crate) fn unquote(text: &str) -> Result<String, Box<dyn std::error::Error>>
|
|||||||
return Err("Quoted text does not end with quote.".into());
|
return Err("Quoted text does not end with quote.".into());
|
||||||
}
|
}
|
||||||
let interior_text = &text[1..(text.len() - 1)];
|
let interior_text = &text[1..(text.len() - 1)];
|
||||||
let mut state = ParseState::Normal;
|
let mut state = UnquoteState::Normal;
|
||||||
for current_char in interior_text.bytes() {
|
for (offset, current_char) in interior_text.bytes().enumerate() {
|
||||||
// Check to see if octal finished
|
// Check to see if octal finished
|
||||||
state = match (state, current_char) {
|
state = match (state, current_char) {
|
||||||
(ParseState::Octal(octal), b'0'..=b'7') if octal.len() < MAX_OCTAL_LENGTH => {
|
(
|
||||||
ParseState::Octal(octal)
|
UnquoteState::Octal {
|
||||||
|
octal_begin_offset,
|
||||||
|
octal,
|
||||||
|
},
|
||||||
|
b'0'..=b'7',
|
||||||
|
) if octal.len() < MAX_OCTAL_LENGTH => UnquoteState::Octal {
|
||||||
|
octal_begin_offset,
|
||||||
|
octal,
|
||||||
|
},
|
||||||
|
(
|
||||||
|
UnquoteState::Octal {
|
||||||
|
octal_begin_offset,
|
||||||
|
octal,
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
) => {
|
||||||
|
let octal_number_string = String::from_utf8(octal)?;
|
||||||
|
let decoded_byte = u8::from_str_radix(&octal_number_string, 8)?;
|
||||||
|
let mut out: Vec<u8> = Vec::with_capacity(interior_text.len());
|
||||||
|
out.extend_from_slice(&interior_text.as_bytes()[..octal_begin_offset]);
|
||||||
|
out.push(decoded_byte);
|
||||||
|
UnquoteState::HasEscape { out }
|
||||||
}
|
}
|
||||||
(ParseState::Octal(octal), _) => {
|
(UnquoteState::HasEscapeOctal { out, octal }, b'0'..=b'7')
|
||||||
|
if octal.len() < MAX_OCTAL_LENGTH =>
|
||||||
|
{
|
||||||
|
UnquoteState::HasEscapeOctal { out, octal }
|
||||||
|
}
|
||||||
|
(UnquoteState::HasEscapeOctal { mut out, octal }, _) => {
|
||||||
let octal_number_string = String::from_utf8(octal)?;
|
let octal_number_string = String::from_utf8(octal)?;
|
||||||
let decoded_byte = u8::from_str_radix(&octal_number_string, 8)?;
|
let decoded_byte = u8::from_str_radix(&octal_number_string, 8)?;
|
||||||
out.push(decoded_byte);
|
out.push(decoded_byte);
|
||||||
ParseState::Normal
|
UnquoteState::HasEscape { out }
|
||||||
}
|
}
|
||||||
(state, _) => state,
|
(state, _) => state,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = match (state, current_char) {
|
state = match (state, current_char) {
|
||||||
(ParseState::Normal, b'\\') => ParseState::Escape,
|
(UnquoteState::Normal, b'\\') => UnquoteState::Escape,
|
||||||
(ParseState::Normal, _) => {
|
(UnquoteState::Normal, _) => UnquoteState::Normal,
|
||||||
|
(UnquoteState::HasEscape { out }, b'\\') => UnquoteState::HasEscapeEscape { out },
|
||||||
|
(UnquoteState::HasEscape { mut out }, _) => {
|
||||||
out.push(current_char);
|
out.push(current_char);
|
||||||
ParseState::Normal
|
UnquoteState::HasEscape { out }
|
||||||
}
|
}
|
||||||
(ParseState::Escape, b'n') => {
|
(UnquoteState::Escape, b'n') => {
|
||||||
|
let mut out: Vec<u8> = Vec::with_capacity(interior_text.len());
|
||||||
|
// Subtract 1 from offset to account for backslash.
|
||||||
|
out.extend_from_slice(&interior_text.as_bytes()[..(offset - 1)]);
|
||||||
out.push(b'\n');
|
out.push(b'\n');
|
||||||
ParseState::Normal
|
UnquoteState::HasEscape { out }
|
||||||
}
|
}
|
||||||
(ParseState::Escape, b'\\') => {
|
(UnquoteState::HasEscapeEscape { mut out }, b'n') => {
|
||||||
|
out.push(b'\n');
|
||||||
|
UnquoteState::HasEscape { out }
|
||||||
|
}
|
||||||
|
(UnquoteState::Escape, b'\\') => {
|
||||||
|
let mut out: Vec<u8> = Vec::with_capacity(interior_text.len());
|
||||||
|
// Subtract 1 from offset to account for backslash.
|
||||||
|
out.extend_from_slice(&interior_text.as_bytes()[..(offset - 1)]);
|
||||||
out.push(b'\\');
|
out.push(b'\\');
|
||||||
ParseState::Normal
|
UnquoteState::HasEscape { out }
|
||||||
}
|
}
|
||||||
(ParseState::Escape, b'"') => {
|
(UnquoteState::HasEscapeEscape { mut out }, b'\\') => {
|
||||||
|
out.push(b'\\');
|
||||||
|
UnquoteState::HasEscape { out }
|
||||||
|
}
|
||||||
|
(UnquoteState::Escape, b'"') => {
|
||||||
|
let mut out: Vec<u8> = Vec::with_capacity(interior_text.len());
|
||||||
|
// Subtract 1 from offset to account for backslash.
|
||||||
|
out.extend_from_slice(&interior_text.as_bytes()[..(offset - 1)]);
|
||||||
out.push(b'"');
|
out.push(b'"');
|
||||||
ParseState::Normal
|
UnquoteState::HasEscape { out }
|
||||||
}
|
}
|
||||||
(ParseState::Escape, b'0'..=b'7') => {
|
(UnquoteState::HasEscapeEscape { mut out }, b'"') => {
|
||||||
|
out.push(b'"');
|
||||||
|
UnquoteState::HasEscape { out }
|
||||||
|
}
|
||||||
|
(UnquoteState::Escape, b'0'..=b'7') => {
|
||||||
let mut octal = Vec::with_capacity(MAX_OCTAL_LENGTH);
|
let mut octal = Vec::with_capacity(MAX_OCTAL_LENGTH);
|
||||||
octal.push(current_char);
|
octal.push(current_char);
|
||||||
ParseState::Octal(octal)
|
// Substract 1 from offset to account for backslash
|
||||||
|
UnquoteState::Octal {
|
||||||
|
octal_begin_offset: offset - 1,
|
||||||
|
octal,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(ParseState::Octal(mut octal), b'0'..=b'7') => {
|
(UnquoteState::HasEscapeEscape { out }, b'0'..=b'7') => {
|
||||||
|
let mut octal = Vec::with_capacity(MAX_OCTAL_LENGTH);
|
||||||
octal.push(current_char);
|
octal.push(current_char);
|
||||||
ParseState::Octal(octal)
|
// Substract 1 from offset to account for backslash
|
||||||
|
UnquoteState::HasEscapeOctal { out, octal }
|
||||||
}
|
}
|
||||||
_ => panic!("Invalid state unquoting string."),
|
(
|
||||||
|
UnquoteState::Octal {
|
||||||
|
octal_begin_offset,
|
||||||
|
mut octal,
|
||||||
|
},
|
||||||
|
b'0'..=b'7',
|
||||||
|
) => {
|
||||||
|
octal.push(current_char);
|
||||||
|
UnquoteState::Octal {
|
||||||
|
octal_begin_offset,
|
||||||
|
octal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(UnquoteState::HasEscapeOctal { out, mut octal }, b'0'..=b'7') => {
|
||||||
|
octal.push(current_char);
|
||||||
|
UnquoteState::HasEscapeOctal { out, octal }
|
||||||
|
}
|
||||||
|
(state, _) => panic!(
|
||||||
|
"Invalid state unquoting string: {:?} | {} | {:?}",
|
||||||
|
state, offset, interior_text
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(String::from_utf8(out)?)
|
match state {
|
||||||
|
UnquoteState::Normal | UnquoteState::Escape | UnquoteState::Octal { .. } => {
|
||||||
|
Ok(Cow::Borrowed(interior_text))
|
||||||
|
}
|
||||||
|
UnquoteState::HasEscape { out } => Ok(Cow::Owned(String::from_utf8(out)?)),
|
||||||
|
UnquoteState::HasEscapeEscape { mut out } => {
|
||||||
|
out.push(b'\\');
|
||||||
|
Ok(Cow::Owned(String::from_utf8(out)?))
|
||||||
|
}
|
||||||
|
UnquoteState::HasEscapeOctal { mut out, octal } => {
|
||||||
|
out.push(b'\\');
|
||||||
|
out.extend(octal);
|
||||||
|
Ok(Cow::Owned(String::from_utf8(out)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use super::compare_field::compare_property_list_of_quoted_string;
|
use super::compare_field::compare_property_list_of_quoted_string;
|
||||||
@@ -206,10 +207,10 @@ pub(crate) fn get_property_unquoted_atom<'s>(
|
|||||||
/// Get a named property containing an quoted string from the emacs token.
|
/// Get a named property containing an quoted string from the emacs token.
|
||||||
///
|
///
|
||||||
/// Returns None if key is not found.
|
/// Returns None if key is not found.
|
||||||
pub(crate) fn get_property_quoted_string(
|
pub(crate) fn get_property_quoted_string<'s>(
|
||||||
emacs: &Token<'_>,
|
emacs: &Token<'s>,
|
||||||
key: &str,
|
key: &str,
|
||||||
) -> Result<Option<String>, Box<dyn std::error::Error>> {
|
) -> Result<Option<Cow<'s, str>>, Box<dyn std::error::Error>> {
|
||||||
get_property(emacs, key)?
|
get_property(emacs, key)?
|
||||||
.map(Token::as_atom)
|
.map(Token::as_atom)
|
||||||
.map_or(Ok(None), |r| r.map(Some))?
|
.map_or(Ok(None), |r| r.map(Some))?
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ pub(crate) type Res<T, U> = IResult<T, U, CustomError>;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CustomError {
|
pub enum CustomError {
|
||||||
#[allow(dead_code)]
|
|
||||||
Text(String),
|
|
||||||
Static(&'static str),
|
Static(&'static str),
|
||||||
IO(std::io::Error),
|
IO(std::io::Error),
|
||||||
Parser(ErrorKind),
|
Parser(ErrorKind),
|
||||||
@@ -35,9 +33,3 @@ impl From<&'static str> for CustomError {
|
|||||||
CustomError::Static(value)
|
CustomError::Static(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for CustomError {
|
|
||||||
fn from(value: String) -> Self {
|
|
||||||
CustomError::Text(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -90,12 +90,11 @@ impl<'r, 's> Iterator for AllAstNodeIter<'r, 's> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r, 's> IntoIterator for AstNode<'r, 's> {
|
impl<'r, 's> AstNode<'r, 's> {
|
||||||
type Item = AstNode<'r, 's>;
|
/// Iterate all AST nodes.
|
||||||
|
///
|
||||||
type IntoIter = AllAstNodeIter<'r, 's>;
|
/// This is different from the iter/into_iter functions which iterate a single level of the children. This iterates the entire tree including returning the root node itself.
|
||||||
|
pub fn iter_all_ast_nodes(self) -> AllAstNodeIter<'r, 's> {
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
|
||||||
AllAstNodeIter {
|
AllAstNodeIter {
|
||||||
root: Some(self),
|
root: Some(self),
|
||||||
queue: VecDeque::new(),
|
queue: VecDeque::new(),
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ fn impl_balanced_bracket<
|
|||||||
let contents_end = remaining;
|
let contents_end = remaining;
|
||||||
|
|
||||||
let (remaining, _) = end_parser(remaining)?;
|
let (remaining, _) = end_parser(remaining)?;
|
||||||
let contents = if contents_start != contents_end {
|
let contents = if Into::<&str>::into(contents_start) != Into::<&str>::into(contents_end) {
|
||||||
Some(contents_start.get_until(contents_end))
|
Some(contents_start.get_until(contents_end))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -244,7 +244,7 @@ mod tests {
|
|||||||
let input = OrgSource::new("()");
|
let input = OrgSource::new("()");
|
||||||
let (remaining, call) = opt(babel_call_call)(input)?;
|
let (remaining, call) = opt(babel_call_call)(input)?;
|
||||||
assert_eq!(Into::<&str>::into(remaining), "()");
|
assert_eq!(Into::<&str>::into(remaining), "()");
|
||||||
assert_eq!(call, None);
|
assert!(call.is_none());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,8 @@ use crate::context::RefContext;
|
|||||||
use crate::error::CustomError;
|
use crate::error::CustomError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
use crate::parser::macros::element;
|
use crate::parser::macros::element;
|
||||||
use crate::types::AffiliatedKeywords;
|
|
||||||
use crate::types::Object;
|
use crate::types::Object;
|
||||||
use crate::types::Paragraph;
|
use crate::types::Paragraph;
|
||||||
use crate::types::PlainText;
|
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
@@ -80,13 +78,10 @@ pub(crate) fn broken_end<'b, 'g, 'r, 's>(
|
|||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
Paragraph {
|
Paragraph::of_text(
|
||||||
source: input.get_until(remaining).into(),
|
input.get_until(remaining).into(),
|
||||||
affiliated_keywords: AffiliatedKeywords::default(),
|
input.get_until(lead_in_remaining).into(),
|
||||||
children: vec![Object::PlainText(PlainText {
|
),
|
||||||
source: input.get_until(lead_in_remaining).into(),
|
|
||||||
})],
|
|
||||||
},
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,13 +134,10 @@ pub(crate) fn broken_dynamic_block<'b, 'g, 'r, 's>(
|
|||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
Paragraph {
|
Paragraph::of_text(
|
||||||
source: input.get_until(remaining).into(),
|
input.get_until(remaining).into(),
|
||||||
affiliated_keywords: AffiliatedKeywords::default(),
|
input.get_until(lead_in_remaining).into(),
|
||||||
children: vec![Object::PlainText(PlainText {
|
),
|
||||||
source: input.get_until(lead_in_remaining).into(),
|
|
||||||
})],
|
|
||||||
},
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,12 +210,12 @@ mod tests {
|
|||||||
use crate::context::GlobalSettings;
|
use crate::context::GlobalSettings;
|
||||||
use crate::context::List;
|
use crate::context::List;
|
||||||
use crate::parser::element_parser::element;
|
use crate::parser::element_parser::element;
|
||||||
use crate::types::CitationReference;
|
|
||||||
use crate::types::Element;
|
use crate::types::Element;
|
||||||
use crate::types::GetStandardProperties;
|
use crate::types::GetStandardProperties;
|
||||||
|
use crate::types::StandardProperties;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn citation_simple() {
|
fn citation_simple() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let input = OrgSource::new("[cite:@foo]");
|
let input = OrgSource::new("[cite:@foo]");
|
||||||
let global_settings = GlobalSettings::default();
|
let global_settings = GlobalSettings::default();
|
||||||
let initial_context = ContextElement::document_context();
|
let initial_context = ContextElement::document_context();
|
||||||
@@ -232,23 +232,31 @@ mod tests {
|
|||||||
"[cite:@foo]"
|
"[cite:@foo]"
|
||||||
);
|
);
|
||||||
assert_eq!(first_paragraph.children.len(), 1);
|
assert_eq!(first_paragraph.children.len(), 1);
|
||||||
assert_eq!(
|
|
||||||
first_paragraph
|
match first_paragraph
|
||||||
.children
|
.children
|
||||||
.get(0)
|
.first()
|
||||||
.expect("Len already asserted to be 1"),
|
.expect("Len already asserted to be 1.")
|
||||||
&Object::Citation(Citation {
|
{
|
||||||
source: "[cite:@foo]",
|
Object::Citation(inner) => {
|
||||||
style: None,
|
assert_eq!(inner.get_source(), "[cite:@foo]");
|
||||||
prefix: vec![],
|
assert_eq!(inner.children.len(), 1);
|
||||||
suffix: vec![],
|
assert!(inner.prefix.is_empty());
|
||||||
children: vec![CitationReference {
|
assert!(inner.suffix.is_empty());
|
||||||
source: "@foo",
|
assert!(inner.style.is_none());
|
||||||
key: "foo",
|
let citation_reference = inner
|
||||||
prefix: vec![],
|
.children
|
||||||
suffix: vec![]
|
.first()
|
||||||
}]
|
.expect("Len already asserted to be 1.");
|
||||||
})
|
assert_eq!(citation_reference.get_source(), "@foo");
|
||||||
);
|
assert_eq!(citation_reference.key, "foo");
|
||||||
|
assert!(citation_reference.prefix.is_empty());
|
||||||
|
assert!(citation_reference.suffix.is_empty());
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err("Child should be a citation.".into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ fn document_org_source<'b, 'g, 'r, 's>(
|
|||||||
{
|
{
|
||||||
// If there are radio targets in this document then we need to parse the entire document again with the knowledge of the radio targets.
|
// If there are radio targets in this document then we need to parse the entire document again with the knowledge of the radio targets.
|
||||||
let all_radio_targets: Vec<&Vec<Object<'_>>> = Into::<AstNode>::into(&document)
|
let all_radio_targets: Vec<&Vec<Object<'_>>> = Into::<AstNode>::into(&document)
|
||||||
.into_iter()
|
.iter_all_ast_nodes()
|
||||||
.filter_map(|ast_node| {
|
.filter_map(|ast_node| {
|
||||||
if let AstNode::RadioTarget(ast_node) = ast_node {
|
if let AstNode::RadioTarget(ast_node) = ast_node {
|
||||||
Some(ast_node)
|
Some(ast_node)
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ use crate::types::Drawer;
|
|||||||
use crate::types::Element;
|
use crate::types::Element;
|
||||||
use crate::types::Keyword;
|
use crate::types::Keyword;
|
||||||
use crate::types::Paragraph;
|
use crate::types::Paragraph;
|
||||||
use crate::types::SetSource;
|
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
@@ -81,9 +80,8 @@ where
|
|||||||
))(remaining)
|
))(remaining)
|
||||||
{
|
{
|
||||||
Ok((remain, (_not_immediate_exit, first_line, (_trailing_whitespace, _exit_contents)))) => {
|
Ok((remain, (_not_immediate_exit, first_line, (_trailing_whitespace, _exit_contents)))) => {
|
||||||
let mut element = Element::Paragraph(Paragraph::of_text(first_line.into()));
|
|
||||||
let source = get_consumed(remaining, remain);
|
let source = get_consumed(remaining, remain);
|
||||||
element.set_source(source.into());
|
let element = Element::Paragraph(Paragraph::of_text(source.into(), first_line.into()));
|
||||||
(remain, vec![element])
|
(remain, vec![element])
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ use crate::types::DynamicBlock;
|
|||||||
use crate::types::Element;
|
use crate::types::Element;
|
||||||
use crate::types::Keyword;
|
use crate::types::Keyword;
|
||||||
use crate::types::Paragraph;
|
use crate::types::Paragraph;
|
||||||
use crate::types::SetSource;
|
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
@@ -88,9 +87,7 @@ where
|
|||||||
))))(remaining)?;
|
))))(remaining)?;
|
||||||
let leading_blank_lines =
|
let leading_blank_lines =
|
||||||
leading_blank_lines.map(|(source, (first_line, _remaining_lines))| {
|
leading_blank_lines.map(|(source, (first_line, _remaining_lines))| {
|
||||||
let mut element = Element::Paragraph(Paragraph::of_text(first_line.into()));
|
Element::Paragraph(Paragraph::of_text(source.into(), first_line.into()))
|
||||||
element.set_source(source.into());
|
|
||||||
element
|
|
||||||
});
|
});
|
||||||
let (remaining, (mut children, _exit_contents)) =
|
let (remaining, (mut children, _exit_contents)) =
|
||||||
many_till(element_matcher, exit_matcher)(remaining)?;
|
many_till(element_matcher, exit_matcher)(remaining)?;
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ use crate::types::Element;
|
|||||||
use crate::types::Keyword;
|
use crate::types::Keyword;
|
||||||
use crate::types::Paragraph;
|
use crate::types::Paragraph;
|
||||||
use crate::types::QuoteBlock;
|
use crate::types::QuoteBlock;
|
||||||
use crate::types::SetSource;
|
|
||||||
use crate::types::SpecialBlock;
|
use crate::types::SpecialBlock;
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
@@ -257,9 +256,7 @@ fn greater_block_body<'c, 'b, 'g, 'r, 's>(
|
|||||||
))))(remaining)?;
|
))))(remaining)?;
|
||||||
let leading_blank_lines =
|
let leading_blank_lines =
|
||||||
leading_blank_lines.map(|(source, (first_line, _remaining_lines))| {
|
leading_blank_lines.map(|(source, (first_line, _remaining_lines))| {
|
||||||
let mut element = Element::Paragraph(Paragraph::of_text(first_line.into()));
|
Element::Paragraph(Paragraph::of_text(source.into(), first_line.into()))
|
||||||
element.set_source(source.into());
|
|
||||||
element
|
|
||||||
});
|
});
|
||||||
let (remaining, (mut children, _exit_contents)) =
|
let (remaining, (mut children, _exit_contents)) =
|
||||||
many_till(element_matcher, exit_matcher)(remaining)?;
|
many_till(element_matcher, exit_matcher)(remaining)?;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ pub(crate) fn apply_in_buffer_settings<'g, 's, 'sf>(
|
|||||||
}) {
|
}) {
|
||||||
let (_, (in_progress_words, complete_words)) =
|
let (_, (in_progress_words, complete_words)) =
|
||||||
todo_keywords(kw.value).map_err(|err| match err {
|
todo_keywords(kw.value).map_err(|err| match err {
|
||||||
nom::Err::Incomplete(_) => CustomError::Text(err.to_string()),
|
nom::Err::Incomplete(_) => panic!("This parser does not support streaming."),
|
||||||
nom::Err::Error(e) => e,
|
nom::Err::Error(e) => e,
|
||||||
nom::Err::Failure(e) => e,
|
nom::Err::Failure(e) => e,
|
||||||
})?;
|
})?;
|
||||||
@@ -123,7 +123,7 @@ pub(crate) fn apply_in_buffer_settings<'g, 's, 'sf>(
|
|||||||
kw.value,
|
kw.value,
|
||||||
)
|
)
|
||||||
.map_err(|err: nom::Err<_>| match err {
|
.map_err(|err: nom::Err<_>| match err {
|
||||||
nom::Err::Incomplete(_) => CustomError::Text(err.to_string()),
|
nom::Err::Incomplete(_) => panic!("This parser does not support streaming."),
|
||||||
nom::Err::Error(e) => e,
|
nom::Err::Error(e) => e,
|
||||||
nom::Err::Failure(e) => e,
|
nom::Err::Failure(e) => e,
|
||||||
})?;
|
})?;
|
||||||
@@ -141,7 +141,7 @@ pub(crate) fn apply_in_buffer_settings<'g, 's, 'sf>(
|
|||||||
.filter(|kw| kw.key.eq_ignore_ascii_case("link"))
|
.filter(|kw| kw.key.eq_ignore_ascii_case("link"))
|
||||||
{
|
{
|
||||||
let (_, (link_key, link_value)) = link_template(kw.value).map_err(|err| match err {
|
let (_, (link_key, link_value)) = link_template(kw.value).map_err(|err| match err {
|
||||||
nom::Err::Incomplete(_) => CustomError::Text(err.to_string()),
|
nom::Err::Incomplete(_) => panic!("This parser does not support streaming."),
|
||||||
nom::Err::Error(e) => e,
|
nom::Err::Error(e) => e,
|
||||||
nom::Err::Failure(e) => e,
|
nom::Err::Failure(e) => e,
|
||||||
})?;
|
})?;
|
||||||
@@ -157,7 +157,7 @@ pub(crate) fn apply_in_buffer_settings<'g, 's, 'sf>(
|
|||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
pub(crate) fn apply_post_parse_in_buffer_settings<'g, 's, 'sf>(document: &mut Document<'s>) {
|
pub(crate) fn apply_post_parse_in_buffer_settings<'g, 's, 'sf>(document: &mut Document<'s>) {
|
||||||
document.category = Into::<AstNode>::into(&*document)
|
document.category = Into::<AstNode>::into(&*document)
|
||||||
.into_iter()
|
.iter_all_ast_nodes()
|
||||||
.filter_map(|ast_node| {
|
.filter_map(|ast_node| {
|
||||||
if let AstNode::Keyword(ast_node) = ast_node {
|
if let AstNode::Keyword(ast_node) = ast_node {
|
||||||
if ast_node.key.eq_ignore_ascii_case("category") {
|
if ast_node.key.eq_ignore_ascii_case("category") {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::bytes::complete::is_not;
|
use nom::bytes::complete::is_not;
|
||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
@@ -651,6 +653,11 @@ fn switch_word<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ContentState {
|
||||||
|
Normal,
|
||||||
|
Modified(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
tracing::instrument(ret, level = "debug", skip(context))
|
tracing::instrument(ret, level = "debug", skip(context))
|
||||||
@@ -658,8 +665,8 @@ fn switch_word<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|||||||
pub(crate) fn content<'b, 'g, 'r, 's>(
|
pub(crate) fn content<'b, 'g, 'r, 's>(
|
||||||
context: RefContext<'b, 'g, 'r, 's>,
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, String> {
|
) -> Res<OrgSource<'s>, Cow<'s, str>> {
|
||||||
let mut ret = String::new();
|
let mut state = ContentState::Normal;
|
||||||
let mut remaining = input;
|
let mut remaining = input;
|
||||||
let exit_matcher_parser = parser_with_context!(exit_matcher_parser)(context);
|
let exit_matcher_parser = parser_with_context!(exit_matcher_parser)(context);
|
||||||
loop {
|
loop {
|
||||||
@@ -669,13 +676,28 @@ pub(crate) fn content<'b, 'g, 'r, 's>(
|
|||||||
|
|
||||||
let (remain, (pre_escape_whitespace, line)) = content_line(remaining)?;
|
let (remain, (pre_escape_whitespace, line)) = content_line(remaining)?;
|
||||||
if let Some(val) = pre_escape_whitespace {
|
if let Some(val) = pre_escape_whitespace {
|
||||||
ret.push_str(Into::<&str>::into(val));
|
if let ContentState::Modified(ref mut ret) = state {
|
||||||
|
ret.push_str(Into::<&str>::into(val));
|
||||||
|
} else {
|
||||||
|
let mut ret = String::new();
|
||||||
|
ret.push_str(Into::<&str>::into(input.get_until(remaining)));
|
||||||
|
ret.push_str(Into::<&str>::into(val));
|
||||||
|
state = ContentState::Modified(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let ContentState::Modified(ref mut ret) = state {
|
||||||
|
ret.push_str(line.into());
|
||||||
}
|
}
|
||||||
ret.push_str(line.into());
|
|
||||||
remaining = remain;
|
remaining = remain;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((remaining, ret))
|
match state {
|
||||||
|
ContentState::Normal => Ok((
|
||||||
|
remaining,
|
||||||
|
Cow::Borrowed(Into::<&str>::into(input.get_until(remaining))),
|
||||||
|
)),
|
||||||
|
ContentState::Modified(ret) => Ok((remaining, Cow::Owned(ret))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use nom::Slice;
|
|||||||
|
|
||||||
pub(crate) type BracketDepth = i16;
|
pub(crate) type BracketDepth = i16;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone)]
|
||||||
pub(crate) struct OrgSource<'s> {
|
pub(crate) struct OrgSource<'s> {
|
||||||
full_source: &'s str,
|
full_source: &'s str,
|
||||||
start: usize,
|
start: usize,
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ mod tests {
|
|||||||
use crate::types::PlainText;
|
use crate::types::PlainText;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn plain_text_radio_target() {
|
fn plain_text_radio_target() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let input = OrgSource::new("foo bar baz");
|
let input = OrgSource::new("foo bar baz");
|
||||||
let radio_target_match = vec![Object::PlainText(PlainText { source: "bar" })];
|
let radio_target_match = vec![Object::PlainText(PlainText { source: "bar" })];
|
||||||
let global_settings = GlobalSettings {
|
let global_settings = GlobalSettings {
|
||||||
@@ -200,21 +200,31 @@ mod tests {
|
|||||||
"foo bar baz"
|
"foo bar baz"
|
||||||
);
|
);
|
||||||
assert_eq!(first_paragraph.children.len(), 3);
|
assert_eq!(first_paragraph.children.len(), 3);
|
||||||
assert_eq!(
|
match first_paragraph
|
||||||
first_paragraph
|
.children
|
||||||
.children
|
.get(1)
|
||||||
.get(1)
|
.expect("Len already asserted to be 3.")
|
||||||
.expect("Len already asserted to be 3"),
|
{
|
||||||
&Object::RadioLink(RadioLink {
|
Object::RadioLink(inner) => {
|
||||||
source: "bar ",
|
assert_eq!(inner.get_standard_properties().get_source(), "bar ");
|
||||||
children: vec![Object::PlainText(PlainText { source: "bar" })],
|
assert_eq!(inner.path, "bar");
|
||||||
path: "bar"
|
assert_eq!(inner.children.len(), 1);
|
||||||
})
|
let child = inner
|
||||||
);
|
.children
|
||||||
|
.first()
|
||||||
|
.expect("Length already asserted to be 1.");
|
||||||
|
assert!(matches!(child, Object::PlainText(_)));
|
||||||
|
assert_eq!(child.get_standard_properties().get_source(), "bar");
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err("Child should be a radio link.".into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bold_radio_target() {
|
fn bold_radio_target() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let input = OrgSource::new("foo *bar* baz");
|
let input = OrgSource::new("foo *bar* baz");
|
||||||
let radio_target_match = vec![Object::Bold(Bold {
|
let radio_target_match = vec![Object::Bold(Bold {
|
||||||
source: "*bar*",
|
source: "*bar*",
|
||||||
@@ -239,19 +249,26 @@ mod tests {
|
|||||||
"foo *bar* baz"
|
"foo *bar* baz"
|
||||||
);
|
);
|
||||||
assert_eq!(first_paragraph.children.len(), 3);
|
assert_eq!(first_paragraph.children.len(), 3);
|
||||||
assert_eq!(
|
match first_paragraph
|
||||||
first_paragraph
|
.children
|
||||||
.children
|
.get(1)
|
||||||
.get(1)
|
.expect("Len already asserted to be 3.")
|
||||||
.expect("Len already asserted to be 3"),
|
{
|
||||||
&Object::RadioLink(RadioLink {
|
Object::RadioLink(inner) => {
|
||||||
source: "*bar* ",
|
assert_eq!(inner.get_standard_properties().get_source(), "*bar* ");
|
||||||
children: vec![Object::Bold(Bold {
|
assert_eq!(inner.path, "*bar* ");
|
||||||
source: "*bar* ",
|
assert_eq!(inner.children.len(), 1);
|
||||||
children: vec![Object::PlainText(PlainText { source: "bar" })]
|
let child = inner
|
||||||
})],
|
.children
|
||||||
path: "*bar* "
|
.first()
|
||||||
})
|
.expect("Length already asserted to be 1.");
|
||||||
);
|
assert!(matches!(child, Object::Bold(_)));
|
||||||
|
assert_eq!(child.get_standard_properties().get_source(), "*bar* ");
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err("Child should be a radio link.".into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ use super::CenterBlock;
|
|||||||
use super::Drawer;
|
use super::Drawer;
|
||||||
use super::GetStandardProperties;
|
use super::GetStandardProperties;
|
||||||
use super::QuoteBlock;
|
use super::QuoteBlock;
|
||||||
use super::SetSource;
|
|
||||||
use super::SpecialBlock;
|
use super::SpecialBlock;
|
||||||
use super::StandardProperties;
|
use super::StandardProperties;
|
||||||
|
|
||||||
@@ -55,38 +54,6 @@ pub enum Element<'s> {
|
|||||||
LatexEnvironment(LatexEnvironment<'s>),
|
LatexEnvironment(LatexEnvironment<'s>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> SetSource<'s> for Element<'s> {
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
||||||
fn set_source(&mut self, source: &'s str) {
|
|
||||||
match self {
|
|
||||||
Element::Paragraph(obj) => obj.source = source,
|
|
||||||
Element::PlainList(obj) => obj.source = source,
|
|
||||||
Element::CenterBlock(obj) => obj.source = source,
|
|
||||||
Element::QuoteBlock(obj) => obj.source = source,
|
|
||||||
Element::SpecialBlock(obj) => obj.source = source,
|
|
||||||
Element::DynamicBlock(obj) => obj.source = source,
|
|
||||||
Element::FootnoteDefinition(obj) => obj.source = source,
|
|
||||||
Element::Comment(obj) => obj.source = source,
|
|
||||||
Element::Drawer(obj) => obj.source = source,
|
|
||||||
Element::PropertyDrawer(obj) => obj.source = source,
|
|
||||||
Element::Table(obj) => obj.source = source,
|
|
||||||
Element::VerseBlock(obj) => obj.source = source,
|
|
||||||
Element::CommentBlock(obj) => obj.source = source,
|
|
||||||
Element::ExampleBlock(obj) => obj.source = source,
|
|
||||||
Element::ExportBlock(obj) => obj.source = source,
|
|
||||||
Element::SrcBlock(obj) => obj.source = source,
|
|
||||||
Element::Clock(obj) => obj.source = source,
|
|
||||||
Element::DiarySexp(obj) => obj.source = source,
|
|
||||||
Element::Planning(obj) => obj.source = source,
|
|
||||||
Element::FixedWidthArea(obj) => obj.source = source,
|
|
||||||
Element::HorizontalRule(obj) => obj.source = source,
|
|
||||||
Element::Keyword(obj) => obj.source = source,
|
|
||||||
Element::BabelCall(obj) => obj.source = source,
|
|
||||||
Element::LatexEnvironment(obj) => obj.source = source,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'s> GetStandardProperties<'s> for Element<'s> {
|
impl<'s> GetStandardProperties<'s> for Element<'s> {
|
||||||
fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s> {
|
fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s> {
|
||||||
match self {
|
match self {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use super::object::Object;
|
use super::object::Object;
|
||||||
use super::AffiliatedKeywords;
|
use super::AffiliatedKeywords;
|
||||||
use super::GetAffiliatedKeywords;
|
use super::GetAffiliatedKeywords;
|
||||||
@@ -59,7 +61,7 @@ pub struct ExampleBlock<'s> {
|
|||||||
pub retain_labels: RetainLabels,
|
pub retain_labels: RetainLabels,
|
||||||
pub use_labels: bool,
|
pub use_labels: bool,
|
||||||
pub label_format: Option<&'s str>,
|
pub label_format: Option<&'s str>,
|
||||||
pub contents: String,
|
pub contents: Cow<'s, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -68,7 +70,7 @@ pub struct ExportBlock<'s> {
|
|||||||
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
pub affiliated_keywords: AffiliatedKeywords<'s>,
|
||||||
pub export_type: Option<&'s str>,
|
pub export_type: Option<&'s str>,
|
||||||
pub data: Option<&'s str>,
|
pub data: Option<&'s str>,
|
||||||
pub contents: String,
|
pub contents: Cow<'s, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -83,7 +85,7 @@ pub struct SrcBlock<'s> {
|
|||||||
pub retain_labels: RetainLabels,
|
pub retain_labels: RetainLabels,
|
||||||
pub use_labels: bool,
|
pub use_labels: bool,
|
||||||
pub label_format: Option<&'s str>,
|
pub label_format: Option<&'s str>,
|
||||||
pub contents: String,
|
pub contents: Cow<'s, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -169,11 +171,11 @@ impl<'s> Paragraph<'s> {
|
|||||||
/// Generate a paragraph of the passed in text with no additional properties.
|
/// Generate a paragraph of the passed in text with no additional properties.
|
||||||
///
|
///
|
||||||
/// This is used for elements that support an "empty" content like greater blocks.
|
/// This is used for elements that support an "empty" content like greater blocks.
|
||||||
pub(crate) fn of_text(input: &'s str) -> Self {
|
pub(crate) fn of_text(source: &'s str, body: &'s str) -> Self {
|
||||||
Paragraph {
|
Paragraph {
|
||||||
source: input,
|
source,
|
||||||
affiliated_keywords: AffiliatedKeywords::default(),
|
affiliated_keywords: AffiliatedKeywords::default(),
|
||||||
children: vec![Object::PlainText(PlainText { source: input })],
|
children: vec![Object::PlainText(PlainText { source: body })],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,13 @@ mod greater_element;
|
|||||||
mod lesser_element;
|
mod lesser_element;
|
||||||
mod macros;
|
mod macros;
|
||||||
mod object;
|
mod object;
|
||||||
mod source;
|
|
||||||
mod standard_properties;
|
mod standard_properties;
|
||||||
mod util;
|
mod util;
|
||||||
pub use affiliated_keyword::AffiliatedKeyword;
|
pub use affiliated_keyword::AffiliatedKeyword;
|
||||||
pub use affiliated_keyword::AffiliatedKeywordValue;
|
pub use affiliated_keyword::AffiliatedKeywordValue;
|
||||||
pub use affiliated_keyword::AffiliatedKeywords;
|
pub use affiliated_keyword::AffiliatedKeywords;
|
||||||
pub use affiliated_keyword::GetAffiliatedKeywords;
|
pub use affiliated_keyword::GetAffiliatedKeywords;
|
||||||
pub(crate) use ast_node::AstNode;
|
pub use ast_node::AstNode;
|
||||||
pub use document::Document;
|
pub use document::Document;
|
||||||
pub use document::DocumentElement;
|
pub use document::DocumentElement;
|
||||||
pub use document::Heading;
|
pub use document::Heading;
|
||||||
@@ -113,5 +112,4 @@ pub use object::WarningDelay;
|
|||||||
pub use object::WarningDelayType;
|
pub use object::WarningDelayType;
|
||||||
pub use object::Year;
|
pub use object::Year;
|
||||||
pub use object::YearInner;
|
pub use object::YearInner;
|
||||||
pub(crate) use source::SetSource;
|
|
||||||
pub use standard_properties::StandardProperties;
|
pub use standard_properties::StandardProperties;
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ use super::util::to_lowercase;
|
|||||||
use super::GetStandardProperties;
|
use super::GetStandardProperties;
|
||||||
use super::StandardProperties;
|
use super::StandardProperties;
|
||||||
|
|
||||||
// TODO: Why did we make Object implement PartialEq again? Was it just for tests?
|
#[derive(Debug)]
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum Object<'s> {
|
pub enum Object<'s> {
|
||||||
Bold(Bold<'s>),
|
Bold(Bold<'s>),
|
||||||
Italic(Italic<'s>),
|
Italic(Italic<'s>),
|
||||||
@@ -41,48 +40,48 @@ pub enum Object<'s> {
|
|||||||
Timestamp(Timestamp<'s>),
|
Timestamp(Timestamp<'s>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct Bold<'s> {
|
pub struct Bold<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub children: Vec<Object<'s>>,
|
pub children: Vec<Object<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct Italic<'s> {
|
pub struct Italic<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub children: Vec<Object<'s>>,
|
pub children: Vec<Object<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct Underline<'s> {
|
pub struct Underline<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub children: Vec<Object<'s>>,
|
pub children: Vec<Object<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct StrikeThrough<'s> {
|
pub struct StrikeThrough<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub children: Vec<Object<'s>>,
|
pub children: Vec<Object<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct Code<'s> {
|
pub struct Code<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub contents: &'s str,
|
pub contents: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct Verbatim<'s> {
|
pub struct Verbatim<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub contents: &'s str,
|
pub contents: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct PlainText<'s> {
|
pub struct PlainText<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct RegularLink<'s> {
|
pub struct RegularLink<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub link_type: LinkType<'s>,
|
pub link_type: LinkType<'s>,
|
||||||
@@ -105,21 +104,21 @@ pub struct RegularLink<'s> {
|
|||||||
pub application: Option<Cow<'s, str>>,
|
pub application: Option<Cow<'s, str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct RadioTarget<'s> {
|
pub struct RadioTarget<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
pub children: Vec<Object<'s>>,
|
pub children: Vec<Object<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct RadioLink<'s> {
|
pub struct RadioLink<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub path: &'s str,
|
pub path: &'s str,
|
||||||
pub children: Vec<Object<'s>>,
|
pub children: Vec<Object<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct PlainLink<'s> {
|
pub struct PlainLink<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub link_type: LinkType<'s>,
|
pub link_type: LinkType<'s>,
|
||||||
@@ -129,7 +128,7 @@ pub struct PlainLink<'s> {
|
|||||||
pub application: Option<&'s str>,
|
pub application: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct AngleLink<'s> {
|
pub struct AngleLink<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub link_type: LinkType<'s>,
|
pub link_type: LinkType<'s>,
|
||||||
@@ -147,7 +146,7 @@ pub struct AngleLink<'s> {
|
|||||||
pub application: Option<&'s str>,
|
pub application: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct OrgMacro<'s> {
|
pub struct OrgMacro<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
|
|
||||||
@@ -164,7 +163,7 @@ pub struct OrgMacro<'s> {
|
|||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct Entity<'s> {
|
pub struct Entity<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub name: &'s str,
|
pub name: &'s str,
|
||||||
@@ -177,27 +176,27 @@ pub struct Entity<'s> {
|
|||||||
pub use_brackets: bool,
|
pub use_brackets: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct LatexFragment<'s> {
|
pub struct LatexFragment<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct ExportSnippet<'s> {
|
pub struct ExportSnippet<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub backend: &'s str,
|
pub backend: &'s str,
|
||||||
pub contents: Option<&'s str>,
|
pub contents: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct FootnoteReference<'s> {
|
pub struct FootnoteReference<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub label: Option<&'s str>,
|
pub label: Option<&'s str>,
|
||||||
pub definition: Vec<Object<'s>>,
|
pub definition: Vec<Object<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct Citation<'s> {
|
pub struct Citation<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub style: Option<&'s str>,
|
pub style: Option<&'s str>,
|
||||||
@@ -206,7 +205,7 @@ pub struct Citation<'s> {
|
|||||||
pub children: Vec<CitationReference<'s>>,
|
pub children: Vec<CitationReference<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct CitationReference<'s> {
|
pub struct CitationReference<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub key: &'s str,
|
pub key: &'s str,
|
||||||
@@ -214,7 +213,7 @@ pub struct CitationReference<'s> {
|
|||||||
pub suffix: Vec<Object<'s>>,
|
pub suffix: Vec<Object<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct InlineBabelCall<'s> {
|
pub struct InlineBabelCall<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
@@ -224,7 +223,7 @@ pub struct InlineBabelCall<'s> {
|
|||||||
pub end_header: Option<&'s str>,
|
pub end_header: Option<&'s str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct InlineSourceBlock<'s> {
|
pub struct InlineSourceBlock<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub language: &'s str,
|
pub language: &'s str,
|
||||||
@@ -232,31 +231,31 @@ pub struct InlineSourceBlock<'s> {
|
|||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct LineBreak<'s> {
|
pub struct LineBreak<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct Target<'s> {
|
pub struct Target<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct StatisticsCookie<'s> {
|
pub struct StatisticsCookie<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub value: &'s str,
|
pub value: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct Subscript<'s> {
|
pub struct Subscript<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub use_brackets: bool,
|
pub use_brackets: bool,
|
||||||
pub children: Vec<Object<'s>>,
|
pub children: Vec<Object<'s>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct Superscript<'s> {
|
pub struct Superscript<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub use_brackets: bool,
|
pub use_brackets: bool,
|
||||||
@@ -264,7 +263,7 @@ pub struct Superscript<'s> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Perhaps there is an optimization of converting to unix time we can do to shrink this struct. (ref: clippy::large_enum_variant on Element)
|
// TODO: Perhaps there is an optimization of converting to unix time we can do to shrink this struct. (ref: clippy::large_enum_variant on Element)
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Timestamp<'s> {
|
pub struct Timestamp<'s> {
|
||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
pub timestamp_type: TimestampType,
|
pub timestamp_type: TimestampType,
|
||||||
@@ -277,7 +276,7 @@ pub struct Timestamp<'s> {
|
|||||||
pub warning_delay: Option<WarningDelay>,
|
pub warning_delay: Option<WarningDelay>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum TimestampType {
|
pub enum TimestampType {
|
||||||
Diary,
|
Diary,
|
||||||
Active,
|
Active,
|
||||||
@@ -286,7 +285,7 @@ pub enum TimestampType {
|
|||||||
InactiveRange,
|
InactiveRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum TimestampRangeType {
|
pub enum TimestampRangeType {
|
||||||
None,
|
None,
|
||||||
DateRange,
|
DateRange,
|
||||||
@@ -299,19 +298,19 @@ pub type DayOfMonthInner = u8;
|
|||||||
pub type HourInner = u8;
|
pub type HourInner = u8;
|
||||||
pub type MinuteInner = u8;
|
pub type MinuteInner = u8;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Year(YearInner);
|
pub struct Year(YearInner);
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Month(MonthInner);
|
pub struct Month(MonthInner);
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DayOfMonth(DayOfMonthInner);
|
pub struct DayOfMonth(DayOfMonthInner);
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Hour(HourInner);
|
pub struct Hour(HourInner);
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Minute(MinuteInner);
|
pub struct Minute(MinuteInner);
|
||||||
|
|
||||||
impl Year {
|
impl Year {
|
||||||
@@ -386,7 +385,7 @@ impl Minute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Date<'s> {
|
pub struct Date<'s> {
|
||||||
year: Year,
|
year: Year,
|
||||||
month: Month,
|
month: Month,
|
||||||
@@ -444,7 +443,7 @@ impl<'s> Date<'s> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Time<'s> {
|
pub struct Time<'s> {
|
||||||
hour: Hour,
|
hour: Hour,
|
||||||
minute: Minute,
|
minute: Minute,
|
||||||
@@ -478,20 +477,20 @@ impl<'s> Time<'s> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum RepeaterType {
|
pub enum RepeaterType {
|
||||||
Cumulative,
|
Cumulative,
|
||||||
CatchUp,
|
CatchUp,
|
||||||
Restart,
|
Restart,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum WarningDelayType {
|
pub enum WarningDelayType {
|
||||||
All,
|
All,
|
||||||
First,
|
First,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum TimeUnit {
|
pub enum TimeUnit {
|
||||||
Hour,
|
Hour,
|
||||||
Day,
|
Day,
|
||||||
@@ -502,14 +501,14 @@ pub enum TimeUnit {
|
|||||||
|
|
||||||
pub type RepeaterWarningDelayValueType = u16;
|
pub type RepeaterWarningDelayValueType = u16;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Repeater {
|
pub struct Repeater {
|
||||||
pub repeater_type: RepeaterType,
|
pub repeater_type: RepeaterType,
|
||||||
pub value: RepeaterWarningDelayValueType,
|
pub value: RepeaterWarningDelayValueType,
|
||||||
pub unit: TimeUnit,
|
pub unit: TimeUnit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct WarningDelay {
|
pub struct WarningDelay {
|
||||||
pub warning_delay_type: WarningDelayType,
|
pub warning_delay_type: WarningDelayType,
|
||||||
pub value: RepeaterWarningDelayValueType,
|
pub value: RepeaterWarningDelayValueType,
|
||||||
@@ -718,7 +717,7 @@ impl<'s> Timestamp<'s> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub enum LinkType<'s> {
|
pub enum LinkType<'s> {
|
||||||
File,
|
File,
|
||||||
Protocol(Cow<'s, str>),
|
Protocol(Cow<'s, str>),
|
||||||
@@ -787,7 +786,7 @@ impl<'s> OrgMacro<'s> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub enum FootnoteReferenceType {
|
pub enum FootnoteReferenceType {
|
||||||
Standard,
|
Standard,
|
||||||
Inline,
|
Inline,
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
pub(crate) trait SetSource<'s> {
|
|
||||||
fn set_source(&mut self, source: &'s str);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user