Skip to content

Commit 8122d36

Browse files
committed
Adding conversion from collection to cell range
1 parent b2a046e commit 8122d36

File tree

7 files changed

+180
-20
lines changed

7 files changed

+180
-20
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Combine the power of clojure with all the LibreOffice calc features!!!
55

66
ClojureCalc is a wrapper for clojure 1.6 on libre office and possibly open office.
77

8-
[Download v2.0.0](https://github.com/beothorn/ClojureCalc/releases/download/2.0.0/ClojureCalc.oxt)
8+
[Download v2.1.0](https://github.com/beothorn/ClojureCalc/releases/download/2.1.0/ClojureCalc.oxt)
99
=============
1010

1111

@@ -15,11 +15,12 @@ Usage
1515
=c( string with a clojure function, without wrapping parenthesis )
1616
=clj( string with a clojure expression )
1717
=cn( cell range to convert to a clojure numeric collection )
18-
=cs( cell range to convert to a clojure collection of strings )
18+
=cs( cell range to convert to a clojure collection of strings )
19+
=cljtorange( clojure collection; cell text; cell range to fill with values)
1920

2021
Note: Three single quotes are replaced by a double quote
2122

22-
![screenshot](http://i.imgur.com/FNga1Az.png "Really cool example")
23+
![screenshot](http://i.imgur.com/FzeLwJg.png "Really cool example")
2324

2425
Examples
2526
---------------------

registry/data/org/openoffice/Office/CalcAddins.xcu

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,47 @@
104104
</node>
105105
</node>
106106
</node>
107+
<node oor:name="cljToRange" oor:op="replace">
108+
<prop oor:name="DisplayName">
109+
<value xml:lang="en">cljToRange</value>
110+
</prop>
111+
<prop oor:name="Description">
112+
Converts clojure collection to cell range
113+
<value/>
114+
</prop>
115+
<prop oor:name="Category">
116+
<value>Add-In</value>
117+
</prop>
118+
<prop oor:name="CompatibilityName">
119+
<value/>
120+
</prop>
121+
<node oor:name="Parameters">
122+
<node oor:name="collection" oor:op="replace">
123+
<prop oor:name="DisplayName">
124+
<value xml:lang="en">Collection that will be written on cell range</value>
125+
</prop>
126+
<prop oor:name="Description">
127+
<value/>
128+
</prop>
129+
</node>
130+
<node oor:name="title" oor:op="replace">
131+
<prop oor:name="DisplayName">
132+
<value xml:lang="en">Text to show on this cell</value>
133+
</prop>
134+
<prop oor:name="Description">
135+
<value/>
136+
</prop>
137+
</node>
138+
<node oor:name="cells" oor:op="replace">
139+
<prop oor:name="DisplayName">
140+
<value xml:lang="en">Cells where the collection will be written</value>
141+
</prop>
142+
<prop oor:name="Description">
143+
<value/>
144+
</prop>
145+
</node>
146+
</node>
147+
</node>
107148
</node>
108149
</node>
109150
</node>

src/com/github/beothorn/clojurecalc/ClojureCalcImpl.java

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package com.github.beothorn.clojurecalc;
22

3+
import com.sun.star.lang.IndexOutOfBoundsException;
34
import com.sun.star.lang.XLocalizable;
45
import com.sun.star.lang.XServiceInfo;
56
import com.sun.star.lang.XSingleComponentFactory;
67
import com.sun.star.lib.uno.helper.Factory;
78
import com.sun.star.lib.uno.helper.WeakBase;
89
import com.sun.star.registry.XRegistryKey;
10+
import com.sun.star.table.XCellRange;
911
import com.sun.star.uno.XComponentContext;
12+
import java.util.List;
13+
import java.util.logging.Level;
14+
import java.util.logging.Logger;
1015

1116
public class ClojureCalcImpl extends WeakBase implements XServiceInfo, XLocalizable, XClojureCalc{
1217

@@ -30,20 +35,7 @@ public static XSingleComponentFactory __getComponentFactory(String sImplementati
3035
public static boolean __writeRegistryServiceInfo(XRegistryKey xRegistryKey ) {
3136
return Factory.writeRegistryServiceInfo(m_implementationName, m_serviceNames, xRegistryKey);
3237
}
33-
34-
// org.openoffice.addin.XTestAddin:
35-
public int redouble(int nValue)
36-
{
37-
// TODO !!!
38-
// Exchange the default return implementation.
39-
// NOTE: Default initialized polymorphic structs can cause problems
40-
// because of missing default initialization of primitive types of
41-
// some C++ compilers or different Any initialization in Java and C++
42-
// polymorphic structs.
43-
return 0;
44-
}
45-
46-
// com.sun.star.lang.XServiceInfo:
38+
4739
public String getImplementationName() {
4840
return m_implementationName;
4941
}
@@ -85,10 +77,36 @@ public String c(String exp)
8577
}
8678

8779
public String cn(String[][] cells){
88-
return ClojureInterpreter.toClojureCollectionNumber(cells);
80+
try{
81+
return ClojureInterpreter.toClojureCollectionNumber(cells);
82+
}catch(Exception e){
83+
return e.getMessage();
84+
}
8985
}
9086

9187
public String cs(String[][] cells){
92-
return ClojureInterpreter.toClojureCollectionString(cells);
88+
try{
89+
return ClojureInterpreter.toClojureCollectionString(cells);
90+
}catch(Exception e){
91+
return e.getMessage();
92+
}
93+
}
94+
95+
public String cljToRange(String collection, String title, XCellRange cells){
96+
try {
97+
final List<List<String>> listOfListsOfValues = ClojureInterpreter.fromClojureCollectionStringToList(collection);
98+
for (int lineIndex = 0; lineIndex < listOfListsOfValues.size(); lineIndex++) {
99+
final List<String> line = listOfListsOfValues.get(lineIndex);
100+
for (int column = 0; column < line.size(); column++) {
101+
final String value = line.get(column);
102+
cells.getCellByPosition(column, lineIndex).setFormula(value);
103+
}
104+
}
105+
return title;
106+
} catch (IndexOutOfBoundsException ex) {
107+
return "Cell Range is too small for values";
108+
} catch (Exception e){
109+
return e.getMessage();
110+
}
93111
}
94112
}

src/com/github/beothorn/clojurecalc/ClojureInterpreter.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import clojure.java.api.Clojure;
44
import clojure.lang.IFn;
55
import clojure.lang.LazySeq;
6+
import clojure.lang.PersistentVector;
7+
import java.util.ArrayList;
68
import java.util.Iterator;
9+
import java.util.List;
710

811
public class ClojureInterpreter {
912

@@ -98,4 +101,70 @@ private static String evalResultToString(String exp) {
98101
}
99102
return result;
100103
}
104+
105+
static List<List<String>> fromClojureCollectionStringToList(String cljColString) {
106+
ClassLoader previous = Thread.currentThread().getContextClassLoader();
107+
final ClassLoader parentClassLoader = ClojureCalcImpl.class.getClassLoader();
108+
Thread.currentThread().setContextClassLoader(parentClassLoader);
109+
try {
110+
return internalFromClojureCollectionStringToList(cljColString);
111+
}catch(Exception e){
112+
List<List<String>> x = new ArrayList<List<String>>();
113+
final ArrayList<String> message = new ArrayList<String>();
114+
message.add(e.getMessage());
115+
x.add(message);
116+
return x;
117+
} finally {
118+
Thread.currentThread().setContextClassLoader(previous);
119+
}
120+
}
121+
122+
private static List<List<String>> internalFromClojureCollectionStringToList(String cljColString) {
123+
final IFn eval = Clojure.var("clojure.core", "load-string");
124+
Object evalResult = eval.invoke(cljColString);
125+
IFn str = Clojure.var("clojure.core", "str");
126+
if(!(evalResult instanceof PersistentVector)){
127+
return new ArrayList<List<String>>();
128+
}
129+
130+
final Object[] array = ((PersistentVector) evalResult).toArray();
131+
if(array.length == 0){
132+
return new ArrayList<List<String>>();
133+
}
134+
135+
if(array[0] instanceof PersistentVector){ //we assume it's a list of lists
136+
final ArrayList<List<String>> collectionElements = new ArrayList<List<String>>();
137+
for (int i = 0; i < array.length; i++) {
138+
if(array[i] instanceof PersistentVector){
139+
ArrayList<String> line = new ArrayList<String>();
140+
final Object[] subArray = ((PersistentVector) array[i]).toArray();
141+
for (int j = 0; j < subArray.length; j++) {
142+
line.add(subArray[j].toString());
143+
}
144+
collectionElements.add(line);
145+
}else{
146+
ArrayList<String> line = new ArrayList<String>();
147+
line.add(array[i].toString());
148+
collectionElements.add(line);
149+
}
150+
}
151+
152+
return collectionElements;
153+
}else{
154+
final ArrayList<List<String>> collectionElements = new ArrayList<List<String>>();
155+
ArrayList<String> line = new ArrayList<String>();
156+
for (int i = 0; i < array.length; i++) {
157+
if(array[i] instanceof PersistentVector){
158+
final Object[] subArray = ((PersistentVector) evalResult).toArray();
159+
160+
}else{
161+
line.add(array[i].toString());
162+
}
163+
}
164+
165+
collectionElements.add(line);
166+
167+
return collectionElements;
168+
}
169+
}
101170
}

src/com/github/beothorn/clojurecalc/XClojureCalc.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module com { module github { module beothorn { module clojurecalc {
2424
string c([in] string exp);
2525
string cn([in] sequence< sequence< string > > cells);
2626
string cs([in] sequence< sequence< string > > cells);
27+
string cljToRange([in] string exp, [in] string title, [in] com::sun::star::table::XCellRange cells);
2728
};
2829
}; }; }; };
2930

src/description.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--Created with Apache OpenOffice API plug-in for NetBeans Version 2.0.6.000205-->
33
<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink">
4-
<version value="2.0.0"/>
4+
<version value="2.1.0"/>
55
<identifier value="com.github.beothorn.clojurecalc.ClojureCalc"/>
6+
<display-name>
7+
<name lang="en">ClojureCalc</name>
8+
</display-name>
9+
<publisher>
10+
<name lang="en" xlink:href="https://github.com/beothorn/ClojureCalc">Beothorn</name>
11+
</publisher>
612
</description>

test/com/github/beothorn/clojurecalc/ClojureInterpreterTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.github.beothorn.clojurecalc;
22

3+
import java.util.List;
34
import junit.framework.TestCase;
45
import junit.framework.Assert;
56

@@ -41,6 +42,29 @@ public void testStringCellsToMatrix(){
4142
Assert.assertEquals("['''a''' '''b''' '''3''']", clojureCollectionStrings);
4243
}
4344

45+
public void testClojureCollectionStringToJavaLists(){
46+
assertClojureListToLists("[1 2 3]", "{{1 2 3 } }");
47+
assertClojureListToLists("[[1 2 3] [4 5 6]]", "{{1 2 3 } {4 5 6 } }");
48+
}
49+
50+
private void assertClojureListToLists(final String clojureCollection, final String expected) {
51+
String asString = listsToString(ClojureInterpreter.fromClojureCollectionStringToList(clojureCollection));
52+
Assert.assertEquals(expected, asString);
53+
}
54+
55+
private String listsToString(List<List<String>> lists) {
56+
String asString = "{";
57+
for (List<String> list : lists) {
58+
asString += "{";
59+
for (String string : list) {
60+
asString += string+" ";
61+
}
62+
asString += "} ";
63+
}
64+
asString += "}";
65+
return asString;
66+
}
67+
4468
private void runAndAssert(final String exp, final String expected) {
4569
final String result = ClojureInterpreter.runClojure(exp);
4670
Assert.assertEquals(expected, result);

0 commit comments

Comments
 (0)