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

SVG renderer #2

Closed
octref opened this issue Jan 4, 2019 · 5 comments
Closed

SVG renderer #2

octref opened this issue Jan 4, 2019 · 5 comments

Comments

@octref
Copy link
Collaborator

octref commented Jan 4, 2019

This would make it easy to:

  • Export to Sketch
  • Capture screenshot in Puppeteer
@iamtekeste
Copy link

I would love to see this happen.
What can I do to make this a reality?

@canibanoglu
Copy link

So I played a bit with this recently and I'm afraid it doesn't look straightforward or maybe I'm missing something very obvious.

One of the first problems with SVG is that it really isn't similar HTML in how it works. Working with text content is definitely harder, for example you have to manually position every text element etc.

First obvious attempt was to use dom-to-image by passing the HTML output from shiki to the .toSvg metho but that didn't go well at all:

  • Line breaks don't work and there are some strange characters appearing sometimes (See the image below)
  • The generated svg is HUGE. This is happening because dom-to-image inlines all computed styles to every single span.

Screenshot 2020-01-15 at 17 40 55

I think this can still be done though as long as we don't care about text wrapping as it has to be done manually for SVG. I will update this as I start working on it later.

@canibanoglu
Copy link

I covered some more ground and I have something like the following. I'm not confident in my SVG-foo though and I don't know if this would be the best way to generate an SVG filled with text. I would appreciate it if someone could take a look.

@octref I can prepare a PR if you're OK with it?

