Coder Social home page Coder Social logo

g-plane / markup_fmt Goto Github PK

View Code? Open in Web Editor NEW
46.0 2.0 0.0 746 KB

Configurable HTML/Vue/Svelte/Astro/Jinja/Twig/Nunjucks/Vento formatter, with dprint integration which behaves as dprint-plugin-html, dprint-plugin-vue, dprint-plugin-svelte and dprint-plugin-astro but all in one.

License: MIT License

Rust 100.00%
dprint formatter formatting html prettier svelte vue dprint-plugin astro jinja jinja2 nunjucks twig vento

markup_fmt's Introduction

markup_fmt

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

GitHub Downloads

Notes for Vue and Svelte Users

This formatter provides some options such as vBindStyle, vOnStyle and more for Vue and svelteAttrShorthand and svelteDirectiveShorthand for Svelte.

It's recommended to enable these options in this formatter and disable the corresponding rules in eslint-plugin-vue and eslint-plugin-svelte if you used. This will make ESLint faster because less rules will be executed.

Getting Started

dprint

We've provided dprint integration.

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 to format TypeScript/JavaScript code and Malva to format CSS/SCSS/Sass/Less code.

Run the commands below to add plugins:

dprint config add g-plane/markup_fmt
dprint config add g-plane/malva
dprint config add typescript

If you also want to format JSON in <script> tag whose "type" is "importmap" or "application/json", you can add dprint-plugin-json:

dprint config add json

Or Biome:

- dprint config add typescript
- dprint config add json
+ dprint config add biome

After adding the dprint plugins, update your dprint.json and add configuration:

{
  // ...
  "plugins": [
    // ... other plugins URL
    "https://plugins.dprint.dev/g-plane/markup_fmt-v0.7.0.wasm"
  ],
  "markup": { // <-- the key name here is "markup", not "markup_fmt"
    // config comes here
  }
}

You can also read dprint CLI documentation for using dprint to format files.

Use as a Rust crate

Please read the documentation.

Configuration

Please refer to Configuration.

Credit

Tests come from:

License

MIT License

Copyright (c) 2023-present Pig Fang

markup_fmt's People

Contributors

g-plane avatar magic-akari avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

markup_fmt's Issues

External code wrapper is leaked in error message

If there's an error when formatting with external formatter, error message will be like:

