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

feat: Code block #1177

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

feat: Code block #1177

wants to merge 8 commits into from

Conversation

areknawo
Copy link

This PR adds a code block with syntax highlighting (using prosemirror-highlight) to the core.

BlockNote Code block Example

Copy link

vercel bot commented Oct 22, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
blocknote ✅ Ready (Inspect) Visit Preview Oct 25, 2024 8:17am
blocknote-website ✅ Ready (Inspect) Visit Preview Oct 25, 2024 8:17am

Copy link

vercel bot commented Oct 22, 2024

@areknawo is attempting to deploy a commit to the TypeCell Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Collaborator

@YousefED YousefED left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great!

I think the only things remaining would be to add this block to the nodeconversions / htmlconversions unit tests (we can also do this) and to the default schema showcase (https://blocknote-git-fork-areknawo-main-typecell.vercel.app/basic/all-blocks)

I also noticed that we don't correctly set the language when it's parsed from markdown (you can try this here: https://blocknote-git-fork-areknawo-main-typecell.vercel.app/interoperability/converting-blocks-from-md).

One other thing I'm in doubt of is which languages we should show in the default dropdown. Maybe it makes more sense to limit options to some popular languages by default, what do you think?

return {
indentLineWithTab: true,
supportedLanguages: [
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbd: maybe we should use plain text or javascript as default

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also wasn't sure about this. Usually, in HTML/MD, code blocks without language simply leave it out, so I made an empty string the default and assigned a Code label to it. I think the empty string makes sense, but label can be changed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have a text language (https://shiki.style/languages#plain-text) for plain text.

Then we can still decide to upon creation initialize with plain text vs javascript. Maybe let's do javascript for now because otherwise people don't really notice the syntax highlighting

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I think I can add defaultLanguage option with text as the default.
For text, txt, plain values, I understand renderHTML should skip them, not to add class="language-text" to the HTML?

!$from.parent.textContent &&
isTextSelection(selection)
) {
const from = $from.pos - $from.parentOffset - 2;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you explain what's happening here? Or add a comment in the code?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean a specific line or the keyboard shortcut as a whole?

As for the shortcut - this one removes an empty code block on DELETE from the inside (common behavior across different WYSIWYG editors that didn't work out-of-the-box in BlockNote). I can add a comment

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The specific line. My reasoning; when I read this code with a manual position fix in the review, I figured there's probably something interesting going on - so I was triggered to ask about this. From your reply that seems to be the case indeed, so let's document it with a comment and turn this into shared knowledge.

TLDR: if there's a "workaround" needed for something, let's try to document that as much as possible in the code for others or your "future self"

@@ -3,7 +3,7 @@
"private": true,
"version": "0.17.1",
"scripts": {
"dev": "vite",
"dev": "vite --host",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this do anything when not passing a host?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It exposes the dev server on the local network. I didn't mean to leave it, but it's helpful for testing on different devices

@areknawo
Copy link
Author

I also noticed that we don't correctly set the language when it's parsed from markdown (you can try this here: https://blocknote-git-fork-areknawo-main-typecell.vercel.app/interoperability/converting-blocks-from-md).

I see that you specifically modify rehype handler to use a data-language attribute. I can add support for it in the block.
As for the handler - it also adds a newline at the end of the block - what's the purpose of it and can it be removed?

One other thing I'm in doubt of is which languages we should show in the default dropdown. Maybe it makes more sense to limit options to some popular languages by default, what do you think?

Wasn't sure about this, especially with Shiki having support for different language variants (e.g. TypeScript, TSX, TypeScript with Tags - which one to leave then?). Makes sense to have a smaller list, but not sure what the subset should be?

};

export const codeBlockPropSchema = {
...defaultProps,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YousefED Should the code block support default props (e.g. textAlignment, backgroundColor, etc.). I've referenced it from other blocks, but I'm not sure if it makes sense here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good spot, let's remove

@YousefED
Copy link
Collaborator

I see that you specifically modify rehype handler to use a data-language attribute. I can add support for it in the block.
As for the handler - it also adds a newline at the end of the block - what's the purpose of it and can it be removed?

Cool. newline, not sure, let's remove it (might have been TypeCell related)

Makes sense to have a smaller list

What about this list: https://shiki.style/languages -> web bundle, but

  • without: angular, astro, blade, coffee, handlebars, html derivative, http, imba, jinja, jison, json5, marko, mdc, stylus, ts-tags
  • with: haskell, c#, latex, lua, mermaid, ruby, rust, scala, swift, kotlin, objective c

What do you think?

@areknawo
Copy link
Author

What do you think?

I think it's a good selection. It's always going to be a bit subjective, but it makes sense to shorten it a little bit by default

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

Successfully merging this pull request may close these issues.

2 participants