Generated SVG
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
    <style>
        .s-c-1 {
            fill: #FFFFFF;
        }
        
        .s-c-2 {
            fill: #292D3E;
        }
        
        .s-c-3 {
            fill: #676E95;
        }
        
        .s-c-4 {
            fill: #F78C6C;
        }
        
        .s-c-5 {
            fill: #89DDFF;
        }
        
        .s-c-6 {
            fill: #C3E88D;
        }
        
        .s-c-7 {
            fill: #FFCB6B;
        }
        
        .s-c-8 {
            fill: #A6ACCD;
        }
        
        .s-c-9 {
            fill: #82AAFF;
        }
        
        .s-c-10 {
            fill: #FF5370;
        }
        
        .s-c-11 {
            fill: #F07178;
        }
        
        .s-c-12 {
            fill: #C792EA;
        }
        
        .s-c-13 {
            fill: #A6ACCD90;
        }
        
        .s-c-14 {
            fill: #4E5579;
        }
        
        .s-c-15 {
            fill: #B2CCD6;
        }
        
        .s-c-16 {
            fill: #C17E70;
        }
    </style>
    <rect width="100%" height="100%" fill="#292D3E" />
    <text x="10" y="16">
        <tspan>
            <tspan class="s-c-5">import</tspan>
            <tspan class="s-c-5">{</tspan>
            <tspan class="s-c-8">renderToHtml</tspan>
            <tspan class="s-c-5">}</tspan>
            <tspan class="s-c-5">from</tspan>
            <tspan class="s-c-5">'</tspan>
            <tspan class="s-c-6">./renderer</tspan>
            <tspan class="s-c-5">'</tspan>
        </tspan>
    </text>
    <text x="10" y="48">
        <tspan>
            <tspan class="s-c-5">import</tspan>
            <tspan class="s-c-5">{</tspan>
            <tspan class="s-c-8">getTheme</tspan>
            <tspan class="s-c-5">,</tspan>
            <tspan class="s-c-8">TTheme</tspan>
            <tspan class="s-c-5">,</tspan>
            <tspan class="s-c-8">IShikiTheme</tspan>
            <tspan class="s-c-5">}</tspan>
            <tspan class="s-c-5">from</tspan>
            <tspan class="s-c-5">'</tspan>
            <tspan class="s-c-6">shiki-themes</tspan>
            <tspan class="s-c-5">'</tspan>
        </tspan>
    </text>
    <text x="10" y="80">
        <tspan>
            <tspan class="s-c-5">export</tspan>
            <tspan class="s-c-12">interface</tspan>
            <tspan class="s-c-7">HighlighterOptions</tspan>
            <tspan class="s-c-5">{</tspan>
        </tspan>
    </text>
    <text x="20" y="96">
        <tspan>
            <tspan class="s-c-8">theme</tspan>
            <tspan class="s-c-12">:</tspan>
            <tspan class="s-c-7">TTheme</tspan>
            <tspan class="s-c-12">|</tspan>
            <tspan class="s-c-7">IShikiTheme</tspan>
        </tspan>
    </text>
    <text x="20" y="112">
        <tspan>
            <tspan class="s-c-8">langs</tspan>
            <tspan class="s-c-12">?:</tspan>
            <tspan class="s-c-7">TLang</tspan>
            <tspan class="s-c-1">[]</tspan>
        </tspan>
    </text>
    <text x="10" y="128">
        <tspan>
            <tspan class="s-c-5">}</tspan>
        </tspan>
    </text>
    <text x="10" y="160">
        <tspan>
            <tspan class="s-c-5">export</tspan>
            <tspan class="s-c-12">async</tspan>
            <tspan class="s-c-12">function</tspan>
            <tspan class="s-c-9">getHighlighter</tspan>
            <tspan class="s-c-5">(</tspan>
            <tspan class="s-c-10">options</tspan>
            <tspan class="s-c-12">:</tspan>
            <tspan class="s-c-7">HighlighterOptions</tspan>
            <tspan class="s-c-5">)</tspan>
            <tspan class="s-c-5">{</tspan>
        </tspan>
    </text>
    <text x="20" y="176">
        <tspan>
            <tspan class="s-c-12">let</tspan>
            <tspan class="s-c-8">t</tspan>
            <tspan class="s-c-12">:</tspan>
            <tspan class="s-c-7">IShikiTheme</tspan>
        </tspan>
    </text>
    <text x="20" y="192">
        <tspan>
            <tspan class="s-c-5">if</tspan>
            <tspan class="s-c-1"> (</tspan>
            <tspan class="s-c-12">typeof</tspan>
            <tspan class="s-c-8">options</tspan>
            <tspan class="s-c-5">.</tspan>
            <tspan class="s-c-8">theme</tspan>
            <tspan class="s-c-12">===</tspan>
            <tspan class="s-c-5">'</tspan>
            <tspan class="s-c-6">string</tspan>
            <tspan class="s-c-5">'</tspan>
            <tspan class="s-c-1">) </tspan>
            <tspan class="s-c-5">{</tspan>
        </tspan>
    </text>
    <text x="30" y="208">
        <tspan>
            <tspan class="s-c-8">t</tspan>
            <tspan class="s-c-12">=</tspan>
            <tspan class="s-c-9">getTheme</tspan>
            <tspan class="s-c-1">(</tspan>
            <tspan class="s-c-8">options</tspan>
            <tspan class="s-c-5">.</tspan>
            <tspan class="s-c-8">theme</tspan>
            <tspan class="s-c-1">)</tspan>
        </tspan>
    </text>
    <text x="20" y="224">
        <tspan>
            <tspan class="s-c-5">}</tspan>
            <tspan class="s-c-5">else</tspan>
            <tspan class="s-c-5">if</tspan>
            <tspan class="s-c-1"> (</tspan>
            <tspan class="s-c-8">options</tspan>
            <tspan class="s-c-5">.</tspan>
            <tspan class="s-c-8">theme</tspan>
            <tspan class="s-c-5">.</tspan>
            <tspan class="s-c-1">name) </tspan>
            <tspan class="s-c-5">{</tspan>
        </tspan>
    </text>
    <text x="30" y="240">
        <tspan>
            <tspan class="s-c-8">t</tspan>
            <tspan class="s-c-12">=</tspan>
            <tspan class="s-c-8">options</tspan>
            <tspan class="s-c-5">.</tspan>
            <tspan class="s-c-8">theme</tspan>
        </tspan>
    </text>
    <text x="20" y="256">
        <tspan>
            <tspan class="s-c-5">}</tspan>
            <tspan class="s-c-5">else</tspan>
            <tspan class="s-c-5">{</tspan>
        </tspan>
    </text>
    <text x="30" y="272">
        <tspan>
            <tspan class="s-c-8">t</tspan>
            <tspan class="s-c-12">=</tspan>
            <tspan class="s-c-9">getTheme</tspan>
            <tspan class="s-c-1">(</tspan>
            <tspan class="s-c-5">'</tspan>
            <tspan class="s-c-6">nord</tspan>
            <tspan class="s-c-5">'</tspan>
            <tspan class="s-c-1">)</tspan>
        </tspan>
    </text>
    <text x="20" y="288">
        <tspan>
            <tspan class="s-c-5">}</tspan>
        </tspan>
    </text>
    <text x="20" y="320">
        <tspan>
            <tspan class="s-c-12">let</tspan>
            <tspan class="s-c-8">langs</tspan>
            <tspan class="s-c-12">:</tspan>
            <tspan class="s-c-7">TLang</tspan>
            <tspan class="s-c-1">[] </tspan>
            <tspan class="s-c-12">=</tspan>
            <tspan class="s-c-1"> [</tspan>
            <tspan class="s-c-12">...</tspan>
            <tspan class="s-c-8">commonLangIds</tspan>
            <tspan class="s-c-5">,</tspan>
            <tspan class="s-c-12">...</tspan>
            <tspan class="s-c-8">commonLangAliases</tspan>
            <tspan class="s-c-1">]</tspan>
        </tspan>
    </text>
    <text x="20" y="352">
        <tspan>
            <tspan class="s-c-5">if</tspan>
            <tspan class="s-c-1"> (</tspan>
            <tspan class="s-c-8">options</tspan>
            <tspan class="s-c-5">.</tspan>
            <tspan class="s-c-8">langs</tspan>
            <tspan class="s-c-1">) </tspan>
            <tspan class="s-c-5">{</tspan>
        </tspan>
    </text>
    <text x="30" y="368">
        <tspan>
            <tspan class="s-c-8">langs</tspan>
            <tspan class="s-c-12">=</tspan>
            <tspan class="s-c-8">options</tspan>
            <tspan class="s-c-5">.</tspan>
            <tspan class="s-c-8">langs</tspan>
        </tspan>
    </text>
    <text x="20" y="384">
        <tspan>
            <tspan class="s-c-5">}</tspan>
        </tspan>
    </text>
    <text x="20" y="416">
        <tspan>
            <tspan class="s-c-12">const</tspan>
            <tspan class="s-c-8">langRegistrations</tspan>
            <tspan class="s-c-12">=</tspan>
            <tspan class="s-c-9">getLangRegistrations</tspan>
            <tspan class="s-c-1">(</tspan>
            <tspan class="s-c-8">langs</tspan>
            <tspan class="s-c-1">)</tspan>
        </tspan>
    </text>
    <text x="20" y="448">
        <tspan>
            <tspan class="s-c-12">const</tspan>
            <tspan class="s-c-8">s</tspan>
            <tspan class="s-c-12">=</tspan>
            <tspan class="s-c-12">new</tspan>
            <tspan class="s-c-7">Shiki</tspan>
            <tspan class="s-c-1">(</tspan>
            <tspan class="s-c-8">t</tspan>
            <tspan class="s-c-5">,</tspan>
            <tspan class="s-c-8">langRegistrations</tspan>
            <tspan class="s-c-1">)</tspan>
        </tspan>
    </text>
    <text x="20" y="464">
        <tspan>
            <tspan class="s-c-5">return</tspan>
            <tspan class="s-c-5">await</tspan>
            <tspan class="s-c-8">s</tspan>
            <tspan class="s-c-5">.</tspan>
            <tspan class="s-c-9">getHighlighter</tspan>
            <tspan class="s-c-1">()</tspan>
        </tspan>
    </text>
    <text x="10" y="480">
        <tspan>
            <tspan class="s-c-5">}</tspan>
        </tspan>
    </text>
</svg>

@canibanoglu
Copy link

Aaand I just realized that there is a svg branch already on this repo right here...

@octref
Copy link
Collaborator Author

octref commented Feb 6, 2020

@canibanoglu You run into the same issue I have: There's no one SVG that would work consistently between design tools such as Figma/AI/Sketch.
I'd be interested in looking this myself as well. If you already find a good solution, maybe send that as a WIP PR and we can take a look together.

octref added a commit that referenced this issue Aug 17, 2020
@octref octref closed this as completed in 87ae289 Aug 18, 2020
octref added a commit that referenced this issue Aug 18, 2020
antfu pushed a commit that referenced this issue Jan 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants