Skip to content

Commit 5c5af9e

Browse files
committed
manage parasites
1 parent 73f07c6 commit 5c5af9e

17 files changed

Lines changed: 309 additions & 0 deletions
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: Manage Parasites
3+
type: docs
4+
url: "/hub/plug-ins/folder/Manage-Parasites"
5+
---
6+
7+
## Introduction
8+
9+
A comprehensive parasite management tool for Script-Fu that lets you inspect, add, and remove parasites across all three scopes (global, image, and item). Parasites are GIMP's mechanism for attaching custom data—think of them as key-value pairs that can store plug-in settings, metadata, or any other information that needs to persist.
10+
11+
The standalone version includes all library functions inlined (~1,100 lines), making it a complete working example and a reusable library for your own scripts.
12+
13+
**Key Features:**
14+
15+
- List parasites with nine precision options (from single items to everything)
16+
- Remove parasites with matching granular control
17+
- Remove specific parasites by name (searches all scopes)
18+
- Add new parasites with automatic scope prefixing
19+
- Control persistence mode (session vs. persist between sessions)
20+
- Comprehensive library functions for parasite operations
21+
22+
[manage-parasites.zip](../../../../downloads/manage-parasites.zip)
23+
[Installation](../#installation)
24+
25+
### Plug-in Menu Location
26+
27+
Tools -> Manage Parasites
28+
29+
### Parasite Scopes
30+
31+
Parasites exist in three scopes:
32+
33+
- **Global** - Attached to GIMP itself, available across all images and sessions
34+
- **Image** - Attached to a specific image, saved with the XCF file
35+
- **Item** - Attached to individual layers, channels, or paths
36+
37+
### Nine Precision Options
38+
39+
Both **List Parasites** and **Remove Parasites** support the same nine options:
40+
41+
1. **None** - Do nothing
42+
2. **Global** - Only global parasites
43+
3. **Active Image** - Only the current image's parasites
44+
4. **Active Item** - Only the active layer's parasites
45+
5. **Active Image (all layers)** - All layer parasites on current image
46+
6. **Active Image + Item + Global** - Everything on current image plus global
47+
7. **All Open Images** - Image parasites across all open images
48+
8. **All Open Images (all layers)** - All layer parasites across all images
49+
9. **Everything** - Absolutely everything (global + all images + all items)
50+
51+
### Additional Operations
52+
53+
- **Remove Specific by Name** - Searches all scopes and removes matching parasites
54+
- **Add Parasite** - Creates new parasites with automatic scope prefixing
55+
- **Persist Mode** - Toggle between session-only and persistent storage
56+
57+
### Common Use Cases
58+
59+
- **Store plug-in preferences** globally for reuse across sessions
60+
- **Track image processing history** with metadata attached to images
61+
- **Mark special layers** for automated processing or exclusion
62+
- **Debug plug-in data** by listing what's attached where
63+
- **Clean up orphaned parasites** from development or testing

content/hub/plug-ins/folder/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ These plug-ins currently only work in [**GIMP 3**](https://www.gimp.org/news/202
2323
{{< card link="Select-All-Layers" title="Select All Layers" icon="view-list" >}}
2424
{{< card link="Alpha-To-Show-Mask" title="Alpha to Show Mask" icon="selector" >}}
2525
{{< card link="Crop-Layer-To-Mask" title="Crop Layer To Mask" icon="selector" >}}
26+
{{< card link="Manage-Parasites" title="Manage Parasites" icon="annotation" >}}
2627

2728
{{< /cards >}}
2829

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
---
2+
title: Manage Parasites
3+
type: docs
4+
url: "/hub/practical-applications/Manage-Parasites"
5+
---
6+
7+
## Introduction
8+
9+
The [**Manage Parasites**](../../plug-ins/folder/Manage-Parasites/) plug-in is a comprehensive practical example that demonstrates building a complete parasite management system in Script-Fu. The **standalone version** is approximately **1,100 lines** (all libraries inlined), providing a fully-featured tool for working with parasites across all three scopes in GIMP.
10+
11+
### What are Parasites?
12+
13+
Parasites are GIMP's mechanism for attaching custom data to different parts of your workspace. Think of them as **key-value pairs** that can store settings, metadata, or any other information your plug-ins need to persist.
14+
15+
Parasites exist in **three scopes**:
16+
17+
1. **Global parasites** - Attached to GIMP itself, available across all images and sessions
18+
2. **Image parasites** - Attached to a specific image, saved with the XCF file
19+
3. **Item parasites** - Attached to individual layers, channels, or paths
20+
21+
### Common Uses for Parasites
22+
23+
- **Plug-in settings** - Store user preferences that persist between sessions
24+
- **Image metadata** - Track processing history, copyright info, or custom attributes
25+
- **Layer annotations** - Mark layers with special purposes or processing flags
26+
- **Workflow data** - Store temporary processing state or cross-plug-in communication
27+
- **EXIF/IPTC data** - GIMP stores image metadata as parasites (e.g., `exif-data`, `gimp-comment`)
28+
29+
### Persistence Modes
30+
31+
Parasites can operate in two modes:
32+
33+
- **Session mode** - Data exists only during the current GIMP session (lost on exit)
34+
- **Persist mode** - Data is saved and restored between GIMP sessions
35+
36+
This plug-in lets you control which mode to use when adding or modifying parasites.
37+
38+
## Architecture Overview
39+
40+
The plug-in provides four main operations, each with precise scope control:
41+
42+
```scheme
43+
(define (script-fu-manage-parasites image drawables
44+
list-option
45+
remove-option
46+
remove-specific-name
47+
add-parasite
48+
parasite-name
49+
parasite-value
50+
parasite-scope
51+
persist-mode)
52+
;; Main logic orchestrates four operations:
53+
;; 1. List parasites based on precise option (9 choices)
54+
;; 2. Remove parasites based on precise option (9 choices)
55+
;; 3. Remove specific parasite by name (searches all scopes)
56+
;; 4. Add new parasite with automatic scope prefixing
57+
```
58+
59+
The structure is straightforward:
60+
61+
1. **Set attachment mode** based on persist-mode toggle
62+
2. **List parasites** using the selected list-option
63+
3. **Remove parasites** using the selected remove-option
64+
4. **Remove specific** parasite by name (if enabled)
65+
5. **Add new** parasite (if enabled)
66+
67+
## Nine Scope Options
68+
69+
Both the **List** and **Remove** operations support the same nine precision options:
70+
71+
### Individual Scopes
72+
73+
- **None** - Do nothing
74+
- **Global** - Only global parasites (GIMP-wide)
75+
- **Active Image** - Only the current image's parasites
76+
- **Active Item** - Only the active layer's parasites
77+
78+
### Compound Scopes
79+
80+
- **Active Image (all layers)** - All layer parasites on current image
81+
- **Active Image + Item + Global** - Everything related to current image plus global
82+
- **All Open Images** - Image parasites across all open images
83+
- **All Open Images (all layers)** - All layer parasites across all images
84+
- **Everything** - Absolutely everything (global + all images + all items)
85+
86+
This granular control lets you precisely target the parasites you want to inspect or remove, from a single layer to your entire GIMP environment.
87+
88+
## Parasite Naming Convention
89+
90+
The plug-in uses **scope prefixes** to organize parasites:
91+
92+
- **Global parasites**: `"global-name"`
93+
- **Image parasites**: `"image-name"`
94+
- **Item parasites**: `"item-name"`
95+
96+
When **adding** parasites through this plug-in, you provide the **base name** without the prefix. The plug-in automatically adds the appropriate prefix based on your scope selection:
97+
98+
```scheme
99+
;; You provide: "my-setting"
100+
;; Plug-in creates:
101+
;; "global-my-setting" (if scope is Global)
102+
;; "image-my-setting" (if scope is Image)
103+
;; "item-my-setting" (if scope is Item)
104+
```
105+
106+
When **removing by name**, the plug-in is smart about searching - it will try all scope variations:
107+
108+
```scheme
109+
;; You provide: "test"
110+
;; Plug-in searches for:
111+
;; "global-test", "image-test", "item-test"
112+
;; And removes any it finds
113+
```
114+
115+
## Listing Parasites
116+
117+
The listing functions display parasite names and values to the Error Console:
118+
119+
```scheme
120+
(define (list-global-parasites)
121+
(let ((parasites (global-get-parasite-list)))
122+
(if (null? parasites)
123+
(message "No global parasites found")
124+
(begin
125+
(message "=== GLOBAL PARASITES ===")
126+
(for-each
127+
(lambda (name)
128+
(let ((data (global-get-parasite-data name)))
129+
(message " " name ": " data)))
130+
parasites)
131+
(message "Total: " (length parasites) " global parasite(s)")))))
132+
```
133+
134+
Example output when listing everything:
135+
136+
```text
137+
=== COMPREHENSIVE LIST (EVERYTHING) ===
138+
=== GLOBAL PARASITES ===
139+
global-settings: #t
140+
global-last-folder: /home/user/images
141+
Total: 2 global parasite(s)
142+
143+
Image: landscape.xcf
144+
image-copyright: © 2025 John Doe
145+
image-processed: 2025-10-17
146+
Total: 2 parasite(s) across 1 image(s)
147+
148+
Image: portrait.xcf | Layer: Background
149+
item-blend-mode: overlay
150+
Total: 1 parasite(s) across 3 layer(s) in 2 image(s)
151+
```
152+
153+
## Removing Parasites
154+
155+
The removal functions mirror the listing structure, providing the same granular control:
156+
157+
```scheme
158+
(define (remove-all-global-parasites)
159+
(let ((parasites (global-get-parasite-list)))
160+
(if (null? parasites)
161+
(message "No global parasites to remove")
162+
(begin
163+
(for-each
164+
(lambda (name)
165+
(gimp-detach-parasite name))
166+
parasites)
167+
(message "Removed " (length parasites) " global parasite(s)")))))
168+
```
169+
170+
The **remove everything** option provides a clean sweep:
171+
172+
```scheme
173+
(define (remove-everything-parasites)
174+
(remove-all-global-parasites)
175+
(remove-all-images-parasites)
176+
(remove-all-items-all-images-parasites)
177+
(message "Removed all parasites from everywhere"))
178+
```
179+
180+
## Remove Specific by Name
181+
182+
The **Remove Specific by Name** feature is particularly powerful. It searches all three scopes and removes any matching parasites:
183+
184+
```scheme
185+
(define (remove-parasite-by-name name image item)
186+
(let ((removed-count 0)
187+
(global-name (if (string-prefix? "global-" name)
188+
name
189+
(string-append "global-" name)))
190+
(image-name (if (string-prefix? "image-" name)
191+
name
192+
(string-append "image-" name)))
193+
(item-name (if (string-prefix? "item-" name)
194+
name
195+
(string-append "item-" name))))
196+
;; Try all three scopes and report what was found
197+
...
198+
(if (= removed-count 0)
199+
(message "Parasite '" name "' not found in any scope")
200+
(message "Total removed: " removed-count " parasite(s)"))))
201+
```
202+
203+
This is useful when you know the base name of a parasite but aren't sure which scope(s) it exists in.
204+
205+
## Adding Parasites
206+
207+
The add operation automatically handles scope prefixing and data type conversion:
208+
209+
```scheme
210+
(define (add-parasite-with-scope name value scope image item)
211+
(let ((prefixed-name (case scope
212+
((global) (string-append "global-" name))
213+
((image) (string-append "image-" name))
214+
((item) (string-append "item-" name)))))
215+
(case scope
216+
((global)
217+
(set-attr prefixed-name value)
218+
(message "Added global parasite: " prefixed-name " = " value))
219+
((image)
220+
(set-attr prefixed-name image value)
221+
(message "Added image parasite: " prefixed-name " = " value))
222+
((item)
223+
(if item
224+
(begin
225+
(set-attr prefixed-name item value)
226+
(message "Added item parasite to '"
227+
(item-get-name item)
228+
"': " prefixed-name " = " value))
229+
(message "Error: No active layer selected"))))))
230+
```
231+
232+
## Conclusion
233+
234+
The Manage Parasites plug-in demonstrates advanced Script-Fu techniques:
235+
236+
- **Comprehensive scope control** - Nine precision options for listing and removing
237+
- **Flexible naming** - Automatic prefix handling for cleaner code
238+
- **Smart searching** - Find and remove parasites across all scopes
239+
- **Data type handling** - Automatic serialization and deserialization
240+
- **Persistence control** - Choose between session and permanent storage
241+
242+
This is a **working tool** that you can use to inspect, debug, and manage parasites in your GIMP workflow, while also serving as a comprehensive example of how to work with GIMP's parasite system in Script-Fu. The standalone version (1,100+ lines) includes all necessary library functions, making it easy to study the complete implementation.
243+
244+
Whether you need to debug plugin data, clean up orphaned parasites, or simply understand what's attached to your images and layers, this plug-in provides all the tools you need.

content/hub/practical-applications/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ Let's look at how the concepts and examples we've covered can be used to create
1111
{{< cards >}}
1212
{{< card link="Gaussian-Glow" title="Gaussian Glow" icon="light-bulb" >}}
1313
{{< card link="Batch-Process" title="Batch Process" icon="cog" >}}
14+
{{< card link="Manage-Parasites" title="Manage Parasites" icon="annotation" >}}
1415
{{< /cards >}}
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

static/downloads/glow-layer.zip

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)