Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Vento support #12

Merged
merged 4 commits into from
Apr 2, 2024
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
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
**/*.astro linguist-detectable=false
**/*.jinja linguist-detectable=false
**/*.njk linguist-detectable=false
**/*.vto linguist-detectable=false
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# markup_fmt

markup_fmt is a configurable HTML/Vue/Svelte/Astro/Jinja/Twig/Nunjucks formatter.
markup_fmt is a configurable HTML/Vue/Svelte/Astro/Jinja/Twig/Nunjucks/Vento formatter.

![GitHub Downloads](https://img.shields.io/github/downloads/g-plane/markup_fmt/latest/plugin.wasm?style=for-the-badge)

Expand All @@ -19,7 +19,7 @@ This will make ESLint faster because less rules will be executed.

We've provided [dprint](https://dprint.dev/) integration.

This plugin only formats HTML syntax of your HTML/Vue/Svelte/Astro/Jinja/Twig/Nunjucks files.
This plugin only formats HTML syntax of your HTML/Vue/Svelte/Astro/Jinja/Twig/Nunjucks/Vento files.
You also need other dprint plugins to format the code in `<script>` and `<style>` tags.
You can use [dprint-plugin-typescript](https://github.com/dprint/dprint-plugin-typescript) to
format TypeScript/JavaScript code and [Malva](https://github.com/g-plane/malva) to format CSS/SCSS/Sass/Less code.
Expand Down
2 changes: 1 addition & 1 deletion dprint_plugin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl SyncPluginHandler<FormatOptions> for MarkupFmtPluginHandler {
},
file_matching: FileMatchingInfo {
file_extensions: [
"html", "vue", "svelte", "astro", "jinja", "jinja2", "twig", "njk",
"html", "vue", "svelte", "astro", "jinja", "jinja2", "twig", "njk", "vto",
]
.into_iter()
.map(String::from)
Expand Down
4 changes: 2 additions & 2 deletions dprint_plugin/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{fs, path::Path, process::Command};
#[test]
fn integration_with_dprint_ts_snapshot() {
glob!(
"integration/**/*.{html,vue,svelte,astro,jinja,njk}",
"integration/**/*.{html,vue,svelte,astro,jinja,njk,vto}",
|path| {
let file = fs::File::open(path).unwrap();

Expand Down Expand Up @@ -33,7 +33,7 @@ fn integration_with_dprint_ts_snapshot() {
#[test]
fn integration_with_biome_snapshot() {
glob!(
"integration/**/*.{html,vue,svelte,astro,jinja,njk}",
"integration/**/*.{html,vue,svelte,astro,jinja,njk,vto}",
|path| {
let file = fs::File::open(path).unwrap();

Expand Down
11 changes: 11 additions & 0 deletions dprint_plugin/tests/integration/basic.vto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{ { name:"Óscar",surname:'Otero'}|>JSON.stringify(null,2) }}

{{ if ! it . user }}
No user found!
{{ /if }}

{{ for odd_number of [1,2,3].filter(n=>n%2) }}
{{ /for }}

{{ for await item of getItems( ) }}
{{ /for }}
15 changes: 15 additions & 0 deletions dprint_plugin/tests/integration/biome/basic.vto.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
source: dprint_plugin/tests/integration.rs
---
{{ { name: "Óscar", surname: "Otero" } |> JSON.stringify(null, 2) }}

{{ if !it.user }}
No user found!
{{ /if }}

{{ for odd_number of [1, 2, 3].filter((n) => n % 2) }}
{{ /for }}

{{ for await item of getItems() }}
{{ /for }}

5 changes: 5 additions & 0 deletions dprint_plugin/tests/integration/biome/eval.vto.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: dprint_plugin/tests/integration.rs
---
{{> console.log("Hello, world!") }}

6 changes: 6 additions & 0 deletions dprint_plugin/tests/integration/biome/import.vto.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
source: dprint_plugin/tests/integration.rs
---
{{ import { message } from "./vars.vto" }}
{{ import fns from "./functions.vto" }}

15 changes: 15 additions & 0 deletions dprint_plugin/tests/integration/dprint_ts/basic.vto.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
source: dprint_plugin/tests/integration.rs
---
{{ { name: "Óscar", surname: "Otero" } |> JSON.stringify(null, 2) }}

{{ if !it.user }}
No user found!
{{ /if }}

{{ for odd_number of [1, 2, 3].filter(n => n % 2) }}
{{ /for }}

{{ for await item of getItems() }}
{{ /for }}

5 changes: 5 additions & 0 deletions dprint_plugin/tests/integration/dprint_ts/eval.vto.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: dprint_plugin/tests/integration.rs
---
{{> console.log("Hello, world!") }}

6 changes: 6 additions & 0 deletions dprint_plugin/tests/integration/dprint_ts/import.vto.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
source: dprint_plugin/tests/integration.rs
---
{{ import { message } from "./vars.vto" }}
{{ import fns from "./functions.vto" }}

1 change: 1 addition & 0 deletions dprint_plugin/tests/integration/eval.vto
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{> console . log( 'Hello, world!' ) }}
2 changes: 2 additions & 0 deletions dprint_plugin/tests/integration/import.vto
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{{ import {message} from './vars.vto' }}
{{ import fns from './functions.vto' }}
2 changes: 1 addition & 1 deletion markup_fmt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "markup_fmt"
version = "0.6.0"
edition = "2021"
authors = ["Pig Fang <[email protected]>"]
description = "Configurable HTML/Vue/Svelte/Astro/Jinja/Twig/Nunjucks formatter."
description = "Configurable HTML/Vue/Svelte/Astro/Jinja/Twig/Nunjucks/Vento formatter."
repository = "https://github.com/g-plane/markup_fmt"
license = "MIT"
exclude = ["/tests"]
Expand Down
2 changes: 1 addition & 1 deletion markup_fmt/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
markup_fmt is a configurable HTML/Vue/Svelte/Astro/Jinja/Twig/Nunjucks formatter.
markup_fmt is a configurable HTML/Vue/Svelte/Astro/Jinja/Twig/Nunjucks/Vento formatter.

## Basic Usage

Expand Down
36 changes: 36 additions & 0 deletions markup_fmt/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ pub enum Node<'s> {
SvelteInterpolation(SvelteInterpolation<'s>),
SvelteKeyBlock(SvelteKeyBlock<'s>),
TextNode(TextNode<'s>),
VentoBlock(VentoBlock<'s>),
VentoComment(VentoComment<'s>),
VentoEval(VentoEval<'s>),
VentoInterpolation(VentoInterpolation<'s>),
VentoTag(VentoTag<'s>),
VueInterpolation(VueInterpolation<'s>),
}

Expand Down Expand Up @@ -184,6 +189,37 @@ pub struct TextNode<'s> {
pub line_breaks: usize,
}

#[derive(Clone, Debug)]
pub struct VentoBlock<'s> {
pub body: Vec<VentoTagOrChildren<'s>>,
}

#[derive(Clone, Debug)]
pub struct VentoComment<'s> {
pub raw: &'s str,
}

#[derive(Clone, Debug)]
pub struct VentoEval<'s> {
pub raw: &'s str,
}

#[derive(Clone, Debug)]
pub struct VentoInterpolation<'s> {
pub expr: &'s str,
}

#[derive(Clone, Debug)]
pub struct VentoTag<'s> {
pub tag: &'s str,
}

#[derive(Clone, Debug)]
pub enum VentoTagOrChildren<'s> {
Tag(VentoTag<'s>),
Children(Vec<Node<'s>>),
}

#[derive(Clone, Debug)]
pub struct VueInterpolation<'s> {
pub expr: &'s str,
Expand Down
28 changes: 26 additions & 2 deletions markup_fmt/src/ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ where
{
pub(crate) fn script_indent(&self) -> bool {
match self.language {
Language::Html | Language::Jinja => self
Language::Html | Language::Jinja | Language::Vento => self
.options
.html_script_indent
.unwrap_or(self.options.script_indent),
Expand All @@ -50,7 +50,7 @@ where

pub(crate) fn style_indent(&self) -> bool {
match self.language {
Language::Html | Language::Jinja => self
Language::Html | Language::Jinja | Language::Vento => self
.options
.html_style_indent
.unwrap_or(self.options.style_indent),
Expand Down Expand Up @@ -170,6 +170,30 @@ where
}
}

pub(crate) fn format_stmt_header(&mut self, keyword: &str, code: &str) -> String {
if code.trim().is_empty() {
String::new()
} else {
let wrapped = format!("{keyword} ({code}) {{}}");
let formatted = self.format_with_external_formatter(
Path::new("stmt_header.js"),
&wrapped,
self.print_width
.saturating_sub(self.indent_level)
.saturating_sub(keyword.len() + 1), // this is technically wrong, just workaround
);
formatted
.strip_prefix(keyword)
.map(|s| s.trim_start())
.and_then(|s| s.strip_prefix("("))
.and_then(|s| s.trim_end().strip_suffix('}'))
.and_then(|s| s.trim_end().strip_suffix('{'))
.and_then(|s| s.trim_end().strip_suffix(')'))
.unwrap_or(code)
.to_owned()
}
}

pub(crate) fn format_script<'a>(&mut self, code: &'a str, lang: &str) -> Cow<'a, str> {
self.format_with_external_formatter(
Path::new(&format!("script.{lang}")),
Expand Down
2 changes: 2 additions & 0 deletions markup_fmt/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub enum SyntaxErrorKind {
ExpectSvelteThenBlock,
ExpectTagName,
ExpectTextNode,
ExpectVentoBlockEnd,
ExpectVueDirective,
UnknownSvelteBlock,
}
Expand Down Expand Up @@ -78,6 +79,7 @@ impl fmt::Display for SyntaxError {
SyntaxErrorKind::ExpectSvelteThenBlock => "expect Svelte then block".into(),
SyntaxErrorKind::ExpectTagName => "expect tag name".into(),
SyntaxErrorKind::ExpectTextNode => "expect text node".into(),
SyntaxErrorKind::ExpectVentoBlockEnd => "expect Vento block end".into(),
SyntaxErrorKind::ExpectVueDirective => "expect Vue directive".into(),
SyntaxErrorKind::UnknownSvelteBlock => "unknown Svelte block".into(),
};
Expand Down
17 changes: 12 additions & 5 deletions markup_fmt/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ static NON_WS_SENSITIVE_TAGS: [&str; 69] = [
];

pub(crate) fn is_whitespace_sensitive_tag(name: &str, language: Language) -> bool {
if matches!(language, Language::Html | Language::Jinja) {
if matches!(language, Language::Html | Language::Jinja | Language::Vento) {
// There's also a tag called "a" in SVG, so we need to check it specially.
name.eq_ignore_ascii_case("a")
|| !NON_WS_SENSITIVE_TAGS
Expand All @@ -99,7 +99,7 @@ static VOID_ELEMENTS: [&str; 14] = [
];

pub(crate) fn is_void_element(name: &str, language: Language) -> bool {
if matches!(language, Language::Html | Language::Jinja) {
if matches!(language, Language::Html | Language::Jinja | Language::Vento) {
VOID_ELEMENTS
.iter()
.any(|tag| tag.eq_ignore_ascii_case(name))
Expand All @@ -109,7 +109,7 @@ pub(crate) fn is_void_element(name: &str, language: Language) -> bool {
}

pub(crate) fn is_html_tag(name: &str, language: Language) -> bool {
if matches!(language, Language::Html | Language::Jinja) {
if matches!(language, Language::Html | Language::Jinja | Language::Vento) {
css_dataset::tags::STANDARD_HTML_TAGS
.iter()
.any(|tag| tag.eq_ignore_ascii_case(name))
Expand All @@ -127,7 +127,7 @@ pub(crate) fn is_html_tag(name: &str, language: Language) -> bool {
}

pub(crate) fn is_svg_tag(name: &str, language: Language) -> bool {
if matches!(language, Language::Html | Language::Jinja) {
if matches!(language, Language::Html | Language::Jinja | Language::Vento) {
css_dataset::tags::SVG_TAGS
.iter()
.any(|tag| tag.eq_ignore_ascii_case(name))
Expand All @@ -137,7 +137,7 @@ pub(crate) fn is_svg_tag(name: &str, language: Language) -> bool {
}

pub(crate) fn is_mathml_tag(name: &str, language: Language) -> bool {
if matches!(language, Language::Html | Language::Jinja) {
if matches!(language, Language::Html | Language::Jinja | Language::Vento) {
css_dataset::tags::MATH_ML_TAGS
.iter()
.any(|tag| tag.eq_ignore_ascii_case(name))
Expand All @@ -147,3 +147,10 @@ pub(crate) fn is_mathml_tag(name: &str, language: Language) -> bool {
.any(|tag| *tag == name)
}
}

pub(crate) fn parse_vento_tag(tag: &str) -> (&str, &str) {
let trimmed = tag.trim();
trimmed
.split_once(|c: char| c.is_ascii_whitespace())
.unwrap_or((trimmed, ""))
}
1 change: 1 addition & 0 deletions markup_fmt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ pub fn detect_language(path: impl AsRef<Path>) -> Option<Language> {
Some("svelte") => Some(Language::Svelte),
Some("astro") => Some(Language::Astro),
Some("jinja" | "jinja2" | "twig" | "njk") => Some(Language::Jinja),
Some("vto") => Some(Language::Vento),
_ => None,
}
}
Loading