Compare commits
67 Commits
a4a83d047d
...
v0.1.15
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
320b5f8568 | ||
|
|
99b2af6c99 | ||
|
|
6e71acdb7d | ||
|
|
8406d37991 | ||
|
|
64bb597908 | ||
|
|
068864ea87 | ||
|
|
03a3ddbd63 | ||
|
|
122adee23b | ||
|
|
556afecbb8 | ||
|
|
e4407cbdd1 | ||
|
|
f57d60dab0 | ||
|
|
0aa3939a75 | ||
|
|
52cb81e75e | ||
|
|
945121202d | ||
|
|
f4e0dddd9d | ||
|
|
6b62176fd0 | ||
|
|
44483b4d54 | ||
|
|
48d3de77fe | ||
|
|
680b176501 | ||
|
|
dc0338e978 | ||
|
|
ff3e0a50af | ||
|
|
03c8c07fe0 | ||
|
|
3a6fc5b669 | ||
|
|
d258cdb839 | ||
|
|
aa5629354e | ||
|
|
efc4a04829 | ||
|
|
dd611ea64a | ||
|
|
4bd5f3bec7 | ||
|
|
c2b3509b6a | ||
|
|
7f3f5fb889 | ||
|
|
e0fbf17226 | ||
|
|
4e18cbafba | ||
|
|
46c36d7f3e | ||
|
|
c46a935cfc | ||
|
|
f50415cb32 | ||
|
|
4f1a151e97 | ||
|
|
c8e3fdba51 | ||
|
|
4b3fc20c62 | ||
|
|
3131f8ac64 | ||
|
|
60a4835590 | ||
|
|
172d72aa46 | ||
|
|
b4fcc6500b | ||
|
|
ddb6f31562 | ||
|
|
dc080b30fc | ||
|
|
9901e17437 | ||
|
|
ea000894f0 | ||
|
|
e7742b529a | ||
|
|
8eba0c4923 | ||
|
|
e0c0070a13 | ||
|
|
65ce116998 | ||
|
|
e348e7d4e3 | ||
|
|
492090470c | ||
|
|
3ec900c8df | ||
|
|
d0a008ed22 | ||
|
|
f2292f1c07 | ||
|
|
44392cfcca | ||
|
|
110630d230 | ||
|
|
ebe12d96c1 | ||
|
|
24c8ac8e21 | ||
|
|
259ad6e242 | ||
|
|
dd1f7c7777 | ||
|
|
c1b471208d | ||
|
|
606bab9e6d | ||
|
|
0edf5620a2 | ||
|
|
cdf87641c5 | ||
|
|
eb2995dd3b | ||
|
|
cd6a64c015 |
@@ -127,7 +127,7 @@ spec:
|
||||
- name: command
|
||||
value: ["cargo", "fix"]
|
||||
- name: args
|
||||
value: ["--allow-dirty"]
|
||||
value: ["--all-targets", "--all-features", "--allow-dirty"]
|
||||
- name: docker-image
|
||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||
- name: commit-changes
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[package]
|
||||
name = "organic"
|
||||
version = "0.1.13"
|
||||
version = "0.1.15"
|
||||
authors = ["Tom Alexander <tom@fizz.buzz>"]
|
||||
description = "An org-mode parser."
|
||||
edition = "2021"
|
||||
@@ -45,12 +45,14 @@ path = "src/lib.rs"
|
||||
required-features = ["wasm"]
|
||||
|
||||
[[bin]]
|
||||
# This bin exists for development purposes only. The real target of this crate is the library.
|
||||
name = "wasm_test"
|
||||
path = "src/bin_wasm_test.rs"
|
||||
required-features = ["wasm_test"]
|
||||
|
||||
[dependencies]
|
||||
futures = { version = "0.3.28", optional = true }
|
||||
gloo-utils = "0.2.0"
|
||||
nom = "7.1.1"
|
||||
opentelemetry = { version = "0.20.0", optional = true, default-features = false, features = ["trace", "rt-tokio"] }
|
||||
opentelemetry-otlp = { version = "0.13.0", optional = true }
|
||||
|
||||
13
Makefile
13
Makefile
@@ -7,6 +7,7 @@ MAKEFLAGS += --no-builtin-rules
|
||||
TESTJOBS := 4
|
||||
OS:=$(shell uname -s)
|
||||
RELEASEFLAGS :=
|
||||
WASMTARGET := bundler # or web
|
||||
|
||||
ifeq ($(OS),Linux)
|
||||
TESTJOBS:=$(shell nproc)
|
||||
@@ -32,11 +33,7 @@ release:
|
||||
.PHONY: wasm
|
||||
wasm:
|
||||
> cargo build --target=wasm32-unknown-unknown --profile wasm --bin wasm --features wasm
|
||||
> wasm-bindgen --target web --out-dir target/wasm32-unknown-unknown/js target/wasm32-unknown-unknown/wasm/wasm.wasm
|
||||
|
||||
.PHONY: run_wasm
|
||||
run_wasm:
|
||||
> cat /tmp/test.org | cargo run --profile wasm --bin wasm_test --features wasm_test
|
||||
> wasm-bindgen --target $(WASMTARGET) --out-dir target/wasm32-unknown-unknown/js target/wasm32-unknown-unknown/wasm/wasm.wasm
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@@ -58,6 +55,10 @@ clippy:
|
||||
test:
|
||||
> cargo test --no-default-features --features compare --no-fail-fast --lib --test test_loader -- --test-threads $(TESTJOBS)
|
||||
|
||||
.PHONY: doc
|
||||
doc:
|
||||
> cargo doc --no-deps --open --lib --release --all-features
|
||||
|
||||
.PHONY: dockertest
|
||||
dockertest:
|
||||
> $(MAKE) -C docker/organic_test
|
||||
@@ -76,6 +77,8 @@ buildtest:
|
||||
> cargo build --no-default-features --features compare,tracing
|
||||
> cargo build --no-default-features --features compare,foreign_document_test
|
||||
> cargo build --no-default-features --features compare,tracing,foreign_document_test
|
||||
> cargo build --target wasm32-unknown-unknown --profile wasm --bin wasm --no-default-features --features wasm
|
||||
> cargo build --bin wasm_test --no-default-features --features wasm_test
|
||||
|
||||
.PHONY: foreign_document_test
|
||||
foreign_document_test:
|
||||
|
||||
@@ -10,17 +10,16 @@ Currently, Organic parses most documents the same as the official org-mode parse
|
||||
|
||||
### Project Goals
|
||||
- We aim to provide perfect parity with the emacs org-mode parser. In that regard, any document that parses differently between Emacs and Organic is considered a bug.
|
||||
- The parser should have minimal dependencies. This should reduce effort w.r.t.: security audits, legal compliance, portability.
|
||||
- The parser should be usable everywhere. In the interest of getting org-mode used in as many places as possible, this parser should be usable by everyone everywhere. This means:
|
||||
- The parser should have minimal dependencies.
|
||||
- The parser should be usable everywhere. In the interest of getting org used in as many places as possible, this parser should be usable by everyone everywhere. This means:
|
||||
- It must have a permissive license.
|
||||
- We will investigate compiling to WASM. This is an important goal of the project and will definitely happen, but only after the parser has a more stable API.
|
||||
- It compiles to both natively and to wasm.
|
||||
- We will investigate compiling to a C library for native linking to other code. This is more of a maybe-goal for the project.
|
||||
### Project Non-Goals
|
||||
- This project will not include an elisp engine since that would drastically increase the complexity of the code. Any features requiring an elisp engine will not be implemented (for example, Emacs supports embedded eval expressions in documents but this parser will never support that).
|
||||
- This project is exclusively an org-mode **parser**. This limits its scope to roughly the output of `(org-element-parse-buffer)`. It will not render org-mode documents in other formats like HTML or LaTeX.
|
||||
### Project Maybe-Goals
|
||||
- table.el support. Currently we support org-mode tables but org-mode also allows table.el tables. So far, their use in org-mode documents seems rather uncommon so this is a low-priority feature.
|
||||
- Document editing support. I do not anticipate any advanced editing features to make editing ergonomic, but it should be relatively easy to be able to parse an org-mode document and serialize it back into org-mode. This would enable cool features to be built on top of the library like auto-formatters. To accomplish this feature, We'd have to capture all of the various separators and whitespace that we are currently simply throwing away. This would add many additional fields to the parsed structs and it would add more noise to the parsers themselves, so I do not want to approach this feature until the parser is more complete since it would make modifications and refactoring more difficult.
|
||||
### Supported Versions
|
||||
This project targets the version of Emacs and Org-mode that are built into the [organic-test docker image](docker/organic_test/Dockerfile). This is newer than the version of Org-mode that shipped with Emacs 29.1. The parser itself does not depend on Emacs or Org-mode though, so this only matters for development purposes when running the automated tests that compare against upstream Org-mode.
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ endif
|
||||
# NOTE: This target will write to folders underneath the git-root
|
||||
.PHONY: run
|
||||
run: build
|
||||
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)
|
||||
docker run --rm --init -t --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
|
||||
shell: build
|
||||
|
||||
@@ -1,28 +1,8 @@
|
||||
use organic::parser::parse_with_settings;
|
||||
use organic::settings::GlobalSettings;
|
||||
use organic::wasm::ParseResult;
|
||||
use organic::wasm::ToWasm;
|
||||
use organic::wasm::ToWasmContext;
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn parse_org(org_contents: &str) -> wasm_bindgen::JsValue {
|
||||
let rust_parsed = match parse_with_settings(org_contents, &GlobalSettings::default()) {
|
||||
Ok(document) => document,
|
||||
Err(err) => {
|
||||
return serde_wasm_bindgen::to_value(&ParseResult::Error(format!("{:?}", err)))
|
||||
.unwrap();
|
||||
}
|
||||
};
|
||||
let to_wasm_context = ToWasmContext::new(org_contents);
|
||||
let wasm_document = match rust_parsed.to_wasm(to_wasm_context) {
|
||||
Ok(document) => document,
|
||||
Err(err) => {
|
||||
return serde_wasm_bindgen::to_value(&ParseResult::Error(format!("{:?}", err)))
|
||||
.unwrap();
|
||||
}
|
||||
};
|
||||
serde_wasm_bindgen::to_value(&ParseResult::Success(wasm_document)).unwrap()
|
||||
organic::wasm_cli::parse_org(org_contents)
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
use std::path::Path;
|
||||
|
||||
use crate::compare::diff::compare_document;
|
||||
use crate::compare::diff::DiffResult;
|
||||
use crate::compare::sexp::sexp;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::LocalFileAccessInterface;
|
||||
use crate::parser::parse_file_with_settings;
|
||||
use crate::parser::parse_with_settings;
|
||||
use crate::util::emacs_parse_anonymous_org_document;
|
||||
use crate::util::emacs_parse_file_org_document;
|
||||
use crate::util::foreground_color;
|
||||
use crate::util::print_versions;
|
||||
use crate::util::reset_color;
|
||||
use crate::util::cli::emacs_parse_anonymous_org_document;
|
||||
use crate::util::cli::emacs_parse_file_org_document;
|
||||
use crate::util::cli::print_versions;
|
||||
use crate::util::elisp::sexp;
|
||||
use crate::util::terminal::foreground_color;
|
||||
use crate::util::terminal::reset_color;
|
||||
|
||||
pub async fn run_anonymous_compare<P: AsRef<str>>(
|
||||
org_contents: P,
|
||||
|
||||
@@ -9,8 +9,6 @@ use super::diff::artificial_owned_diff_scope;
|
||||
use super::diff::compare_ast_node;
|
||||
use super::diff::DiffEntry;
|
||||
use super::diff::DiffStatus;
|
||||
use super::sexp::unquote;
|
||||
use super::sexp::Token;
|
||||
use super::util::get_property;
|
||||
use super::util::get_property_numeric;
|
||||
use super::util::get_property_quoted_string;
|
||||
@@ -20,6 +18,8 @@ use crate::types::CharOffsetInLine;
|
||||
use crate::types::LineNumber;
|
||||
use crate::types::RetainLabels;
|
||||
use crate::types::SwitchNumberLines;
|
||||
use crate::util::elisp::unquote;
|
||||
use crate::util::elisp::Token;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum EmacsField<'s> {
|
||||
|
||||
@@ -16,10 +16,6 @@ use super::compare_field::compare_property_retain_labels;
|
||||
use super::compare_field::compare_property_set_of_quoted_string;
|
||||
use super::compare_field::compare_property_single_ast_node;
|
||||
use super::compare_field::compare_property_unquoted_atom;
|
||||
use super::elisp_fact::ElispFact;
|
||||
use super::elisp_fact::GetElispFact;
|
||||
use super::sexp::unquote;
|
||||
use super::sexp::Token;
|
||||
use super::util::affiliated_keywords_names;
|
||||
use super::util::assert_no_children;
|
||||
use super::util::compare_additional_properties;
|
||||
@@ -109,8 +105,12 @@ use crate::types::Verbatim;
|
||||
use crate::types::VerseBlock;
|
||||
use crate::types::WarningDelayType;
|
||||
use crate::types::Year;
|
||||
use crate::util::foreground_color;
|
||||
use crate::util::reset_color;
|
||||
use crate::util::elisp::unquote;
|
||||
use crate::util::elisp::Token;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::util::elisp_fact::GetElispFact;
|
||||
use crate::util::terminal::foreground_color;
|
||||
use crate::util::terminal::reset_color;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DiffEntry<'b, 's> {
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
mod compare;
|
||||
mod compare_field;
|
||||
mod diff;
|
||||
mod elisp_fact;
|
||||
mod macros;
|
||||
mod sexp;
|
||||
mod util;
|
||||
pub use compare::run_anonymous_compare;
|
||||
pub use compare::run_anonymous_compare_with_settings;
|
||||
@@ -12,14 +10,3 @@ pub use compare::run_compare_on_file;
|
||||
pub use compare::run_compare_on_file_with_settings;
|
||||
pub use compare::silent_anonymous_compare;
|
||||
pub use compare::silent_compare_on_file;
|
||||
pub(crate) use compare_field::EmacsField;
|
||||
pub(crate) use elisp_fact::ElispFact;
|
||||
pub use sexp::sexp;
|
||||
pub(crate) use sexp::unquote;
|
||||
pub(crate) use sexp::TextWithProperties;
|
||||
pub use sexp::Token;
|
||||
pub(crate) use util::get_emacs_standard_properties;
|
||||
pub(crate) use util::get_property;
|
||||
pub(crate) use util::get_property_quoted_string;
|
||||
pub(crate) use util::maybe_token_to_usize;
|
||||
pub(crate) use util::EmacsStandardProperties;
|
||||
|
||||
@@ -8,14 +8,15 @@ use super::compare_field::compare_property_quoted_string;
|
||||
use super::compare_field::ComparePropertiesResult;
|
||||
use super::diff::DiffEntry;
|
||||
use super::diff::DiffStatus;
|
||||
use super::elisp_fact::GetElispFact;
|
||||
use super::sexp::Token;
|
||||
use crate::compare::diff::compare_ast_node;
|
||||
use crate::compare::sexp::unquote;
|
||||
use crate::types::AffiliatedKeywordValue;
|
||||
use crate::types::AstNode;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::StandardProperties;
|
||||
use crate::util::elisp::get_emacs_standard_properties;
|
||||
use crate::util::elisp::unquote;
|
||||
use crate::util::elisp::Token;
|
||||
use crate::util::elisp_fact::GetElispFact;
|
||||
|
||||
/// Check if the child string slice is a slice of the parent string slice.
|
||||
fn is_slice_of(parent: &str, child: &str) -> bool {
|
||||
@@ -145,80 +146,6 @@ fn assert_post_blank<'b, 's, S: StandardProperties<'s> + ?Sized>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) struct EmacsStandardProperties {
|
||||
pub(crate) begin: Option<usize>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) post_affiliated: Option<usize>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) contents_begin: Option<usize>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) contents_end: Option<usize>,
|
||||
pub(crate) end: Option<usize>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) post_blank: Option<usize>,
|
||||
}
|
||||
|
||||
pub(crate) fn get_emacs_standard_properties(
|
||||
emacs: &Token<'_>,
|
||||
) -> Result<EmacsStandardProperties, Box<dyn std::error::Error>> {
|
||||
let children = emacs.as_list()?;
|
||||
let attributes_child = children.get(1).ok_or("Should have an attributes child.")?;
|
||||
let attributes_map = attributes_child.as_map()?;
|
||||
let standard_properties = attributes_map.get(":standard-properties");
|
||||
Ok(if standard_properties.is_some() {
|
||||
let mut std_props = standard_properties
|
||||
.expect("if statement proves its Some")
|
||||
.as_vector()?
|
||||
.iter();
|
||||
let begin = maybe_token_to_usize(std_props.next())?;
|
||||
let post_affiliated = maybe_token_to_usize(std_props.next())?;
|
||||
let contents_begin = maybe_token_to_usize(std_props.next())?;
|
||||
let contents_end = maybe_token_to_usize(std_props.next())?;
|
||||
let end = maybe_token_to_usize(std_props.next())?;
|
||||
let post_blank = maybe_token_to_usize(std_props.next())?;
|
||||
EmacsStandardProperties {
|
||||
begin,
|
||||
post_affiliated,
|
||||
contents_begin,
|
||||
contents_end,
|
||||
end,
|
||||
post_blank,
|
||||
}
|
||||
} else {
|
||||
let begin = maybe_token_to_usize(attributes_map.get(":begin").copied())?;
|
||||
let end = maybe_token_to_usize(attributes_map.get(":end").copied())?;
|
||||
let contents_begin = maybe_token_to_usize(attributes_map.get(":contents-begin").copied())?;
|
||||
let contents_end = maybe_token_to_usize(attributes_map.get(":contents-end").copied())?;
|
||||
let post_blank = maybe_token_to_usize(attributes_map.get(":post-blank").copied())?;
|
||||
let post_affiliated =
|
||||
maybe_token_to_usize(attributes_map.get(":post-affiliated").copied())?;
|
||||
EmacsStandardProperties {
|
||||
begin,
|
||||
post_affiliated,
|
||||
contents_begin,
|
||||
contents_end,
|
||||
end,
|
||||
post_blank,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) 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))?
|
||||
.and_then(|val| {
|
||||
if val == "nil" {
|
||||
None
|
||||
} else {
|
||||
Some(val.parse::<usize>())
|
||||
}
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?)
|
||||
}
|
||||
|
||||
/// Get a named property from the emacs token.
|
||||
///
|
||||
/// Returns Ok(None) if value is nil or absent.
|
||||
|
||||
@@ -24,7 +24,7 @@ pub(crate) fn record_event(event_type: EventType, input: OrgSource<'_>) {
|
||||
*db.entry(key).or_insert(0) += 1;
|
||||
}
|
||||
|
||||
pub fn report(original_document: &str) {
|
||||
pub(crate) fn report(original_document: &str) {
|
||||
let mut db = GLOBAL_DATA.lock().unwrap();
|
||||
let db = db.get_or_insert_with(HashMap::new);
|
||||
let mut results: Vec<_> = db.iter().collect();
|
||||
|
||||
@@ -2,5 +2,5 @@ mod database;
|
||||
mod event_type;
|
||||
|
||||
pub(crate) use database::record_event;
|
||||
pub use database::report;
|
||||
pub(crate) use database::report;
|
||||
pub(crate) use event_type::EventType;
|
||||
|
||||
15
src/lib.rs
15
src/lib.rs
@@ -4,25 +4,28 @@
|
||||
#![feature(is_sorted)]
|
||||
#![feature(test)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
// TODO: #![warn(missing_docs)]
|
||||
#![allow(clippy::bool_assert_comparison)] // Sometimes you want the long form because its easier to see at a glance.
|
||||
|
||||
extern crate test;
|
||||
|
||||
// TODO: I only include compare to use some shared stuff like sexp and DiffResult. Ideally, this would be moved to a shared module.
|
||||
#[cfg(any(feature = "compare", feature = "wasm_test"))]
|
||||
#[cfg(feature = "compare")]
|
||||
pub mod compare;
|
||||
#[cfg(any(feature = "compare", feature = "wasm_test"))]
|
||||
pub mod util;
|
||||
pub mod parse_cli;
|
||||
#[cfg(any(feature = "compare", feature = "wasm", feature = "wasm_test"))]
|
||||
mod util;
|
||||
#[cfg(any(feature = "wasm", feature = "wasm_test"))]
|
||||
pub mod wasm;
|
||||
mod wasm;
|
||||
#[cfg(any(feature = "wasm", feature = "wasm_test"))]
|
||||
pub mod wasm_cli;
|
||||
#[cfg(feature = "wasm_test")]
|
||||
pub mod wasm_test;
|
||||
|
||||
mod context;
|
||||
mod error;
|
||||
#[cfg(feature = "event_count")]
|
||||
pub mod event_count;
|
||||
mod event_count;
|
||||
mod iter;
|
||||
pub mod parser;
|
||||
pub mod types;
|
||||
|
||||
62
src/main.rs
62
src/main.rs
@@ -1,12 +1,4 @@
|
||||
#![feature(round_char_boundary)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
|
||||
use ::organic::parser::parse;
|
||||
use organic::parser::parse_with_settings;
|
||||
use organic::settings::GlobalSettings;
|
||||
use organic::settings::LocalFileAccessInterface;
|
||||
use organic::parse_cli::main_body;
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
use crate::init_tracing::init_telemetry;
|
||||
@@ -30,55 +22,3 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
main_body_result
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn main_body() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args = std::env::args().skip(1);
|
||||
if args.is_empty() {
|
||||
let org_contents = read_stdin_to_string()?;
|
||||
run_anonymous_parse(org_contents)
|
||||
} else {
|
||||
for arg in args {
|
||||
run_parse_on_file(arg)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn read_stdin_to_string() -> Result<String, Box<dyn std::error::Error>> {
|
||||
let mut stdin_contents = String::new();
|
||||
std::io::stdin()
|
||||
.lock()
|
||||
.read_to_string(&mut stdin_contents)?;
|
||||
Ok(stdin_contents)
|
||||
}
|
||||
|
||||
fn run_anonymous_parse<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let org_contents = org_contents.as_ref();
|
||||
let rust_parsed = parse(org_contents)?;
|
||||
println!("{:#?}", rust_parsed);
|
||||
#[cfg(feature = "event_count")]
|
||||
organic::event_count::report(org_contents);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let org_path = org_path.as_ref();
|
||||
let parent_directory = org_path
|
||||
.parent()
|
||||
.ok_or("Should be contained inside a directory.")?;
|
||||
let org_contents = std::fs::read_to_string(org_path)?;
|
||||
let org_contents = org_contents.as_str();
|
||||
let file_access_interface = LocalFileAccessInterface {
|
||||
working_directory: Some(parent_directory.to_path_buf()),
|
||||
};
|
||||
let global_settings = GlobalSettings {
|
||||
file_access: &file_access_interface,
|
||||
..Default::default()
|
||||
};
|
||||
let rust_parsed = parse_with_settings(org_contents, &global_settings)?;
|
||||
println!("{:#?}", rust_parsed);
|
||||
#[cfg(feature = "event_count")]
|
||||
organic::event_count::report(org_contents);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
59
src/parse_cli/mod.rs
Normal file
59
src/parse_cli/mod.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::parser::parse;
|
||||
use crate::parser::parse_with_settings;
|
||||
use crate::settings::GlobalSettings;
|
||||
use crate::settings::LocalFileAccessInterface;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub fn main_body() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args = std::env::args().skip(1);
|
||||
if args.is_empty() {
|
||||
let org_contents = read_stdin_to_string()?;
|
||||
run_anonymous_parse(org_contents)
|
||||
} else {
|
||||
for arg in args {
|
||||
run_parse_on_file(arg)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn read_stdin_to_string() -> Result<String, Box<dyn std::error::Error>> {
|
||||
let mut stdin_contents = String::new();
|
||||
std::io::stdin()
|
||||
.lock()
|
||||
.read_to_string(&mut stdin_contents)?;
|
||||
Ok(stdin_contents)
|
||||
}
|
||||
|
||||
fn run_anonymous_parse<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let org_contents = org_contents.as_ref();
|
||||
let rust_parsed = parse(org_contents)?;
|
||||
println!("{:#?}", rust_parsed);
|
||||
#[cfg(feature = "event_count")]
|
||||
crate::event_count::report(org_contents);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let org_path = org_path.as_ref();
|
||||
let parent_directory = org_path
|
||||
.parent()
|
||||
.ok_or("Should be contained inside a directory.")?;
|
||||
let org_contents = std::fs::read_to_string(org_path)?;
|
||||
let org_contents = org_contents.as_str();
|
||||
let file_access_interface = LocalFileAccessInterface {
|
||||
working_directory: Some(parent_directory.to_path_buf()),
|
||||
};
|
||||
let global_settings = GlobalSettings {
|
||||
file_access: &file_access_interface,
|
||||
..Default::default()
|
||||
};
|
||||
let rust_parsed = parse_with_settings(org_contents, &global_settings)?;
|
||||
println!("{:#?}", rust_parsed);
|
||||
#[cfg(feature = "event_count")]
|
||||
crate::event_count::report(org_contents);
|
||||
Ok(())
|
||||
}
|
||||
191
src/util/cli.rs
Normal file
191
src/util/cli.rs
Normal file
@@ -0,0 +1,191 @@
|
||||
use std::path::Path;
|
||||
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::settings::GlobalSettings;
|
||||
use crate::settings::HeadlineLevelFilter;
|
||||
|
||||
pub async fn print_versions() -> Result<(), Box<dyn std::error::Error>> {
|
||||
eprintln!("Using emacs version: {}", get_emacs_version().await?.trim());
|
||||
eprintln!(
|
||||
"Using org-mode version: {}",
|
||||
get_org_mode_version().await?.trim()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async 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 cmd = cmd
|
||||
.arg("-q")
|
||||
.arg("--no-site-file")
|
||||
.arg("--no-splash")
|
||||
.arg("--batch")
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
|
||||
let out = cmd.output().await?;
|
||||
out.status.exit_ok()?;
|
||||
Ok(String::from_utf8(out.stderr)?)
|
||||
}
|
||||
|
||||
pub(crate) async 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 cmd = cmd
|
||||
.arg("-q")
|
||||
.arg("--no-site-file")
|
||||
.arg("--no-splash")
|
||||
.arg("--batch")
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
|
||||
let out = cmd.output().await?;
|
||||
out.status.exit_ok()?;
|
||||
Ok(String::from_utf8(out.stderr)?)
|
||||
}
|
||||
|
||||
pub(crate) async fn emacs_parse_anonymous_org_document<'g, 's, C>(
|
||||
file_contents: C,
|
||||
global_settings: &GlobalSettings<'g, 's>,
|
||||
) -> Result<String, Box<dyn std::error::Error>>
|
||||
where
|
||||
C: AsRef<str>,
|
||||
{
|
||||
let escaped_file_contents = escape_elisp_string(file_contents);
|
||||
let elisp_script = format!(
|
||||
r#"(progn
|
||||
(erase-buffer)
|
||||
(require 'org)
|
||||
(defun org-table-align () t)
|
||||
(insert "{escaped_file_contents}")
|
||||
{global_settings}
|
||||
(org-mode)
|
||||
(message "%s" (pp-to-string (org-element-parse-buffer)))
|
||||
)"#,
|
||||
escaped_file_contents = escaped_file_contents,
|
||||
global_settings = global_settings_elisp(global_settings)
|
||||
);
|
||||
let mut cmd = Command::new("emacs");
|
||||
let cmd = cmd
|
||||
.arg("-q")
|
||||
.arg("--no-site-file")
|
||||
.arg("--no-splash")
|
||||
.arg("--batch")
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
let out = cmd.output().await?;
|
||||
let status = out.status.exit_ok();
|
||||
if status.is_err() {
|
||||
eprintln!(
|
||||
"Emacs errored out: {}\n{}",
|
||||
String::from_utf8(out.stdout)?,
|
||||
String::from_utf8(out.stderr)?
|
||||
);
|
||||
status?;
|
||||
unreachable!();
|
||||
}
|
||||
let org_sexp = out.stderr;
|
||||
Ok(String::from_utf8(org_sexp)?)
|
||||
}
|
||||
|
||||
pub(crate) async fn emacs_parse_file_org_document<'g, 's, P>(
|
||||
file_path: P,
|
||||
global_settings: &GlobalSettings<'g, 's>,
|
||||
) -> Result<String, Box<dyn std::error::Error>>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let file_path = file_path.as_ref().canonicalize()?;
|
||||
let containing_directory = file_path.parent().ok_or(format!(
|
||||
"Failed to get containing directory for path {}",
|
||||
file_path.display()
|
||||
))?;
|
||||
let elisp_script = format!(
|
||||
r#"(progn
|
||||
(require 'org)
|
||||
(defun org-table-align () t)
|
||||
(setq vc-handled-backends nil)
|
||||
{global_settings}
|
||||
(find-file-read-only "{file_path}")
|
||||
(org-mode)
|
||||
(message "%s" (pp-to-string (org-element-parse-buffer)))
|
||||
)"#,
|
||||
global_settings = global_settings_elisp(global_settings),
|
||||
file_path = file_path
|
||||
.as_os_str()
|
||||
.to_str()
|
||||
.expect("File name should be valid utf-8.")
|
||||
);
|
||||
let mut cmd = Command::new("emacs");
|
||||
let cmd = cmd
|
||||
.current_dir(containing_directory)
|
||||
.arg("-q")
|
||||
.arg("--no-site-file")
|
||||
.arg("--no-splash")
|
||||
.arg("--batch")
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
let out = cmd.output().await?;
|
||||
let status = out.status.exit_ok();
|
||||
if status.is_err() {
|
||||
eprintln!(
|
||||
"Emacs errored out: {}\n{}",
|
||||
String::from_utf8(out.stdout)?,
|
||||
String::from_utf8(out.stderr)?
|
||||
);
|
||||
status?;
|
||||
unreachable!();
|
||||
}
|
||||
let org_sexp = out.stderr;
|
||||
Ok(String::from_utf8(org_sexp)?)
|
||||
}
|
||||
|
||||
fn escape_elisp_string<C>(file_contents: C) -> String
|
||||
where
|
||||
C: AsRef<str>,
|
||||
{
|
||||
let source = file_contents.as_ref();
|
||||
let source_len = source.len();
|
||||
// We allocate a string 10% larger than the source to account for escape characters. Without this, we would have more allocations during processing.
|
||||
let mut output = String::with_capacity(source_len + (source_len / 10));
|
||||
for c in source.chars() {
|
||||
match c {
|
||||
'"' | '\\' => {
|
||||
output.push('\\');
|
||||
output.push(c);
|
||||
}
|
||||
_ => {
|
||||
output.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
/// Generate elisp to configure org-mode parsing settings
|
||||
///
|
||||
/// Currently only org-list-allow-alphabetical is supported.
|
||||
fn global_settings_elisp(global_settings: &GlobalSettings) -> String {
|
||||
// This string concatenation is wildly inefficient but its only called in tests 🤷.
|
||||
let mut ret = "".to_owned();
|
||||
if global_settings.list_allow_alphabetical {
|
||||
ret += "(setq org-list-allow-alphabetical t)\n"
|
||||
}
|
||||
if global_settings.tab_width != crate::settings::DEFAULT_TAB_WIDTH {
|
||||
ret += format!("(setq-default tab-width {})", global_settings.tab_width).as_str();
|
||||
}
|
||||
if global_settings.odd_levels_only != HeadlineLevelFilter::default() {
|
||||
ret += match global_settings.odd_levels_only {
|
||||
HeadlineLevelFilter::Odd => "(setq org-odd-levels-only t)\n",
|
||||
HeadlineLevelFilter::OddEven => "(setq org-odd-levels-only nil)\n",
|
||||
};
|
||||
}
|
||||
ret
|
||||
}
|
||||
14
src/util/elisp/mod.rs
Normal file
14
src/util/elisp/mod.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
mod sexp;
|
||||
mod util;
|
||||
|
||||
pub use sexp::sexp;
|
||||
pub(crate) use sexp::unquote;
|
||||
#[cfg(feature = "wasm_test")]
|
||||
pub(crate) use sexp::TextWithProperties;
|
||||
pub use sexp::Token;
|
||||
#[cfg(feature = "compare")]
|
||||
pub(crate) use util::get_emacs_standard_properties;
|
||||
#[cfg(feature = "wasm_test")]
|
||||
pub(crate) use util::maybe_token_to_usize;
|
||||
#[cfg(feature = "wasm_test")]
|
||||
pub(crate) use util::EmacsStandardProperties;
|
||||
@@ -61,6 +61,7 @@ impl<'s> Token<'s> {
|
||||
}?)
|
||||
}
|
||||
|
||||
#[cfg(feature = "compare")]
|
||||
pub(crate) fn as_text<'p>(
|
||||
&'p self,
|
||||
) -> Result<&'p TextWithProperties<'s>, Box<dyn std::error::Error>> {
|
||||
76
src/util/elisp/util.rs
Normal file
76
src/util/elisp/util.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use super::Token;
|
||||
|
||||
pub(crate) 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))?
|
||||
.and_then(|val| {
|
||||
if val == "nil" {
|
||||
None
|
||||
} else {
|
||||
Some(val.parse::<usize>())
|
||||
}
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?)
|
||||
}
|
||||
|
||||
pub(crate) struct EmacsStandardProperties {
|
||||
pub(crate) begin: Option<usize>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) post_affiliated: Option<usize>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) contents_begin: Option<usize>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) contents_end: Option<usize>,
|
||||
pub(crate) end: Option<usize>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) post_blank: Option<usize>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "compare")]
|
||||
pub(crate) fn get_emacs_standard_properties(
|
||||
emacs: &Token<'_>,
|
||||
) -> Result<EmacsStandardProperties, Box<dyn std::error::Error>> {
|
||||
let children = emacs.as_list()?;
|
||||
let attributes_child = children.get(1).ok_or("Should have an attributes child.")?;
|
||||
let attributes_map = attributes_child.as_map()?;
|
||||
let standard_properties = attributes_map.get(":standard-properties");
|
||||
Ok(if standard_properties.is_some() {
|
||||
let mut std_props = standard_properties
|
||||
.expect("if statement proves its Some")
|
||||
.as_vector()?
|
||||
.iter();
|
||||
let begin = maybe_token_to_usize(std_props.next())?;
|
||||
let post_affiliated = maybe_token_to_usize(std_props.next())?;
|
||||
let contents_begin = maybe_token_to_usize(std_props.next())?;
|
||||
let contents_end = maybe_token_to_usize(std_props.next())?;
|
||||
let end = maybe_token_to_usize(std_props.next())?;
|
||||
let post_blank = maybe_token_to_usize(std_props.next())?;
|
||||
EmacsStandardProperties {
|
||||
begin,
|
||||
post_affiliated,
|
||||
contents_begin,
|
||||
contents_end,
|
||||
end,
|
||||
post_blank,
|
||||
}
|
||||
} else {
|
||||
let begin = maybe_token_to_usize(attributes_map.get(":begin").copied())?;
|
||||
let end = maybe_token_to_usize(attributes_map.get(":end").copied())?;
|
||||
let contents_begin = maybe_token_to_usize(attributes_map.get(":contents-begin").copied())?;
|
||||
let contents_end = maybe_token_to_usize(attributes_map.get(":contents-end").copied())?;
|
||||
let post_blank = maybe_token_to_usize(attributes_map.get(":post-blank").copied())?;
|
||||
let post_affiliated =
|
||||
maybe_token_to_usize(attributes_map.get(":post-affiliated").copied())?;
|
||||
EmacsStandardProperties {
|
||||
begin,
|
||||
post_affiliated,
|
||||
contents_begin,
|
||||
contents_end,
|
||||
end,
|
||||
post_blank,
|
||||
}
|
||||
})
|
||||
}
|
||||
241
src/util/mod.rs
241
src/util/mod.rs
@@ -1,233 +1,8 @@
|
||||
use std::borrow::Cow;
|
||||
use std::path::Path;
|
||||
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::settings::GlobalSettings;
|
||||
use crate::settings::HeadlineLevelFilter;
|
||||
|
||||
pub async fn print_versions() -> Result<(), Box<dyn std::error::Error>> {
|
||||
eprintln!("Using emacs version: {}", get_emacs_version().await?.trim());
|
||||
eprintln!(
|
||||
"Using org-mode version: {}",
|
||||
get_org_mode_version().await?.trim()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async 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 cmd = cmd
|
||||
.arg("-q")
|
||||
.arg("--no-site-file")
|
||||
.arg("--no-splash")
|
||||
.arg("--batch")
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
|
||||
let out = cmd.output().await?;
|
||||
out.status.exit_ok()?;
|
||||
Ok(String::from_utf8(out.stderr)?)
|
||||
}
|
||||
|
||||
pub(crate) async 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 cmd = cmd
|
||||
.arg("-q")
|
||||
.arg("--no-site-file")
|
||||
.arg("--no-splash")
|
||||
.arg("--batch")
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
|
||||
let out = cmd.output().await?;
|
||||
out.status.exit_ok()?;
|
||||
Ok(String::from_utf8(out.stderr)?)
|
||||
}
|
||||
|
||||
pub(crate) async fn emacs_parse_anonymous_org_document<'g, 's, C>(
|
||||
file_contents: C,
|
||||
global_settings: &GlobalSettings<'g, 's>,
|
||||
) -> Result<String, Box<dyn std::error::Error>>
|
||||
where
|
||||
C: AsRef<str>,
|
||||
{
|
||||
let escaped_file_contents = escape_elisp_string(file_contents);
|
||||
let elisp_script = format!(
|
||||
r#"(progn
|
||||
(erase-buffer)
|
||||
(require 'org)
|
||||
(defun org-table-align () t)
|
||||
(insert "{escaped_file_contents}")
|
||||
{global_settings}
|
||||
(org-mode)
|
||||
(message "%s" (pp-to-string (org-element-parse-buffer)))
|
||||
)"#,
|
||||
escaped_file_contents = escaped_file_contents,
|
||||
global_settings = global_settings_elisp(global_settings)
|
||||
);
|
||||
let mut cmd = Command::new("emacs");
|
||||
let cmd = cmd
|
||||
.arg("-q")
|
||||
.arg("--no-site-file")
|
||||
.arg("--no-splash")
|
||||
.arg("--batch")
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
let out = cmd.output().await?;
|
||||
let status = out.status.exit_ok();
|
||||
if status.is_err() {
|
||||
eprintln!(
|
||||
"Emacs errored out: {}\n{}",
|
||||
String::from_utf8(out.stdout)?,
|
||||
String::from_utf8(out.stderr)?
|
||||
);
|
||||
status?;
|
||||
unreachable!();
|
||||
}
|
||||
let org_sexp = out.stderr;
|
||||
Ok(String::from_utf8(org_sexp)?)
|
||||
}
|
||||
|
||||
pub(crate) async fn emacs_parse_file_org_document<'g, 's, P>(
|
||||
file_path: P,
|
||||
global_settings: &GlobalSettings<'g, 's>,
|
||||
) -> Result<String, Box<dyn std::error::Error>>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let file_path = file_path.as_ref().canonicalize()?;
|
||||
let containing_directory = file_path.parent().ok_or(format!(
|
||||
"Failed to get containing directory for path {}",
|
||||
file_path.display()
|
||||
))?;
|
||||
let elisp_script = format!(
|
||||
r#"(progn
|
||||
(require 'org)
|
||||
(defun org-table-align () t)
|
||||
(setq vc-handled-backends nil)
|
||||
{global_settings}
|
||||
(find-file-read-only "{file_path}")
|
||||
(org-mode)
|
||||
(message "%s" (pp-to-string (org-element-parse-buffer)))
|
||||
)"#,
|
||||
global_settings = global_settings_elisp(global_settings),
|
||||
file_path = file_path
|
||||
.as_os_str()
|
||||
.to_str()
|
||||
.expect("File name should be valid utf-8.")
|
||||
);
|
||||
let mut cmd = Command::new("emacs");
|
||||
let cmd = cmd
|
||||
.current_dir(containing_directory)
|
||||
.arg("-q")
|
||||
.arg("--no-site-file")
|
||||
.arg("--no-splash")
|
||||
.arg("--batch")
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
let out = cmd.output().await?;
|
||||
let status = out.status.exit_ok();
|
||||
if status.is_err() {
|
||||
eprintln!(
|
||||
"Emacs errored out: {}\n{}",
|
||||
String::from_utf8(out.stdout)?,
|
||||
String::from_utf8(out.stderr)?
|
||||
);
|
||||
status?;
|
||||
unreachable!();
|
||||
}
|
||||
let org_sexp = out.stderr;
|
||||
Ok(String::from_utf8(org_sexp)?)
|
||||
}
|
||||
|
||||
fn escape_elisp_string<C>(file_contents: C) -> String
|
||||
where
|
||||
C: AsRef<str>,
|
||||
{
|
||||
let source = file_contents.as_ref();
|
||||
let source_len = source.len();
|
||||
// We allocate a string 10% larger than the source to account for escape characters. Without this, we would have more allocations during processing.
|
||||
let mut output = String::with_capacity(source_len + (source_len / 10));
|
||||
for c in source.chars() {
|
||||
match c {
|
||||
'"' | '\\' => {
|
||||
output.push('\\');
|
||||
output.push(c);
|
||||
}
|
||||
_ => {
|
||||
output.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
/// Generate elisp to configure org-mode parsing settings
|
||||
///
|
||||
/// Currently only org-list-allow-alphabetical is supported.
|
||||
fn global_settings_elisp(global_settings: &GlobalSettings) -> String {
|
||||
// This string concatenation is wildly inefficient but its only called in tests 🤷.
|
||||
let mut ret = "".to_owned();
|
||||
if global_settings.list_allow_alphabetical {
|
||||
ret += "(setq org-list-allow-alphabetical t)\n"
|
||||
}
|
||||
if global_settings.tab_width != crate::settings::DEFAULT_TAB_WIDTH {
|
||||
ret += format!("(setq-default tab-width {})", global_settings.tab_width).as_str();
|
||||
}
|
||||
if global_settings.odd_levels_only != HeadlineLevelFilter::default() {
|
||||
ret += match global_settings.odd_levels_only {
|
||||
HeadlineLevelFilter::Odd => "(setq org-odd-levels-only t)\n",
|
||||
HeadlineLevelFilter::OddEven => "(setq org-odd-levels-only nil)\n",
|
||||
};
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn should_use_color() -> bool {
|
||||
!std::env::var("NO_COLOR").is_ok_and(|val| !val.is_empty())
|
||||
}
|
||||
|
||||
pub(crate) fn foreground_color(red: u8, green: u8, blue: u8) -> Cow<'static, str> {
|
||||
if should_use_color() {
|
||||
format!(
|
||||
"\x1b[38;2;{red};{green};{blue}m",
|
||||
red = red,
|
||||
green = green,
|
||||
blue = blue
|
||||
)
|
||||
.into()
|
||||
} else {
|
||||
Cow::from("")
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn background_color(red: u8, green: u8, blue: u8) -> Cow<'static, str> {
|
||||
if should_use_color() {
|
||||
format!(
|
||||
"\x1b[48;2;{red};{green};{blue}m",
|
||||
red = red,
|
||||
green = green,
|
||||
blue = blue
|
||||
)
|
||||
.into()
|
||||
} else {
|
||||
Cow::from("")
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn reset_color() -> &'static str {
|
||||
if should_use_color() {
|
||||
"\x1b[0m"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
#[cfg(any(feature = "compare", feature = "wasm_test"))]
|
||||
pub mod cli;
|
||||
#[cfg(any(feature = "compare", feature = "wasm_test"))]
|
||||
pub mod elisp;
|
||||
#[cfg(any(feature = "compare", feature = "wasm", feature = "wasm_test"))]
|
||||
pub mod elisp_fact;
|
||||
#[cfg(any(feature = "compare", feature = "wasm_test"))]
|
||||
pub mod terminal;
|
||||
|
||||
42
src/util/terminal.rs
Normal file
42
src/util/terminal.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
fn should_use_color() -> bool {
|
||||
!std::env::var("NO_COLOR").is_ok_and(|val| !val.is_empty())
|
||||
}
|
||||
|
||||
pub(crate) fn foreground_color(red: u8, green: u8, blue: u8) -> Cow<'static, str> {
|
||||
if should_use_color() {
|
||||
format!(
|
||||
"\x1b[38;2;{red};{green};{blue}m",
|
||||
red = red,
|
||||
green = green,
|
||||
blue = blue
|
||||
)
|
||||
.into()
|
||||
} else {
|
||||
Cow::from("")
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn background_color(red: u8, green: u8, blue: u8) -> Cow<'static, str> {
|
||||
if should_use_color() {
|
||||
format!(
|
||||
"\x1b[48;2;{red};{green};{blue}m",
|
||||
red = red,
|
||||
green = green,
|
||||
blue = blue
|
||||
)
|
||||
.into()
|
||||
} else {
|
||||
Cow::from("")
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn reset_color() -> &'static str {
|
||||
if should_use_color() {
|
||||
"\x1b[0m"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use serde::Deserialize;
|
||||
@@ -31,12 +30,6 @@ pub struct AdditionalProperties {
|
||||
pub(crate) properties: HashMap<String, AdditionalPropertyValue>,
|
||||
}
|
||||
|
||||
impl AdditionalProperties {
|
||||
pub(crate) fn get_elisp_names<'c>(&'c self) -> impl Iterator<Item = String> + 'c {
|
||||
self.properties.keys().map(move |key| format!(":{}", key))
|
||||
}
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
AdditionalProperties,
|
||||
AffiliatedKeywords<'s>,
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::AngleLink;
|
||||
use crate::types::LinkType;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "format")]
|
||||
#[serde(rename = "angle")]
|
||||
pub struct WasmAngleLink {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "type")]
|
||||
pub(crate) link_type: String,
|
||||
pub(crate) path: String,
|
||||
#[serde(rename = "raw-link")]
|
||||
pub(crate) raw_link: String,
|
||||
pub(crate) application: Option<String>,
|
||||
#[serde(rename = "search-option")]
|
||||
pub(crate) search_option: Option<String>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +31,23 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::AngleLink(original) },
|
||||
{ "TODO".into() },
|
||||
{ "link".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmAngleLink {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
link_type: match &original.link_type {
|
||||
LinkType::File => "file".to_owned(),
|
||||
LinkType::Protocol(protocol) => protocol.clone().into_owned(),
|
||||
LinkType::Id => "id".to_owned(),
|
||||
LinkType::CustomId => "custom-id".to_owned(),
|
||||
LinkType::CodeRef => "coderef".to_owned(),
|
||||
LinkType::Fuzzy => "fuzzy".to_owned(),
|
||||
},
|
||||
path: original.get_path().into_owned(),
|
||||
raw_link: original.raw_link.to_owned(),
|
||||
application: original.application.map(|c| c.to_owned()),
|
||||
search_option: original.get_search_option().map(Cow::into_owned),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,14 +5,22 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::BabelCall;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmBabelCall {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) call: Option<String>,
|
||||
#[serde(rename = "inside-header")]
|
||||
pub(crate) inside_header: Option<String>,
|
||||
pub(crate) arguments: Option<String>,
|
||||
#[serde(rename = "end-header")]
|
||||
pub(crate) end_header: Option<String>,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +29,21 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::BabelCall(original) },
|
||||
{ "TODO".into() },
|
||||
{ "babel-call".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmBabelCall {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
call: original.call.map(|s| s.to_owned()),
|
||||
inside_header: original.inside_header.map(|s| s.to_owned()),
|
||||
arguments: original.arguments.map(|s| s.to_owned()),
|
||||
end_header: original.end_header.map(|s| s.to_owned()),
|
||||
value: original.value.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Bold;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
||||
@@ -5,8 +5,9 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::CenterBlock;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -21,8 +22,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::CenterBlock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "center-block".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
let children = original
|
||||
.children
|
||||
.iter()
|
||||
@@ -36,7 +41,7 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmCenterBlock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Citation;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmCitation {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) style: Option<String>,
|
||||
pub(crate) prefix: Option<Vec<WasmAstNode>>,
|
||||
pub(crate) suffix: Option<Vec<WasmAstNode>>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,7 +21,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Citation(original) },
|
||||
{ "TODO".into() },
|
||||
{ "citation".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -32,11 +32,39 @@ to_wasm!(
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let prefix = original
|
||||
.prefix
|
||||
.iter()
|
||||
.map(|child| {
|
||||
child
|
||||
.to_wasm(wasm_context.clone())
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let suffix = original
|
||||
.suffix
|
||||
.iter()
|
||||
.map(|child| {
|
||||
child
|
||||
.to_wasm(wasm_context.clone())
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok((
|
||||
children,
|
||||
WasmCitation {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
style: original.style.map(|s| s.to_owned()),
|
||||
prefix: if prefix.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(prefix)
|
||||
},
|
||||
suffix: if suffix.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(suffix)
|
||||
},
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::CitationReference;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmCitationReference {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) key: String,
|
||||
pub(crate) prefix: Option<Vec<WasmAstNode>>,
|
||||
pub(crate) suffix: Option<Vec<WasmAstNode>>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +21,41 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::CitationReference(original) },
|
||||
{ "TODO".into() },
|
||||
{ "citation-reference".into() },
|
||||
{
|
||||
let prefix = original
|
||||
.prefix
|
||||
.iter()
|
||||
.map(|child| {
|
||||
child
|
||||
.to_wasm(wasm_context.clone())
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let suffix = original
|
||||
.suffix
|
||||
.iter()
|
||||
.map(|child| {
|
||||
child
|
||||
.to_wasm(wasm_context.clone())
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmCitationReference {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
key: original.key.to_owned(),
|
||||
prefix: if prefix.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(prefix)
|
||||
},
|
||||
suffix: if suffix.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(suffix)
|
||||
},
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,17 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Clock;
|
||||
use crate::types::ClockStatus;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmClock {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "value")]
|
||||
pub(crate) timestamp: Box<WasmAstNode>,
|
||||
pub(crate) duration: Option<String>,
|
||||
pub(crate) status: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +23,20 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Clock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "clock".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmClock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
timestamp: Box::new(Into::<WasmAstNode>::into(
|
||||
original.timestamp.to_wasm(wasm_context.clone())?,
|
||||
)),
|
||||
duration: original.duration.map(|s| s.to_owned()),
|
||||
status: match original.status {
|
||||
ClockStatus::Running => "running",
|
||||
ClockStatus::Closed => "closed",
|
||||
}
|
||||
.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,13 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Code;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmCode {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +19,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Code(original) },
|
||||
{ "TODO".into() },
|
||||
{ "code".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmCode {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
value: original.contents.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,13 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Comment;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmComment {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +19,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Comment(original) },
|
||||
{ "TODO".into() },
|
||||
{ "comment".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmComment {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
value: original.get_value(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,14 +5,16 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::CommentBlock;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmCommentBlock {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +23,17 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::CommentBlock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "comment-block".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmCommentBlock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
value: original.contents.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,14 +5,16 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::DiarySexp;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmDiarySexp {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +23,17 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::DiarySexp(original) },
|
||||
{ "TODO".into() },
|
||||
{ "diary-sexp".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmDiarySexp {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
value: original.value.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ use super::additional_property::AdditionalPropertyValue;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Document;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -29,7 +29,7 @@ to_wasm!(
|
||||
{ WasmAstNode::Document(original) },
|
||||
{ "org-data".into() },
|
||||
{
|
||||
let category = original.category.as_ref().map(String::as_str);
|
||||
let category = original.category.as_deref();
|
||||
let path = original.path.clone();
|
||||
|
||||
let mut additional_properties = AdditionalProperties::default();
|
||||
|
||||
@@ -5,14 +5,17 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Drawer;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmDrawer {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "drawer-name")]
|
||||
pub(crate) drawer_name: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,8 +24,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Drawer(original) },
|
||||
{ "TODO".into() },
|
||||
{ "drawer".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
let children = original
|
||||
.children
|
||||
.iter()
|
||||
@@ -36,7 +43,8 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmDrawer {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
drawer_name: original.drawer_name.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,14 +5,18 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::DynamicBlock;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmDynamicBlock {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "block-name")]
|
||||
pub(crate) block_name: String,
|
||||
pub(crate) arguments: Option<String>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,8 +25,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::DynamicBlock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "dynamic-block".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
let children = original
|
||||
.children
|
||||
.iter()
|
||||
@@ -36,7 +44,9 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmDynamicBlock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
block_name: original.block_name.to_owned(),
|
||||
arguments: original.parameters.map(|s| s.to_owned()),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -2,17 +2,26 @@ use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::headline::Noop;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Entity;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmEntity {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) name: String,
|
||||
pub(crate) latex: String,
|
||||
#[serde(rename = "latex-math-p")]
|
||||
pub(crate) latex_math_mode: bool,
|
||||
pub(crate) html: String,
|
||||
pub(crate) ascii: String,
|
||||
pub(crate) latin1: Noop,
|
||||
#[serde(rename = "utf-8")]
|
||||
pub(crate) utf8: String,
|
||||
#[serde(rename = "use-brackets-p")]
|
||||
pub(crate) use_brackets: bool,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +30,19 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Entity(original) },
|
||||
{ "TODO".into() },
|
||||
{ "entity".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmEntity {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
name: original.name.to_owned(),
|
||||
latex: original.latex.to_owned(),
|
||||
latex_math_mode: original.latex_math_mode,
|
||||
html: original.html.to_owned(),
|
||||
ascii: original.ascii.to_owned(),
|
||||
latin1: Noop {},
|
||||
utf8: original.utf8.to_owned(),
|
||||
use_brackets: original.use_brackets,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -3,16 +3,35 @@ use serde::Serialize;
|
||||
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::src_block::WasmNumberLines;
|
||||
use super::src_block::WasmNumberLinesWrapper;
|
||||
use super::src_block::WasmRetainLabels;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::CharOffsetInLine;
|
||||
use crate::types::ExampleBlock;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::RetainLabels;
|
||||
use crate::types::SwitchNumberLines;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmExampleBlock {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) value: String,
|
||||
pub(crate) switches: Option<String>,
|
||||
#[serde(rename = "number-lines")]
|
||||
pub(crate) number_lines: Option<WasmNumberLinesWrapper>,
|
||||
#[serde(rename = "preserve-indent")]
|
||||
pub(crate) preserve_indent: Option<CharOffsetInLine>,
|
||||
#[serde(rename = "retain-labels")]
|
||||
pub(crate) retain_labels: WasmRetainLabels,
|
||||
#[serde(rename = "use-labels")]
|
||||
pub(crate) use_labels: bool,
|
||||
#[serde(rename = "label-fmt")]
|
||||
pub(crate) label_format: Option<String>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +40,35 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::ExampleBlock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "example-block".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmExampleBlock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
value: original.get_value().into_owned(),
|
||||
switches: original.switches.map(|s| s.to_owned()),
|
||||
number_lines: match original.number_lines {
|
||||
None => None,
|
||||
Some(SwitchNumberLines::New(n)) => Some(WasmNumberLinesWrapper {
|
||||
inner: WasmNumberLines::New(n),
|
||||
}),
|
||||
Some(SwitchNumberLines::Continued(n)) => Some(WasmNumberLinesWrapper {
|
||||
inner: WasmNumberLines::Continued(n),
|
||||
}),
|
||||
},
|
||||
preserve_indent: original.preserve_indent,
|
||||
retain_labels: match original.retain_labels {
|
||||
RetainLabels::No => WasmRetainLabels::YesNo(false),
|
||||
RetainLabels::Yes => WasmRetainLabels::YesNo(true),
|
||||
RetainLabels::Keep(n) => WasmRetainLabels::Keep(n),
|
||||
},
|
||||
use_labels: original.use_labels,
|
||||
label_format: original.label_format.map(|s| s.to_owned()),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,14 +5,18 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::ExportBlock;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmExportBlock {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "type")]
|
||||
pub(crate) export_type: Option<String>,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +25,18 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::ExportBlock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "export-block".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmExportBlock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
export_type: original.get_export_type(),
|
||||
value: original.get_value().into_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::ExportSnippet;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmExportSnippet {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "back-end")]
|
||||
pub(crate) backend: String,
|
||||
pub(crate) value: Option<String>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +21,13 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::ExportSnippet(original) },
|
||||
{ "TODO".into() },
|
||||
{ "export-snippet".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmExportSnippet {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
backend: original.backend.to_owned(),
|
||||
value: original.contents.map(|s| s.to_owned()),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::FixedWidthArea;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
||||
@@ -2,17 +2,22 @@ use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::headline::Noop;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::FootnoteDefinition;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmFootnoteDefinition {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) label: String,
|
||||
#[serde(rename = "pre-blank")]
|
||||
pub(crate) pre_blank: Noop,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,8 +26,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::FootnoteDefinition(original) },
|
||||
{ "TODO".into() },
|
||||
{ "footnote-definition".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
let children = original
|
||||
.children
|
||||
.iter()
|
||||
@@ -36,7 +45,9 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmFootnoteDefinition {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
label: original.label.to_owned(),
|
||||
pre_blank: Noop {},
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,16 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::FootnoteReference;
|
||||
use crate::types::FootnoteReferenceType;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmFootnoteReference {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) label: Option<String>,
|
||||
#[serde(rename = "type")]
|
||||
pub(crate) footnote_reference_type: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +22,27 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::FootnoteReference(original) },
|
||||
{ "TODO".into() },
|
||||
{ "footnote-reference".into() },
|
||||
{
|
||||
let children = original
|
||||
.definition
|
||||
.iter()
|
||||
.map(|child| {
|
||||
child
|
||||
.to_wasm(wasm_context.clone())
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
children,
|
||||
WasmFootnoteReference {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
label: original.label.map(|s| s.to_owned()),
|
||||
footnote_reference_type: match original.get_type() {
|
||||
FootnoteReferenceType::Standard => "standard",
|
||||
FootnoteReferenceType::Inline => "inline",
|
||||
}
|
||||
.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use super::AdditionalPropertyValue;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Heading;
|
||||
use crate::types::HeadlineLevel;
|
||||
use crate::types::PriorityCookie;
|
||||
use crate::types::TodoKeywordType;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -37,9 +37,13 @@ pub struct WasmHeadline {
|
||||
pub(crate) deadline: Option<Box<WasmAstNode>>,
|
||||
pub(crate) closed: Option<Box<WasmAstNode>>,
|
||||
#[serde(rename = "pre-blank")]
|
||||
pub(crate) pre_blank: usize,
|
||||
pub(crate) pre_blank: Noop,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "noop")]
|
||||
pub struct Noop {}
|
||||
|
||||
to_wasm!(
|
||||
WasmHeadline,
|
||||
Heading<'s>,
|
||||
@@ -108,7 +112,7 @@ to_wasm!(
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(|child| Box::new(child)),
|
||||
.map(Box::new),
|
||||
deadline: original
|
||||
.deadline
|
||||
.as_ref()
|
||||
@@ -118,7 +122,7 @@ to_wasm!(
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(|child| Box::new(child)),
|
||||
.map(Box::new),
|
||||
closed: original
|
||||
.closed
|
||||
.as_ref()
|
||||
@@ -128,8 +132,8 @@ to_wasm!(
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(|child| Box::new(child)),
|
||||
pre_blank: 0, // TODO: Should this be a no-op?
|
||||
.map(Box::new),
|
||||
pre_blank: Noop {},
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::HorizontalRule;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -21,12 +22,16 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::HorizontalRule(original) },
|
||||
{ "TODO".into() },
|
||||
{ "horizontal-rule".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmHorizontalRule {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,19 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::InlineBabelCall;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmInlineBabelCall {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) call: String,
|
||||
#[serde(rename = "inside-header")]
|
||||
pub(crate) inside_header: Option<String>,
|
||||
pub(crate) arguments: Option<String>,
|
||||
#[serde(rename = "end-header")]
|
||||
pub(crate) end_header: Option<String>,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +25,16 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::InlineBabelCall(original) },
|
||||
{ "TODO".into() },
|
||||
{ "inline-babel-call".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmInlineBabelCall {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
call: original.call.to_owned(),
|
||||
inside_header: original.inside_header.map(|s| s.to_owned()),
|
||||
arguments: original.arguments.map(|s| s.to_owned()),
|
||||
end_header: original.end_header.map(|s| s.to_owned()),
|
||||
value: original.value.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::InlineSourceBlock;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmInlineSourceBlock {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) language: String,
|
||||
pub(crate) value: String,
|
||||
pub(crate) parameters: Option<String>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +21,14 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::InlineSourceBlock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "inline-src-block".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmInlineSourceBlock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
language: original.language.to_owned(),
|
||||
value: original.value.to_owned(),
|
||||
parameters: original.parameters.map(str::to_owned),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,16 +4,12 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Italic;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmItalic {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
}
|
||||
pub struct WasmItalic {}
|
||||
|
||||
to_wasm!(
|
||||
WasmItalic,
|
||||
@@ -21,7 +17,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Italic(original) },
|
||||
{ "TODO".into() },
|
||||
{ "italic".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -33,11 +29,6 @@ to_wasm!(
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok((
|
||||
children,
|
||||
WasmItalic {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
},
|
||||
))
|
||||
Ok((children, WasmItalic {}))
|
||||
}
|
||||
);
|
||||
|
||||
@@ -5,14 +5,17 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::Keyword;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmKeyword {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) key: String,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +24,18 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Keyword(original) },
|
||||
{ "TODO".into() },
|
||||
{ "keyword".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmKeyword {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
key: original.key.to_uppercase(),
|
||||
value: original.value.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,14 +5,16 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::LatexEnvironment;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmLatexEnvironment {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +23,17 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::LatexEnvironment(original) },
|
||||
{ "TODO".into() },
|
||||
{ "latex-environment".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmLatexEnvironment {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
value: original.value.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,13 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::LatexFragment;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmLatexFragment {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +19,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::LatexFragment(original) },
|
||||
{ "TODO".into() },
|
||||
{ "latex-fragment".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmLatexFragment {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
value: original.value.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,16 +4,12 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::LineBreak;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmLineBreak {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
}
|
||||
pub struct WasmLineBreak {}
|
||||
|
||||
to_wasm!(
|
||||
WasmLineBreak,
|
||||
@@ -21,13 +17,6 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::LineBreak(original) },
|
||||
{ "TODO".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmLineBreak {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
},
|
||||
))
|
||||
}
|
||||
{ "line-break".into() },
|
||||
{ Ok((Vec::new(), WasmLineBreak {},)) }
|
||||
);
|
||||
|
||||
@@ -11,6 +11,7 @@ macro_rules! to_wasm {
|
||||
$wasm_context: crate::wasm::to_wasm::ToWasmContext<'_>,
|
||||
) -> Result<Self::Output, crate::error::CustomError> {
|
||||
let $original = self;
|
||||
#[allow(unused_braces)]
|
||||
$fnbody
|
||||
}
|
||||
}
|
||||
@@ -23,6 +24,7 @@ macro_rules! to_wasm {
|
||||
&self,
|
||||
$wasm_context: crate::wasm::to_wasm::ToWasmContext<'_>,
|
||||
) -> Result<Self::Output, crate::error::CustomError> {
|
||||
#[allow(unused_variables)]
|
||||
let $original = self;
|
||||
let standard_properties =
|
||||
self.to_wasm_standard_properties($wasm_context.clone())?;
|
||||
@@ -38,18 +40,15 @@ macro_rules! to_wasm {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<WasmAstNode> for crate::wasm::ast_node::WasmAstNodeWrapper<$ostruct> {
|
||||
fn into(self) -> WasmAstNode {
|
||||
let $original = self;
|
||||
impl From<crate::wasm::ast_node::WasmAstNodeWrapper<$ostruct>> for WasmAstNode {
|
||||
fn from($original: crate::wasm::ast_node::WasmAstNodeWrapper<$ostruct>) -> Self {
|
||||
let ret = $toastnodebody;
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasm_test")]
|
||||
impl<'s> crate::compare::ElispFact<'s> for $ostruct {
|
||||
impl<'s> crate::util::elisp_fact::ElispFact<'s> for $ostruct {
|
||||
fn get_elisp_name<'b>(&'b self) -> std::borrow::Cow<'s, str> {
|
||||
let $original = self;
|
||||
let ret = $elispnamebody;
|
||||
ret
|
||||
}
|
||||
|
||||
@@ -65,67 +65,12 @@ mod verse_block;
|
||||
|
||||
pub use additional_property::AdditionalProperties;
|
||||
pub use additional_property::AdditionalPropertyValue;
|
||||
pub(crate) use angle_link::WasmAngleLink;
|
||||
pub use ast_node::WasmAstNode;
|
||||
#[cfg(feature = "wasm_test")]
|
||||
pub use ast_node::WasmAstNodeWrapper;
|
||||
pub(crate) use babel_call::WasmBabelCall;
|
||||
pub(crate) use bold::WasmBold;
|
||||
pub(crate) use center_block::WasmCenterBlock;
|
||||
pub(crate) use citation::WasmCitation;
|
||||
pub(crate) use citation_reference::WasmCitationReference;
|
||||
pub(crate) use clock::WasmClock;
|
||||
pub(crate) use code::WasmCode;
|
||||
pub(crate) use comment::WasmComment;
|
||||
pub(crate) use comment_block::WasmCommentBlock;
|
||||
pub(crate) use diary_sexp::WasmDiarySexp;
|
||||
#[cfg(feature = "wasm_test")]
|
||||
pub use document::WasmDocument;
|
||||
pub(crate) use drawer::WasmDrawer;
|
||||
pub(crate) use dynamic_block::WasmDynamicBlock;
|
||||
pub(crate) use entity::WasmEntity;
|
||||
pub(crate) use example_block::WasmExampleBlock;
|
||||
pub(crate) use export_block::WasmExportBlock;
|
||||
pub(crate) use export_snippet::WasmExportSnippet;
|
||||
pub(crate) use fixed_width_area::WasmFixedWidthArea;
|
||||
pub(crate) use footnote_definition::WasmFootnoteDefinition;
|
||||
pub(crate) use footnote_reference::WasmFootnoteReference;
|
||||
pub(crate) use headline::WasmHeadline;
|
||||
pub(crate) use horizontal_rule::WasmHorizontalRule;
|
||||
pub(crate) use inline_babel_call::WasmInlineBabelCall;
|
||||
pub(crate) use inline_source_block::WasmInlineSourceBlock;
|
||||
pub(crate) use italic::WasmItalic;
|
||||
pub(crate) use keyword::WasmKeyword;
|
||||
pub(crate) use latex_environment::WasmLatexEnvironment;
|
||||
pub(crate) use latex_fragment::WasmLatexFragment;
|
||||
pub(crate) use line_break::WasmLineBreak;
|
||||
pub(crate) use node_property::WasmNodeProperty;
|
||||
pub(crate) use org_macro::WasmOrgMacro;
|
||||
pub(crate) use paragraph::WasmParagraph;
|
||||
pub use parse_result::ParseResult;
|
||||
pub(crate) use plain_link::WasmPlainLink;
|
||||
pub(crate) use plain_list::WasmPlainList;
|
||||
pub(crate) use plain_list_item::WasmPlainListItem;
|
||||
pub(crate) use plain_text::WasmPlainText;
|
||||
pub(crate) use planning::WasmPlanning;
|
||||
pub(crate) use property_drawer::WasmPropertyDrawer;
|
||||
pub(crate) use quote_block::WasmQuoteBlock;
|
||||
pub(crate) use radio_link::WasmRadioLink;
|
||||
pub(crate) use radio_target::WasmRadioTarget;
|
||||
pub(crate) use regular_link::WasmRegularLink;
|
||||
pub(crate) use section::WasmSection;
|
||||
pub(crate) use special_block::WasmSpecialBlock;
|
||||
pub(crate) use src_block::WasmSrcBlock;
|
||||
pub(crate) use standard_properties::WasmStandardProperties;
|
||||
pub(crate) use statistics_cookie::WasmStatisticsCookie;
|
||||
pub(crate) use strike_through::WasmStrikeThrough;
|
||||
pub(crate) use subscript::WasmSubscript;
|
||||
pub(crate) use superscript::WasmSuperscript;
|
||||
pub(crate) use table::WasmTable;
|
||||
pub(crate) use table_cell::WasmTableCell;
|
||||
pub(crate) use table_row::WasmTableRow;
|
||||
pub(crate) use target::WasmTarget;
|
||||
pub(crate) use timestamp::WasmTimestamp;
|
||||
pub use to_wasm::ToWasm;
|
||||
pub use to_wasm::ToWasmContext;
|
||||
pub(crate) use underline::WasmUnderline;
|
||||
pub(crate) use verbatim::WasmVerbatim;
|
||||
pub(crate) use verse_block::WasmVerseBlock;
|
||||
|
||||
@@ -4,15 +4,14 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::NodeProperty;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmNodeProperty {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) key: String,
|
||||
pub(crate) value: Option<String>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +20,13 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::NodeProperty(original) },
|
||||
{ "TODO".into() },
|
||||
{ "node-property".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmNodeProperty {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
key: original.property_name.to_owned(),
|
||||
value: original.value.map(|s| s.to_owned()),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::OrgMacro;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmOrgMacro {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) key: String,
|
||||
pub(crate) value: String,
|
||||
pub(crate) args: Vec<String>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +21,14 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::OrgMacro(original) },
|
||||
{ "TODO".into() },
|
||||
{ "macro".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmOrgMacro {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
key: original.key.to_lowercase(),
|
||||
value: original.value.to_owned(),
|
||||
args: original.get_args().map(|s| s.into_owned()).collect(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::Paragraph;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
||||
@@ -4,15 +4,23 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::LinkType;
|
||||
use crate::types::PlainLink;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "format")]
|
||||
#[serde(rename = "plain")]
|
||||
pub struct WasmPlainLink {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "type")]
|
||||
pub(crate) link_type: String,
|
||||
pub(crate) path: String,
|
||||
#[serde(rename = "raw-link")]
|
||||
pub(crate) raw_link: String,
|
||||
pub(crate) application: Option<String>,
|
||||
#[serde(rename = "search-option")]
|
||||
pub(crate) search_option: Option<String>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +29,23 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::PlainLink(original) },
|
||||
{ "TODO".into() },
|
||||
{ "link".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmPlainLink {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
link_type: match &original.link_type {
|
||||
LinkType::File => "file".to_owned(),
|
||||
LinkType::Protocol(protocol) => protocol.clone().into_owned(),
|
||||
LinkType::Id => "id".to_owned(),
|
||||
LinkType::CustomId => "custom-id".to_owned(),
|
||||
LinkType::CodeRef => "coderef".to_owned(),
|
||||
LinkType::Fuzzy => "fuzzy".to_owned(),
|
||||
},
|
||||
path: original.path.to_owned(),
|
||||
raw_link: original.raw_link.to_owned(),
|
||||
application: original.application.map(str::to_owned),
|
||||
search_option: original.search_option.map(str::to_owned),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,14 +5,18 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::PlainList;
|
||||
use crate::types::PlainListType;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmPlainList {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "type")]
|
||||
pub(crate) list_type: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,8 +25,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::PlainList(original) },
|
||||
{ "TODO".into() },
|
||||
{ "plain-list".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
let children = original
|
||||
.children
|
||||
.iter()
|
||||
@@ -36,7 +44,13 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmPlainList {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
list_type: match original.list_type {
|
||||
PlainListType::Unordered => "unordered",
|
||||
PlainListType::Ordered => "ordered",
|
||||
PlainListType::Descriptive => "descriptive",
|
||||
}
|
||||
.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,21 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::CheckboxType;
|
||||
use crate::types::PlainListItem;
|
||||
use crate::types::PlainListItemCounter;
|
||||
use crate::types::PlainListItemPreBlank;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmPlainListItem {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) tag: Vec<WasmAstNode>,
|
||||
pub(crate) bullet: String,
|
||||
pub(crate) counter: Option<PlainListItemCounter>,
|
||||
pub(crate) checkbox: Option<String>,
|
||||
#[serde(rename = "pre-blank")]
|
||||
pub(crate) pre_blank: PlainListItemPreBlank,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,7 +27,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::PlainListItem(original) },
|
||||
{ "TODO".into() },
|
||||
{ "item".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -36,7 +42,26 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmPlainListItem {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
tag: original
|
||||
.tag
|
||||
.iter()
|
||||
.map(|child| {
|
||||
child
|
||||
.to_wasm(wasm_context.clone())
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
bullet: original.bullet.to_owned(),
|
||||
counter: original.counter,
|
||||
checkbox: original.checkbox.as_ref().map(|(checkbox_type, _)| {
|
||||
match checkbox_type {
|
||||
CheckboxType::On => "on",
|
||||
CheckboxType::Trans => "trans",
|
||||
CheckboxType::Off => "off",
|
||||
}
|
||||
.to_owned()
|
||||
}),
|
||||
pre_blank: original.pre_blank,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::PlainText;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
||||
@@ -4,8 +4,8 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Planning;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -35,7 +35,7 @@ to_wasm!(
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(|child| Box::new(child)),
|
||||
.map(Box::new),
|
||||
deadline: original
|
||||
.deadline
|
||||
.as_ref()
|
||||
@@ -45,7 +45,7 @@ to_wasm!(
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(|child| Box::new(child)),
|
||||
.map(Box::new),
|
||||
closed: original
|
||||
.closed
|
||||
.as_ref()
|
||||
@@ -55,7 +55,7 @@ to_wasm!(
|
||||
.map(Into::<WasmAstNode>::into)
|
||||
})
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(|child| Box::new(child)),
|
||||
.map(Box::new),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,16 +4,12 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::PropertyDrawer;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmPropertyDrawer {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
}
|
||||
pub struct WasmPropertyDrawer {}
|
||||
|
||||
to_wasm!(
|
||||
WasmPropertyDrawer,
|
||||
@@ -21,7 +17,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::PropertyDrawer(original) },
|
||||
{ "TODO".into() },
|
||||
{ "property-drawer".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -33,11 +29,6 @@ to_wasm!(
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok((
|
||||
children,
|
||||
WasmPropertyDrawer {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
},
|
||||
))
|
||||
Ok((children, WasmPropertyDrawer {}))
|
||||
}
|
||||
);
|
||||
|
||||
@@ -5,8 +5,9 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::QuoteBlock;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -21,8 +22,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::QuoteBlock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "quote-block".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
let children = original
|
||||
.children
|
||||
.iter()
|
||||
@@ -36,7 +41,7 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmQuoteBlock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,22 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::RadioLink;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "format")]
|
||||
#[serde(rename = "plain")]
|
||||
pub struct WasmRadioLink {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "type")]
|
||||
pub(crate) link_type: String,
|
||||
pub(crate) path: String,
|
||||
#[serde(rename = "raw-link")]
|
||||
pub(crate) raw_link: String,
|
||||
pub(crate) application: Option<String>, // Always None
|
||||
#[serde(rename = "search-option")]
|
||||
pub(crate) search_option: Option<String>, // Always None
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,7 +28,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::RadioLink(original) },
|
||||
{ "TODO".into() },
|
||||
{ "link".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -36,7 +43,11 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmRadioLink {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
link_type: "radio".to_owned(),
|
||||
path: original.path.to_owned(),
|
||||
raw_link: original.get_raw_link().to_owned(),
|
||||
application: None,
|
||||
search_option: None,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,13 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::RadioTarget;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmRadioTarget {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,7 +19,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::RadioTarget(original) },
|
||||
{ "TODO".into() },
|
||||
{ "radio-target".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -36,7 +34,7 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmRadioTarget {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
value: original.value.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::LinkType;
|
||||
use crate::types::RegularLink;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "format")]
|
||||
#[serde(rename = "bracket")]
|
||||
pub struct WasmRegularLink {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "type")]
|
||||
pub(crate) link_type: String,
|
||||
pub(crate) path: String,
|
||||
#[serde(rename = "raw-link")]
|
||||
pub(crate) raw_link: String,
|
||||
pub(crate) application: Option<String>,
|
||||
#[serde(rename = "search-option")]
|
||||
pub(crate) search_option: Option<String>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,7 +31,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::RegularLink(original) },
|
||||
{ "TODO".into() },
|
||||
{ "link".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -36,7 +46,21 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmRegularLink {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
link_type: match &original.link_type {
|
||||
LinkType::File => "file".to_owned(),
|
||||
LinkType::Protocol(protocol) => protocol.clone().into_owned(),
|
||||
LinkType::Id => "id".to_owned(),
|
||||
LinkType::CustomId => "custom-id".to_owned(),
|
||||
LinkType::CodeRef => "coderef".to_owned(),
|
||||
LinkType::Fuzzy => "fuzzy".to_owned(),
|
||||
},
|
||||
path: original.get_path().into_owned(),
|
||||
raw_link: original.get_raw_link().into_owned(),
|
||||
application: original
|
||||
.application
|
||||
.as_ref()
|
||||
.map(|c| c.clone().into_owned()),
|
||||
search_option: original.get_search_option().map(Cow::into_owned),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Section;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
||||
@@ -2,17 +2,23 @@ use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::headline::Noop;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::SpecialBlock;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmSpecialBlock {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "type")]
|
||||
pub(crate) block_type: String,
|
||||
pub(crate) parameters: Option<String>,
|
||||
pub(crate) results: Noop,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,8 +27,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::SpecialBlock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "special-block".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
let children = original
|
||||
.children
|
||||
.iter()
|
||||
@@ -36,7 +46,10 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmSpecialBlock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
block_type: original.block_type.to_owned(),
|
||||
parameters: original.parameters.map(|s| s.to_owned()),
|
||||
results: Noop {},
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,14 +5,56 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::CharOffsetInLine;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::LineNumber;
|
||||
use crate::types::RetainLabels;
|
||||
use crate::types::SrcBlock;
|
||||
use crate::types::SwitchNumberLines;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmSrcBlock {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) language: Option<String>,
|
||||
pub(crate) value: String,
|
||||
pub(crate) switches: Option<String>,
|
||||
pub(crate) parameters: Option<String>,
|
||||
#[serde(rename = "number-lines")]
|
||||
pub(crate) number_lines: Option<WasmNumberLinesWrapper>,
|
||||
#[serde(rename = "preserve-indent")]
|
||||
pub(crate) preserve_indent: Option<CharOffsetInLine>,
|
||||
#[serde(rename = "retain-labels")]
|
||||
pub(crate) retain_labels: WasmRetainLabels,
|
||||
#[serde(rename = "use-labels")]
|
||||
pub(crate) use_labels: bool,
|
||||
#[serde(rename = "label-fmt")]
|
||||
pub(crate) label_format: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub(crate) enum WasmRetainLabels {
|
||||
YesNo(bool),
|
||||
Keep(CharOffsetInLine),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub(crate) enum WasmNumberLines {
|
||||
#[serde(rename = "new")]
|
||||
New(LineNumber),
|
||||
#[serde(rename = "continued")]
|
||||
Continued(LineNumber),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename = "number-lines")]
|
||||
#[serde(tag = "number-lines")]
|
||||
pub(crate) struct WasmNumberLinesWrapper {
|
||||
#[serde(flatten)]
|
||||
pub(crate) inner: WasmNumberLines,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +63,37 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::SrcBlock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "src-block".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmSrcBlock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
language: original.language.map(|s| s.to_owned()),
|
||||
value: original.get_value().into_owned(),
|
||||
switches: original.switches.map(|s| s.to_owned()),
|
||||
parameters: original.parameters.map(|s| s.to_owned()),
|
||||
number_lines: match original.number_lines {
|
||||
None => None,
|
||||
Some(SwitchNumberLines::New(n)) => Some(WasmNumberLinesWrapper {
|
||||
inner: WasmNumberLines::New(n),
|
||||
}),
|
||||
Some(SwitchNumberLines::Continued(n)) => Some(WasmNumberLinesWrapper {
|
||||
inner: WasmNumberLines::Continued(n),
|
||||
}),
|
||||
},
|
||||
preserve_indent: original.preserve_indent,
|
||||
retain_labels: match original.retain_labels {
|
||||
RetainLabels::No => WasmRetainLabels::YesNo(false),
|
||||
RetainLabels::Yes => WasmRetainLabels::YesNo(true),
|
||||
RetainLabels::Keep(n) => WasmRetainLabels::Keep(n),
|
||||
},
|
||||
use_labels: original.use_labels,
|
||||
label_format: original.label_format.map(|s| s.to_owned()),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::StatisticsCookie;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
||||
@@ -4,16 +4,12 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::StrikeThrough;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmStrikeThrough {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
}
|
||||
pub struct WasmStrikeThrough {}
|
||||
|
||||
to_wasm!(
|
||||
WasmStrikeThrough,
|
||||
@@ -21,7 +17,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::StrikeThrough(original) },
|
||||
{ "TODO".into() },
|
||||
{ "strike-through".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -33,11 +29,6 @@ to_wasm!(
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok((
|
||||
children,
|
||||
WasmStrikeThrough {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
},
|
||||
))
|
||||
Ok((children, WasmStrikeThrough {}))
|
||||
}
|
||||
);
|
||||
|
||||
@@ -4,15 +4,14 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Subscript;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmSubscript {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "use-brackets-p")]
|
||||
pub(crate) use_brackets: bool,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,7 +20,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Subscript(original) },
|
||||
{ "TODO".into() },
|
||||
{ "subscript".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -36,7 +35,7 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmSubscript {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
use_brackets: original.use_brackets,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,14 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Superscript;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmSuperscript {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "use-brackets-p")]
|
||||
pub(crate) use_brackets: bool,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,7 +20,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Superscript(original) },
|
||||
{ "TODO".into() },
|
||||
{ "superscript".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -36,7 +35,7 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmSuperscript {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
use_brackets: original.use_brackets,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
@@ -5,14 +7,27 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::Table;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmTable {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "tblfm")]
|
||||
pub(crate) formulas: Option<WasmStringSet>,
|
||||
#[serde(rename = "type")]
|
||||
pub(crate) table_type: String,
|
||||
pub(crate) value: Option<String>, // Always None
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "string-set")]
|
||||
#[serde(rename = "string-set")]
|
||||
pub(crate) struct WasmStringSet {
|
||||
value: BTreeSet<String>,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,8 +36,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Table(original) },
|
||||
{ "TODO".into() },
|
||||
{ "table".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
let children = original
|
||||
.children
|
||||
.iter()
|
||||
@@ -36,7 +55,20 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmTable {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
formulas: if original.formulas.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(WasmStringSet {
|
||||
value: original
|
||||
.formulas
|
||||
.iter()
|
||||
.map(|kw| kw.value.to_owned())
|
||||
.collect(),
|
||||
})
|
||||
},
|
||||
table_type: "org".to_owned(),
|
||||
value: None,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,16 +4,12 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::TableCell;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmTableCell {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
}
|
||||
pub struct WasmTableCell {}
|
||||
|
||||
to_wasm!(
|
||||
WasmTableCell,
|
||||
@@ -21,7 +17,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::TableCell(original) },
|
||||
{ "TODO".into() },
|
||||
{ "table-cell".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -33,11 +29,6 @@ to_wasm!(
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok((
|
||||
children,
|
||||
WasmTableCell {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
},
|
||||
))
|
||||
Ok((children, WasmTableCell {}))
|
||||
}
|
||||
);
|
||||
|
||||
@@ -4,15 +4,15 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::TableRow;
|
||||
use crate::types::TableRowType;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmTableRow {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
#[serde(rename = "type")]
|
||||
pub(crate) row_type: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,7 +21,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::TableRow(original) },
|
||||
{ "TODO".into() },
|
||||
{ "table-row".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -36,7 +36,11 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmTableRow {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
row_type: match original.get_type() {
|
||||
TableRowType::Standard => "standard",
|
||||
TableRowType::Rule => "rule",
|
||||
}
|
||||
.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,13 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Target;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmTarget {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +19,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Target(original) },
|
||||
{ "TODO".into() },
|
||||
{ "target".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmTarget {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
value: original.value.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::DayOfMonthInner;
|
||||
use crate::types::HourInner;
|
||||
use crate::types::MinuteInner;
|
||||
@@ -17,6 +16,7 @@ use crate::types::TimestampRangeType;
|
||||
use crate::types::TimestampType;
|
||||
use crate::types::WarningDelayType;
|
||||
use crate::types::YearInner;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
||||
@@ -4,16 +4,12 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Underline;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmUnderline {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
}
|
||||
pub struct WasmUnderline {}
|
||||
|
||||
to_wasm!(
|
||||
WasmUnderline,
|
||||
@@ -21,7 +17,7 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Underline(original) },
|
||||
{ "TODO".into() },
|
||||
{ "underline".into() },
|
||||
{
|
||||
let children = original
|
||||
.children
|
||||
@@ -33,11 +29,6 @@ to_wasm!(
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok((
|
||||
children,
|
||||
WasmUnderline {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
},
|
||||
))
|
||||
Ok((children, WasmUnderline {}))
|
||||
}
|
||||
);
|
||||
|
||||
@@ -4,15 +4,13 @@ use serde::Serialize;
|
||||
use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::Verbatim;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WasmVerbatim {
|
||||
#[serde(flatten)]
|
||||
pub(crate) additional_properties: AdditionalProperties,
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
to_wasm!(
|
||||
@@ -21,12 +19,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::Verbatim(original) },
|
||||
{ "TODO".into() },
|
||||
{ "verbatim".into() },
|
||||
{
|
||||
Ok((
|
||||
Vec::new(),
|
||||
WasmVerbatim {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
value: original.contents.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ use super::ast_node::WasmAstNode;
|
||||
use super::macros::to_wasm;
|
||||
use super::to_wasm::ToWasm;
|
||||
use super::AdditionalProperties;
|
||||
use crate::compare::ElispFact;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::VerseBlock;
|
||||
use crate::util::elisp_fact::ElispFact;
|
||||
use crate::wasm::to_wasm::ToWasmStandardProperties;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -21,8 +22,12 @@ to_wasm!(
|
||||
original,
|
||||
wasm_context,
|
||||
{ WasmAstNode::VerseBlock(original) },
|
||||
{ "TODO".into() },
|
||||
{ "verse-block".into() },
|
||||
{
|
||||
let additional_properties = original
|
||||
.get_affiliated_keywords()
|
||||
.to_wasm(wasm_context.clone())?;
|
||||
|
||||
let children = original
|
||||
.children
|
||||
.iter()
|
||||
@@ -36,7 +41,7 @@ to_wasm!(
|
||||
Ok((
|
||||
children,
|
||||
WasmVerseBlock {
|
||||
additional_properties: AdditionalProperties::default(),
|
||||
additional_properties,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
25
src/wasm_cli/mod.rs
Normal file
25
src/wasm_cli/mod.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use gloo_utils::format::JsValueSerdeExt;
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
use crate::parser::parse_with_settings;
|
||||
use crate::settings::GlobalSettings;
|
||||
use crate::wasm::ParseResult;
|
||||
use crate::wasm::ToWasm;
|
||||
use crate::wasm::ToWasmContext;
|
||||
|
||||
pub fn parse_org(org_contents: &str) -> wasm_bindgen::JsValue {
|
||||
let rust_parsed = match parse_with_settings(org_contents, &GlobalSettings::default()) {
|
||||
Ok(document) => document,
|
||||
Err(err) => {
|
||||
return JsValue::from_serde(&ParseResult::Error(format!("{:?}", err))).unwrap();
|
||||
}
|
||||
};
|
||||
let to_wasm_context = ToWasmContext::new(org_contents);
|
||||
let wasm_document = match rust_parsed.to_wasm(to_wasm_context) {
|
||||
Ok(document) => document,
|
||||
Err(err) => {
|
||||
return JsValue::from_serde(&ParseResult::Error(format!("{:?}", err))).unwrap();
|
||||
}
|
||||
};
|
||||
JsValue::from_serde(&ParseResult::Success(wasm_document)).unwrap()
|
||||
}
|
||||
@@ -1,29 +1,31 @@
|
||||
use std::borrow::Borrow;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::diff::WasmDiffResult;
|
||||
use super::diff::WasmDiffStatus;
|
||||
use crate::compare::maybe_token_to_usize;
|
||||
use crate::compare::unquote;
|
||||
use crate::compare::EmacsStandardProperties;
|
||||
use crate::compare::TextWithProperties;
|
||||
use crate::compare::Token;
|
||||
use crate::util::elisp::maybe_token_to_usize;
|
||||
use crate::util::elisp::unquote;
|
||||
use crate::util::elisp::EmacsStandardProperties;
|
||||
use crate::util::elisp::TextWithProperties;
|
||||
use crate::util::elisp::Token;
|
||||
use crate::wasm::WasmAstNodeWrapper;
|
||||
use crate::wasm::WasmDocument;
|
||||
|
||||
pub fn wasm_compare_document<'e, 's, 'w>(
|
||||
pub fn wasm_compare_document<'s>(
|
||||
source: &'s str,
|
||||
emacs: &'e Token<'s>,
|
||||
wasm: &'w WasmAstNodeWrapper<WasmDocument>,
|
||||
emacs: &Token<'s>,
|
||||
wasm: &WasmAstNodeWrapper<WasmDocument>,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
let wasm_json = serde_json::to_string(&wasm)?;
|
||||
let wasm_json_parsed = serde_json::from_str(&wasm_json)?;
|
||||
compare_json_value(source, emacs, &wasm_json_parsed)
|
||||
}
|
||||
|
||||
fn compare_json_value<'b, 's>(
|
||||
fn compare_json_value<'s>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
emacs: &Token<'s>,
|
||||
wasm: &serde_json::Value,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
// println!("XXXXXXXXXXXXXX compare_json_value XXXXXXXXXXXXXX");
|
||||
@@ -54,6 +56,14 @@ fn compare_json_value<'b, 's>(
|
||||
// We hit an object tree additional property.
|
||||
compare_object_tree(source, el, wasm)
|
||||
}
|
||||
(serde_json::Value::Object(wasm), Token::List(el)) if wasm.contains_key("number-lines") => {
|
||||
// We hit an object tree additional property.
|
||||
compare_number_lines(source, el, wasm)
|
||||
}
|
||||
(serde_json::Value::Object(wasm), Token::List(el)) if wasm.contains_key("string-set") => {
|
||||
// We hit an object tree additional property.
|
||||
compare_string_set(source, el, wasm)
|
||||
}
|
||||
(serde_json::Value::Object(w), Token::TextWithProperties(e)) if is_plain_text(w) => {
|
||||
compare_plain_text(source, e, w)
|
||||
}
|
||||
@@ -77,12 +87,27 @@ fn compare_json_value<'b, 's>(
|
||||
(serde_json::Value::Number(w), Token::Atom(e)) if w.to_string().as_str() == (*e) => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(serde_json::Value::Number(w), Token::Atom(e)) => {
|
||||
let mut result = WasmDiffResult::default();
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Value mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = e,
|
||||
wasm = w,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
Ok(result)
|
||||
}
|
||||
(serde_json::Value::Array(w), Token::Atom("nil")) if w.is_empty() => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(serde_json::Value::String(w), Token::Atom(e)) if w.as_str() == *e => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(serde_json::Value::Object(w), _) if w.contains_key("noop") => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(serde_json::Value::Null, Token::Atom(_)) => todo!(),
|
||||
(serde_json::Value::Null, Token::List(_)) => todo!(),
|
||||
(serde_json::Value::Null, Token::TextWithProperties(_)) => todo!(),
|
||||
@@ -91,7 +116,7 @@ fn compare_json_value<'b, 's>(
|
||||
(serde_json::Value::Bool(_), Token::List(_)) => todo!(),
|
||||
(serde_json::Value::Bool(_), Token::TextWithProperties(_)) => todo!(),
|
||||
(serde_json::Value::Bool(_), Token::Vector(_)) => todo!(),
|
||||
(serde_json::Value::Number(_), Token::Atom(_)) => todo!(),
|
||||
// (serde_json::Value::Number(_), Token::Atom(_)) => todo!(),
|
||||
(serde_json::Value::Number(_), Token::List(_)) => todo!(),
|
||||
(serde_json::Value::Number(_), Token::TextWithProperties(_)) => todo!(),
|
||||
(serde_json::Value::Number(_), Token::Vector(_)) => todo!(),
|
||||
@@ -122,15 +147,18 @@ fn compare_json_value<'b, 's>(
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_optional_json_value<'b, 's>(
|
||||
fn compare_optional_json_value<'s>(
|
||||
source: &'s str,
|
||||
emacs: Option<&'b Token<'s>>,
|
||||
emacs: Option<&Token<'s>>,
|
||||
wasm: Option<&serde_json::Value>,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
match (emacs, wasm) {
|
||||
(None, None) | (None, Some(serde_json::Value::Null)) | (Some(Token::Atom("nil")), None) => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(None, Some(serde_json::Value::Object(w))) if w.contains_key("noop") => {
|
||||
Ok(WasmDiffResult::default())
|
||||
}
|
||||
(Some(e), Some(w)) => compare_json_value(source, e, w),
|
||||
_ => Ok(WasmDiffResult {
|
||||
status: vec![WasmDiffStatus::Bad(
|
||||
@@ -147,10 +175,10 @@ fn compare_optional_json_value<'b, 's>(
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_ast_node<'e, 's, 'w>(
|
||||
fn compare_ast_node<'s>(
|
||||
source: &'s str,
|
||||
emacs: &'e Vec<Token<'s>>,
|
||||
wasm: &'w serde_json::Map<String, serde_json::Value>,
|
||||
emacs: &[Token<'s>],
|
||||
wasm: &serde_json::Map<String, serde_json::Value>,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
let mut result = WasmDiffResult::default();
|
||||
let mut emacs_list_iter = emacs.iter();
|
||||
@@ -249,11 +277,13 @@ fn compare_ast_node<'e, 's, 'w>(
|
||||
{
|
||||
// Compare attributes.
|
||||
for attribute_name in wasm_attributes_map.keys() {
|
||||
let mut layer = WasmDiffResult::default();
|
||||
layer.name = Cow::Owned(attribute_name.clone());
|
||||
let mut layer = WasmDiffResult::<'_> {
|
||||
name: Cow::Owned(attribute_name.clone()),
|
||||
..Default::default()
|
||||
};
|
||||
let wasm_attribute_value = wasm_attributes_map.get(attribute_name);
|
||||
let emacs_key = wasm_key_to_emacs_key(attribute_name);
|
||||
let emacs_attribute_value = emacs_attributes_map.get(emacs_key.as_str()).map(|e| *e);
|
||||
let emacs_attribute_value = emacs_attributes_map.get(emacs_key.as_str()).copied();
|
||||
let inner_layer =
|
||||
compare_optional_json_value(source, emacs_attribute_value, wasm_attribute_value)?;
|
||||
if !inner_layer.name.is_empty() {
|
||||
@@ -267,8 +297,10 @@ fn compare_ast_node<'e, 's, 'w>(
|
||||
|
||||
{
|
||||
// Compare standard-properties.
|
||||
let mut layer = WasmDiffResult::default();
|
||||
layer.name = "standard-properties".into();
|
||||
let mut layer = WasmDiffResult::<'_> {
|
||||
name: "standard-properties".into(),
|
||||
..Default::default()
|
||||
};
|
||||
let emacs_standard_properties = wasm_get_emacs_standard_properties(&emacs_attributes_map)?;
|
||||
let wasm_standard_properties = wasm
|
||||
.get("standard-properties")
|
||||
@@ -321,12 +353,13 @@ fn compare_ast_node<'e, 's, 'w>(
|
||||
|
||||
{
|
||||
// Compare children.
|
||||
let mut layer = WasmDiffResult::default();
|
||||
layer.name = "children".into();
|
||||
let mut layer = WasmDiffResult::<'_> {
|
||||
name: "children".into(),
|
||||
..Default::default()
|
||||
};
|
||||
if let Some(wasm_iter) = wasm
|
||||
.get("children")
|
||||
.map(|children| children.as_array())
|
||||
.flatten()
|
||||
.and_then(|children| children.as_array())
|
||||
.map(|children| children.iter())
|
||||
{
|
||||
layer.extend(wasm_compare_list(source, emacs_list_iter, wasm_iter)?)?;
|
||||
@@ -347,10 +380,10 @@ fn wasm_key_to_emacs_key<WK: std::fmt::Display>(wasm_key: WK) -> String {
|
||||
format!(":{key}", key = wasm_key)
|
||||
}
|
||||
|
||||
fn compare_quoted_string<'e, 's, 'w>(
|
||||
source: &'s str,
|
||||
emacs: &'e str,
|
||||
wasm: &'w String,
|
||||
fn compare_quoted_string<'s>(
|
||||
_source: &'s str,
|
||||
emacs: &str,
|
||||
wasm: &String,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
let mut result = WasmDiffResult::default();
|
||||
let emacs_text = unquote(emacs)?;
|
||||
@@ -411,7 +444,7 @@ pub(crate) fn wasm_get_emacs_standard_properties(
|
||||
|
||||
fn wasm_compare_list<'e, 's: 'e, 'w, EI, WI>(
|
||||
source: &'s str,
|
||||
emacs: EI,
|
||||
mut emacs: EI,
|
||||
wasm: WI,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>>
|
||||
where
|
||||
@@ -420,6 +453,9 @@ where
|
||||
{
|
||||
let emacs_length = emacs.len();
|
||||
let wasm_length = wasm.len();
|
||||
if emacs_length == 1 && wasm_length == 0 && emacs.all(|t| matches!(t.as_atom(), Ok(r#""""#))) {
|
||||
return Ok(WasmDiffResult::default());
|
||||
}
|
||||
if emacs_length != wasm_length {
|
||||
return Ok(WasmDiffResult {
|
||||
status: vec![WasmDiffStatus::Bad(
|
||||
@@ -446,10 +482,10 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn compare_optional_pair<'e, 's, 'w>(
|
||||
fn compare_optional_pair<'s>(
|
||||
source: &'s str,
|
||||
emacs: &'e Vec<Token<'s>>,
|
||||
wasm: &'w serde_json::Map<String, serde_json::Value>,
|
||||
emacs: &Vec<Token<'s>>,
|
||||
wasm: &serde_json::Map<String, serde_json::Value>,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
let mut result = WasmDiffResult::default();
|
||||
let wasm_optval = wasm
|
||||
@@ -496,10 +532,10 @@ fn compare_optional_pair<'e, 's, 'w>(
|
||||
});
|
||||
}
|
||||
let emacs_optval = emacs
|
||||
.first()
|
||||
.get(2)
|
||||
.expect("If-statement proves this will be Some.");
|
||||
let emacs_val = emacs
|
||||
.get(2)
|
||||
.first()
|
||||
.expect("If-statement proves this will be Some.");
|
||||
result.extend(compare_json_value(source, emacs_optval, wasm_optval)?)?;
|
||||
result.extend(compare_json_value(source, emacs_val, wasm_val)?)?;
|
||||
@@ -507,10 +543,10 @@ fn compare_optional_pair<'e, 's, 'w>(
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn compare_object_tree<'e, 's, 'w>(
|
||||
fn compare_object_tree<'s>(
|
||||
source: &'s str,
|
||||
emacs: &'e Vec<Token<'s>>,
|
||||
wasm: &'w serde_json::Map<String, serde_json::Value>,
|
||||
emacs: &[Token<'s>],
|
||||
wasm: &serde_json::Map<String, serde_json::Value>,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
let mut result = WasmDiffResult::default();
|
||||
let wasm_attributes = wasm
|
||||
@@ -533,7 +569,6 @@ fn compare_object_tree<'e, 's, 'w>(
|
||||
}
|
||||
|
||||
for (emacs_attribute, wasm_attribute) in emacs.iter().zip(wasm_attributes.iter()) {
|
||||
let emacs_attribute = emacs_attribute.as_list()?;
|
||||
let wasm_attribute = wasm_attribute
|
||||
.as_array()
|
||||
.ok_or("Wasm middle layer in object tree should be a list.")?;
|
||||
@@ -547,6 +582,16 @@ fn compare_object_tree<'e, 's, 'w>(
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
if let Ok("nil") = emacs_attribute.as_atom() {
|
||||
if let Some(serde_json::Value::Null) = wasm_attribute.first() {
|
||||
if let Some(serde_json::Value::Array(w)) = wasm_attribute.get(1) {
|
||||
if w.is_empty() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let emacs_attribute = emacs_attribute.as_list()?;
|
||||
if let Some(serde_json::Value::Null) = wasm_attribute.first() {
|
||||
// If optval is null then the emacs array should only contain 1 value.
|
||||
if emacs_attribute.len() != 1 {
|
||||
@@ -569,11 +614,11 @@ fn compare_object_tree<'e, 's, 'w>(
|
||||
.expect("If-statement proves this will be Some.");
|
||||
result.extend(compare_json_value(source, emacs_val, wasm_val)?)?;
|
||||
} else {
|
||||
// If optval is not null, then the emacs array should contain 3 values, the optval, a dot, and the val.
|
||||
if emacs_attribute.len() != 3 {
|
||||
// If optval is not null, then the emacs array should contain a list, the first child of which is a list for optval, and all other entries to the outer list are the val.
|
||||
if emacs_attribute.len() < 2 {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Emacs middle layer in object tree should have a length of 3. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
"Emacs middle layer in object tree should have a length of at least 2. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs_attribute,
|
||||
wasm = wasm_attribute
|
||||
)
|
||||
@@ -581,27 +626,171 @@ fn compare_object_tree<'e, 's, 'w>(
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
let emacs_optval = emacs_attribute
|
||||
.first()
|
||||
.expect("If-statement proves this will be Some.");
|
||||
let emacs_optval = emacs_attribute.iter().skip(1);
|
||||
let wasm_optval = wasm_attribute
|
||||
.first()
|
||||
.expect("If-statement proves this will be Some.");
|
||||
.expect("If-statement proves this will be Some.")
|
||||
.as_array()
|
||||
.ok_or("first value in wasm object tree should be a list.")?;
|
||||
let emacs_val = emacs_attribute
|
||||
.get(2)
|
||||
.expect("If-statement proves this will be Some.");
|
||||
.first()
|
||||
.ok_or("If-statement proves this will be Some.")?;
|
||||
let wasm_val = wasm_attribute
|
||||
.get(1)
|
||||
.expect("If-statement proves this will be Some.");
|
||||
result.extend(compare_json_value(source, emacs_optval, wasm_optval)?)?;
|
||||
result.extend(compare_json_value(source, emacs_val, wasm_val)?)?;
|
||||
.expect("If-statement proves this will be Some.")
|
||||
.as_array()
|
||||
.ok_or("2nd value in wasm object tree should be a list.")?;
|
||||
result.extend(wasm_compare_list(source, emacs_optval, wasm_optval.iter())?)?;
|
||||
if let Ok("nil") = emacs_val.as_atom() {
|
||||
result.extend(wasm_compare_list(
|
||||
source,
|
||||
std::iter::empty(),
|
||||
wasm_val.iter(),
|
||||
)?)?;
|
||||
} else {
|
||||
result.extend(wasm_compare_list(
|
||||
source,
|
||||
emacs_val.as_list()?.iter(),
|
||||
wasm_val.iter(),
|
||||
)?)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn is_plain_text<'e, 's, 'w>(wasm: &'w serde_json::Map<String, serde_json::Value>) -> bool {
|
||||
fn compare_number_lines<'s>(
|
||||
_source: &'s str,
|
||||
emacs: &[Token<'s>],
|
||||
wasm: &serde_json::Map<String, serde_json::Value>,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
let mut result = WasmDiffResult::default();
|
||||
let mut emacs_iter = emacs.iter();
|
||||
let emacs_directive = emacs_iter
|
||||
.next()
|
||||
.ok_or("Emacs number lines should have 3 children.")?
|
||||
.as_atom()?;
|
||||
let emacs_number: i64 = emacs_iter
|
||||
.nth(1)
|
||||
.ok_or("Emacs number lines should have 3 children.")?
|
||||
.as_atom()?
|
||||
.parse()?;
|
||||
if wasm.contains_key("new") {
|
||||
let wasm_number = wasm
|
||||
.get("new")
|
||||
.ok_or(r#"Wasm number lines should have a "new" attribute."#)?
|
||||
.as_i64()
|
||||
.ok_or(r#"Wasm number lines "new" attribute should be a number."#)?;
|
||||
if emacs_directive != "new" {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Number lines directive mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs_directive,
|
||||
wasm = "new"
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
if emacs_number != wasm_number {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Number lines number mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs_number,
|
||||
wasm = wasm_number
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
} else if wasm.contains_key("continued") {
|
||||
let wasm_number = wasm
|
||||
.get("continued")
|
||||
.ok_or(r#"Wasm number lines should have a "continued" attribute."#)?
|
||||
.as_i64()
|
||||
.ok_or(r#"Wasm number lines "continued" attribute should be a number."#)?;
|
||||
if emacs_directive != "continued" {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Number lines directive mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs_directive,
|
||||
wasm = "continued"
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
if emacs_number != wasm_number {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Number lines number mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||
emacs = emacs_number,
|
||||
wasm = wasm_number
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
} else {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Unrecognized number lines directive. Wasm=({wasm:?}).",
|
||||
wasm = wasm
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn compare_string_set<'s>(
|
||||
_source: &'s str,
|
||||
emacs: &[Token<'s>],
|
||||
wasm: &serde_json::Map<String, serde_json::Value>,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
let mut result = WasmDiffResult::default();
|
||||
let wasm_list = wasm
|
||||
.get("value")
|
||||
.ok_or(r#"Wasm string set should have a "value" attribute."#)?
|
||||
.as_array()
|
||||
.ok_or(r#"Wasm string set "value" attribute should be a list."#)?;
|
||||
let wasm_strings = wasm_list
|
||||
.iter()
|
||||
.map(|v| v.as_str().ok_or("Non-string in wasm string set."))
|
||||
.collect::<Result<BTreeSet<_>, &'static str>>()?;
|
||||
let emacs_strings = emacs
|
||||
.iter()
|
||||
.map(|v| v.as_atom())
|
||||
.collect::<Result<Vec<_>, Box<dyn std::error::Error>>>()?
|
||||
.into_iter()
|
||||
.map(unquote)
|
||||
.collect::<Result<Vec<_>, Box<dyn std::error::Error>>>()?;
|
||||
let emacs_strings = emacs_strings
|
||||
.iter()
|
||||
.map(|s| s.borrow())
|
||||
.collect::<BTreeSet<&str>>();
|
||||
|
||||
let mismatched: Vec<_> = emacs_strings
|
||||
.symmetric_difference(&wasm_strings)
|
||||
.copied()
|
||||
.collect();
|
||||
if !mismatched.is_empty() {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"String set mismatch. MismatchedValues=({values:?}).",
|
||||
values = mismatched.join(", ")
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn is_plain_text(wasm: &serde_json::Map<String, serde_json::Value>) -> bool {
|
||||
if let Some(serde_json::Value::String(node_type)) = wasm.get("ast-node") {
|
||||
node_type == "plain-text"
|
||||
} else {
|
||||
@@ -609,13 +798,15 @@ fn is_plain_text<'e, 's, 'w>(wasm: &'w serde_json::Map<String, serde_json::Value
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_plain_text<'e, 's, 'w>(
|
||||
fn compare_plain_text<'s>(
|
||||
source: &'s str,
|
||||
emacs: &'e TextWithProperties<'s>,
|
||||
wasm: &'w serde_json::Map<String, serde_json::Value>,
|
||||
emacs: &TextWithProperties<'s>,
|
||||
wasm: &serde_json::Map<String, serde_json::Value>,
|
||||
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||
let mut result = WasmDiffResult::default();
|
||||
result.name = "plain-text".into();
|
||||
let mut result = WasmDiffResult::<'_> {
|
||||
name: "plain-text".into(),
|
||||
..Default::default()
|
||||
};
|
||||
if !is_plain_text(wasm) {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::util::foreground_color;
|
||||
use crate::util::reset_color;
|
||||
use crate::util::terminal::foreground_color;
|
||||
use crate::util::terminal::reset_color;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WasmDiffResult<'s> {
|
||||
@@ -12,6 +12,7 @@ pub struct WasmDiffResult<'s> {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum WasmDiffStatus {
|
||||
#[allow(dead_code)]
|
||||
Good,
|
||||
Bad(Cow<'static, str>),
|
||||
}
|
||||
@@ -50,7 +51,7 @@ impl<'s> WasmDiffResult<'s> {
|
||||
fn print_indented(
|
||||
&self,
|
||||
indentation: usize,
|
||||
original_document: &str,
|
||||
_original_document: &str,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let status_text = {
|
||||
if self.is_self_bad() {
|
||||
@@ -90,7 +91,7 @@ impl<'s> WasmDiffResult<'s> {
|
||||
);
|
||||
|
||||
for child in self.children.iter() {
|
||||
child.print_indented(indentation + 1, original_document)?;
|
||||
child.print_indented(indentation + 1, _original_document)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
macro_rules! wasm_compare {
|
||||
($source:expr, $emacs:expr, $wasm:expr, $(($emacs_field:expr, $wasm_value_getter:expr, $compare_fn: expr)),*) => {{
|
||||
let mut result = WasmDiffResult::default();
|
||||
let emacs_list = $emacs.as_list()?;
|
||||
let mut emacs_list_iter = emacs_list.iter();
|
||||
let emacs_name = emacs_list_iter
|
||||
.next()
|
||||
.ok_or("Should have an attributes child.")?
|
||||
.as_atom()?;
|
||||
result.name = emacs_name.into();
|
||||
let emacs_attributes_map = emacs_list_iter
|
||||
.next()
|
||||
.ok_or("Should have an attributes child.")?
|
||||
.as_map()?;
|
||||
let mut emacs_keys: std::collections::BTreeSet<&str> =
|
||||
emacs_attributes_map.keys().map(|s| *s).collect();
|
||||
|
||||
// Mark :standard-properties as seen because it will be handled separately.
|
||||
if emacs_keys.contains(":standard-properties") {
|
||||
emacs_keys.remove(":standard-properties");
|
||||
} else {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
"Emacs node lacked :standard-properties field.".into(),
|
||||
));
|
||||
}
|
||||
|
||||
{
|
||||
// Compare name.
|
||||
let wasm_name = $wasm.get_elisp_name();
|
||||
|
||||
if emacs_name != wasm_name {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"AST node name mismatch. Emacs=({emacs}) Wasm=({wasm}).",
|
||||
emacs = emacs_name,
|
||||
wasm = wasm_name,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Compare standard properties.
|
||||
result.extend(wasm_compare_standard_properties($source, $emacs, &$wasm.standard_properties)?)?;
|
||||
}
|
||||
|
||||
{
|
||||
// Compare additional properties.
|
||||
let additional_property_names: Vec<String> = $wasm.additional_properties.get_elisp_names().collect();
|
||||
for additional_property in additional_property_names.iter().map(String::as_str).map(EmacsField::Required) {
|
||||
match additional_property {
|
||||
EmacsField::Required(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
}
|
||||
EmacsField::Optional(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
}
|
||||
EmacsField::Required(name) => {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Emacs node lacked required field ({name}).",
|
||||
name = name,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
EmacsField::Optional(_name) => {}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
result.extend(wasm_compare_additional_properties($source, $emacs, &$wasm.additional_properties)?)?;
|
||||
}
|
||||
|
||||
{
|
||||
// Compare children.
|
||||
result.extend(wasm_compare_list(
|
||||
$source,
|
||||
emacs_list_iter,
|
||||
$wasm.children.iter(),
|
||||
)?)?;
|
||||
}
|
||||
|
||||
{
|
||||
// Check for properties that are missing from the elisp node.
|
||||
$(
|
||||
match $emacs_field {
|
||||
EmacsField::Required(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
}
|
||||
EmacsField::Optional(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
}
|
||||
EmacsField::Required(name) => {
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Emacs node lacked required field ({name}).",
|
||||
name = name,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
EmacsField::Optional(_name) => {}
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
||||
{
|
||||
// Check for elisp properties that were not compared.
|
||||
if !emacs_keys.is_empty() {
|
||||
let unexpected_keys: Vec<&str> = emacs_keys.into_iter().collect();
|
||||
let unexpected_keys = unexpected_keys.join(", ");
|
||||
result.status.push(WasmDiffStatus::Bad(
|
||||
format!(
|
||||
"Emacs node had extra field(s): ({field_names}).",
|
||||
field_names = unexpected_keys,
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
// Compare properties.
|
||||
$(
|
||||
let emacs_name = match $emacs_field {
|
||||
EmacsField::Required(name) => {
|
||||
name
|
||||
},
|
||||
EmacsField::Optional(name) => {
|
||||
name
|
||||
},
|
||||
};
|
||||
result.extend($compare_fn($source, $emacs, $wasm, emacs_name, $wasm_value_getter)?)?;
|
||||
)*
|
||||
}
|
||||
|
||||
result
|
||||
}};
|
||||
}
|
||||
pub(crate) use wasm_compare;
|
||||
@@ -1,6 +1,5 @@
|
||||
mod compare;
|
||||
mod diff;
|
||||
mod macros;
|
||||
mod runner;
|
||||
|
||||
pub use runner::wasm_run_anonymous_compare;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
use std::path::Path;
|
||||
|
||||
use super::compare::wasm_compare_document;
|
||||
use crate::compare::sexp;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::parser::parse_file_with_settings;
|
||||
use crate::parser::parse_with_settings;
|
||||
use crate::settings::LocalFileAccessInterface;
|
||||
use crate::util::emacs_parse_anonymous_org_document;
|
||||
use crate::util::emacs_parse_file_org_document;
|
||||
use crate::util::foreground_color;
|
||||
use crate::util::print_versions;
|
||||
use crate::util::reset_color;
|
||||
use crate::util::cli::emacs_parse_anonymous_org_document;
|
||||
use crate::util::cli::emacs_parse_file_org_document;
|
||||
use crate::util::cli::print_versions;
|
||||
use crate::util::elisp::sexp;
|
||||
use crate::util::terminal::foreground_color;
|
||||
use crate::util::terminal::reset_color;
|
||||
use crate::wasm::ToWasm;
|
||||
use crate::wasm::ToWasmContext;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user