2010-06-01 03:36:36 +08:00
; -----------------------------------------------------------------------------
; GIMP palette export toolkit -
; Written by Barak Itkin <lightningismyname@gmail.com>
2009-08-02 20:30:57 +08:00
;
2010-06-01 03:36:36 +08:00
; This script includes various exporters for GIMP palettes, and other
; utility function to help in exporting to other (text-based) formats.
2009-08-02 20:30:57 +08:00
; See instruction on adding new exporters at the end
;
2024-04-22 02:59:59 +08:00
; !!! Here run functions call script-fu-use-v3, to bind PDB returns succintly.
2010-06-01 03:36:36 +08:00
; -----------------------------------------------------------------------------
2009-08-02 20:30:57 +08:00
; Numbers and Math
2010-06-01 03:36:36 +08:00
; -----------------------------------------------------------------------------
2009-08-02 20:30:57 +08:00
2016-06-26 04:54:10 +08:00
; For all the operations below, this is the order of respectable digits:
2009-08-02 20:30:57 +08:00
( define conversion-digits ( list "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
2010-06-01 03:36:36 +08:00
"a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k"
"l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v"
"w" "x" "y" "z" ) )
2009-08-02 20:30:57 +08:00
; Converts a decimal number to another base. The returned number is a string
( define ( convert-decimal-to-base num base )
2024-04-22 02:59:59 +08:00
( if ( < num base )
( list-ref conversion-digits num )
2015-08-16 02:20:19 +08:00
( let loop ( ( val num )
2024-04-22 02:59:59 +08:00
( order ( inexact->exact ( truncate ( / ( log num )
2015-08-16 02:20:19 +08:00
( log base ) ) ) ) )
( result "" ) )
( let* ( ( power ( expt base order ) )
( digit ( quotient val power ) ) )
( if ( zero? order )
2024-04-22 02:59:59 +08:00
( string-append result ( list-ref conversion-digits digit ) )
2015-08-16 02:20:19 +08:00
( loop ( - val ( * digit power ) )
( pred order )
( string-append result ( list-ref conversion-digits digit ) ) ) ) ) ) ) )
2009-08-02 20:30:57 +08:00
; Convert a string representation of a number in some base, to a decimal number
( define ( convert-base-to-decimal base num-str )
( define ( convert-char num-char )
( if ( char-numeric? num-char )
( string->number ( string num-char ) )
( + 10 ( - ( char->integer num-char ) ( char->integer #\a ) ) )
)
)
( define ( calc base num-str num )
( if ( equal? num-str "" )
num
( calc base
( substring num-str 1 )
( + ( * num base ) ( convert-char ( string-ref num-str 0 ) ) )
)
)
)
( calc base num-str 0 )
)
2010-06-01 03:36:36 +08:00
; If a string num-str is shorter then size, pad it with pad-str in the
2013-01-27 23:52:38 +08:00
; beginning until it's at least size long
2009-08-02 20:30:57 +08:00
( define ( pre-pad-number num-str size pad-str )
( if ( < ( string-length num-str ) size )
( pre-pad-number ( string-append pad-str num-str ) size pad-str )
num-str
)
)
2010-06-01 03:36:36 +08:00
; -----------------------------------------------------------------------------
2021-02-24 19:33:03 +08:00
; Color converters
2010-06-01 03:36:36 +08:00
; -----------------------------------------------------------------------------
2009-08-02 20:30:57 +08:00
2010-06-01 03:36:36 +08:00
; The standard way for representing a color would be a list of red
; green and blue (GIMP's default)
2009-08-02 20:30:57 +08:00
( define color-get-red car )
( define color-get-green cadr )
( define color-get-blue caddr )
; Convert a color to a hexadecimal string
; '(255 255 255) => "#ffffff"
( define ( color-rgb-to-hexa-decimal color )
( string-append "#"
2010-06-01 03:36:36 +08:00
( pre-pad-number
( convert-decimal-to-base ( color-get-red color ) 16 ) 2 "0" )
( pre-pad-number
( convert-decimal-to-base ( color-get-green color ) 16 ) 2 "0" )
( pre-pad-number
( convert-decimal-to-base ( color-get-blue color ) 16 ) 2 "0" )
2009-08-02 20:30:57 +08:00
)
)
; Convert a color to a css color
; '(255 255 255) => "rgb(255, 255, 255)"
( define ( color-rgb-to-css color )
( string-append "rgb(" ( number->string ( color-get-red color ) )
", " ( number->string ( color-get-green color ) )
2023-02-20 02:45:47 +08:00
", " ( number->string ( color-get-blue color ) ) ");" )
2009-08-02 20:30:57 +08:00
)
2013-01-27 23:52:38 +08:00
; Convert a color to a simple pair of braces with comma separated values
2009-08-02 20:30:57 +08:00
; '(255 255 255) => "(255, 255, 255)"
2019-09-22 01:10:46 +08:00
( define ( color-rgb-to-comma-separated-list color )
2009-08-02 20:30:57 +08:00
( string-append "(" ( number->string ( color-get-red color ) )
", " ( number->string ( color-get-green color ) )
", " ( number->string ( color-get-blue color ) ) ")" )
)
2010-06-01 03:36:36 +08:00
; -----------------------------------------------------------------------------
2009-08-02 20:30:57 +08:00
; Export utils
2010-06-01 03:36:36 +08:00
; -----------------------------------------------------------------------------
2009-08-02 20:30:57 +08:00
2018-04-19 02:57:03 +08:00
; List of characters that should not appear in file names
2009-08-02 20:30:57 +08:00
( define illegal-file-name-chars ( list #\\ #\/ #\: #\* #\? #\" #\< #\> #\| ) )
; A function to filter a list lst by a given predicate pred
( define ( filter pred lst )
( if ( null? lst )
' ( )
( if ( pred ( car lst ) )
( cons ( car lst ) ( filter pred ( cdr lst ) ) )
( filter pred ( cdr lst ) )
)
)
)
; A function to check if a certain value obj is inside a list lst
( define ( contained? obj lst ) ( member obj lst ) )
2010-06-01 03:36:36 +08:00
; This functions filters a string to have only characters which are
; either alpha-numeric or contained in more-legal (which is a variable
; holding a list of characters)
2009-08-02 20:30:57 +08:00
( define ( clean str more-legal )
( list->string ( filter ( lambda ( ch ) ( or ( char-alphabetic? ch )
( char-numeric? ch )
( contained? ch more-legal ) ) )
( string->list str ) ) )
)
2013-01-27 23:52:38 +08:00
; A function that receives the a file-name, and filters out all the
2010-06-01 03:36:36 +08:00
; character that shouldn't appear in file names. Then, it makes sure
; the remaining name isn't only white-spaces. If it's only
; white-spaces, the function returns false. Otherwise, it returns the
; fixed file-name
2009-08-02 20:30:57 +08:00
( define ( valid-file-name name )
2010-06-01 03:36:36 +08:00
( let* ( ( clean ( list->string ( filter ( lambda ( ch )
( not ( contained?
ch illegal-file-name-chars ) ) )
2009-08-02 20:30:57 +08:00
( string->list name ) ) ) )
2010-06-01 03:36:36 +08:00
( clean-without-spaces ( list->string ( filter ( lambda ( ch )
( not ( char-whitespace?
ch ) ) )
2009-08-02 20:30:57 +08:00
( string->list clean ) ) ) )
)
( if ( equal? clean-without-spaces "" )
#f
clean
)
)
)
2024-04-22 02:59:59 +08:00
( define ( bad-file-name )
( gimp-message ( string-append _ "The filename you entered is not a suitable name for a file."
"\n\n"
_ "All characters in the name are either white-spaces or characters which can not appear in filenames." ) ) )
; Return path to a file, or abort with error to Gimp.
;
; IN filename is from a string widget.
; A user entered the filename. It could be strange characters, empty, etc.
; Valid: see valid-file-name, which may be overly strict for some platforms.
;
; IN directory-name is from a GtkFileChooser widget in mode "choose folder"
; When empty, returned path is just the in filename.
; When not empty, returned path is to the filename in that directory.
; The file at that path might exist already.
;
; FUTURE a proper widget for choosing a file destination.
( define ( get-path-or-abort directory-name filename )
( let* ( ( validated-file-name ( valid-file-name filename ) )
( result-path "" ) )
( if ( not validated-file-name )
( begin
( bad-file-name ) ; gimp-message w translated text
( quit -1 ) ) )
; FUTURE: The above should be (error "Invalid file name"))
; with the existing translated text, when ScriptFu error is fixed.
( set! result-path
( if ( > ( string-length directory-name ) 0 )
; result is full path
( string-append directory-name DIR-SEPARATOR validated-file-name )
; result is just the filename
validated-file-name ) )
; Side effect.
; Tell the user the mangled path, might be different than user entered.
; The user should not need to search for the file.
( gimp-message ( string-append _ "Exported palette to file: " result-path ) )
result-path ) )
2010-06-01 03:36:36 +08:00
; Filters a string from all the characters which are not alpha-numeric
; (this also removes whitespaces)
2009-08-02 20:30:57 +08:00
( define ( name-alpha-numeric str )
( clean str ' ( ) )
)
2010-06-01 03:36:36 +08:00
; This function does the same as name-alpha-numeric, with an added
2013-01-27 23:52:38 +08:00
; operation - it removes any numbers from the beginning
2009-08-02 20:30:57 +08:00
( define ( name-standard str )
( let ( ( cleaned ( clean str ' ( ) ) ) )
( while ( char-numeric? ( string-ref cleaned 0 ) )
( set! cleaned ( substring cleaned 1 ) )
)
cleaned
)
)
( define name-no-conversion ( lambda ( obj ) obj ) )
( define color-none ( lambda ( x ) "" ) )
( define name-none ( lambda ( x ) "" ) )
( define displayln ( lambda ( obj ) ( display obj ) ( display "\n" ) ) )
; The loop for exporting all the colors
2024-04-22 02:59:59 +08:00
( define ( export-palette palette ; since v3, palette is numeric ID
color-convertor name-convertor
2009-08-02 20:30:57 +08:00
start name-pre name-after name-color-seperator
color-pre color-after entry-seperator end )
( define ( write-color-line index )
( display name-pre )
2024-04-22 02:59:59 +08:00
( display ( name-convertor ( gimp-palette-entry-get-name palette index ) ) )
2009-08-02 20:30:57 +08:00
( display name-after )
( display name-color-seperator )
( display color-pre )
2024-04-22 02:59:59 +08:00
( display ( color-convertor ( gimp-palette-entry-get-color palette index ) ) )
2009-08-02 20:30:57 +08:00
( display color-after )
)
2024-04-22 02:59:59 +08:00
( let ( ( color-count ( gimp-palette-get-color-count palette ) )
( i 0 ) )
2009-08-02 20:30:57 +08:00
( display start )
( while ( < i ( - color-count 1 ) )
( begin
( write-color-line i )
( display entry-seperator )
( set! i ( + 1 i ) )
)
)
( write-color-line i )
( display end )
)
)
2024-04-22 02:59:59 +08:00
; -----------
; Methods for getting palette and its name from context.
; These plugins are in the RMB pop-up menu of the Palettes dockable.
; User clicking RMB on a palette puts it in the Gimp context i.e chooses it.
; The palette is not actually passed as an arg to these plugins.
; -----------
; Return numeric ID of palette in context.
( define ( palette-in-context ) ( gimp-context-get-palette ) )
; Return name of palette in context.
; Since v3, resources in ScriptFu have numeric ID, not a string
( define ( palette-name-in-context ) ( gimp-resource-get-name ( palette-in-context ) ) )
; -----------
; Register exporter as run-function of a plugin.
; -----------
2010-06-01 03:36:36 +08:00
( define ( register-palette-exporter
2024-04-22 02:59:59 +08:00
export-type export-name file-type description author copyright date )
2009-08-02 20:30:57 +08:00
( script-fu-register ( string-append "gimp-palette-export-" export-type )
2010-06-01 03:36:36 +08:00
export-name
2009-08-02 20:30:57 +08:00
description
author
copyright
date
""
2010-06-01 03:36:36 +08:00
SF-DIRNAME _ "Folder for the output file" ""
SF-STRING _ "The name of the file to create (if a file with this name already exist, it will be replaced)"
( string-append "palette." file-type )
2009-08-02 20:30:57 +08:00
)
2010-06-01 03:36:36 +08:00
( script-fu-menu-register ( string-append "gimp-palette-export-" export-type )
2024-02-25 07:13:01 +08:00
"<Palettes>/Palettes Menu/Export as" )
2009-08-02 20:30:57 +08:00
)
2010-06-01 03:36:36 +08:00
; -----------------------------------------------------------------------------
2009-08-02 20:30:57 +08:00
; Exporters
2024-04-22 02:59:59 +08:00
; Run functions of the plugins.
2010-06-01 03:36:36 +08:00
; -----------------------------------------------------------------------------
2009-08-02 20:30:57 +08:00
( define ( gimp-palette-export-css directory-name file-name )
2024-04-22 02:59:59 +08:00
( script-fu-use-v3 )
( let ( ( path ( get-path-or-abort directory-name file-name ) ) )
( with-output-to-file path
( lambda ( ) ( export-palette ( palette-in-context )
color-rgb-to-css
name-alpha-numeric ; name-convertor
"/* Generated with GIMP Palette Export */\n" ; start
"." ; name-pre
"" ; name-after
" { " ; name-color-seperator
"color: " ; color-pre
" }" ; color-after
"\n" ; entry-seperator
"" ; end
) ) ) ) )
2023-07-16 22:22:58 +08:00
( register-palette-exporter "css" _ "_CSS stylesheet..." "css"
2010-06-01 03:36:36 +08:00
( string-append _ "Export the active palette as a CSS stylesheet with the color entry name as their class name, and the color itself as the color attribute" )
2024-04-22 02:59:59 +08:00
"Barak Itkin" "Barak Itkin" "May 15, 2009" )
2009-08-02 20:30:57 +08:00
( define ( gimp-palette-export-php directory-name file-name )
2024-04-22 02:59:59 +08:00
( script-fu-use-v3 )
( let ( ( path ( get-path-or-abort directory-name file-name ) ) )
( with-output-to-file path
( lambda ( ) ( export-palette ( palette-in-context )
color-rgb-to-hexa-decimal
name-standard ; name-convertor
"<?php\n/* Generated with GIMP Palette Export */\n$colors={\n" ; start
"'" ; name-pre
"'" ; name-after
" => " ; name-color-seperator
"'" ; color-pre
"'" ; color-after
",\n" ; entry-seperator
"}\n?>" ; end
) ) ) ) )
2023-07-16 22:22:58 +08:00
( register-palette-exporter "php" _ "P_HP dictionary..." "php"
2010-04-20 04:03:55 +08:00
_ "Export the active palette as a PHP dictionary (name => color)"
2024-04-22 02:59:59 +08:00
"Barak Itkin" "Barak Itkin" "May 15, 2009" )
2009-08-02 20:30:57 +08:00
( define ( gimp-palette-export-python directory-name file-name )
2024-04-22 02:59:59 +08:00
( script-fu-use-v3 )
( let ( ( path ( get-path-or-abort directory-name file-name ) ) )
( with-output-to-file path
( lambda ( )
( displayln "# Generated with GIMP Palette Export" )
( displayln ( string-append
"# Based on the palette " ( palette-name-in-context ) ) )
( export-palette ( palette-in-context )
color-rgb-to-hexa-decimal
name-standard ; name-convertor
"colors={\n" ; start
"'" ; name-pre
"'" ; name-after
": " ; name-color-seperator
"'" ; color-pre
"'" ; color-after
",\n" ; entry-seperator
"}" ; end
) ) ) ) )
2023-07-16 22:22:58 +08:00
( register-palette-exporter "python" _ "_Python dictionary..." "py"
2010-04-20 04:03:55 +08:00
_ "Export the active palette as a Python dictionary (name: color)"
2024-04-22 02:59:59 +08:00
"Barak Itkin" "Barak Itkin" "May 15, 2009" )
2009-08-02 20:30:57 +08:00
( define ( gimp-palette-export-text directory-name file-name )
2024-04-22 02:59:59 +08:00
( script-fu-use-v3 )
( let ( ( path ( get-path-or-abort directory-name file-name ) ) )
( with-output-to-file path
( lambda ( )
( export-palette ( palette-in-context )
color-rgb-to-hexa-decimal
name-none ; name-convertor
"" ; start
"" ; name-pre
"" ; name-after
"" ; name-color-seperator
"" ; color-pre
"" ; color-after
"\n" ; entry-seperator
"" ; end
) ) ) ) )
2023-07-16 22:22:58 +08:00
( register-palette-exporter "text" _ "_Text file..." "txt"
2010-04-20 04:03:55 +08:00
_ "Write all the colors in a palette to a text file, one hexadecimal value per line (no names)"
2024-04-22 02:59:59 +08:00
"Barak Itkin" "Barak Itkin" "May 15, 2009" )
2009-08-02 20:30:57 +08:00
( define ( gimp-palette-export-java directory-name file-name )
2024-04-22 02:59:59 +08:00
( script-fu-use-v3 )
( let ( ( path ( get-path-or-abort directory-name file-name ) ) )
( with-output-to-file path
( lambda ( )
( let ( ( palette-name ( palette-name-in-context ) ) )
( displayln "" )
( displayln "import java.awt.Color;" )
( displayln "import java.util.Hashtable;" )
( displayln "" )
( displayln "// Generated with GIMP palette Export " )
( displayln ( string-append
"// Based on the palette " palette-name ) )
( displayln ( string-append
"public class "
( name-standard palette-name ) " {" ) )
( displayln "" )
( displayln " Hashtable<String, Color> colors;" )
( displayln "" )
( displayln ( string-append
" public "
( name-standard palette-name ) "() {" ) )
( export-palette ( palette-in-context )
color-rgb-to-comma-separated-list
name-no-conversion
" colors = new Hashtable<String,Color>();\n" ; start
" colors.put(\"" ; name-pre
"\"" ; name-after
", " ; name-color-seperator
"new Color" ; color-pre
");" ; color-after
"\n" ; entry-seperator
"\n }" ; end
)
( display "\n}" ) ) ) ) ) )
2009-08-02 20:30:57 +08:00
2023-07-16 22:22:58 +08:00
( register-palette-exporter "java" _ "J_ava map..." "java"
2023-07-15 22:23:01 +08:00
_ "Export the active palette as a java.util.Hashtable<String,Color>"
2024-04-22 02:59:59 +08:00
"Barak Itkin" "Barak Itkin" "May 15, 2009" )
2010-06-01 03:36:36 +08:00