Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/format_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ mod test {
extension: None,
text: "const content = html`<div>broken html</p>`".into(),
config: &config,
external_formatter: Some(&|media_type, _text, _config| {
assert!(matches!(media_type, deno_ast::MediaType::Html));
external_formatter: Some(&|lang, _text, _config| {
assert!(matches!(lang, "html"));
Err(anyhow::anyhow!("Syntax error from external formatter"))
}),
});
Expand Down
9 changes: 5 additions & 4 deletions src/generation/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ use super::*;
use crate::configuration::*;
use crate::utils::Stack;

/// A callback that will be called when encountering certain tagged templates.
/// A callback that will be called when encountering tagged templates.
///
/// Currently supports `css`, `html` and `sql` tagged templated.
/// It is up to the caller to decide if a certain tagged template should be formatted
/// by the external formatter.
///
/// Examples:
/// ```ignore
Expand All @@ -41,11 +42,11 @@ use crate::utils::Stack;
/// active IS TRUE;
/// ```
///
/// External formatter should return `None` if it doesn't understand given `MediaType`, in such
/// External formatter should return `None` if it doesn't understand given language, in such
/// cases the templates will be left as they are.
///
/// Only templates with no interpolation are supported.
pub type ExternalFormatter = dyn Fn(MediaType, String, &Configuration) -> anyhow::Result<Option<String>>;
pub type ExternalFormatter = dyn Fn(&str, String, &Configuration) -> anyhow::Result<Option<String>>;

pub(crate) struct GenerateDiagnostic {
pub message: String,
Expand Down
25 changes: 9 additions & 16 deletions src/generation/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3016,13 +3016,13 @@ fn gen_spread_element<'a>(node: &SpreadElement<'a>, context: &mut Context<'a>) -
/// Detects the type of embedded language automatically.
fn maybe_gen_tagged_tpl_with_external_formatter<'a>(node: &TaggedTpl<'a>, context: &mut Context<'a>) -> Option<PrintItems> {
let external_formatter = context.external_formatter.as_ref()?;
let media_type = detect_embedded_language_type(node)?;
let embedded_lang = normalize_embedded_language_type(node)?;

let placeholder_css = "@dpr1nt_";
let placeholder_other = "dpr1nt_";
// First creates text with placeholders for the expressions.
let placeholder_text = match media_type {
MediaType::Css => placeholder_css,
let placeholder_text = match embedded_lang {
"css" => placeholder_css,
_ => placeholder_other,
};
let text = capacity_builder::StringBuilder::<String>::build(|builder| {
Expand All @@ -3043,7 +3043,7 @@ fn maybe_gen_tagged_tpl_with_external_formatter<'a>(node: &TaggedTpl<'a>, contex
.unwrap();

// Then formats the text with the external formatter.
let formatted_tpl = match external_formatter(media_type, text.replace(r"\\", "\\"), context.config) {
let formatted_tpl = match external_formatter(embedded_lang, text.replace(r"\\", "\\"), context.config) {
Ok(formatted_tpl) => formatted_tpl?.replace("\\", r"\\"),
Err(err) => {
context.diagnostics.push(context::GenerateDiagnostic {
Expand Down Expand Up @@ -3102,29 +3102,22 @@ fn maybe_gen_tagged_tpl_with_external_formatter<'a>(node: &TaggedTpl<'a>, contex
Some(items)
}

/// Detects the type of embedded language in a tagged template literal.
fn detect_embedded_language_type<'a>(node: &TaggedTpl<'a>) -> Option<MediaType> {
/// Normalizes the type of embedded language in a tagged template literal.
fn normalize_embedded_language_type<'a>(node: &TaggedTpl<'a>) -> Option<&'a str> {
match node.tag {
Expr::Ident(ident) => {
match ident.sym().as_str() {
"css" => Some(MediaType::Css), // css`...`
"html" => Some(MediaType::Html), // html`...`
"sql" => Some(MediaType::Sql), // sql`...`
_ => None,
}
}
Expr::Ident(ident) => return Some(ident.sym().as_str()),
Expr::Member(member_expr) => {
if let Expr::Ident(ident) = member_expr.obj {
if ident.sym().as_str() == "styled" {
return Some(MediaType::Css); // styled.foo`...`
return Some("css"); // styled.foo`...`
}
}
None
}
Expr::Call(call_expr) => {
if let Callee::Expr(Expr::Ident(ident)) = call_expr.callee {
if ident.sym().as_str() == "styled" {
return Some(MediaType::Css); // styled(Button)`...`
return Some("css"); // styled(Button)`...`
}
}
None
Expand Down
Loading