Compare commits

...

6 Commits

Author SHA1 Message Date
Tom Alexander
172d72aa46
Implement src block.
Some checks failed
clippy Build clippy has failed
rust-foreign-document-test Build rust-foreign-document-test has succeeded
rust-build Build rust-build has failed
rust-test Build rust-test has failed
2023-12-30 17:40:15 -05:00
Tom Alexander
b4fcc6500b
Implement verse block. 2023-12-30 16:47:24 -05:00
Tom Alexander
ddb6f31562
Implement angle link. 2023-12-30 16:41:55 -05:00
Tom Alexander
dc080b30fc
Implement citation reference. 2023-12-30 16:35:01 -05:00
Tom Alexander
9901e17437
Implement citation. 2023-12-30 16:33:02 -05:00
Tom Alexander
ea000894f0
Implement entity. 2023-12-30 16:24:51 -05:00
7 changed files with 281 additions and 24 deletions

View File

@ -1,18 +1,28 @@
use std::borrow::Cow;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use super::ast_node::WasmAstNode; use super::ast_node::WasmAstNode;
use super::macros::to_wasm; use super::macros::to_wasm;
use super::to_wasm::ToWasm; use super::to_wasm::ToWasm;
use super::AdditionalProperties;
use crate::compare::ElispFact; use crate::compare::ElispFact;
use crate::types::AngleLink; use crate::types::AngleLink;
use crate::types::LinkType;
use crate::wasm::to_wasm::ToWasmStandardProperties; use crate::wasm::to_wasm::ToWasmStandardProperties;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "format")]
#[serde(rename = "angle")]
pub struct WasmAngleLink { pub struct WasmAngleLink {
#[serde(flatten)] #[serde(rename = "type")]
pub(crate) additional_properties: AdditionalProperties, 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!( to_wasm!(
@ -21,12 +31,23 @@ to_wasm!(
original, original,
wasm_context, wasm_context,
{ WasmAstNode::AngleLink(original) }, { WasmAstNode::AngleLink(original) },
{ "TODO".into() }, { "link".into() },
{ {
Ok(( Ok((
Vec::new(), Vec::new(),
WasmAngleLink { 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),
}, },
)) ))
} }

View File

@ -4,15 +4,15 @@ use serde::Serialize;
use super::ast_node::WasmAstNode; use super::ast_node::WasmAstNode;
use super::macros::to_wasm; use super::macros::to_wasm;
use super::to_wasm::ToWasm; use super::to_wasm::ToWasm;
use super::AdditionalProperties;
use crate::compare::ElispFact; use crate::compare::ElispFact;
use crate::types::Citation; use crate::types::Citation;
use crate::wasm::to_wasm::ToWasmStandardProperties; use crate::wasm::to_wasm::ToWasmStandardProperties;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct WasmCitation { pub struct WasmCitation {
#[serde(flatten)] pub(crate) style: Option<String>,
pub(crate) additional_properties: AdditionalProperties, pub(crate) prefix: Option<Vec<WasmAstNode>>,
pub(crate) suffix: Option<Vec<WasmAstNode>>,
} }
to_wasm!( to_wasm!(
@ -21,7 +21,7 @@ to_wasm!(
original, original,
wasm_context, wasm_context,
{ WasmAstNode::Citation(original) }, { WasmAstNode::Citation(original) },
{ "TODO".into() }, { "citation".into() },
{ {
let children = original let children = original
.children .children
@ -32,11 +32,39 @@ to_wasm!(
.map(Into::<WasmAstNode>::into) .map(Into::<WasmAstNode>::into)
}) })
.collect::<Result<Vec<_>, _>>()?; .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(( Ok((
children, children,
WasmCitation { 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)
},
}, },
)) ))
} }

View File

@ -4,15 +4,15 @@ use serde::Serialize;
use super::ast_node::WasmAstNode; use super::ast_node::WasmAstNode;
use super::macros::to_wasm; use super::macros::to_wasm;
use super::to_wasm::ToWasm; use super::to_wasm::ToWasm;
use super::AdditionalProperties;
use crate::compare::ElispFact; use crate::compare::ElispFact;
use crate::types::CitationReference; use crate::types::CitationReference;
use crate::wasm::to_wasm::ToWasmStandardProperties; use crate::wasm::to_wasm::ToWasmStandardProperties;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct WasmCitationReference { pub struct WasmCitationReference {
#[serde(flatten)] pub(crate) key: String,
pub(crate) additional_properties: AdditionalProperties, pub(crate) prefix: Option<Vec<WasmAstNode>>,
pub(crate) suffix: Option<Vec<WasmAstNode>>,
} }
to_wasm!( to_wasm!(
@ -21,12 +21,41 @@ to_wasm!(
original, original,
wasm_context, wasm_context,
{ WasmAstNode::CitationReference(original) }, { 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(( Ok((
Vec::new(), Vec::new(),
WasmCitationReference { 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)
},
}, },
)) ))
} }

View File

