riccardoperra / codeimage

A tool to beautify your code screenshots. Built with SolidJS and Fastify.
https://codeimage.dev
MIT License
1.35k stars 74 forks source link

🚀 - Support for pasting rich text from VSCode #577

Closed Not-Jayden closed 6 months ago

Not-Jayden commented 10 months ago

Which @codeimage/* package(s) are relevant/releated to the feature request?

No response

Description

There are a lot of languages out there without proper support for syntax highlighting, seemingly primarily due to the bottleneck of what languages codemirror can support. Particularly, I was trying to use CodeImage to display some Svelte code, but unfortunately could not get the syntax highlighting I was hoping for.

As a workaround, I suspect adding support for pasting RTF data (like you get when copying from VSCode) would be a simple(r) and more flexible approach for support syntax highlighting for any language.

riccardoperra commented 10 months ago

Hey, what do you mean pasting RTF data? Just like google docs?

image

Anyway, it seems that there is a Svelte extension for CodeMirror (https://github.com/replit/codemirror-lang-svelte), so it may be added to codeimage if needed.

Not-Jayden commented 10 months ago

@riccardoperra Yep exactly. I didn't properly investigate how the copied data from VSCode, looking at it more it seems like it's just HTML.

e.g. copying this from vscode

image

gives me this raw data in my clipboard

<meta charset='utf-8'><div style="color: #cccccc;background-color: #1f1f1f;font-family: Fira Code, Menlo, Monaco, 'Courier New', monospace, Menlo, Monaco, 'Courier New', monospace;font-weight: normal;font-size: 12px;line-height: 18px;white-space: pre;"><div><span style="color: #569cd6;">const</span><span style="color: #cccccc;"> </span><span style="color: #4fc1ff;">colourStatusPositive</span><span style="color: #cccccc;"> </span><span style="color: #d4d4d4;">=</span><span style="color: #cccccc;"> </span><span style="color: #ce9178;">'#00d592'</span><span style="color: #cccccc;"> </span><span style="color: #c586c0;">satisfies</span><span style="color: #cccccc;"> </span><span style="color: #4ec9b0;">ColourHex</span><span style="color: #cccccc;">;</span></div></div>

Good to know about Svelte, I can maybe give that a go later. Though in fairness I think there are a lot of more popular languages that deserve to be added beforehand, which is why I figure supporting rich text/html potentially might be higher value for more people.

riccardoperra commented 10 months ago

That would be helpful but very difficult to handle in my opinion 😫 I need to do a bit of investigation

How do I know if the user want to paste rtf or just the code? The text from the clipboard seems doesn’t have any hint about the “language” used..

Currently the editable zone is entirely made with CodeMirror, in that case I should add a new “modality” and probably let the editor readonly.

Another case, what if I want to edit the pasted text? I should probably return to my editor, then change the code, then paste again to CodeImage.

If you have any ideas, I gladly accept feedback 😃

Anyway at the moment adding Svelte syntax can be added for the December update I want to release

Not-Jayden commented 10 months ago

@riccardoperra

Yeah, you can't particularly know the user's intention unfortunately. My thoughts are you should prompt the user with a confirmation modal when they make a paste with html type text (maybe with some additional validation that the HTML contains styled text), and/or only support it when the language is set to plain text. Though it looks like that would change the preview file extension to .txt which isn't ideal.

Otherwise if it's just the plain text in the clipboard there'd be no prompt.

Pseudo-paste interception code:

editor.addEventListener('paste', async (event) => {
    // Check if there's HTML data in the clipboard
    if (clipboardData.types.includes('text/html')) {
        // Ask the user if they want to paste with formatting
        const shouldPasteWithFormatting = await promptPasteWithFormattingConfirmation();
        if (shouldPasteWithFormatting) {
            // handle formatted paste
            return;
        }
    }

    // If there's no HTML data or the user chose not to paste HTML, paste as plain text
    if (clipboardData.types.includes('text/plain')) {
        const plainTextData = clipboardData.getData('text/plain');
        // handle regular paste
    }
});

And yeah haven't dug around in the codebase too much, might be a challenge if the editor is quite baked into codemirror. I can probably take a peak later this week.

riccardoperra commented 10 months ago

That idea is not bad 🤔 everything related to codemirror is here:

https://github.com/riccardoperra/codeimage/tree/main/apps/codeimage/src/components/CustomEditor

I'm already listening to the paste event in order to show a toast to format the content with prettier

https://github.com/riccardoperra/codeimage/blob/d68f3d00320dc7b7ec38e8276abed1dfcb00f50e/apps/codeimage/src/components/CustomEditor/CanvasEditor.tsx#L55-L101

In that case if the user confirm, we should set a flag in order to be able to switch between the CustomEditor and the component with the formatted text.

In case user could also "rollback" the action, we might only need to get the code from htmlElement.outerText and switch that flag

Then we should add from scratch the component that displays the formatted content, adding also support for lineNumbers (i don't think this will be difficult, otherwise we could just disable it).

We might also need to parse the html div in order to retrieve the background-color property and set it to the "terminal" frame

stale[bot] commented 7 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.