Add support for raw (unescaped HTML) blocks
This commit is contained in:
parent
7171145aa5
commit
91ba94a38a
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -780,6 +780,7 @@ dependencies = [
|
||||
"hornbeam_grammar",
|
||||
"hornbeam_ir",
|
||||
"html-escape",
|
||||
"insta",
|
||||
"itertools",
|
||||
"pollster",
|
||||
"thiserror",
|
||||
@ -940,16 +941,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "insta"
|
||||
version = "1.28.0"
|
||||
version = "1.38.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea5b3894afe466b4bcf0388630fc15e11938a6074af0cd637c825ba2ec8a099"
|
||||
checksum = "3eab73f58e59ca6526037208f0e98851159ec1633cf17b6cd2e1f2c3fd5d53cc"
|
||||
dependencies = [
|
||||
"console",
|
||||
"lazy_static",
|
||||
"linked-hash-map",
|
||||
"serde",
|
||||
"similar",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2117,12 +2117,3 @@ checksum = "f46aab759304e4d7b2075a9aecba26228bb073ee8c50db796b2c72c676b5d807"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
@ -15,6 +15,7 @@ pub enum Block {
|
||||
ForBlock(ForBlock),
|
||||
MatchBlock(MatchBlock),
|
||||
Text(StringExpr),
|
||||
RawUnescapedHtml(StringExpr),
|
||||
DefineExpandSlot(DefineExpandSlot),
|
||||
DefineFragment(DefineFragment),
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ BlockContent = _{
|
||||
Element |
|
||||
IfBlock |
|
||||
Text |
|
||||
RawUnescapedHtml |
|
||||
DefineExpandSlot |
|
||||
ForBlock |
|
||||
MatchBlock |
|
||||
@ -34,6 +35,10 @@ Text = {
|
||||
String ~ lineEnd
|
||||
}
|
||||
|
||||
RawUnescapedHtml = {
|
||||
"raw" ~ ws+ ~ String ~ lineEnd
|
||||
}
|
||||
|
||||
IfBlock = {
|
||||
"if" ~ ws+ ~ IfCondition ~ lineEnd ~ NewBlock ~
|
||||
ElseBlock?
|
||||
|
@ -202,6 +202,12 @@ impl HornbeamParser {
|
||||
)?))
|
||||
}
|
||||
|
||||
fn RawUnescapedHtml(input: Node) -> PCResult<Block> {
|
||||
Ok(Block::RawUnescapedHtml(HornbeamParser::String(
|
||||
input.into_children().single()?,
|
||||
)?))
|
||||
}
|
||||
|
||||
fn String(input: Node) -> PCResult<StringExpr> {
|
||||
let mut pieces = Vec::new();
|
||||
for node in input.into_children() {
|
||||
@ -491,6 +497,7 @@ impl HornbeamParser {
|
||||
Ok(match input.as_rule() {
|
||||
Rule::Element => Some(HornbeamParser::Element(input)?),
|
||||
Rule::Text => Some(HornbeamParser::Text(input)?),
|
||||
Rule::RawUnescapedHtml => Some(HornbeamParser::RawUnescapedHtml(input)?),
|
||||
Rule::IfBlock => Some(HornbeamParser::IfBlock(input)?),
|
||||
Rule::ForBlock => Some(HornbeamParser::ForBlock(input)?),
|
||||
Rule::MatchBlock => Some(HornbeamParser::MatchBlock(input)?),
|
||||
@ -666,4 +673,17 @@ div
|
||||
)
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn raw() {
|
||||
assert_yaml_snapshot!(parse_template(
|
||||
r#"
|
||||
div
|
||||
span
|
||||
raw "<u>wow $x ${$x} @wowage{}</u>"
|
||||
"#,
|
||||
"inp"
|
||||
)
|
||||
.unwrap());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
---
|
||||
source: hornbeam_grammar/src/parser.rs
|
||||
expression: "parse_template(r#\"\ndiv\n span\n raw \"<u>wow $x ${$x} @wowage{}</u>\"\n \"#,\n \"inp\").unwrap()"
|
||||
---
|
||||
blocks:
|
||||
- HtmlElement:
|
||||
name: div
|
||||
children:
|
||||
- HtmlElement:
|
||||
name: span
|
||||
children:
|
||||
- RawUnescapedHtml:
|
||||
pieces:
|
||||
- Literal: "<u>wow "
|
||||
- Interpolation:
|
||||
Variable:
|
||||
name: x
|
||||
loc:
|
||||
filename: inp
|
||||
line: 4
|
||||
column: 21
|
||||
- Literal: " "
|
||||
- Interpolation:
|
||||
Variable:
|
||||
name: x
|
||||
loc:
|
||||
filename: inp
|
||||
line: 4
|
||||
column: 26
|
||||
- Literal: " @wowage{}</u>"
|
||||
classes: []
|
||||
dom_id: ~
|
||||
attributes: {}
|
||||
loc:
|
||||
filename: inp
|
||||
line: 3
|
||||
column: 5
|
||||
classes: []
|
||||
dom_id: ~
|
||||
attributes: {}
|
||||
loc:
|
||||
filename: inp
|
||||
line: 2
|
||||
column: 1
|
||||
|
@ -29,3 +29,6 @@ tracing = "0.1.37"
|
||||
[features]
|
||||
default = ["fluent"]
|
||||
fluent = ["fluent-templates"]
|
||||
|
||||
[dev-dependencies]
|
||||
insta = "1.38.0"
|
||||
|
56
hornbeam_interpreter/tests/snapshots.rs
Normal file
56
hornbeam_interpreter/tests/snapshots.rs
Normal file
@ -0,0 +1,56 @@
|
||||
use bevy_reflect::Reflect;
|
||||
use hornbeam_interpreter::{localisation::NoLocalisation, LoadedTemplates, Params};
|
||||
use insta::assert_snapshot;
|
||||
|
||||
#[derive(Reflect)]
|
||||
struct SimpleTestStruct {
|
||||
wombat: u64,
|
||||
apple: u64,
|
||||
banana: String,
|
||||
carrot: String,
|
||||
}
|
||||
|
||||
fn simple_test_struct() -> SimpleTestStruct {
|
||||
SimpleTestStruct {
|
||||
wombat: 42,
|
||||
apple: 78,
|
||||
banana: "banana!!!".to_owned(),
|
||||
carrot: "mmm CARROT".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn simple_render(template: &str) -> String {
|
||||
let mut templates = LoadedTemplates::new(NoLocalisation);
|
||||
templates
|
||||
.load_template_from_str("main", template, "main.hnb")
|
||||
.expect("failed to load template");
|
||||
let params = Params::default()
|
||||
.set("sts", simple_test_struct())
|
||||
.set("five", 5);
|
||||
let prepared = templates.prepare("main", None, params, "en".to_owned());
|
||||
prepared.render_to_string().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn snapshot_001() {
|
||||
assert_snapshot!(simple_render(
|
||||
r#"
|
||||
html
|
||||
body
|
||||
"this was a triumph :>"
|
||||
br
|
||||
raw "<u>making a note here, huge success</u>"
|
||||
|
||||
if $five == 5
|
||||
"FIVE!!! $five"
|
||||
br
|
||||
|
||||
if $five < 10
|
||||
"five is less than ten!"
|
||||
br
|
||||
|
||||
if $five > 5
|
||||
"weird..."
|
||||
"#
|
||||
))
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: hornbeam_interpreter/tests/snapshots.rs
|
||||
expression: "simple_render(r#\"\nhtml\n body\n \"this was a triumph :>\"\n br\n raw \"<u>making a note here, huge success</u>\"\n\n if $five == 5\n \"FIVE!!! $five\"\n br\n\n if $five < 10\n \"five is less than ten!\"\n br\n\n if $five > 5\n \"weird...\"\n \"#)"
|
||||
---
|
||||
<!DOCTYPE html><html><body>this was a triumph :><br><u>making a note here, huge success</u>FIVE!!! 5<br>five is less than ten!<br></body></html>
|
@ -132,7 +132,7 @@ fn pull_out_entrypoints_from_block<'a>(
|
||||
}
|
||||
}
|
||||
}
|
||||
Block::Text(_) | Block::DefineExpandSlot(_) => { /* nop */ }
|
||||
Block::Text(_) | Block::RawUnescapedHtml(_) | Block::DefineExpandSlot(_) => { /* nop */ }
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -411,6 +411,41 @@ fn compile_ast_block_to_steps<'a>(
|
||||
}
|
||||
}
|
||||
}
|
||||
Block::RawUnescapedHtml(text) => {
|
||||
for piece in &text.pieces {
|
||||
match piece {
|
||||
StringPiece::Literal(lit) => {
|
||||
instructions.push(Step {
|
||||
def: StepDef::WriteLiteral {
|
||||
text: lit.clone(),
|
||||
escape: false,
|
||||
},
|
||||
locator: Locator::empty(),
|
||||
});
|
||||
}
|
||||
StringPiece::Interpolation(expr) => {
|
||||
instructions.push(Step {
|
||||
def: StepDef::WriteEval {
|
||||
expr: expr.clone(),
|
||||
escape: false,
|
||||
},
|
||||
locator: Locator::empty(),
|
||||
});
|
||||
}
|
||||
piece @ StringPiece::Localise { .. } => {
|
||||
instructions.push(Step {
|
||||
def: StepDef::WriteEval {
|
||||
expr: Expression::StringExpr(StringExpr {
|
||||
pieces: vec![piece.clone()],
|
||||
}),
|
||||
escape: false,
|
||||
},
|
||||
locator: Locator::empty(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Block::DefineExpandSlot(slot) => {
|
||||
instructions.push(Step {
|
||||
def: StepDef::CallSlotWithParentScope {
|
||||
|
Loading…
Reference in New Issue
Block a user