The Wayback Machine - https://web.archive.org/web/20210209105123/https://github.com/sveltejs/svelte/issues/5972
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

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

Open
mizchi opened this issue Feb 9, 2021 · 0 comments
Open

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

mizchi opened this issue Feb 9, 2021 · 0 comments

Comments

@mizchi
Copy link

@mizchi mizchi commented Feb 9, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant