1 /* Copyright (c) 2002-2012 The University of the West Indies
2  *
3  * Contact: robert.lancashire@uwimona.edu.jm
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2.1 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package jspecview.common;
21 
22 import java.util.Hashtable;
23 
24 import java.util.Map;
25 import java.util.Map.Entry;
26 
27 import javajs.util.Lst;
28 import javajs.util.PT;
29 import javajs.util.SB;
30 
31 
32 
33 
34 /**
35  * ScriptToken takes care of script command processing
36  *
37  * @author Bob Hanson hansonr@stolaf.edu
38  */
39 
40 public enum ScriptToken {
41 
42   // null tip means DON'T SHOW
43   UNKNOWN,
44   APPLETID,
45   APPLETREADYCALLBACKFUNCTIONNAME,
46   AUTOINTEGRATE("TF", "automatically integrate an NMR spectrum"),
47   BACKGROUNDCOLOR("C", "set the background color"),
48   CLOSE("spectrumId or fileName or ALL or VIEWS or SIMULATIONS", "close one or more views or simulations"),
49   COMPOUNDMENUON(), // not implemented
50   COORDCALLBACKFUNCTIONNAME,
51   COORDINATESCOLOR("C", "set the color of the coordinates shown in the upper right-hand corner"),
52   COORDINATESON("T", "turn on or off the coordinates shown in the upper right-hand corner"),
53   DEBUG("TF", "turn debugging on and off"),
54   DEFAULTLOADSCRIPT("\"script...\"", "set the script to be run after each file is loaded"),
55   DEFAULTNMRNORMALIZATION("maxYvalue", "set the value to be given the largest peak in an HMR spectrum"),
56   DISPLAYFONTNAME(),
57   DISPLAY1D("T", "turn on or off display of 1D spectra when 1D and 2D spectra are loaded"),
58   DISPLAY2D("T", "turn on or off display of the 2D spectrum when 1D and 2D spectra are loaded"),
59   ENABLEZOOM("T", "allow or disallow zooming"),
60   ENDINDEX,
61   FINDX("value", "move the vertical-line cursor to a specific x-axis value"),
62   GETPROPERTY("[propertyName] or ALL or NAMES", "get a property value or all property values as key/value pairs, or a list of names"),
63   GETSOLUTIONCOLOR(" FILL or FILLNONE or FILLALL or FILLALLNONE","estimate the solution color for UV/VIS spectra"),
64   GRIDCOLOR("C", "color of the grid"),
65   GRIDON("T", "turn the grid lines on or off"),
66   HELP("[command]", "get this listing or help for a specific command"),
67   HIDDEN,
68   HIGHLIGHTCOLOR("C", "set the highlight color"),
69   HIGHLIGHT("OFF or X1 X2 [OFF] or X1 X2 r g b [a]", "turns on or off a highlight color, possibily setting its color, where r g b a are 0-255 or 0.0-1.0"),
70   INTEGRALOFFSET("percent", "sets the integral offset from baseline"),
71   INTEGRALRANGE("percent", "sets the height of the total integration"),
72   INTEGRATE("", "see INTEGRATION"), // same as INTEGRATION
73   INTEGRATION("ON/OFF/TOGGLE/AUTO/CLEAR/MIN value/MARK ppm1-ppm2:norm,ppm3-ppm4,...", "show/hide integration or set integrals (1D 1H NMR only)"),
74   INTEGRALPLOTCOLOR("C", "color of the integration line"),
75   INTEGRATIONRATIOS("'x:value,x:value,..'","annotate the spectrum with numbers or text at specific x values"),
76   INTERFACE("SINGLE or OVERLAY", "set how multiple spectra are displayed"),
77   INVERTY("", "invert the Y axis"),
78   IRMODE("A or T or TOGGLE", "set the IR mode to absorption or transmission"),
79   JMOL("...Jmol command...", "send a command to Jmol (if present)"),
80   JSV,
81   LABEL("x y [color and/or \"text\"]", "add a text label"),
82   LINK("AB or ABC or NONE or ALL", "synchronize the crosshair of a 2D spectrum with 1D cursors"),
83   LOAD("[APPEND] \"fileName\" [first] [last]; use \"\" for current file; $H1/name or $C13/name for simulation", "load a specturm"),
84   LOADFILECALLBACKFUNCTIONNAME,
85   LOADIMAGINARY("TF","set TRUE to load imaginary NMR component"),
86   MENUON,
87   OBSCURE,
88   OVERLAY, // same as "VIEW"
89   OVERLAYSTACKED("TF", "whether viewed spectra are shown separately, in a stack"),
90   PEAK("[IR,CNMR,HNMR,MS] [#nnn or ID=xxx or text] [ALL], for example: PEAK HNMR #3",
91   			"highlights a peak based on its number or title text, optionally checking all loade spectra"),
92   PEAKCALLBACKFUNCTIONNAME,
93   PEAKLIST("[THRESHOLD=n] [INTERPOLATE=PARABOLIC or NONE]", "creates a peak list based on a threshold value and parabolic or no interpolation"),
94   PEAKTABCOLOR("C", "sets the color of peak marks for a peak listing"),
95   PEAKTABSON("T", "show peak tabs for simulated spectra"),
96   PLOTAREACOLOR("C", "sets the color of the plot background"),
97   PLOTCOLOR("C", "sets the color of the graph line"),
98   PLOTCOLORS("color,color,color,...", "sets the colors of multiple plots"),
99   POINTSONLY("TF", "show points only for all data"),
100   PRINT("", "prints the current spectrum"),
101   REVERSEPLOT("T", "reverses the x-axis of a spectrum"),
102   SCALEBY("factor", "multiplies the y-scale of the spectrum by a factor"),
103   SCALECOLOR("C", "sets the color of the x-axis and y-axis scales"),
104   SCRIPT("filename.jsv", "runs a script from a file"),
105   SELECT("spectrumID, spectrumID,...", "selects one or more spectra based on IDs"),
106   SETPEAK("xNew, xOld xNew, ?, or NONE", "sets nearest peak to xOld ppm to a new value; NONE resets (1D NMR only)"),
107   SETX("xNew, xOld xNew, ?, or NONE", "sets an old ppm position in the spectrum to a new value; NONE resets (1D NMR only)"),
108   SHIFTX("dx or NONE", "shifts the x-axis of a 1D NMR spectrum by the given ppm; NONE resets (1D NMR only)"),
109   SHOWERRORS("shows recent errors"),
110   SHOWINTEGRATION("T", "shows an integration listing"),
111   SHOWKEY("T", "shows a color key when multiple spectra are displayed"),
112   SHOWMEASUREMENTS("T", "shows a listing of measurements"),
113   SHOWMENU("displays the popup menu"),
114   SHOWPEAKLIST("T", "shows a listing for peak picking"),
115   SHOWPROPERTIES("displays the header information of a JDX file"),
116   SHOWSOURCE("displays the source JDX file associated with the selected data"),
117   SPECTRUM("id", "displays a specific spectrum, where id is a number 1, 2, 3... or a file.spectrum number such as 2.1"),
118   SPECTRUMNUMBER("n", "displays the nth spectrum loaded"),
119   STACKOFFSETY("percent", "sets the y-axis offset of stacked spectra"),
120   STARTINDEX,
121   SYNCCALLBACKFUNCTIONNAME,
122   SYNCID,
123   TEST,
124   TITLEON("T", "turns the title in the bottom left corner on or off"), // default OFF for application, ON for applet
125   TITLEBOLDON("T", "makes the title bold"),
126   TITLECOLOR("C", "sets the color of the title"),
127   TITLEFONTNAME("fontName", "sets the title font"),
128   UNITSCOLOR("C", "sets the color of the x-axis and y-axis units"),
129   VERSION,
130   VIEW("spectrumID, spectrumID, ... Example: VIEW 3.1, 3.2  or  VIEW \"acetophenone\"", "creates a view of one or more spectra"),
131   XSCALEON("T", "set FALSE to turn off the x-axis scale"),
132   XUNITSON("T", "set FALSE to turn off the x-axis units"),
133   YSCALE("[ALL] lowValue highValue"),
134   YSCALEON("T", "set FALSE to turn off the y-axis scale"),
135   YUNITSON("T", "set FALSE to turn off the y-axis units"),
136   WINDOW,
137   WRITE("[XY,DIF,DIFDUP,PAC,FIX,SQZ,AML,CML,JPG,PDF,PNG,SVG] \"filename\"", "writes a file in the specified format"),
138   ZOOM("OUT or PREVIOUS or NEXT or x1,x2 or x1,y1 x2,y2", "sets the zoom"),
139   ZOOMBOXCOLOR, ZOOMBOXCOLOR2; // not implemented
140 
141   private String tip, description;
142 
getTip()143   public String getTip() {
144     return "  "
145         + (tip == "T" ? "TRUE/FALSE/TOGGLE"
146             : tip == "TF" ? "TRUE or FALSE"
147             : tip == "C" ? "COLOR"
148             : tip);
149 
150   }
151 
ScriptToken()152   private ScriptToken() {
153   }
154 
ScriptToken(String tip)155   private ScriptToken(String tip) {
156     this.tip = tip;
157     this.description = "";
158   }
159 
ScriptToken(String tip, String description)160   private ScriptToken(String tip, String description) {
161     this.tip = tip;
162     this.description = "-- " + description;
163   }
164 
165   private static Map<String, ScriptToken> htParams;
166 
getParams()167   private static Map<String, ScriptToken> getParams() {
168     if (htParams == null) {
169       htParams = new Hashtable<String, ScriptToken>();
170       for (ScriptToken item : values())
171         htParams.put(item.name(), item);
172     }
173     return htParams;
174   }
175 
getScriptToken(String name)176   public static ScriptToken getScriptToken(String name) {
177     ScriptToken st = getParams().get(name.toUpperCase());
178     return (st == null ? UNKNOWN : st);
179   }
180 
getScriptTokenList(String name, boolean isExact)181   public static Lst<ScriptToken> getScriptTokenList(String name,
182                                                      boolean isExact) {
183     if (name != null)
184     	name = name.toUpperCase();
185     Lst<ScriptToken> list = new Lst<ScriptToken>();
186     if (isExact) {
187       ScriptToken st = getScriptToken(name);
188       if (st != null)
189         list.addLast(st);
190     } else {
191       for (Entry<String, ScriptToken> entry : getParams().entrySet())
192         if ((name == null || entry.getKey().startsWith(name))
193         		&& entry.getValue().tip != null)
194           list.addLast(entry.getValue());
195     }
196     return list;
197   }
198 
199   /**
200    * tweak command options depending upon special cases
201    *
202    * @param st
203    * @param params
204    * @param cmd
205    * @return adjusted value
206    */
getValue(ScriptToken st, ScriptTokenizer params, String cmd)207   public static String getValue(ScriptToken st, ScriptTokenizer params,
208                                 String cmd) {
209     if (!params.hasMoreTokens())
210       return "";
211     switch (st) {
212     default:
213       return ScriptTokenizer.nextStringToken(params, true);
214     case CLOSE:
215     case GETPROPERTY:
216     case INTEGRATION:
217     case INTEGRATE:
218     case JMOL:
219     case LABEL:
220     case LOAD:
221     case PEAK:
222     case PLOTCOLORS:
223     case YSCALE:
224     case WRITE:
225       // take full command
226       return removeCommandName(cmd);
227     case SELECT:
228     case OVERLAY: // deprecated
229     case VIEW:
230     case ZOOM:
231       // commas to spaces
232       return removeCommandName(cmd).replace(',', ' ').trim();
233     }
234   }
235 
removeCommandName(String cmd)236   private static String removeCommandName(String cmd) {
237     int pt = cmd.indexOf(" ");
238     if (pt < 0)
239       return "";
240     return cmd.substring(pt).trim();
241   }
242 
getKey(ScriptTokenizer eachParam)243   public static String getKey(ScriptTokenizer eachParam) {
244     String key = eachParam.nextToken();
245     if (key.startsWith("#") || key.startsWith("//"))
246       return null;
247     if (key.equalsIgnoreCase("SET"))
248       key = eachParam.nextToken();
249     return key.toUpperCase();
250   }
251 
252   /**
253    * read a string for possibly quoted tokens separated by space until // or #
254    * is reached.
255    *
256    * @param value
257    * @return list of tokens
258    */
getTokens(String value)259   public static Lst<String> getTokens(String value) {
260 		if (value.startsWith("'") && value.endsWith("'"))
261 			value = "\"" + PT.trim(value, "'") + "\"";
262     Lst<String> tokens = new Lst<String>();
263     ScriptTokenizer st = new ScriptTokenizer(value, false);
264     while (st.hasMoreTokens()) {
265       String s = ScriptTokenizer.nextStringToken(st, false);
266       if (s.startsWith("//") || s.startsWith("#"))
267         break;
268       tokens.addLast(s);
269     }
270     return tokens;
271   }
272 
getNameList(Lst<ScriptToken> list)273   public static String getNameList(Lst<ScriptToken> list) {
274     if (list.size() == 0)
275       return "";
276     SB sb = new SB();
277     for (int i = 0; i < list.size(); i++)
278       sb.append(",").append(list.get(i).toString());
279     return sb.toString().substring(1);
280   }
281 
getDescription()282 	public String getDescription() {
283 		return description;
284 	}
285 
286 }
287