This guide explains how to add a new function to the Patterning library and ensure it's available everywhere: workbench, CLI, tutorials, and other places.
When you add a new function to Patterning, you need to update several places to ensure it's available in all environments:
- Define the function in the appropriate namespace
- Add to key-bindings in the dynamic evaluation system
- Update the
:allowlist in SCI contexts - Test in all environments
Add your function to the appropriate namespace in src/cljc/patterning/. For example, if adding a color function:
File: src/cljc/patterning/color.cljc
(defn my-new-function
"Description of what this function does"
[param1 param2]
;; Your function implementation
)File: src/cljc/patterning/dynamic.cljc
Add your function to the key-bindings in the get-sci-context-config function:
:key-bindings {'basic-turtle (get p-lib-turtle-sci 'basic-turtle)
'l-system (get p-lib-lsystems-sci 'l-system)
'PI (get p-maths-sci 'PI)
'p-color (get p-color-sci 'p-color)
'hex-color (get p-color-sci 'hex-color)
'my-new-function (get p-color-sci 'my-new-function) ; ← Add this line
'poly (get p-lib-std-sci 'poly)
;; ... rest of key-bindings
}Important: Use the correct namespace reference:
- For
patterning.colorfunctions:(get p-color-sci 'function-name) - For
patterning.layoutsfunctions:(get p-layouts-sci 'function-name) - For
patterning.library.stdfunctions:(get p-lib-std-sci 'function-name) - etc.
Good news! The :allow list is now centralized and automatically includes all Patterning functions. Once you add your function to the key-bindings (step 2), it will be automatically available in both the workbench and CLI.
The :allow list is managed by get-core-allow-list in dynamic.cljc and includes all functions from (keys all-bindings), which covers all your Patterning functions.
No additional changes needed! The SCI context automatically picks up your function through the key-bindings you added in step 2. Both the workbench and CLI will have access to your function.
- Rebuild:
lein build-workbench - Open
http://localhost:8002/ - Try your function:
(my-new-function param1 param2)
- Create a test file with your function
- Run:
lein run -m patterning.cli test-file.clj output.svg svg 400 400
- Create a markdown file with a pattern using your function
- Run:
python tutorial/generate_pattern_page.py input.md output.html tutorial_root
Add your function to any relevant documentation:
- API documentation (if you have it)
- Function reference (if you maintain one)
- Example patterns using your new function
Cause: Function not in key-bindings or :allow list
Solution: Check steps 2 and 3 above
Cause: Missing from worker's :allow list
Solution: Add to workbench/worker.cljs :allow list
Cause: Missing from main key-bindings
Solution: Add to first key-bindings section in dynamic.cljc
Cause: Function not properly exported from namespace
Solution: Ensure function is public (not private with defn-)
When adding a new function, update these files:
- Function definition:
src/cljc/patterning/[namespace].cljc - Key-bindings:
src/cljc/patterning/dynamic.cljc(both sections) - Worker allow list:
workbench/worker.cljs - Test in workbench: Rebuild and test
- Test in CLI: Create test pattern
- Test in tutorial: Generate tutorial page
- Update documentation: Add to relevant docs
Here's a complete example of adding an HSL color function:
(defn hsl-color
"Convert HSL values to p-color format"
([h s l] (hsl-color h s l 255))
([h s l a]
;; HSL to RGB conversion implementation
(let [r (hsl-to-rgb h s l)
g (hsl-to-rgb h s l)
b (hsl-to-rgb h s l)]
(p-color r g b a)))):key-bindings {'basic-turtle (get p-lib-turtle-sci 'basic-turtle)
;; ... existing bindings
'hsl-color (get p-color-sci 'hsl-color)
;; ... rest of bindings
}:allow (set (concat (keys all-bindings)
['let 'let* 'def 'defn 'fn 'fn* 'if 'when 'cond 'case 'do '-> '->>
;; ... existing allows
'hsl-color
]));; In workbench or CLI:
(hsl-color 120 100 50) ; Green
(p-color/hsl-color 0 100 50) ; Red via namespaceSimplified Process: To add a new function to Patterning:
- Add the function to the appropriate namespace
- Add to key-bindings in
dynamic.cljc - Rebuild the workbench:
lein build-workbench - Test in workbench, CLI, and tutorial generation
That's it! The :allow list is now centralized and automatically includes all Patterning functions, so you don't need to manually update it anymore.
The key insight is that Patterning uses two different SCI contexts:
- Main context (for CLI) - uses
get-sci-context - Worker context (for workbench) - uses
get-sci-context-config
Both automatically pick up your function through the centralized key-bindings configuration, eliminating the need for manual :allow list updates.