<p>Not sure why I wasn't able to find this initially, but here's a <a href="https://files.fieldofview.com/cura/Replacement_Patterns.html" rel="nofollow noreferrer">list of replacement strings</a> that can be used in the Start/End G-code settings of the machine/printer profile.</p>
<p>In my Machine profile settings, I inserted the below text at the top of the Start G-code section:</p>
<pre><code>; Cura/Material/Profile settings
;Layer Height: {layer_height}
;MINZ: {layer_height_0}
;Print Speed: {speed_print}
;first_layer_bed_temp: {material_print_temperature_layer_0}
;Nozzle diameter = {machine_nozzle_size}
;Filament id = {material_id}
;Filament type = {material_type}
;Filament name = {material_name}
;Filament brand = {material_brand}
;Filament amount = {filament_amount}
;Filament weight = {filament_weight}
;Filament cost = {filament_cost}
;Jobname = {jobname}

; Ender 3 Custom Start G-code
; ... Rest of my start G-code was here
</code></pre>
<p>And now, when I generate a new G-code file, it has the below data in the file:</p>
<pre><code>; Cura/Material/Profile settings
;Layer Height: 0.2
;MINZ: 0.2
;Print Speed: 30.0
;first_layer_bed_temp: 260.0
;Nozzle diameter = 0.4
;Filament id = generic_abs_175 #2
;Filament type = ABS
;Filament name = ASA
;Filament brand = iSANGHU
;Filament amount = [1.01]
;Filament weight = [3.013193642578125]
;Filament cost = [0.05423748556640625]
;Jobname = TN1-148_SHAFT_ADAPTOR

