I'm trying to create a syntax highlighter for the Klipper 3D printer firmware. The language consists of settings elements, comments and Jinja2 template elements. In the first place, I wanted to get a simple highlighting working but I'm hitting a road block.
Highlighter Code:
hljs.registerLanguage("klipper", function (hljs) {
const COMMENT = {
scope: "comment",
variants: [
{ begin: /^\s*[#;].*$/, end: /$/ }, // Standalone comments
{ begin: /(?!\s)[#|;].*/, end: /$/ }, // Inline/trailing comments
],
relevance: 10,
}
const KEY_PART = {
scope: "symbol",
begin: /^[^=\s]+(?=\s*[:=])/,
//end: /^(?!\s).+?\s?[=:](?=(?:[^\n]*$))/,
}
const VALUE_PART = {
scope: "addition",
begin: /[:=][\s*|$]/,
//end: /\r?\n$/, // Match until the end of the line
end: /$/, // Match until the end of the line
excludeBegin: true, // Ensure the separator is not included
excludeEnd: true,
}
const SECTION = {
scope: "addition",
begin: /^\s*\[/,
end: /\]/,
contains: [
{
scope: "title",
match: /[^\]]+/,
},
],
}
const INDENTED_BLOCK = {
scope: "deletion",
begin: /^\s+/,
end: /$/,
relevance: 10,
}
return {
name: "Klipper Config",
aliases: ["klipper", "cfg"],
disableAutodetect: true,
contains: [COMMENT, SECTION, KEY_PART, VALUE_PART, INDENTED_BLOCK],
}
})
My issue is that I cannot get a regex or setting for properly matching the VALUE_PART
, for example:
[idle_timeout]
gcode:
{% if printer.pause_resume.is_paused %}
While a simple key/value pair, like step_pin: PC2
, matches, the regex fails if the key is not directly followed by a value, but the statements are in an indented block below. The indented block should be formatted as INDENTED_BLOCK
. See the following screenshot.
Basically, the VALUE_PART
formatting is "bleeding into" this block, but only for the first line of such an indented block.
Fiddle with the code is here: /
Any pointer how to solve this would be really appreciated. Many thanks in advance.
I'm trying to create a syntax highlighter for the Klipper 3D printer firmware. The language consists of settings elements, comments and Jinja2 template elements. In the first place, I wanted to get a simple highlighting working but I'm hitting a road block.
Highlighter Code:
hljs.registerLanguage("klipper", function (hljs) {
const COMMENT = {
scope: "comment",
variants: [
{ begin: /^\s*[#;].*$/, end: /$/ }, // Standalone comments
{ begin: /(?!\s)[#|;].*/, end: /$/ }, // Inline/trailing comments
],
relevance: 10,
}
const KEY_PART = {
scope: "symbol",
begin: /^[^=\s]+(?=\s*[:=])/,
//end: /^(?!\s).+?\s?[=:](?=(?:[^\n]*$))/,
}
const VALUE_PART = {
scope: "addition",
begin: /[:=][\s*|$]/,
//end: /\r?\n$/, // Match until the end of the line
end: /$/, // Match until the end of the line
excludeBegin: true, // Ensure the separator is not included
excludeEnd: true,
}
const SECTION = {
scope: "addition",
begin: /^\s*\[/,
end: /\]/,
contains: [
{
scope: "title",
match: /[^\]]+/,
},
],
}
const INDENTED_BLOCK = {
scope: "deletion",
begin: /^\s+/,
end: /$/,
relevance: 10,
}
return {
name: "Klipper Config",
aliases: ["klipper", "cfg"],
disableAutodetect: true,
contains: [COMMENT, SECTION, KEY_PART, VALUE_PART, INDENTED_BLOCK],
}
})
My issue is that I cannot get a regex or setting for properly matching the VALUE_PART
, for example:
[idle_timeout]
gcode:
{% if printer.pause_resume.is_paused %}
While a simple key/value pair, like step_pin: PC2
, matches, the regex fails if the key is not directly followed by a value, but the statements are in an indented block below. The indented block should be formatted as INDENTED_BLOCK
. See the following screenshot.
Basically, the VALUE_PART
formatting is "bleeding into" this block, but only for the first line of such an indented block.
Fiddle with the code is here: https://jsfiddle/Sineos/54yz89e3/
Any pointer how to solve this would be really appreciated. Many thanks in advance.
Share Improve this question asked Mar 26 at 18:35 TomTom 9112 bronze badges 4 |1 Answer
Reset to default 0The token \s
also matches \r
and \n
and that's why it is stepping over the line break.
Just doing:
const VALUE_PART = {
scope: "addition",
begin: /[:=]/,
end: /$/, // Match until the end of the line
excludeBegin: true, // Ensure the separator is not included
excludeEnd: true,
}
does the trick. Fiddle is updated.
[\s*|$]
matches a whitespace, a*
, a|
or a$
symbol. Did you mean(?:\s*|$)
? which is basically meaningless in this context, so maybe you wanted a(?:\s|$)
? – Wiktor Stribiżew Commented Mar 26 at 18:43[:=]\s*
. The problem persists, for whatever reason the regex / HighlightJS is stepping over the line break and matching the following indented line. – Tom Commented Mar 26 at 19:33(?!\s)[#|;]
(assuming you want to write(?!\s)[#;]
) is redundant because you can't have at the same position a#
or a;
and a white-space character. In other words,[#:]
only, does the same, the lookahead is useless in this situation. – Casimir et Hippolyte Commented Mar 26 at 20:16