@ -2,17 +2,26 @@ use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use super::ast_node::WasmAstNode; use super::ast_node::WasmAstNode;
use super::headline::Noop;
use super::macros::to_wasm; use super::macros::to_wasm;
use super::to_wasm::ToWasm; use super::to_wasm::ToWasm;
use super::AdditionalProperties;
use crate::compare::ElispFact; use crate::compare::ElispFact;
use crate::types::Entity; use crate::types::Entity;
use crate::wasm::to_wasm::ToWasmStandardProperties; use crate::wasm::to_wasm::ToWasmStandardProperties;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct WasmEntity { pub struct WasmEntity {
#[serde(flatten)] pub(crate) name: String,
pub(crate) additional_properties: AdditionalProperties, 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!( to_wasm!(
@ -21,12 +30,19 @@ to_wasm!(
original, original,
wasm_context, wasm_context,
{ WasmAstNode::Entity(original) }, { WasmAstNode::Entity(original) },
{ "TODO".into() }, { "entity".into() },
{ {
Ok(( Ok((
Vec::new(), Vec::new(),
WasmEntity { 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,
}, },
)) ))
} }

View File

@ -6,13 +6,55 @@ use super::macros::to_wasm;
use super::to_wasm::ToWasm; use super::to_wasm::ToWasm;
use super::AdditionalProperties; use super::AdditionalProperties;
use crate::compare::ElispFact; 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::SrcBlock;
use crate::types::SwitchNumberLines;
use crate::wasm::to_wasm::ToWasmStandardProperties; use crate::wasm::to_wasm::ToWasmStandardProperties;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct WasmSrcBlock { pub struct WasmSrcBlock {
#[serde(flatten)] #[serde(flatten)]
pub(crate) additional_properties: AdditionalProperties, 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)]
enum WasmRetainLabels {
YesNo(bool),
Keep(CharOffsetInLine),
}
#[derive(Debug, Serialize, Deserialize)]
enum WasmNumberLines {
#[serde(rename = "new")]
New(LineNumber),
#[serde(rename = "continued")]
continued(LineNumber),
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename = "number-lines")]
#[serde(tag = "number-lines")]
struct WasmNumberLinesWrapper {
#[serde(flatten)]
inner: WasmNumberLines,
} }
to_wasm!( to_wasm!(
@ -21,12 +63,37 @@ to_wasm!(
original, original,
wasm_context, wasm_context,
{ WasmAstNode::SrcBlock(original) }, { WasmAstNode::SrcBlock(original) },
{ "TODO".into() }, { "src-block".into() },
{ {
let additional_properties = original
.get_affiliated_keywords()
.to_wasm(wasm_context.clone())?;
Ok(( Ok((
Vec::new(), Vec::new(),
WasmSrcBlock { WasmSrcBlock {
additional_properties: AdditionalProperties::default(), additional_properties,
language: original.language.map(|s| s.to_owned()),
value: original.value.to_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()),
}, },
)) ))
} }

View File

@ -6,6 +6,7 @@ use super::macros::to_wasm;
use super::to_wasm::ToWasm; use super::to_wasm::ToWasm;
use super::AdditionalProperties; use super::AdditionalProperties;
use crate::compare::ElispFact; use crate::compare::ElispFact;
use crate::types::GetAffiliatedKeywords;
use crate::types::VerseBlock; use crate::types::VerseBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties; use crate::wasm::to_wasm::ToWasmStandardProperties;
@ -21,8 +22,12 @@ to_wasm!(
original, original,
wasm_context, wasm_context,
{ WasmAstNode::VerseBlock(original) }, { WasmAstNode::VerseBlock(original) },
{ "TODO".into() }, { "verse-block".into() },
{ {
let additional_properties = original
.get_affiliated_keywords()
.to_wasm(wasm_context.clone())?;
let children = original let children = original
.children .children
.iter() .iter()
@ -36,7 +41,7 @@ to_wasm!(
Ok(( Ok((
children, children,
WasmVerseBlock { WasmVerseBlock {
additional_properties: AdditionalProperties::default(), additional_properties,
}, },
)) ))
} }

View File

@ -54,6 +54,10 @@ fn compare_json_value<'b, 's>(
// We hit an object tree additional property. // We hit an object tree additional property.
compare_object_tree(source, el, wasm) 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(w), Token::TextWithProperties(e)) if is_plain_text(w) => { (serde_json::Value::Object(w), Token::TextWithProperties(e)) if is_plain_text(w) => {
compare_plain_text(source, e, w) compare_plain_text(source, e, w)
} }
@ -628,6 +632,93 @@ fn compare_object_tree<'e, 's, 'w>(
Ok(result) Ok(result)
} }
fn compare_number_lines<'e, 's, 'w>(
source: &'s str,
emacs: &'e Vec<Token<'s>>,
wasm: &'w 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
.skip(1)
.next()
.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 is_plain_text<'e, 's, 'w>(wasm: &'w serde_json::Map<String, serde_json::Value>) -> bool { fn is_plain_text<'e, 's, 'w>(wasm: &'w serde_json::Map<String, serde_json::Value>) -> bool {
if let Some(serde_json::Value::String(node_type)) = wasm.get("ast-node") { if let Some(serde_json::Value::String(node_type)) = wasm.get("ast-node") {
node_type == "plain-text" node_type == "plain-text"