macosapplescriptg-code

Select all lines starting with ";" with Applescript


I'm trying to create an applescript that would allow me to clean up a .gcode file by removing all lines that don't begin with a semicolon ";"

Here's a small example of the gcode file:

; HEADER_BLOCK_START
; generated by OrcaSlicer 2.2.0 on 2025-03-27 at 05:46:50
; total layer number: 400
; filament_density: 1.27
; filament_diameter: 1.75
; max_z_height: 80.00
; HEADER_BLOCK_END

; external perimeters extrusion width = 0.42mm
; perimeters extrusion width = 0.45mm
; infill extrusion width = 0.45mm
; solid infill extrusion width = 0.42mm
; top infill extrusion width = 0.42mm
; first layer extrusion width = 0.50mm

; EXECUTABLE_BLOCK_START
M73 P0 R128
M106 S0
M106 P2 S0
;TYPE:Custom
M190 S80
M104 S250
G90
M83
G1 Z5 F6000
G1 E-0.2 F800
G1 X110 Y-110 F6000
G1 E2 F800
G1 Y-110 X55 Z0.25 F4800
G1 X-55 E8 F2400
G1 Y-109.6 F2400
G1 X55 E5 F2400
G1 Y-110 X55 Z0.45 F4800
G1 X-55 E8 F2400
G1 Y-109.6 F2400
G1 X55 E5 F2400
G92 E0
G90
G21
SET_VELOCITY_LIMIT ACCEL=2000
G1 F9530.213
G1 X-52.709 Y-19.074 E.03392
G1 E-1 F2100
;WIPE_START
G1 F9530.213
G1 X-51.946 Y-19.837
;WIPE_END
M106 S0
M106 P2 S0
;TYPE:Custom
; filament end gcode
G1 E-3 F3600
G0 X50 Y50 F30000
M104 S0 ; turn off temperature
M73 P100 R0
; EXECUTABLE_BLOCK_END

; filament used [mm] = 31186.37
; filament used [cm3] = 75.01
; filament used [g] = 95.27
; filament cost = 2.86
; total filament used [g] = 95.27
; total filament cost = 2.86
; total layers count = 400
; estimated printing time (normal mode) = 2h 8m 22s

And here is the result I would like to obtain:

; HEADER_BLOCK_START
; generated by OrcaSlicer 2.2.0 on 2025-03-27 at 05:46:50
; total layer number: 400
; filament_density: 1.27
; filament_diameter: 1.75
; max_z_height: 80.00
; HEADER_BLOCK_END

; external perimeters extrusion width = 0.42mm
; perimeters extrusion width = 0.45mm
; infill extrusion width = 0.45mm
; solid infill extrusion width = 0.42mm
; top infill extrusion width = 0.42mm
; first layer extrusion width = 0.50mm

; filament used [mm] = 31186.37
; filament used [cm3] = 75.01
; filament used [g] = 95.27
; filament cost = 2.86
; total filament used [g] = 95.27
; total filament cost = 2.86
; total layers count = 400
; estimated printing time (normal mode) = 2h 8m 22s

