Skip to content

Commit

Permalink
add Vento support
Browse files Browse the repository at this point in the history
  • Loading branch information
g-plane committed Mar 29, 2024
1 parent 2f58f31 commit 2cfedf4
Show file tree
Hide file tree
Showing 43 changed files with 702 additions and 22 deletions.
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

0 comments on commit 2cfedf4

Please sign in to comment.