feat(config): parse rich text matches

This commit is contained in:
Federico Terzi 2021-04-29 22:35:05 +02:00
parent 302a45aa88
commit 038798a2d6
3 changed files with 74 additions and 53 deletions

View File

@ -17,17 +17,11 @@
* along with espanso. If not, see <https://www.gnu.org/licenses/>. * along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/ */
use crate::{ use crate::{counter::next_id, matches::{Match, Params, TextFormat, UpperCasingStyle, Value, Variable, group::{path::resolve_imports, MatchGroup}}};
counter::next_id,
matches::{
group::{path::resolve_imports, MatchGroup},
Match, UpperCasingStyle, Variable, Params, Value,
},
};
use anyhow::Result; use anyhow::Result;
use log::{error, warn}; use log::{error, warn};
use parse::YAMLMatchGroup; use parse::YAMLMatchGroup;
use regex::{Regex, Captures}; use regex::{Captures, Regex};
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use self::{ use self::{
@ -147,49 +141,66 @@ impl TryFrom<YAMLMatch> for Match {
MatchCause::None MatchCause::None
}; };
let effect = if let Some(replace) = yaml_match.replace { let effect =
let vars: Result<Vec<Variable>> = yaml_match if yaml_match.replace.is_some() || yaml_match.markdown.is_some() || yaml_match.html.is_some()
.vars { // TODO: test markdown and html cases
.unwrap_or_default() let (replace, format) = if let Some(plain) = yaml_match.replace {
.into_iter() (plain, TextFormat::Plain)
.map(|var| var.try_into()) } else if let Some(markdown) = yaml_match.markdown {
.collect(); (markdown, TextFormat::Markdown)
MatchEffect::Text(TextEffect { } else if let Some(html) = yaml_match.html {
replace, (html, TextFormat::Html)
vars: vars?, } else {
}) unreachable!();
} else if let Some(form_layout) = yaml_match.form { // TODO: test form case };
// Replace all the form fields with actual variables
let resolved_layout = VAR_REGEX.replace_all(&form_layout, |caps: &Captures| {
let var_name = caps.get(1).unwrap().as_str();
format!("{{{{form1.{}}}}}", var_name)
}).to_string();
// Convert escaped brakets in forms let vars: Result<Vec<Variable>> = yaml_match
let resolved_layout = resolved_layout.replace("\\{", "{ ").replace("\\}", " }"); .vars
.unwrap_or_default()
.into_iter()
.map(|var| var.try_into())
.collect();
MatchEffect::Text(TextEffect {
replace,
vars: vars?,
format,
})
} else if let Some(form_layout) = yaml_match.form {
// TODO: test form case
// Replace all the form fields with actual variables
let resolved_layout = VAR_REGEX
.replace_all(&form_layout, |caps: &Captures| {
let var_name = caps.get(1).unwrap().as_str();
format!("{{{{form1.{}}}}}", var_name)
})
.to_string();
// Convert the form data to valid variables // Convert escaped brakets in forms
let mut params = Params::new(); let resolved_layout = resolved_layout.replace("\\{", "{ ").replace("\\}", " }");
params.insert("layout".to_string(), Value::String(form_layout));
if let Some(fields) = yaml_match.form_fields { // Convert the form data to valid variables
params.insert("fields".to_string(), Value::Object(convert_params(fields)?)); let mut params = Params::new();
} params.insert("layout".to_string(), Value::String(form_layout));
let vars = vec![Variable { if let Some(fields) = yaml_match.form_fields {
id: next_id(), params.insert("fields".to_string(), Value::Object(convert_params(fields)?));
name: "form1".to_owned(), }
var_type: "form".to_owned(),
params,
}];
MatchEffect::Text(TextEffect { let vars = vec![Variable {
replace: resolved_layout, id: next_id(),
vars, name: "form1".to_owned(),
}) var_type: "form".to_owned(),
} else { params,
MatchEffect::None }];
};
MatchEffect::Text(TextEffect {
replace: resolved_layout,
vars,
format: TextFormat::Plain,
})
} else {
MatchEffect::None
};
if let MatchEffect::None = effect { if let MatchEffect::None = effect {
warn!( warn!(
@ -493,6 +504,7 @@ mod tests {
effect: MatchEffect::Text(TextEffect { effect: MatchEffect::Text(TextEffect {
replace: "world".to_string(), replace: "world".to_string(),
vars, vars,
..Default::default()
}), }),
..Default::default() ..Default::default()
} }
@ -526,6 +538,7 @@ mod tests {
effect: MatchEffect::Text(TextEffect { effect: MatchEffect::Text(TextEffect {
replace: "world".to_string(), replace: "world".to_string(),
vars, vars,
..Default::default()
}), }),
..Default::default() ..Default::default()
} }

View File

@ -98,13 +98,13 @@ pub struct YAMLMatch {
pub force_clipboard: Option<bool>, pub force_clipboard: Option<bool>,
#[serde(default)] #[serde(default)]
pub markdown: Option<String>, // TODO: map pub markdown: Option<String>,
#[serde(default)] #[serde(default)]
pub paragraph: Option<bool>, // TODO: map pub paragraph: Option<bool>,
#[serde(default)] #[serde(default)]
pub html: Option<String>, // TODO: map pub html: Option<String>,
} }
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]

View File

@ -17,11 +17,11 @@
* along with espanso. If not, see <https://www.gnu.org/licenses/>. * along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/ */
use std::collections::{BTreeMap};
use enum_as_inner::EnumAsInner; use enum_as_inner::EnumAsInner;
use ordered_float::OrderedFloat; use ordered_float::OrderedFloat;
use std::collections::BTreeMap;
use crate::counter::{StructId}; use crate::counter::StructId;
pub(crate) mod group; pub(crate) mod group;
pub mod store; pub mod store;
@ -95,13 +95,20 @@ pub enum MatchEffect {
None, None,
Text(TextEffect), Text(TextEffect),
// TODO: image // TODO: image
// TODO: rich text
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TextEffect { pub struct TextEffect {
pub replace: String, pub replace: String,
pub vars: Vec<Variable>, pub vars: Vec<Variable>,
pub format: TextFormat,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum TextFormat {
Plain,
Markdown,
Html,
} }
impl Default for TextEffect { impl Default for TextEffect {
@ -109,6 +116,7 @@ impl Default for TextEffect {
Self { Self {
replace: String::new(), replace: String::new(),
vars: Vec::new(), vars: Vec::new(),
format: TextFormat::Plain,
} }
} }
} }
@ -148,4 +156,4 @@ pub enum Value {
pub enum Number { pub enum Number {
Integer(i64), Integer(i64),
Float(OrderedFloat<f64>), Float(OrderedFloat<f64>),
} }