; Ender 3 Custom Start G-code
</code></pre>
<p>(Note: I had to save an ASA material as ABS because apparently, Cura thinks my printer profile isn't compatible with ASA, so it's saved as ABS. but that value is accurate to what's in the configs)</p>
<p>And it works fine in MoonRaker as well</p>
<p><a href="https://i.sstatic.net/nweTg.png" rel="nofollow noreferrer" title="Screenshot of the left-hand portion of MoonRaker's File List"><img src="https://i.sstatic.net/nweTg.png" alt="Screenshot of the left-hand portion of MoonRaker's File List" title="Screenshot of the left-hand portion of MoonRaker's File List" /></a></p>
<p><a href="https://i.sstatic.net/9Idqi.png" rel="nofollow noreferrer" title="Screenshot of the right-hand portion of MoonRaker's File List"><img src="https://i.sstatic.net/9Idqi.png" alt="Screenshot of the right-hand portion of MoonRaker's File List" title="Screenshot of the right-hand portion of MoonRaker's File List" /></a></p>
<p>Source: <a href="https://community.ultimaker.com/topic/39519-how-to-access-material-type-eg-pla-petg-etc-from-cura-post-processing-plugin/" rel="nofollow noreferrer">How to access material type (eg PLA, PETG etc) from Cura post-processing plugin?</a></p>

CC BY-SA 4.0
2023-12-13T21:18:08.117Z
2023-12-14T05:03:56.270Z
2023-12-14T05:03:56.270Z
J H
<p>I've been using Klipper and Cura for a while now (somewhat new to 3D printing), and I notice whenever I import a new G-code file to Klipper, none of the Slicer settings from Cura display in the G-code files in Klipper. However, when I imported a G-code file from my friend (the PETG one) I noticed it showed up right away:</p>
<p><a href="https://i.sstatic.net/mJ17D.png" rel="nofollow noreferrer" title="Screenshot of the File List from the web interface for klipper"><img src="https://i.sstatic.net/mJ17D.png" alt="Screenshot of the File List from the web interface for klipper" title="Screenshot of the File List from the web interface for klipper" /></a></p>
<p>I looked at the difference in the G-code formats, and I noticed that the file sliced with Prusa had the settings in the bottom of the file in the below (truncated) format:</p>
<pre><code>;TYPE:Custom
; Filament-specific end gcode
; filament used [mm] = 5342.18
; filament used [cm3] = 12.85
; filament used [g] = 16.32
; filament cost = 0.45
; total filament used [g] = 16.32
; total filament cost = 0.45
; estimated printing time (normal mode) = 2h 49m 42s
; estimated printing time (silent mode) = 2h 50m 36s
; prusaslicer_config = begin
; avoid_crossing_perimeters = 0
; avoid_crossing_perimeters_max_detour = 0
; bed_custom_model =
; bed_custom_texture =
; bed_shape = 0x0,250x0,250x210,0x210
; bed_temperature = 90
; before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]\n\n
; between_objects_gcode =
; bottom_fill_pattern = monotonic
; bottom_solid_layers = 5
; bottom_solid_min_thickness = 0.5
; bridge_acceleration = 1000
; bridge_angle = 0
; bridge_fan_speed = 50
; bridge_flow_ratio = 1
; bridge_speed = 25
; cooling = 1
; cooling_tube_length = 5
; elefant_foot_compensation = 0.2
; external_perimeter_extrusion_width = 0.45
; external_perimeter_speed = 25
; external_perimeters_first = 0
; extra_loading_move = -2
; extra_perimeters = 0
; extrusion_multiplier = 1
; extrusion_width = 0.45
; fan_always_on = 1
; fan_below_layer_time = 20
; filament_colour = #FF8000
; filament_cooling_final_speed = 3.4
; filament_cooling_initial_speed = 2.2
; filament_cooling_moves = 4
; filament_cost = 27.82
</code></pre>
<p>Whereas the G-code generated by cura has them in the below format:</p>
<pre><code>;End of Gcode
;SETTING_3 {&quot;global_quality&quot;: &quot;[general]\\nversion = 4\\nname = Filament_Sample-
;SETTING_3 PET-dev.1\\ndefinition = creality_ender3pro\\n\\n[metadata]\\ntype =
;SETTING_3 quality_changes\\nquality_type = standard\\nsetting_version = 22\\n\\
;SETTING_3 n[values]\\nadhesion_type = skirt\\nklipper_experimental_enable = Tru
;SETTING_3 e\\nklipper_ui_temp_support_enable = True\\nretraction_combing = nosk
;SETTING_3 in\\nsupport_enable = False\\nsupport_type = buildplate\\n\\n&quot;, &quot;extr
;SETTING_3 uder_quality&quot;: [&quot;[general]\\nversion = 4\\nname = Filament_Sample-PET
;SETTING_3 -dev.1\\ndefinition = creality_ender3pro\\n\\n[metadata]\\ntype = qua
;SETTING_3 lity_changes\\nquality_type = standard\\nintent_category = default\\n
;SETTING_3 position = 0\\nsetting_version = 22\\n\\n[values]\\nbrim_gap = 0.17\\
;SETTING_3 nbrim_line_count = 14\\ninfill_enable_travel_optimization = True\\nin
;SETTING_3 fill_sparse_density = 100\\ninset_direction = outside_in\\nironing_en
;SETTING_3 abled = True\\nironing_flow = 5.0\\nironing_inset = 0.2\\nironing_mon
;SETTING_3 otonic = True\\nironing_pattern = zigzag\\nmaterial_flow = 90.0\\nret
;SETTING_3 raction_amount = 3.0\\nretraction_hop = 1.0\\nretraction_hop_enabled
;SETTING_3 = True\\nretraction_hop_only_when_collides = True\\nroofing_layer_cou
;SETTING_3 nt = 1\\nroofing_line_width = 0.2\\nroofing_material_flow = 75.0\\nro
;SETTING_3 ofing_pattern = lines\\nskin_monotonic = True\\nskin_overlap = 4.0\\n
;SETTING_3 speed_print = 100.0\\nsupport_angle = 65.0\\nsupport_conical_enabled
;SETTING_3 = True\\nsupport_interface_density = 20\\nsupport_skip_some_zags = Tr
;SETTING_3 ue\\ntop_bottom_pattern_0 = lines\\ntop_layers = 1\\nwall_line_count
;SETTING_3 = 4\\nwall_overhang_angle = 55.0\\nwall_overhang_speed_factor = 80.0\
;SETTING_3 \n\\n&quot;]}
</code></pre>
<p>Prusa has them in a more sensible format, whereas Cura stores them in INI format, stored as strings in a JSON object, which is then stored as a G-code comment (which seems ridiculously overcomplicated)</p>
<p>I already have a bash/jq function I use to parse those comments from the Cura sliced G-code and display it to me, but I'm trying to find a way to have it done automatically while the G-code file is getting generated. I have looked at some plugins for Cura, but I didn't see one that applied to this.</p>
<p>I know I could possibly modify the <code>metadata.py</code> (Moonraker) to have it parse for the Cura style G-code comments, or even write a Cura plugin, but it occurred to me that I can't be the first one to have this issue. And I didn't find anything for it upon Googling it.</p>
<p><strong>The question</strong>: Does anyone have a simple workaround for this that doesn't require writing plugins or modifying existing Moonraker files?</p>
<p>And a bonus question: Why in the world would they store slicer settings nested in three different formats? Why?!</p>
<p><strong>TL;DR:</strong> Cura stores the print config in the G-code comments, but Klipper/Moonraker can't parse them due to the format. Is there a simple way around this? (aside from writing a plugin or modifying Moonraker files)</p>
<p>P.S. I do see that some plugins seem related to this but I don't see one that formats and saves the settings to the G-code file. They either just extract them from the G-code, or require you to execute a script every time (or even launch a Node server..)</p>
<h2>Update (Answer... Kinda)</h2>
<p>So after looking into the Moonraker python, I can see that there actually is a <a href="https://github.com/Arksine/moonraker/blob/master/moonraker/components/file_manager/metadata.py#L459" rel="nofollow noreferrer"><em>Cura</em> class</a> that extends <code>BaseSlicer</code> class, and it's what handles the comment parsing:</p>
<pre><code>class Cura(BaseSlicer):
    def check_identity(self, data: str) -&gt; Optional[Dict[str, str]]:
        match = re.search(r&quot;Cura_SteamEngine\s(.*)&quot;, data)
        if match:
            return {
                'slicer': &quot;Cura&quot;,
                'slicer_version': match.group(1)
            }
        return None
        
    # .. Truncated some rows..

    def has_objects(self) -&gt; bool:
        return self._check_has_objects(self.header_data, r&quot;\n;MESH:&quot;)

    def parse_filament_weight_total(self) -&gt; Optional[float]:
        return regex_find_float(r&quot;;Filament\sweight\s=\s.(%F).&quot;, self.header_data)

    def parse_filament_type(self) -&gt; Optional[str]:
        return regex_find_string(r&quot;;Filament\stype\s=\s(%S)&quot;, self.header_data)

    def parse_filament_name(self) -&gt; Optional[str]:
        return regex_find_string(r&quot;;Filament\sname\s=\s(%S)&quot;, self.header_data)

    # .. Truncated some rows..

    def parse_nozzle_diameter(self) -&gt; Optional[float]:
        return regex_find_float(r&quot;;Nozzle\sdiameter\s=\s(%F)&quot;, self.header_data)
