slab / quill

Quill is a modern WYSIWYG editor built for compatibility and extensibility
https://quilljs.com
BSD 3-Clause "New" or "Revised" License
43.13k stars 3.35k forks source link

Syntax Highlight does not split string as expected #4178

Open PJUllrich opened 4 months ago

PJUllrich commented 4 months ago

This is basically a new issue for #3041 which was closed by the quill-bot.

Steps for Reproduction

Example code

defmodule Test do
  def foo(bar) do
    bar + 2
  end
end

Expected behavior:

The defmodule Test do string is split into three parts hljs-keyword, hljs-title, and hljs-keyword and is highlighted correctly:

CleanShot 2024-05-06 at 10 22 20@2x CleanShot 2024-05-06 at 10 21 47@2x

Actual behavior:

The string is only split into two parts: hljs-class and hljs-keyword and is not highlighted correctly:

CleanShot 2024-05-06 at 10 23 34@2x CleanShot 2024-05-06 at 10 24 03@2x

Platforms:

    "highlight.js": "^11.9.0",
    "quill": "^2.0.1",

Version:

2.0.1

PJUllrich commented 4 months ago

I tracked it down to this piece of the code where the following input is transformed wrongly to the following output.

Somehow, the hljs-class-keyword confuses the highlight(text, language) function and it skips the inner keywords hljs-keyword and hljs-title.

Text Input

defmodule Test do
  def foo(bar) do
    bar + 2
  end
end

Input after call to hljs.highlight()

<span class="hljs-class"><span class="hljs-keyword">defmodule</span> <span class="hljs-title">Test</span></span> <span class="hljs-keyword">do</span>
  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">foo</span></span>(bar) <span class="hljs-keyword">do</span>
    bar + <span class="hljs-number">2</span>
  <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>

Output of recursive highlight()

{
    "ops": [
        {
            "insert": "defmodule Test",
            "attributes": {
                "code-token": "class"
            }
        },
        {
            "insert": " "
        },
        {
            "insert": "do",
            "attributes": {
                "code-token": "keyword"
            }
        },
        {
            "insert": "\n",
            "attributes": {
                "code-block": "elixir"
            }
        },
        {
            "insert": "  "
        },
        {
            "insert": "def foo",
            "attributes": {
                "code-token": "function"
            }
        },
        {
            "insert": "(bar) "
        },
        {
            "insert": "do",
            "attributes": {
                "code-token": "keyword"
            }
        },
        {
            "insert": "\n",
            "attributes": {
                "code-block": "elixir"
            }
        },
        {
            "insert": "    bar + "
        },
        {
            "insert": "2",
            "attributes": {
                "code-token": "number"
            }
        },
        {
            "insert": "\n",
            "attributes": {
                "code-block": "elixir"
            }
        },
        {
            "insert": "  "
        },
        {
            "insert": "end",
            "attributes": {
                "code-token": "keyword"
            }
        },
        {
            "insert": "\n",
            "attributes": {
                "code-block": "elixir"
            }
        },
        {
            "insert": "end",
            "attributes": {
                "code-token": "keyword"
            }
        },
        {
            "insert": "\n",
            "attributes": {
                "code-block": "elixir"
            }
        }
    ]
}
PJUllrich commented 4 months ago

I recreated it in the playground.

Just enter the input text and select Elixir as a language:

defmodule Test do
  def foo(bar) do
    bar + 2
  end
end

https://quilljs.com/playground/snow#codeN4Ig9AlgdgJgpgDwHQCsDOIBcIDGB7KNAFwAIBHAVwgBtqSBeEqOAdxIEUraAKAcgGI4MCETwAnXgBoSwADpQSJALZ4YFanDSYZ8xYrQBPKEQCGCbXIV7FAC2rptLaDDwskd9JN3WS1E1ABzChMAzW0AbW8fGRIAazgDbVkQMQoAIwNk6T80uGokkAAldMyQEgBfLyto4DiEgryIBAgxLN8TXPySZIBRaiaW5Iqq6IBdEb1KqJJRPGo0kzEI6cVw2ps4E3glknCARmkAJmkAMxNqNDhRivGV3d40uZgpEl4Rc4gcF94KWDgxfrMXi3ap6cJvJQhODffDwAC0aWoeBwsWBE0UIMUUysAAc-Dg4DYnv9tLwAMJ4JQ4vCXEj+EhwHGfJAsqTeIgbJRwUloKCuF5gMAkcSvNLpRHQ+TlACUAG4QJJwM5EO4iEpqFgQAAeACEcLhJAAklAcNQKPAZhsSDYIAE7LabERUGhfBA0mJFgYSPqAHzyLVoHBiCA40hoMQ4ejJR1EHFaQU4GBQdBIU14c0nPxiOCpylgEwoMxgfppNBgG12-p2p3oMB7PZIACcSAADOWHVXHUglNBnckfVqwIHg6G-VB-cOQ2GI1GQDG45gE0mU2mM1mc-glPnCwhi26yxX7dXnXWG82235AsFQmXGs0xN3e+h+4PJ6P5P7hAA3EgQGCzoQRHEF8wG-McJyDKcSHDSNkkgP5kGfEAByHSDRxAcogA

findulov commented 1 week ago

I'm getting the same behavior with C# code:

image

boring2 commented 1 day ago

Yes, how can I solve it?