Source code: jpicedt/format/pstricks/parser/PsRPutExpression.java
1 /* jPicEdt version 1.3.2, a picture editor for LaTeX.
2 Copyright (C) 1999-2002 Sylvain Reynal
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 Sylvain Reynal
19 Département de Physique
20 Ecole Nationale Supérieure de l'Electronique et de ses Applications (ENSEA)
21 6, avenue du Ponceau
22 95014 CERGY CEDEX
23 FRANCE
24
25 Tel : 00 +33 130 736 245
26 Fax : 00 +33 130 736 667
27 e-mail : reynal@ensea.fr
28 jPicEdt web page : http://www.jpicedt.org
29 */
30
31 package jpicedt.format.pstricks.parser;
32
33 import jpicedt.graphic.io.parser.*;
34 import jpicedt.graphic.PicPoint;
35 import jpicedt.graphic.model.PicText;
36
37 /**
38 * \\rput[refpoint]{rotation}(x,y){stuff} <br>
39 * \\rput*[refpoint]{rotation}(x,y){stuff} <br>
40 * (line-breaks being allowed b/w each "block"), where : <br>
41 * <ul>
42 * <li>refpoint = B|b|t for vertical and l|r for horizontal (B = baseline), used only for psframebox and rel.
43 * <li>rotation = any angle in degree or U,L,D,R,N,W,S or E.
44 * <li>stuff = whatever ! (this allows in particular to rotate things)
45 * </ul>
46 * Depending on the "stuff" found, instanciates :<ul>
47 * <li> PicText : \\psframebox, \\pscirclebox, \\psovalbox, LR-argument
48 * <li> huuu... [pending] instanciate other elements + handle rotations.
49 * </ul>
50 * @author $Author: reynal $
51 * @version $Id: PsRPutExpression.java,v 1.2 2002/08/05 16:44:10 reynal Exp $
52 *
53 */
54 public class PsRPutExpression extends SequenceExpression implements ExpressionConstants {
55
56 private Pool pool;
57 private String vertAlign = PicText.CENTER_V;
58 private String horAlign = PicText.CENTER_H; // used only if a PicText object is indeed instanciated.
59 private double rotation = 0;
60 private PicPoint rPutPoint = new PicPoint();
61 private StringBuffer hrArgument = new StringBuffer(); // used by HRArgument
62 public final static String RECTANGLE_BOX = "\\psframebox";
63 public final static String CIRCLE_BOX = "\\pscirclebox";
64 public final static String OVAL_BOX = "\\psovalbox";
65
66 public PsRPutExpression(Pool pl){
67
68 super(true); // throw exception if stop before end
69 pool = pl;
70
71 add(new LiteralExpression("\\rput")); // instanciation is done later on, depending on stuff found
72 add(new OptionalExpression(new LiteralExpression("*"))); // not used so far
73 add(WHITE_SPACES_OR_EOL);
74
75 // refpoint -> optional alignment : [vh] where v = b|t|B|"" and h = r|l|"" ("" default to center)
76 SequenceExpression alignmentExp = new SequenceExpression(true); // throw IncompleteSequence Exception
77 alignmentExp.add(new LiteralExpression("["));
78 alignmentExp.add(new Alignment()); // swallows "]" and can return an empty String as in "[]"
79 alignmentExp.add(WHITE_SPACES_OR_EOL);
80 add(new OptionalExpression(alignmentExp));
81
82 // rotation : {angle}
83 SequenceExpression angleExp = new SequenceExpression(true); // throw IncompleteSequence Exception
84 angleExp.add(new LiteralExpression("{"));
85 angleExp.add(new WordExpression("}", true){ // swallow "}"
86 public void action(ParserEvent e){
87 if (DEBUG) System.out.println(e);
88 // [pending] rotation not used yet
89 String s = (String)e.getValue();
90 try {
91 rotation = Double.parseDouble(s);
92 return;
93 } catch (NumberFormatException nex){}
94 if (s.equals("U")) rotation = 0;
95 else if (s.equals("L")) rotation = 90;
96 else if (s.equals("R")) rotation = -90;
97 else if (s.equals("D")) rotation = 180;
98 // [pending] other shortcuts
99 }});
100 angleExp.add(WHITE_SPACES_OR_EOL);
101 add(new OptionalExpression(angleExp));
102
103 // (x,y) :
104 add(new PicPointExpression("(",",",")"){
105 public void action(ParserEvent e){
106 if (DEBUG) System.out.println(e);
107 // same as LatexPutExpression except that we use pstXunit...
108 rPutPoint = ((PicPoint)e.getValue()).toMm(pool.getDouble(PstricksParser.KEY_X_UNIT),pool.getDouble(PstricksParser.KEY_Y_UNIT)); // global var
109 }});
110 add(WHITE_SPACES_OR_EOL);
111
112 // {stuff} :
113 AlternateExpression rputArgs = new AlternateExpression();
114 rputArgs.add(new PsFrameBox(RECTANGLE_BOX)); // \\psframebox
115 rputArgs.add(new PsFrameBox(CIRCLE_BOX)); // \\pscirclebox
116 rputArgs.add(new PsFrameBox(OVAL_BOX)); // \\psovalbox
117 // [pending] add PsPolygon, ... to handle rotation
118 rputArgs.add(new HRArgument()); // pure HR argument (must always be added last)
119 SequenceExpression rputArgsEOL = new SequenceExpression(WHITE_SPACES_OR_EOL,rputArgs,false);
120 add(new EnclosingExpression("{", rputArgsEOL, "}"));
121
122 }
123
124 public String toString(){
125 return "[PsRPutExpression]";
126 }
127
128 /** called when this SequenceExpression was successfully parsed -> reinit locals for next time */
129 public void action(ParserEvent e){
130 if (DEBUG) System.out.println(e);
131 vertAlign = PicText.CENTER_V;
132 horAlign = PicText.CENTER_H; // used only if a PicText object is indeed instanciated.
133 rotation = 0;
134 rPutPoint = new PicPoint();
135 hrArgument = new StringBuffer(); // used by HRArgument
136 }
137
138 /**
139 * [hv] alignment string for \\rput, provided that stuff is an HR-argument, or a box.
140 * Otherwise I noticed it'd no effect in PsTricks. [pending] am I right ?
141 * Note : order is non-significant here, i.e. [hv] or [vh]
142 */
143 class Alignment extends WordExpression {
144
145 public Alignment(){
146 super("]",true);
147 }
148
149 public void action(ParserEvent e){
150 if (DEBUG) System.out.println(e);
151 String s = (String)e.getValue();
152 vertAlign = PicText.CENTER_V; // default
153 if (s.indexOf("t")!=-1) vertAlign = PicText.TOP;
154 else if (s.indexOf("b")!=-1) vertAlign = PicText.BOTTOM;
155 else if (s.indexOf("B")!=-1) vertAlign = PicText.BASELINE;
156 else vertAlign = PicText.CENTER_V;
157
158 horAlign = PicText.CENTER_H; // default
159 if (s.indexOf("l")!=-1) horAlign = PicText.LEFT;
160 else if (s.indexOf("r")!=-1) horAlign = PicText.RIGHT;
161 else horAlign = PicText.CENTER_H;
162 }
163 }
164
165 /**
166 * \\psframebox[param]{text}}
167 */
168 class PsFrameBox extends SequenceExpression {
169
170 private String type;
171
172 /** @param type RECTANGLE_BOX, ... */
173 public PsFrameBox(String type){
174 super(true); // throw IncompleteSequence Exception
175 this.type = type;
176 // command :
177 this.add(new PSTInstanciationExpression(type, new PicText(),pool));
178 this.add(new OptionalExpression(new StarExpression(pool))); // "*"
179 this.add(WHITE_SPACES_OR_EOL);
180 // optional [param]
181 this.add(new OptionalExpression(new EnclosingExpression("[",new PSTParametersExpression(pool,Pool.CURRENT_OBJ_ATTRIBUTES),"]"))); // push in object's attributeSet
182 // {text}
183 this.add(new EnclosedText());
184 }
185 public void action(ParserEvent e){
186 if (DEBUG) System.out.println(e);
187 ((PicText)(pool.currentObj)).setPoint(PicText.P_ANCHOR,rPutPoint);
188 ((PicText)(pool.currentObj)).setHorAlign(horAlign);
189 ((PicText)(pool.currentObj)).setVertAlign(vertAlign);
190 if (type==RECTANGLE_BOX) ((PicText)(pool.currentObj)).setFrameType(PicText.RECTANGLE);
191 else if (type==CIRCLE_BOX) ((PicText)(pool.currentObj)).setFrameType(PicText.CIRCLE);
192 if (type==OVAL_BOX) ((PicText)(pool.currentObj)).setFrameType(PicText.OVAL);
193 }
194 }
195
196 /**
197 * handles {text} content (for PsFrameBox) by setting PicText's text content, replacing
198 * linefeeds by whitespaces beforehands (as TeX does...)
199 */
200 class EnclosedText extends EnclosingExpression {
201
202 public EnclosedText(){
203 super("{", null, "}");
204 }
205 public void action(ParserEvent e){
206 if (DEBUG) System.out.println(e);
207 String txt = getEnclosedString().replace('\n',' ');
208 txt = Context.removeRedundantWhiteSpaces(txt);
209 ((PicText)(pool.currentObj)).setText(txt);
210 }
211 }
212
213 /**
214 * swallow as many chars as possible and push them in "hrArgument" buffer,
215 * replacing CR by whitespaces, as TeX does.
216 */
217 class HRArgumentSucker extends WildCharExpression {
218
219 public HRArgumentSucker(){ // no jokes, but it really sucks !
220 super(ANY_CHAR_EOL);
221 }
222 public void action(ParserEvent e){
223 if (DEBUG) System.out.println(e);
224 Character cc = getCharacter();
225 if (cc.charValue() != '\n') hrArgument.append(cc);
226 else hrArgument.append(' ');
227 }
228 }
229
230 /**
231 * handles content of "{stuff}" when no other expression matches, by instanciating a PicText
232 * with "stuff" as the PicText string
233 */
234 class HRArgument extends RepeatExpression {
235
236 HRArgument(){
237 super(null,0,AT_LEAST);
238 setPattern(new HRArgumentSucker());
239 }
240
241 public void action(ParserEvent e){
242 if (DEBUG) System.out.println(e);
243 pool.currentObj = new PicText(rPutPoint, Context.removeRedundantWhiteSpaces(hrArgument.toString()), PicText.NO_FRAME, horAlign, vertAlign, pool.getAttributeSet(PstricksParser.KEY_ATTRIBUTES));
244 //pool.currentObj.setAttributeSet(pool.pstSet);
245 pool.currentGroup.addChild(pool.currentObj);
246 }
247 }
248
249 }