</code></pre>
<p>And if you look at the regex, it's looking for some config names like <strong>Filament weight</strong>, <strong>Filament name</strong>, <strong>Filament type</strong>, etc. But Cura stores it as just <strong>name</strong>, <strong>weight</strong>, and <strong>type</strong>, but puts it under a <code>[metadata]</code> section.</p>
<p>Also, the Cura-style metadata is all just concatenated into one string, which has a line return injected every 80 characters. This means that depending on the values, some of the <em><strong>names</strong></em> of the metadata items get truncated halfway through, and have another <code>;SETTING_3</code> injected as the prefix, which makes it somewhat of a nightmare to simply parse with RegEx.</p>
<p>I was trying to avoid having to modify any Moonraker code, but it looks like  I'll just have to alter the Cura class to extract all lines that start with <code>;SETTING_3 </code>, then concatenate &gt; JSON Parse &gt; INI Parse.</p>

CC BY-SA 4.0
2023-12-06T15:01:54.463Z
Please don't post text as an image; see [Why are images of text, code and mathematical expressions discouraged?](https://meta.stackexchange.com/questions/320052/why-are-images-of-text-code-and-mathematical-expressions-discouraged).
agarza
CC BY-SA 4.0
2023-12-06T16:21:41.617Z
@agarza hm, ok. Updated. I thought about that but figured it was ok because I wasn't really posting the text to be parsed/read through. I just wanted to show the side by side differences between the two. And I did have the code in the draft and thought it just made it too cluttered/long.
J H
CC BY-SA 4.0
2023-12-06T16:47:30.817Z
Does this answer your question? [Is there a (common) way to embed used Slicer settings inside the G-code file?](https://3dprinting.stackexchange.com/questions/21563/is-there-a-common-way-to-embed-used-slicer-settings-inside-the-g-code-file)
Bob Ortiz
CC BY-SA 4.0
2023-12-06T20:05:34.153Z
@BobOrtiz Not really. I actually found that there is a Class that should be able to do this, already in Moonraker. I just need to see why it doesn't work (I updated y original post)
J H
<ultimaker-cura><g-code><prusaslicer><klipper>
How can I get Cura's slicer settings to save into the G-code in a way that Moonraker/Klipper can read them?
J H
# How can I get Cura's slicer settings to save into the G-code in a way that Moonraker/Klipper can read them?

(Asked by: username_0 on 2023-12-06)

I've been using Klipper and Cura for a while now (somewhat new to 3D printing), and I notice whenever I import a new G-code file to Klipper, none of the Slicer settings from Cura display in the G-code files in Klipper. However, when I imported a G-code file from my friend (the PETG one) I noticed it showed up right away:

[![Screenshot of the File List from the web interface for klipper](https://i.sstatic.net/mJ17D.png "Screenshot of the File List from the web interface for klipper")](https://i.sstatic.net/mJ17D.png "Screenshot of the File List from the web interface for klipper")

I looked at the difference in the G-code formats, and I noticed that the file sliced with Prusa had the settings in the bottom of the file in the below (truncated) format:

```
;TYPE:Custom
; Filament-specific end gcode
; filament used [mm] = 5342.18
; filament used [cm3] = 12.85
; filament used [g] = 16.32
; filament cost = 0.45
; total filament used [g] = 16.32
; total filament cost = 0.45
; estimated printing time (normal mode) = 2h 49m 42s
; estimated printing time (silent mode) = 2h 50m 36s
; prusaslicer_config = begin
; avoid_crossing_perimeters = 0
; avoid_crossing_perimeters_max_detour = 0
; bed_custom_model =
; bed_custom_texture =
; bed_shape = 0x0,250x0,250x210,0x210
; bed_temperature = 90
; before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]\n\n
; between_objects_gcode =
; bottom_fill_pattern = monotonic
; bottom_solid_layers = 5
; bottom_solid_min_thickness = 0.5
; bridge_acceleration = 1000
; bridge_angle = 0
; bridge_fan_speed = 50
; bridge_flow_ratio = 1
; bridge_speed = 25
; cooling = 1
; cooling_tube_length = 5
; elefant_foot_compensation = 0.2
; external_perimeter_extrusion_width = 0.45
; external_perimeter_speed = 25
; external_perimeters_first = 0
; extra_loading_move = -2
; extra_perimeters = 0
; extrusion_multiplier = 1
; extrusion_width = 0.45
; fan_always_on = 1
; fan_below_layer_time = 20
; filament_colour = #FF8000
; filament_cooling_final_speed = 3.4
; filament_cooling_initial_speed = 2.2
; filament_cooling_moves = 4
; filament_cost = 27.82

```

Whereas the G-code generated by cura has them in the below format:

```
;End of Gcode
;SETTING_3 {"global_quality": "[general]\\nversion = 4\\nname = Filament_Sample-
;SETTING_3 PET-dev.1\\ndefinition = creality_ender3pro\\n\\n[metadata]\\ntype =
;SETTING_3 quality_changes\\nquality_type = standard\\nsetting_version = 22\\n\\
;SETTING_3 n[values]\\nadhesion_type = skirt\\nklipper_experimental_enable = Tru
;SETTING_3 e\\nklipper_ui_temp_support_enable = True\\nretraction_combing = nosk
;SETTING_3 in\\nsupport_enable = False\\nsupport_type = buildplate\\n\\n", "extr
;SETTING_3 uder_quality": ["[general]\\nversion = 4\\nname = Filament_Sample-PET
;SETTING_3 -dev.1\\ndefinition = creality_ender3pro\\n\\n[metadata]\\ntype = qua
;SETTING_3 lity_changes\\nquality_type = standard\\nintent_category = default\\n
;SETTING_3 position = 0\\nsetting_version = 22\\n\\n[values]\\nbrim_gap = 0.17\\
;SETTING_3 nbrim_line_count = 14\\ninfill_enable_travel_optimization = True\\nin
;SETTING_3 fill_sparse_density = 100\\ninset_direction = outside_in\\nironing_en
;SETTING_3 abled = True\\nironing_flow = 5.0\\nironing_inset = 0.2\\nironing_mon
;SETTING_3 otonic = True\\nironing_pattern = zigzag\\nmaterial_flow = 90.0\\nret
;SETTING_3 raction_amount = 3.0\\nretraction_hop = 1.0\\nretraction_hop_enabled
;SETTING_3 = True\\nretraction_hop_only_when_collides = True\\nroofing_layer_cou
;SETTING_3 nt = 1\\nroofing_line_width = 0.2\\nroofing_material_flow = 75.0\\nro
;SETTING_3 ofing_pattern = lines\\nskin_monotonic = True\\nskin_overlap = 4.0\\n
;SETTING_3 speed_print = 100.0\\nsupport_angle = 65.0\\nsupport_conical_enabled
;SETTING_3 = True\\nsupport_interface_density = 20\\nsupport_skip_some_zags = Tr
;SETTING_3 ue\\ntop_bottom_pattern_0 = lines\\ntop_layers = 1\\nwall_line_count
;SETTING_3 = 4\\nwall_overhang_angle = 55.0\\nwall_overhang_speed_factor = 80.0\
;SETTING_3 \n\\n"]}

```

Prusa has them in a more sensible format, whereas Cura stores them in INI format, stored as strings in a JSON object, which is then stored as a G-code comment (which seems ridiculously overcomplicated)

I already have a bash/jq function I use to parse those comments from the Cura sliced G-code and display it to me, but I'm trying to find a way to have it done automatically while the G-code file is getting generated. I have looked at some plugins for Cura, but I didn't see one that applied to this.

I know I could possibly modify the `metadata.py` (Moonraker) to have it parse for the Cura style G-code comments, or even write a Cura plugin, but it occurred to me that I can't be the first one to have this issue. And I didn't find anything for it upon Googling it.

**The question**: Does anyone have a simple workaround for this that doesn't require writing plugins or modifying existing Moonraker files?

And a bonus question: Why in the world would they store slicer settings nested in three different formats? Why?!

**TL;DR:** Cura stores the print config in the G-code comments, but Klipper/Moonraker can't parse them due to the format. Is there a simple way around this? (aside from writing a plugin or modifying Moonraker files)

P.S. I do see that some plugins seem related to this but I don't see one that formats and saves the settings to the G-code file. They either just extract them from the G-code, or require you to execute a script every time (or even launch a Node server..)

## Update (Answer... Kinda)

So after looking into the Moonraker python, I can see that there actually is a [*Cura* class](https://github.com/Arksine/moonraker/blob/master/moonraker/components/file_manager/metadata.py#L459) that extends `BaseSlicer` class, and it's what handles the comment parsing:

```
class Cura(BaseSlicer):
    def check_identity(self, data: str) -> Optional[Dict[str, str]]:
        match = re.search(r"Cura_SteamEngine\s(.*)", data)
        if match:
            return {
                'slicer': "Cura",
                'slicer_version': match.group(1)
            }
        return None
        
    # .. Truncated some rows..

    def has_objects(self) -> bool:
        return self._check_has_objects(self.header_data, r"\n;MESH:")

    def parse_filament_weight_total(self) -> Optional[float]:
        return regex_find_float(r";Filament\sweight\s=\s.(%F).", self.header_data)

    def parse_filament_type(self) -> Optional[str]:
        return regex_find_string(r";Filament\stype\s=\s(%S)", self.header_data)

    def parse_filament_name(self) -> Optional[str]:
        return regex_find_string(r";Filament\sname\s=\s(%S)", self.header_data)

    # .. Truncated some rows..

    def parse_nozzle_diameter(self) -> Optional[float]:
        return regex_find_float(r";Nozzle\sdiameter\s=\s(%F)", self.header_data)

```

And if you look at the regex, it's looking for some config names like **Filament weight**, **Filament name**, **Filament type**, etc. But Cura stores it as just **name**, **weight**, and **type**, but puts it under a `[metadata]` section.

Also, the Cura-style metadata is all just concatenated into one string, which has a line return injected every 80 characters. This means that depending on the values, some of the ***names*** of the metadata items get truncated halfway through, and have another `;SETTING_3` injected as the prefix, which makes it somewhat of a nightmare to simply parse with RegEx.

I was trying to avoid having to modify any Moonraker code, but it looks like I'll just have to alter the Cura class to extract all lines that start with `;SETTING_3` , then concatenate > JSON Parse > INI Parse.

**Tags:** ultimaker-cura, g-code, prusaslicer, klipper

> **Comments:**
> **username_1**: Please don't post text as an image; see [Why are images of text, code and mathematical expressions discouraged?](https://meta.stackexchange.com/questions/320052/why-are-images-of-text-code-and-mathematical-expressions-discouraged).  
> **username_0**: @username_1 hm, ok. Updated. I thought about that but figured it was ok because I wasn't really posting the text to be parsed/read through. I just wanted to show the side by side differences between the two. And I did have the code in the draft and thought it just made it too cluttered/long.  
> **username_2**: Does this answer your question? [Is there a (common) way to embed used Slicer settings inside the G-code file?](https://3dprinting.stackexchange.com/questions/21563/is-there-a-common-way-to-embed-used-slicer-settings-inside-the-g-code-file)  
> **username_0**: @username_2 Not really. I actually found that there is a Class that should be able to do this, already in Moonraker. I just need to see why it doesn't work (I updated y original post)  

---

## 1 answers

### Answer by username_0 on 2023-12-13. Score: 1 | Accepted answer

Not sure why I wasn't able to find this initially, but here's a [list of replacement strings](https://files.fieldofview.com/cura/Replacement_Patterns.html) that can be used in the Start/End G-code settings of the machine/printer profile.

In my Machine profile settings, I inserted the below text at the top of the Start G-code section:

```
; Cura/Material/Profile settings
;Layer Height: {layer_height}
;MINZ: {layer_height_0}
;Print Speed: {speed_print}
;first_layer_bed_temp: {material_print_temperature_layer_0}
;Nozzle diameter = {machine_nozzle_size}
;Filament id = {material_id}
;Filament type = {material_type}
;Filament name = {material_name}
;Filament brand = {material_brand}
;Filament amount = {filament_amount}
;Filament weight = {filament_weight}
;Filament cost = {filament_cost}
;Jobname = {jobname}

; Ender 3 Custom Start G-code
; ... Rest of my start G-code was here

```

And now, when I generate a new G-code file, it has the below data in the file:

```
; Cura/Material/Profile settings
;Layer Height: 0.2
;MINZ: 0.2
;Print Speed: 30.0
;first_layer_bed_temp: 260.0
;Nozzle diameter = 0.4
;Filament id = generic_abs_175 #2
;Filament type = ABS
;Filament name = ASA
;Filament brand = iSANGHU
;Filament amount = [1.01]
;Filament weight = [3.013193642578125]
;Filament cost = [0.05423748556640625]
;Jobname = TN1-148_SHAFT_ADAPTOR

; Ender 3 Custom Start G-code

```

(Note: I had to save an ASA material as ABS because apparently, Cura thinks my printer profile isn't compatible with ASA, so it's saved as ABS. but that value is accurate to what's in the configs)

And it works fine in MoonRaker as well

[![Screenshot of the left-hand portion of MoonRaker's File List](https://i.sstatic.net/nweTg.png "Screenshot of the left-hand portion of MoonRaker's File List")](https://i.sstatic.net/nweTg.png "Screenshot of the left-hand portion of MoonRaker's File List")

[![Screenshot of the right-hand portion of MoonRaker's File List](https://i.sstatic.net/9Idqi.png "Screenshot of the right-hand portion of MoonRaker's File List")](https://i.sstatic.net/9Idqi.png "Screenshot of the right-hand portion of MoonRaker's File List")

Source: [How to access material type (eg PLA, PETG etc) from Cura post-processing plugin?](https://community.ultimaker.com/topic/39519-how-to-access-material-type-eg-pla-petg-etc-from-cura-post-processing-plugin/)


---

