mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
handle <% %> template syntax
This commit is contained in:
parent
62481ddc1a
commit
fbfb7861a2
2 changed files with 41 additions and 3 deletions
|
@ -2,7 +2,9 @@ use crate::backend_proto as pt;
|
|||
use crate::backend_proto::backend_input::Value;
|
||||
use crate::err::{AnkiError, Result};
|
||||
use crate::sched::sched_timing_today;
|
||||
use crate::template::{FieldMap, FieldRequirements, ParsedTemplate};
|
||||
use crate::template::{
|
||||
without_legacy_template_directives, FieldMap, FieldRequirements, ParsedTemplate,
|
||||
};
|
||||
use prost::Message;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
|
@ -110,7 +112,8 @@ impl Backend {
|
|||
.template_front
|
||||
.into_iter()
|
||||
.map(|template| {
|
||||
if let Ok(tmpl) = ParsedTemplate::from_text(&template) {
|
||||
let normalized = without_legacy_template_directives(&template);
|
||||
if let Ok(tmpl) = ParsedTemplate::from_text(normalized.as_ref()) {
|
||||
// convert the rust structure into a protobuf one
|
||||
let val = match tmpl.requirements(&map) {
|
||||
FieldRequirements::Any(ords) => Value::Any(pt::TemplateRequirementAny {
|
||||
|
|
|
@ -4,6 +4,7 @@ use nom::branch::alt;
|
|||
use nom::bytes::complete::tag;
|
||||
use nom::error::ErrorKind;
|
||||
use nom::sequence::delimited;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
pub type FieldMap<'a> = HashMap<&'a str, u16>;
|
||||
|
@ -107,7 +108,26 @@ enum ParsedNode<'a> {
|
|||
#[derive(Debug)]
|
||||
pub struct ParsedTemplate<'a>(Vec<ParsedNode<'a>>);
|
||||
|
||||
static ALT_HANDLEBAR_DIRECTIVE: &str = "{{=<% %>=}}";
|
||||
|
||||
/// Convert legacy alternate syntax to standard syntax.
|
||||
pub fn without_legacy_template_directives(text: &str) -> Cow<str> {
|
||||
if text.trim_start().starts_with(ALT_HANDLEBAR_DIRECTIVE) {
|
||||
text.trim_start()
|
||||
.trim_start_matches(ALT_HANDLEBAR_DIRECTIVE)
|
||||
.replace("<%", "{{")
|
||||
.replace("%>", "}}")
|
||||
.into()
|
||||
} else {
|
||||
text.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ParsedTemplate<'_> {
|
||||
/// Create a template from the provided text.
|
||||
///
|
||||
/// The legacy alternate syntax is not supported, so the provided text
|
||||
/// should be run through without_legacy_template_directives() first.
|
||||
pub fn from_text(template: &str) -> Result<ParsedTemplate> {
|
||||
let mut iter = tokens(template);
|
||||
Ok(Self(parse_inner(&mut iter, None)?))
|
||||
|
@ -260,7 +280,7 @@ impl ParsedTemplate<'_> {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{FieldMap, ParsedNode::*, ParsedTemplate as PT};
|
||||
use crate::template::FieldRequirements;
|
||||
use crate::template::{without_legacy_template_directives, FieldRequirements};
|
||||
use std::collections::HashSet;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
|
@ -357,4 +377,19 @@ mod test {
|
|||
FieldRequirements::Any(HashSet::from_iter(vec![0].into_iter()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alt_syntax() {
|
||||
let input = "
|
||||
{{=<% %>=}}
|
||||
<%Front%>
|
||||
<% #Back %>
|
||||
<%/Back%>";
|
||||
let output = "
|
||||
{{Front}}
|
||||
{{ #Back }}
|
||||
{{/Back}}";
|
||||
|
||||
assert_eq!(without_legacy_template_directives(input), output);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue