├── .github
├── build.sh
├── setup.sh
└── workflows
│ ├── build-main.yml
│ └── build-pr.yml
├── .gitignore
├── LICENSE.txt
├── README.md
├── pom.xml
└── src
├── main
├── java
│ └── org
│ │ └── scijava
│ │ └── plugins
│ │ └── scripting
│ │ └── clojure
│ │ ├── ClojureBindings.java
│ │ ├── ClojureScriptEngine.java
│ │ └── ClojureScriptLanguage.java
└── resources
│ └── META-INF
│ └── services
│ └── javax.script.ScriptEngineFactory
└── test
└── java
└── org
└── scijava
└── plugins
└── scripting
└── clojure
└── ClojureTest.java
/.github/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/master/ci-build.sh
3 | sh ci-build.sh
4 |
--------------------------------------------------------------------------------
/.github/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/master/ci-setup-github-actions.sh
3 | sh ci-setup-github-actions.sh
4 |
--------------------------------------------------------------------------------
/.github/workflows/build-main.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | tags:
8 | - "*-[0-9]+.*"
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v2
16 | - name: Set up Java
17 | uses: actions/setup-java@v3
18 | with:
19 | java-version: '8'
20 | distribution: 'zulu'
21 | cache: 'maven'
22 | - name: Set up CI environment
23 | run: .github/setup.sh
24 | - name: Execute the build
25 | run: .github/build.sh
26 | env:
27 | GPG_KEY_NAME: ${{ secrets.GPG_KEY_NAME }}
28 | GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
29 | MAVEN_USER: ${{ secrets.MAVEN_USER }}
30 | MAVEN_PASS: ${{ secrets.MAVEN_PASS }}
31 | OSSRH_PASS: ${{ secrets.OSSRH_PASS }}
32 | SIGNING_ASC: ${{ secrets.SIGNING_ASC }}
33 |
--------------------------------------------------------------------------------
/.github/workflows/build-pr.yml:
--------------------------------------------------------------------------------
1 | name: build PR
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/checkout@v2
14 | - name: Set up Java
15 | uses: actions/setup-java@v3
16 | with:
17 | java-version: '8'
18 | distribution: 'zulu'
19 | cache: 'maven'
20 | - name: Set up CI environment
21 | run: .github/setup.sh
22 | - name: Execute the build
23 | run: .github/build.sh
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.classpath
2 | /.project
3 | /.settings/
4 | /target
5 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 - 2025, Board of Regents of the University of
2 | Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
3 | Institute of Molecular Cell Biology and Genetics.
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without modification,
7 | are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 | POSSIBILITY OF SUCH DAMAGE.
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/scijava/scripting-clojure/actions/workflows/build-main.yml)
2 |
3 | # Clojure Scripting
4 |
5 | This library provides a
6 | [JSR-223-compliant](https://en.wikipedia.org/wiki/Scripting_for_the_Java_Platform)
7 | scripting plugin for the [Clojure](http://clojure.org/) language.
8 |
9 | It is implemented as a `ScriptLanguage` plugin for the [SciJava
10 | Common](https://github.com/scijava/scijava-common) platform, which means that
11 | in addition to being usable directly as a `javax.script.ScriptEngineFactory`,
12 | it also provides some functionality on top, such as the ability to generate
13 | lines of script code based on SciJava events.
14 |
15 | For a complete list of scripting languages available as part of the SciJava
16 | platform, see the
17 | [Scripting](https://github.com/scijava/scijava-common/wiki/Scripting) page on
18 | the SciJava Common wiki.
19 |
20 | See also:
21 | * [Clojure Scripting](http://wiki.imagej.net/Clojure_Scripting)
22 | on the ImageJ wiki.
23 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.scijava
7 | pom-scijava
8 | 40.0.0
9 |
10 |
11 |
12 | scripting-clojure
13 | 1.0.1-SNAPSHOT
14 |
15 | SciJava Scripting: Clojure
16 | JSR-223-compliant Clojure scripting language plugin.
17 | https://github.com/scijava/scripting-clojure
18 | 2013
19 |
20 | SciJava
21 | https://scijava.org/
22 |
23 |
24 |
25 | Simplified BSD License
26 | repo
27 |
28 |
29 |
30 |
31 |
32 | ctrueden
33 | Curtis Rueden
34 | https://imagej.net/User:Rueden
35 |
36 | lead
37 | developer
38 | debugger
39 | reviewer
40 | support
41 | maintainer
42 |
43 |
44 |
45 |
46 |
47 | Johannes Schindelin
48 | https://imagej.net/User:Schindelin
49 | founder
50 | dscho
51 |
52 |
53 | Albert Cardona
54 | https://imagej.net/User:Albertcardona
55 | acardona
56 |
57 |
58 | Kyle Harrington
59 | https://imagej.net/User:Kharrington
60 | kephale
61 |
62 |
63 | Mark Hiner
64 | https://imagej.net/User:Hinerm
65 | hinerm
66 |
67 |
68 |
69 |
70 |
71 | SciJava
72 | https://groups.google.com/group/scijava
73 | https://groups.google.com/group/scijava
74 | scijava@googlegroups.com
75 | https://groups.google.com/group/scijava
76 |
77 |
78 |
79 |
80 | scm:git:https://github.com/scijava/scripting-clojure
81 | scm:git:git@github.com:scijava/scripting-clojure
82 | HEAD
83 | https://github.com/scijava/scripting-clojure
84 |
85 |
86 | GitHub Issues
87 | https://github.com/scijava/scripting-clojure/issues
88 |
89 |
90 | GitHub Actions
91 | https://github.com/scijava/scripting-clojure/actions
92 |
93 |
94 |
95 | org.scijava.plugins.scripting.clojure
96 | bsd_2
97 | Board of Regents of the University of
98 | Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
99 | Institute of Molecular Cell Biology and Genetics.
100 | 1.12.0
101 |
102 |
103 | sign,deploy-to-scijava
104 |
105 |
106 |
107 |
108 |
109 | org.scijava
110 | scijava-common
111 |
112 |
113 |
114 |
115 | org.clojure
116 | clojure
117 | ${clojure.version}
118 |
119 |
120 |
121 |
122 | junit
123 | junit
124 | test
125 |
126 |
127 | org.scijava
128 | scijava-common
129 | tests
130 | test
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/src/main/java/org/scijava/plugins/scripting/clojure/ClojureBindings.java:
--------------------------------------------------------------------------------
1 | /*
2 | * #%L
3 | * JSR-223-compliant Clojure scripting language plugin.
4 | * %%
5 | * Copyright (C) 2013 - 2025 Board of Regents of the University of
6 | * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7 | * Institute of Molecular Cell Biology and Genetics.
8 | * %%
9 | * Redistribution and use in source and binary forms, with or without
10 | * modification, are permitted provided that the following conditions are met:
11 | *
12 | * 1. Redistributions of source code must retain the above copyright notice,
13 | * this list of conditions and the following disclaimer.
14 | * 2. Redistributions in binary form must reproduce the above copyright notice,
15 | * this list of conditions and the following disclaimer in the documentation
16 | * and/or other materials provided with the distribution.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 | * POSSIBILITY OF SUCH DAMAGE.
29 | * #L%
30 | */
31 |
32 | package org.scijava.plugins.scripting.clojure;
33 |
34 | import java.util.Collection;
35 | import java.util.HashMap;
36 | import java.util.Map;
37 | import java.util.Set;
38 |
39 | import javax.script.Bindings;
40 |
41 | import clojure.lang.MapEntry;
42 | import clojure.lang.Namespace;
43 | import clojure.lang.RT;
44 | import clojure.lang.Symbol;
45 | import clojure.lang.Var;
46 |
47 | /**
48 | * A {@link Bindings} wrapper around Clojure's local variables.
49 | *
50 | * @author Johannes Schindelin
51 | */
52 | public class ClojureBindings implements Bindings {
53 |
54 | private static final String CORE_NS = "clojure.core";
55 | private static final String USER_NS = "user";
56 |
57 | public ClojureBindings() {
58 | final Var nameSpace = RT.var(CORE_NS, "*ns*");
59 | Var.pushThreadBindings(RT.map(nameSpace, nameSpace.get()));
60 | RT.var(CORE_NS, "in-ns").invoke(Symbol.intern(USER_NS));
61 | RT.var(CORE_NS, "refer").invoke(Symbol.intern(CORE_NS));
62 | }
63 |
64 | @Override
65 | public int size() {
66 | return Var.getThreadBindings().count();
67 | }
68 |
69 | @Override
70 | public boolean isEmpty() {
71 | return size() == 0;
72 | }
73 |
74 | @Override
75 | public boolean containsKey(final Object key) {
76 | return get(key) != null;
77 | }
78 |
79 | @Override
80 | public boolean containsValue(final Object value) {
81 | return map().containsValue(value);
82 | }
83 |
84 | @Override
85 | public Object get(final Object keyObject) {
86 | String key = (String) keyObject;
87 | final int dot = key.lastIndexOf('.');
88 | final String nameSpace;
89 | if (dot < 0) {
90 | nameSpace = USER_NS;
91 | }
92 | else {
93 | nameSpace = key.substring(0, dot);
94 | key = key.substring(dot + 1);
95 | }
96 | try {
97 | return RT.var(nameSpace, key).get();
98 | }
99 | catch (final Error e) {
100 | return null;
101 | }
102 | }
103 |
104 | private Object get(final String nameSpace, final String key) {
105 | return RT.var(nameSpace, key);
106 | }
107 |
108 | @Override
109 | public Object put(final String name, final Object value) {
110 | final int dot = name.lastIndexOf('.');
111 | final String nameSpace, key;
112 | if (dot < 0) {
113 | nameSpace = USER_NS;
114 | key = name;
115 | }
116 | else {
117 | nameSpace = name.substring(0, dot);
118 | key = name.substring(dot + 1);
119 | }
120 | final Object result = get(nameSpace, key);
121 | try {
122 | final Var var = RT.var(nameSpace, key, null);
123 | var.setDynamic();
124 | Var.pushThreadBindings(RT.map(var, value));
125 | }
126 | catch (final Error e) {
127 | // ignore
128 | }
129 | return result;
130 | }
131 |
132 | @Override
133 | public Object remove(final Object key) {
134 | throw new UnsupportedOperationException();
135 | }
136 |
137 | @Override
138 | public void putAll(final Map extends String, ? extends Object> toMerge) {
139 | for (final Entry extends String, ? extends Object> entry : toMerge
140 | .entrySet())
141 | {
142 | put(entry.getKey(), entry.getValue());
143 | }
144 | }
145 |
146 | @Override
147 | public void clear() {
148 | throw new UnsupportedOperationException();
149 | }
150 |
151 | @Override
152 | public Set keySet() {
153 | return map().keySet();
154 | }
155 |
156 | @Override
157 | public Collection