Skip to content

Provide print(ast: Ast): string as compiler or svelte/printer #5972

Open
@mizchi

Description

@mizchi

Is your feature request related to a problem? Please describe.

Svelte compiler has parse(template: string): Ast but no print(code: Ast) => template printer.

TypeScript compiler (and some program languages) has this feature.

https://learning-notes.mistermicheels.com/javascript/typescript/compiler-api/#programmatically-creating-ast-nodes.

Describe the solution you'd like

Svelte compiler provides print(ast: Ast, optionalFormatter?: {js?: (code:string)=>string , ...} ): string.

import { parse, print } from "svelte/compiler";
const template = `<div {id}>foo</div>`
const parsed = parse(template);
const restored = print(parsed); // => same template

How important is this feature to you?

I'm creating code collaboration editor for non-programmer and programmer on svelte template.

Left side pane is auto generated forms by svelte template AST for non-programmer. By rewriting this, I try to reflect svelte template by ast changes. but svelte compiler does not have printer feature.

I think providing this feature helps svelte ecosystem.

Additional Context

https://github.com/sveltejs/prettier-plugin-svelte has code printer already. (fortunately for me, it works in browser!)

But that is format(template: string): string. I need formatter from ast.

So I hacked this for my workarround.

import prettier from "prettier/standalone";
import produce from "immer";
import { parse } from "svelte/compiler";
import type { Ast } from "svelte/types/compiler/interfaces";
// @ts-ignore
import * as sveltePlugin from "prettier-plugin-svelte";

function printTemplate(ast: Ast) {
  const overridePlugin = produce(sveltePlugin, (d: any) => {
    d.parsers.svelte.parse = () => {
      return { ...ast, __isRoot: true };
    };
  });
  return prettier.format(" dummy ", {
    parser: "svelte",
    plugins: [overridePlugin as any],
  });
}

const code = "<div {id}>text</div>";
const parsed = parse(code);
// override ast
// @ts-ignore
parsed.html.children[0].name = "span";
const out = printTemplate(parsed);
console.log(out); // <span {id}>text</span>

It depend on prettier but formatting js and css are optional feature for template block. Formatters for js and css already exist but svelte html template block formatter does not exists now.

I wrote simple printer (WIP) but I found prettier hack before I finished it.

https://gist.github.com/mizchi/8d51d239bccec98408cffde5ef5b855d

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions