diff --git a/CHANGES.md b/CHANGES.md
index 794f4f4747..5c8f7c2ff8 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -39,6 +39,7 @@ Core Grammars:
- enh(markdown) add entity support [David Schach][] [TaraLei][]
- enh(css) add `justify-items` and `justify-self` attributes [Vasily Polovnyov][]
- enh(css) add `accent-color`, `appearance`, `color-scheme`, `rotate`, `scale` and `translate` attributes [Carl Räfting][]
+- enh(gcode) rewrote language for modern gcode support [Barthélémy Bonhomme][]
New Grammars:
@@ -88,6 +89,7 @@ Themes:
[Rúnar Bjarnason]: https://github.com/runarorama
[Carl Räfting]: https://github.com/carlrafting
[BackupMiles]: https://github.com/BackupMiles
+[Barthélémy Bonhomme]: https://github.com/barthy-koeln
diff --git a/src/languages/gcode.js b/src/languages/gcode.js
index f40224ca9b..822d997514 100644
--- a/src/languages/gcode.js
+++ b/src/languages/gcode.js
@@ -71,57 +71,51 @@ export default function(hljs) {
hljs.QUOTE_STRING_MODE,
hljs.C_NUMBER_MODE,
- // {
- // scope: 'number',
- // match: NUMBER
- // },
-
// gcodes
{
scope: 'title.function',
+ relevance: 10,
variants: [
// G General functions: G0, G5.1, G5.2, …
// M Misc functions: M0, M55.6, M199, …
- { match: /\b[GM]\s*\d+(\.\d+)?/ },
+ { match: /(?, …
+ { match: /(?/ },
// Checksum at end of line: *71, *199, …
{ match: /\*\s*\d+\s*$/ }
]
},
{
- scope: 'name',
- begin: '<',
- end: '>'
+ scope: 'operator', // N Line number: N1, N2, N1020, …
+ match: /^N\s*\d+/
},
-
{
scope: 'variable',
- // Physical axes
+ relevance: 0,
match: /-?#\s*\d+/,
},
{
- scope: 'property',
- // Physical axes
- match: new RegExp(`[ABCUVWXYZ]\\s*${NUMBER.source}`),
+ scope: 'property', // Physical axes
+ match: new RegExp(`(?O003
-N2 G54 G90 G49 G80
-N3 M6 T1
-N4 M3 S1800
-N5 G0 X-.6 Y2.050
-N6 G43 H1 Z.1
-N7 G1 Z-.3 F50.
-N8 G41 D1 Y1.45
-N9 G1 X0 F20.
-N10 G2 J-1.45
+N2 G54 G90 G49 G80
+N3 M6 T1
+N4 M3 S1800
+N5 G0 X-.6 Y2.050
+N6 G43 H1 Z.1
+N7 G1 Z-.3 F50.
+N8 G41 D1 Y1.45
+N9 G1 X0 F20.
+N10 G2 J-1.45
-N11 G1 Z-.2 F50.
-N12 Y-.990
-N13 G40
-N14 G0 X-.6 Y1.590
-N15 G0 Z.1
-N16 M5 G49 G28 G91 Z0
-N17 CALL O9456
-N18 #500=0.004
-N19 #503=[#500+#501]
-N20 VC45=0.0006
-VS4=0.0007
-N21 G90 G10 L20 P3 X5.Y4. Z6.567
-N22 G0 X5000
-N23 IF [#1 LT 0.370] GOTO 49
-N24 X-0.678 Y+.990
-N25 G84.3 X-0.1
-N26 #4=#5*COS[45]
-N27 #4=#5*SIN[45]
-N28 VZOFZ=652.9658
-N29 SAVE_CONFIG
+N11 G1 Z-.2 F50.
+N12 Y-.990
+N13 G40
+N14 G0 X-.6 Y1.590
+N15 G0 Z.1
+N16 M5 G49 G28 G91 Z0
+N17 CALL O9456
+N18 #500=0.004
+N19 #503=[#500+#501]
+N20 VC45=0.0006
+VS4=0.0007
+N21 G90 G10 L20 P3 X5.Y4. Z6.567
+N22 G0 X5000
+N23 IF [#1 LT 0.370] GOTO 49
+N24 X-0.678 Y+.990
+N25 G84.3 X-0.1
+N26 #4=#5*COS[45]
+N27 #4=#5*SIN[45]
+N28 VZOFZ=652.9658
%
diff --git a/test/markup/gcode/extended.expect.txt b/test/markup/gcode/extended.expect.txt
index 5d1782421d..1881720832 100644
--- a/test/markup/gcode/extended.expect.txt
+++ b/test/markup/gcode/extended.expect.txt
@@ -12,49 +12,73 @@
M500
M500
-O<boring> SUB
+O<boring> SUB
#20 = [#1 * SIN[#1]]
#21 = [-#2 * COS[#2]]
#22 = [#3 / COS[#3]]
#23 = [#4 + #4 - #4]
#24 = [[#5 - #5] * TAN[#5]]
-
-O107 IF [#10 GT 5]
- G0 A0 B0 C0 U0 V0 W0 X0 Y0 Z0 *71
- G100 A100 B0
- G5.2 A10.2 B0
- G100 A.2 B0
- G100 A-.2 B0
- G100 A+.2 B0
- T0
- M100 F1 H2 I3 J4 K5 P6 Q7 R8 S9
-O107 ENDIF
-
-O 108 IF [#10 GT 5]
- G 0 A 0 B 0 C 0 U 0 V 0 W 0 X 0 Y 0 Z 0 *71
- G 100 A 100 B 0
- G 5.2 A 10.2 B 0
- G 100 A .2 B 0
- G 100 A -.2 B 0
- G 100 A +.2 B 0
- T 0
- M 100 F 1 H 2 I 3 J 4 K 5 P 6 Q 7 R 8 S 9
+#25=FIX[#101/2.75]
+#26=ROUND[#104]
+#27=ABS[#104]
+
+
+
+N1 O107 IF [#10 GT 5]
+N2 G0 A0 B0 C0 U0 V0 W0 X0 Y0 Z0 *71
+N3 G100 A100 B0
+N4 G5.2 A10.2 B0
+N5 G100 A.2 B0
+N6 G100 A-.2 B0
+N7 G100 A+.2 B0
+N8 T0
+N9 M100 F1 H2 I3 J4 K5 P6 Q7 R8 S9
+N10 M587 S"MYROUTER" P"ABCxyz;" "123"
+N10 O107 ENDIF
+
+
+
+
+O 108 IF [#10 GT 5]
+N 102 G 0 A 0 B 0 C 0 U 0 V 0 W 0 X 0 Y 0 Z 0 *71
+N 103 G 100 A 100 B 0
+N 104 G 5.2 A 10.2 B 0
+N 105 G 100 A .2 B 0
+N 106 G 100 A -.2 B 0
+N 107 G 100 A +.2 B 0
+N 108 T 0
+N 109 M 100 F 1 H 2 I 3 J 4 K 5 P 6 Q 7 R 8 S 9
+N 110 M 587 S "MYROUTER" P "ABCxyz;" "123"
O 108 ENDIF
-
-O109IF[#10GT5]
-G0A0B0C0U0V0W0X0Y0Z0*71
-G100A100B0
-G5.2A10.2B0
-G100A.2B0
-G100A-.2B0
-G100A+.2B0
-T0
-M100F1H2I3J4K5P6Q7R8S9
-O109ENDIF
-
-O<boring> ENDSUB
-
-
-O<boring> CALL [1] [2] [3] [4] [5]
+
+
+
+
+O109IF[#10GT5]
+N202G0A0B0C0U0V0W0X0Y0Z0*71
+N203G100A100B0
+N204G5.2A10.2B0
+N205G100A.2B0
+N206G100A-.2B0
+N207G100A+.2B0
+N208T0
+N209M100F1H2I3J4K5P6Q7R8S9
+N210M587S"MYROUTER"P"ABCxyz;""123"
+0O109ENDIF
+
+O<boring> ENDSUB
+
+O<boring> CALL [1] [2] [3] [4] [5]
+
+
+
+GET_RETRACTION
+TURN_OFF_HEATERS
+MANUAL_STEPPER STEPPER=config_name ENABLE=0 SET_POSITION=11.1 SPEED=22.2 ACCEL=33.3 MOVE=44.4 STOP_ON_ENDSTOP=-1 SYNC=0
+
+SET_SKEW XY=100.0000,100.0000,70.7107
+SKEW_PROFILE SAVE="this name has spaces"
+SAVE_CONFIG
+
%
diff --git a/test/markup/gcode/extended.txt b/test/markup/gcode/extended.txt
index 99b59991b9..5e19021d7f 100644
--- a/test/markup/gcode/extended.txt
+++ b/test/markup/gcode/extended.txt
@@ -19,42 +19,66 @@ O SUB
#22 = [#3 / COS[#3]]
#23 = [#4 + #4 - #4]
#24 = [[#5 - #5] * TAN[#5]]
+#25=FIX[#101/2.75]
+#26=ROUND[#104]
+#27=ABS[#104]
-O107 IF [#10 GT 5]
- G0 A0 B0 C0 U0 V0 W0 X0 Y0 Z0 *71
- G100 A100 B0
- G5.2 A10.2 B0
- G100 A.2 B0
- G100 A-.2 B0
- G100 A+.2 B0
- T0
- M100 F1 H2 I3 J4 K5 P6 Q7 R8 S9
-O107 ENDIF
+; WITH SANE SPACING
+
+N1 O107 IF [#10 GT 5]
+N2 G0 A0 B0 C0 U0 V0 W0 X0 Y0 Z0 *71
+N3 G100 A100 B0
+N4 G5.2 A10.2 B0
+N5 G100 A.2 B0
+N6 G100 A-.2 B0
+N7 G100 A+.2 B0
+N8 T0
+N9 M100 F1 H2 I3 J4 K5 P6 Q7 R8 S9
+N10 M587 S"MYROUTER" P"ABCxyz;" "123"
+N10 O107 ENDIF
+
+
+; WITH EXCESSIVE SPACING
O 108 IF [#10 GT 5]
- G 0 A 0 B 0 C 0 U 0 V 0 W 0 X 0 Y 0 Z 0 *71
- G 100 A 100 B 0
- G 5.2 A 10.2 B 0
- G 100 A .2 B 0
- G 100 A -.2 B 0
- G 100 A +.2 B 0
- T 0
- M 100 F 1 H 2 I 3 J 4 K 5 P 6 Q 7 R 8 S 9
+N 102 G 0 A 0 B 0 C 0 U 0 V 0 W 0 X 0 Y 0 Z 0 *71
+N 103 G 100 A 100 B 0
+N 104 G 5.2 A 10.2 B 0
+N 105 G 100 A .2 B 0
+N 106 G 100 A -.2 B 0
+N 107 G 100 A +.2 B 0
+N 108 T 0
+N 109 M 100 F 1 H 2 I 3 J 4 K 5 P 6 Q 7 R 8 S 9
+N 110 M 587 S "MYROUTER" P "ABCxyz;" "123"
O 108 ENDIF
+
+; WITHOUT SPACING
+
O109IF[#10GT5]
-G0A0B0C0U0V0W0X0Y0Z0*71
-G100A100B0
-G5.2A10.2B0
-G100A.2B0
-G100A-.2B0
-G100A+.2B0
-T0
-M100F1H2I3J4K5P6Q7R8S9
-O109ENDIF
+N202G0A0B0C0U0V0W0X0Y0Z0*71
+N203G100A100B0
+N204G5.2A10.2B0
+N205G100A.2B0
+N206G100A-.2B0
+N207G100A+.2B0
+N208T0
+N209M100F1H2I3J4K5P6Q7R8S9
+N210M587S"MYROUTER"P"ABCxyz;""123"
+0O109ENDIF
O ENDSUB
-
O CALL [1] [2] [3] [4] [5]
+
+; Words as see in Klipper Firmware GCode
+
+GET_RETRACTION
+TURN_OFF_HEATERS
+MANUAL_STEPPER STEPPER=config_name ENABLE=0 SET_POSITION=11.1 SPEED=22.2 ACCEL=33.3 MOVE=44.4 STOP_ON_ENDSTOP=-1 SYNC=0
+
+SET_SKEW XY=100.0000,100.0000,70.7107
+SKEW_PROFILE SAVE="this name has spaces"
+SAVE_CONFIG
+
%