Message: [markup_fmt] failed to format code with external formatter: `<>{content +=      &#x27;{&quot;hello&quot;: &quot;I\&#x27;m a button!&quot;}&#x27;}</>`:
Expected ',', got '+=' at file:///expr.tsx:1:12

  <>{content +=      &#x27;{&quot;hello&quot;: &quot;I\&#x27;m a button!&quot;}&#x27;}</>
             ~~
Had 1 error formatting.

The wrapper like <> and </> shouldn't be printed, otherwise it's confusing.

'associations' config

Since there was another issue about type associations, could you add support for associations ?

I was trying to format svg files but I'm getting an unknown file extension error when setting it in the plugin configuration.

This way we could format unknown extensions with the html formatter as a fallback until having an "official" support when needed.

Keep up the good work !

Add Vento support

Hi, thanks for making this plugin! It's hard to find a good formatter for HTML templates.

Any chance that support for Vento could be added? https://github.com/ventojs/vento

If not, it would be nice to map filetypes to template types (ie, map .vto to Jinja to get some formatting), and add the ability to preserve whitespace around mustaches/tags/blocks.

Thanks!

associate other file extensions

What a cool new formatter! I've been trying it out with dprint and it works great, especially the ability to format embedded CSS and JS tags is brilliant.
I was hoping to use this to format my Jinja2 HTML templates (also known as htmldjango filetype in Neovim). Here's an example:

index.jinja2

<!doctype html>
<html>
  <head>
    <title>Hello World</title>
    <style>
      body {
        font-family: sans-serif;
      }
    </style>
  </head>
  <body>
    <h1>Hello {{ user.name }}</h1>
    {% for item in items %}
      <a>{{ item }}<a>
    {% endfor %}
  </body>
</html>

When I run dprint fmt "**/*.jinja2" --diff | delta dprint says No files found to format with the specified plugins. That makes sense, since markup_fmt expects files with the .html extension. As expected, it works with this trick cat index.jinja2 | dprint fmt --stdin html.

I was hoping to add associations for custom file extensions. I tried it with the following minimal config
dprint.jsonc

{
    "$schema": "https://dprint.dev/schemas/v0.json",
    "incremental": true,
    "typescript": {},
    "malva": {},
    "markup": {
        "associations": [
            "**/*.html",
            "**/*.jinja2"
        ]
    },
    "includes": [
        "**/*.{html,jinja2}"
    ],
    "plugins": [
        "https://plugins.dprint.dev/typescript-0.88.3.wasm",
        "https://plugins.dprint.dev/g-plane/malva-v0.1.2.wasm",
        "https://plugins.dprint.dev/g-plane/markup_fmt-v0.1.1.wasm"
    ]
}

but I am getting the error

Error formatting index.jinja2. Message: unknown file extension of file: index.jinja2

[svelte] Error while parsing inline closures

Using dpring v0.45, I'm unable to parse components in svelte files that have a closure with an inline definition :

        <InputField
          onFocusIn={() => {
            if (userNameError) userNameError = '';
            return null;
          }}
          onFocusOut={validateUserName}
         />

Here's the error message :

Message: [markup_fmt] failed to format code with external formatter: `let e = () => {
            if (userNameError) userNameError = '';
            return null;`:

dprint.json

{
  "lineWidth": 100,
  "indentWidth": 2,
  "typescript": {
    "useTabs": false,
    "quoteStyle": "alwaysSingle",
    "trailingCommas": "never"
  },
  "json": {
  },
  "markdown": {
  },
  "toml": {
  },
  "dockerfile": {
  },
  "markup": {
    "useTabs": true,
    "svg.selfClosing": true,
    "component.selfClosing": true,
    "html.normal.selfClosing": true,
    "html.void.selfClosing": true,
    "svelteAttrShorthand": true,
    "svelteDirectiveShorthand": true
  },
  "excludes": [
    "**/node_modules",
    "**/*-lock.json",
    "drizzle/migrations/**"
  ],
  "plugins": [
    "https://plugins.dprint.dev/typescript-0.88.9.wasm",
    "https://plugins.dprint.dev/json-0.19.1.wasm",
    "https://plugins.dprint.dev/markdown-0.16.3.wasm",
    "https://plugins.dprint.dev/toml-0.5.4.wasm",
    "https://plugins.dprint.dev/dockerfile-0.3.0.wasm",
    "https://plugins.dprint.dev/g-plane/markup_fmt-v0.3.1.wasm",
    "https://plugins.dprint.dev/g-plane/malva-v0.1.4.wasm"
  ]
}

[BUG] `*.selfClosing` doesn't work well

The rule of *.selfClosing says when I set it to true, the tag will be formatted as <div />.

But actually it will be formatted as <div />, so that there are two space in the tag which one is redundant.

I don't know if it should be like that or it's a bug.

Case following:

input:

<div />
<div></div>

output:

<div  /> <!-- an extra space in the tag -->
<div  />

Here comes my markup config:

"markup": {
    "closingBracketSameLine": true,
    "component.selfClosing": true,

    "formatComments": true,

    "html.void.selfClosing": true,
    "html.normal.selfClosing": true,

    "mathml.selfClosing": true,
    "maxAttrsPerLine": 1,

    "printWidth": 88,

    "svg.selfClosing": true,

    "vBindStyle": "short",
    "vForDelimiterStyle": "in",
    "vOnStyle": "short",
    "vSlotStyle": "short"
}

Add support for Angular templates

I've been using markup_fmt together with dprint to format html files in an Angular project for a while and it has been working fairly well with some minor quirks — mostly related to how code gets formatted inside interpolation blocks (anything between {{ and }}).

Now that a new control flow syntax has been introduced, it would be great to have support for this (and Angular in general) especially when it comes to indentation and splitting the closing brackets into different lines.

As an example, this:

@if (loading$ | async) {
  <div class="loader"></div>
}

gets formatted like this:

@if (loading$ | async) {
<div class="loader"></div>
}

Any possibility to have support for Angular templates? Not sure how much of an effort it would be but it would be greatly appreciated — I'd really like to avoid going back to prettier for html formatting...

HTML escaping in Vue cannot be formatted.

dprint.json

{
  "excludes": [
    "**/node_modules"
  ],
  "plugins": [
    "https://plugins.dprint.dev/typescript-0.90.4.wasm",
    "https://plugins.dprint.dev/g-plane/markup_fmt-v0.7.0.wasm"
  ]
}

App.vue

<script setup>
import { ref } from "vue";
const content = ref("");
</script>

<template>
  <button @click="content +=      &#x27;{&quot;hello&quot;: &quot;I\&#x27;m a button!&quot;}&#x27;">click {{ content }}</button>
</template>

Expected result

formatted without issue

Actual result

Error formatting /Users/akari/Developer/my-vue-app/src/App.vue. Message: [markup_fmt] failed to format code with external formatter: `<>{content +=      &#x27;{&quot;hello&quot;: &quot;I\&#x27;m a button!&quot;}&#x27;}</>`:
Expected ',', got '+=' at file:///expr.tsx:1:12

  <>{content +=      &#x27;{&quot;hello&quot;: &quot;I\&#x27;m a button!&quot;}&#x27;}</>
             ~~
Had 1 error formatting.

Replication Steps

Replication Steps

  1. Download this compressed package and extract it, then enter the directory.
  2. Run pnpm i and pnpm dev or pnpm build to ensure the code can run correctly.
  3. Run pnpm fmt to observe the formatting situation.

Formatting an Astro file with ", ', or ` in the component script can clear the file

I formatted the following file, which cleared the entirety of the component script and layout. It seems to have been caused by the "'" in the third line.

Input file index.astro:

---
const a = 1;
const b = "'";
const c = 2;
---

<html></html>

Output file:

---

---

The following input files also result in the same empty output file:

---
//'
---
---
//"
---
---
//`
---

Here is the dprint.json that was used:

{
  "markup": {
  },
  "excludes": [
    "**/node_modules",
    "**/*-lock.json"
  ],
  "plugins": [
    "https://plugins.dprint.dev/g-plane/markup_fmt-v0.5.0.wasm"
  ]
}

The same behavior occurred with the TypeScript plugin added.

Props formatting

I love how dprint handles the formatting in JSX with the component's props, for example

const Component = () => {
    return (
        <Badge color="red" size="xs">
            {"@" + username}
        </Badge>
    )
}

This code formats to this: (the same)

const Component = () => {
    return (
        <Badge color="red" size="xs">
            {"@" + username}
        </Badge>
    )
}

And this code:

const Component = () => {
    return (
        <Badge
            color="red"
            size={25}
        >
            {"@" + username}
        </Badge>
    );
};

to this (also the same)

const Component = () => {
    return (
        <Badge
            color="red"
            size={25}
        >
            {"@" + username}
        </Badge>
    );
};

When you have 2 props, you can select use a new line on every prop, or put it in the same line, this avoid this ugly prettier problem:

Input

<div>
    <Card name="John Doe" age={25} imageUrl="myImageHost.com/x"/>
    <Card name="John Doe" age={25} imageUrl="myImageHost.com/x1242141245939519659"/>
</div>

Output

<div>
    <Card name="John Doe" age={25} imageUrl="myImageHost.com/x" />

    <Card
        name="John Doe"
        age={25}
        imageUrl="myImageHost.com/x1242141245939519659"
    />
</div>;

With no option of be like this:

<div>
    <Card 
        name="John Doe" 
        age={25} 
        imageUrl="myImageHost.com/x" 
    />

    <Card
        name="John Doe"
        age={25}
        imageUrl="myImageHost.com/x1242141245939519659"
    />
</div>;

This plugin has the same problem, and I would like to have an option like mantain the user selection of new lines in props. Thank you for this awesome plugin! I like to use it with Astro

Tag + text wrapping option request

First a thank you.

I switched to markup_fmt and dprint because I dislike the way Prettier formats void tags, and I've been really enjoying the experience, so thank you very much for making this.

Now the question.

markup_fmt wraps space-sensitive tags with long properties + short text content differently to how it wraps them with short properties + long text:

<a
  href="quite-a-long-url-that-just-keeps-going"
>short text</a>

<a href="not-a-long-url">but a long piece of
  text that wraps</a>

I find this a little confusing to read.

Would it be possible to implement an option that's closer to (what I believe is) Prettier's behaviour?

<a  href="quite-a-long-url-that-just-keeps-going"
  >short text</a
>

<a href="not-a-long-url"
  >but a long piece of text that wraps</a
>

or a compromise between the two?

<a
  href="quite-a-long-url-that-just-keeps-going"
>short text</a>

<a href="not-a-long-url"
>but a long piece of text that wraps</a>

format quote in typescript as single quote in attrs

<template>
  <div v-if="label = 'a'"></div>
</template>

is now formatted to

<template>
  <div v-if='label = "a"'></div>
</template>

Is it anyway to keep it as is? I don't want to change my typescript config "quoteStyle": "preferDouble".

Nested Jinja tags aren't formatted correctly

Input

{% if a %}
a start
{% if b %}
b content
{% endif %}
a end
{% endif %}

Expected Output

{% if a %}
  a start
  {% if b %}
    b content
  {% endif %}
  a end
{% endif %}

Actual Output

{% if a %}
  a start
{% if b %}
    b content
  {% endif %}
  a end
{% endif %}

dprint playground

Quotes in Vento attributes

Given the code below:

<a style="--bg-color:{{ link.hex || `#${i?.hex || "fff" }` }}; --text-color:{{ link.textColor || textColor(i?.hex || "fff") }}">

markup_fmt will fail to format.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.