And here is the beginning of my Applescript (Be indulgent, i'm a rookie):

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on open theFiles
    --  Your code goes here
end open

on run
    --  Handle the case where the script is launched without any dropped files
    set source to choose file of type {"gcode"} with prompt "Select the .gcode file"
    Prog_Master(source)
end run

on Prog_Master(source)
    -- extract the name, its folder, and add a "_New" to the modified file name to avoid overwriting the existing one.
    -- this part can be replaced with a "Set Destination to Source"
    -- this will overwrite the source file before the destination file is finished writing: it's more dangerous, but possible!
    tell application "Finder"
        set name to name of source
        set New_Name to (text 1 thru ((lenght of name) - 7) of name) & "_New.gcode"
        set Destination to ((container of source) as text) & New_Name
    end tell
    
    -- we define the search constants (ascii code 59 is a semicolon)
    set Guil to ASCII character 59
end Prog_Master

What I'm trying to do is simply isolate all the parameters/settings of a .gcode file intended for 3D printing.

Thanks for your help.


Solution

  • According to your desired result you want to skip the entire EXECUTABLE_BLOCK.

    This can be accomplished with text item delimiters

    set theText to "; HEADER_BLOCK_START
    ; generated by OrcaSlicer 2.2.0 on 2025-03-27 at 05:46:50
    ; total layer number: 400
    ; filament_density: 1.27
    ; filament_diameter: 1.75
    ; max_z_height: 80.00
    ; HEADER_BLOCK_END
    
    ; external perimeters extrusion width = 0.42mm
    ; perimeters extrusion width = 0.45mm
    ; infill extrusion width = 0.45mm
    ; solid infill extrusion width = 0.42mm
    ; top infill extrusion width = 0.42mm
    ; first layer extrusion width = 0.50mm
    
    ; EXECUTABLE_BLOCK_START
    M73 P0 R128
    M106 S0
    M106 P2 S0
    ;TYPE:Custom
    M190 S80
    M104 S250
    G90
    M83
    G1 Z5 F6000
    G1 E-0.2 F800
    G1 X110 Y-110 F6000
    G1 E2 F800
    G1 Y-110 X55 Z0.25 F4800
    G1 X-55 E8 F2400
    G1 Y-109.6 F2400
    G1 X55 E5 F2400
    G1 Y-110 X55 Z0.45 F4800
    G1 X-55 E8 F2400
    G1 Y-109.6 F2400
    G1 X55 E5 F2400
    G92 E0
    G90
    G21
    SET_VELOCITY_LIMIT ACCEL=2000
    G1 F9530.213
    G1 X-52.709 Y-19.074 E.03392
    G1 E-1 F2100
    ;WIPE_START
    G1 F9530.213
    G1 X-51.946 Y-19.837
    ;WIPE_END
    M106 S0
    M106 P2 S0
    ;TYPE:Custom
    ; filament end gcode
    G1 E-3 F3600
    G0 X50 Y50 F30000
    M104 S0 ; turn off temperature
    M73 P100 R0
    ; EXECUTABLE_BLOCK_END
    
    ; filament used [mm] = 31186.37
    ; filament used [cm3] = 75.01
    ; filament used [g] = 95.27
    ; filament cost = 2.86
    ; total filament used [g] = 95.27
    ; total filament cost = 2.86
    ; total layers count = 400
    ; estimated printing time (normal mode) = 2h 8m 22s"
    
    set {saveTID, text item delimiters} to {text item delimiters, {"; EXECUTABLE_BLOCK_START"}}
    set {startBlock, remainder} to text items of theText
    set text item delimiters to {"; EXECUTABLE_BLOCK_END" & linefeed & linefeed}
    set endBlock to text item 2 of remainder
    set text item delimiters to saveTID
    set theResult to startBlock & endBlock
    

    Edit:

    This is the same code working as applet/droplet, it can even process multiple files. If the text file doesn't contain EXECUTABLE_BLOCK_START it closes the file unmodified and process the next file

    use AppleScript version "2.5"
    use framework "Foundation"
    use scripting additions
    
    
    on open theFiles
        processFiles(theFiles)
    end open
    
    on run
        set sourceFiles to choose file of type {"gcode"} with prompt "Select the .gcode file(s)" with multiple selections allowed
        processFiles(sourceFiles)
    end run
    
    on processFiles(allFiles)
        repeat with aFile in allFiles
            set fileURL to aFile as «class furl»
            set fileDescriptor to open for access fileURL with write permission
            set theText to read fileDescriptor
            set {saveTID, text item delimiters} to {text item delimiters, {"; EXECUTABLE_BLOCK_START"}}
            try
                set {startBlock, remainder} to text items of theText
                set text item delimiters to {"; EXECUTABLE_BLOCK_END" & linefeed & linefeed}
                set endBlock to text item 2 of remainder
                set text item delimiters to saveTID
                set eof of fileDescriptor to 0
                write (startBlock & endBlock) to fileDescriptor
                close access fileDescriptor
            on error e number n
                if n = -1728 then
                    close access fileDescriptor
                else
                    close access fileURL
                end if
                set text item delimiters to saveTID
            end try
        end repeat
    end processFiles