Merge lp:~tapaal-contributor/tapaal/cpn-gui-TikZ-support into lp:~tapaal-contributor/tapaal/cpn-gui-dev
- cpn-gui-TikZ-support
- Merge into cpn-gui-dev
Status: | Superseded |
---|---|
Proposed branch: | lp:~tapaal-contributor/tapaal/cpn-gui-TikZ-support |
Merge into: | lp:~tapaal-contributor/tapaal/cpn-gui-dev |
Diff against target: |
461 lines (+199/-136) 1 file modified
src/net/tapaal/export/TikZExporter.java (+199/-136) |
To merge this branch: | bzr merge lp:~tapaal-contributor/tapaal/cpn-gui-TikZ-support |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jiri Srba | Pending | ||
Review via email:
|
This proposal supersedes a proposal from 2022-02-09.
This proposal has been superseded by a proposal from 2022-02-17.
Commit message
Added TikZ support for colored nets.
Added a framed box to the Tikz output for global variables/
Removed subscripiting from transition- and place names
Changed \mathrm to \mathit
Added more adjustment options for transitions, places and arcs
Description of the change
The TikZ export now shows all of the new features associated with colored nets.
Also added a framed box that contains all the global variables, constants and/or color types for a given net.
Subscripting from transition- and place names have been removed, so it looks more like the GUI.
\mathrm has also been replaces with \mathit.
- 1574. By Kristian Morsing Pedersen <email address hidden>
-
Merged with cpn-gui-dev
- 1575. By Kristian Morsing Pedersen <email address hidden>
-
Labels with multiple lines on arcs now displays correctly
- 1576. By Kristian Morsing Pedersen <email address hidden>
-
Changed default pos of arc labels to 0.5
- 1577. By Kristian Morsing Pedersen <email address hidden>
-
Resolved merge conflicts
- 1578. By Kristian Morsing Pedersen <email address hidden>
-
Removed redundant \\ and changed 0,0 -> 0.0 for age of tokens in initial markings
- 1579. By Kristian Morsing Pedersen <email address hidden>
-
Changed x -> \times in inhibitor arcs
Unmerged revisions
Preview Diff
1 | === modified file 'src/net/tapaal/export/TikZExporter.java' |
2 | --- src/net/tapaal/export/TikZExporter.java 2022-01-07 17:05:54 +0000 |
3 | +++ src/net/tapaal/export/TikZExporter.java 2022-02-17 17:11:33 +0000 |
4 | @@ -3,16 +3,17 @@ |
5 | import java.io.FileWriter; |
6 | import java.io.IOException; |
7 | import java.io.PrintWriter; |
8 | -import java.util.List; |
9 | +import java.util.*; |
10 | |
11 | +import dk.aau.cs.model.CPN.ColorType; |
12 | +import dk.aau.cs.model.CPN.Variable; |
13 | +import dk.aau.cs.model.tapn.Constant; |
14 | import dk.aau.cs.model.tapn.TimedToken; |
15 | |
16 | +import net.tapaal.gui.petrinet.Context; |
17 | import pipe.gui.petrinet.dataLayer.DataLayer; |
18 | import pipe.gui.TAPAALGUI; |
19 | -import pipe.gui.petrinet.graphicElements.Arc; |
20 | -import pipe.gui.petrinet.graphicElements.ArcPathPoint; |
21 | -import pipe.gui.petrinet.graphicElements.Place; |
22 | -import pipe.gui.petrinet.graphicElements.Transition; |
23 | +import pipe.gui.petrinet.graphicElements.*; |
24 | import pipe.gui.petrinet.graphicElements.tapn.TimedInhibitorArcComponent; |
25 | import pipe.gui.petrinet.graphicElements.tapn.TimedInputArcComponent; |
26 | import pipe.gui.petrinet.graphicElements.tapn.TimedPlaceComponent; |
27 | @@ -45,7 +46,7 @@ |
28 | if (option == TikZOutputOption.FULL_LATEX) { |
29 | out.println("\\documentclass[a4paper]{article}"); |
30 | out.println("\\usepackage{tikz}"); |
31 | - out.println("\\usetikzlibrary{petri,arrows}"); |
32 | + out.println("\\usetikzlibrary{petri,arrows,positioning}"); |
33 | out.println("\\usepackage{amstext}"); |
34 | out.println(); |
35 | out.println("\\begin{document}"); |
36 | @@ -62,6 +63,8 @@ |
37 | out.print(exportTransitions(net.getTransitions())); |
38 | out.print(exportArcs(net.getArcs())); |
39 | |
40 | + out.println(exportGlobalVariables()); |
41 | + |
42 | out.println("\\end{tikzpicture}"); |
43 | if (option == TikZOutputOption.FULL_LATEX) { |
44 | out.println("\\end{document}"); |
45 | @@ -94,7 +97,7 @@ |
46 | ArcPathPoint currentPoint = arc.getArcPath().getArcPathPoint(i); |
47 | |
48 | if(currentPoint.getPointType() == ArcPathPoint.STRAIGHT) { |
49 | - arcPoints += "to[bend right=0] (" + (currentPoint.getX()) + "," + (currentPoint.getY() * (-1)) + ") "; |
50 | + arcPoints += "to [bend right=0] (" + (currentPoint.getX()) + "," + (currentPoint.getY() * (-1)) + ") "; |
51 | } else if (currentPoint.getPointType() == ArcPathPoint.CURVED) { |
52 | double xCtrl1 = Math.round(currentPoint.getControl1().getX()); |
53 | double yCtrl1 = Math.round(currentPoint.getControl1().getY() * (-1)); |
54 | @@ -109,21 +112,19 @@ |
55 | } |
56 | |
57 | String arrowType = getArcArrowType(arc); |
58 | - String arcLabel = getArcLabels(arc); |
59 | |
60 | + out.append("% Arc between " + arc.getSource().getName() + " and " + arc.getTarget().getName() + "\n"); |
61 | out.append("\\draw["); |
62 | out.append(arrowType); |
63 | - out.append("] ("); |
64 | + out.append(",pos=0] ("); |
65 | out.append(arc.getSource().getId()); |
66 | out.append(") "); |
67 | out.append(arcPoints); |
68 | - out.append("to[bend right=0]"); |
69 | - out.append(" ("); |
70 | - out.append(arc.getTarget().getId()); |
71 | - out.append(") {};\n"); |
72 | - if(!arcLabel.equals("")) |
73 | - out.append("%% Label for arc between " + arc.getSource().getName() + " and " + arc.getTarget().getName() + "\n"); |
74 | - out.append(arcLabel); |
75 | + out.append("to node[bend right=0,auto]"); |
76 | + out.append(" {"); |
77 | + out.append(handleNameLabel(arc.getNameLabel().getText())); |
78 | + out.append("} "); |
79 | + out.append("(" + arc.getTarget().getId() + ");\n"); |
80 | } |
81 | return out; |
82 | } |
83 | @@ -142,50 +143,6 @@ |
84 | return arrowType; |
85 | } |
86 | |
87 | - protected String getArcLabels(Arc arc) { |
88 | - String arcLabel = ""; |
89 | - String arcLabelPositionString = "\\draw (" + (arc.getNameLabel().getX()) + "," + (arc.getNameLabel().getY())*(-1) + ") node {"; |
90 | - |
91 | - if (arc instanceof TimedInputArcComponent) { |
92 | - if (!(arc.getSource() instanceof TimedTransitionComponent)) { |
93 | - arcLabel = arcLabelPositionString; |
94 | - if (arc.getWeight().value() > 1) { |
95 | - arcLabel += "$" + arc.getWeight().value() + "\\times$\\ "; |
96 | - } |
97 | - |
98 | - if(TAPAALGUI.getApp().getCurrentTab().getLens().isTimed()) { |
99 | - arcLabel += "$\\mathrm{" + replaceWithMathLatex(getGuardAsStringIfNotHidden((TimedInputArcComponent) arc)) + "}$"; |
100 | - if (arc instanceof TimedTransportArcComponent) |
101 | - arcLabel += ":" + ((TimedTransportArcComponent) arc).getGroupNr(); |
102 | - arcLabel += "};\n"; |
103 | - } else { |
104 | - arcLabel += "};\n"; |
105 | - } |
106 | - |
107 | - } else { |
108 | - arcLabel = arcLabelPositionString; |
109 | - if (arc.getWeight().value() > 1) { |
110 | - arcLabel += "$" + arc.getWeight().value() + "\\times$\\ "; |
111 | - } |
112 | - arcLabel += ":" + ((TimedTransportArcComponent) arc).getGroupNr() + "};\n"; |
113 | - } |
114 | - |
115 | - } else { |
116 | - if (arc.getWeight().value() > 1) { |
117 | - arcLabel += arcLabelPositionString + "$" + arc.getWeight().value() + "\\times$\\ };\n"; |
118 | - } |
119 | - } |
120 | - return arcLabel; |
121 | - } |
122 | - |
123 | - private String getGuardAsStringIfNotHidden(TimedInputArcComponent arc) { |
124 | - if (!TAPAALGUI.getApp().showZeroToInfinityIntervals() && arc.getGuardAsString().equals("[0,inf)")){ |
125 | - return ""; |
126 | - } else { |
127 | - return arc.getGuardAsString(); |
128 | - } |
129 | - } |
130 | - |
131 | private StringBuffer exportTransitions(Transition[] transitions) { |
132 | StringBuffer out = new StringBuffer(); |
133 | for (Transition trans : transitions) { |
134 | @@ -195,7 +152,8 @@ |
135 | |
136 | |
137 | out.append("\\node[transition"); |
138 | - out.append(angle); |
139 | + out.append(angle); |
140 | + out.append(handlePlaceAndTransitionLabel(trans.getNameLabel().getText(), trans.getName(), trans.getAttributesVisible())); |
141 | out.append("] at ("); |
142 | out.append((trans.getPositionX())); |
143 | out.append(','); |
144 | @@ -226,31 +184,30 @@ |
145 | out.append(trans.getId()); |
146 | out.append(".center) { };\n"); |
147 | } |
148 | - if (trans.getAttributesVisible()){ |
149 | - boolean isLabelAboveTransition = trans.getY() > trans.getNameLabel().getY(); |
150 | - boolean isLabelBehindTrans = trans.getX() < trans.getNameLabel().getX(); |
151 | - double xOffset = trans.getName().length() > 5 && !isLabelAboveTransition && !isLabelBehindTrans ? trans.getLayerOffset() : 0; |
152 | - |
153 | - out.append("%% label for transition " + trans.getName() + "\n"); |
154 | - out.append("\\draw ("); |
155 | - out.append(trans.getNameLabel().getX() + xOffset + "," + (trans.getNameLabel().getY() * -1) + ")"); |
156 | - out.append(" node "); |
157 | - out.append(" {"); |
158 | - out.append(exportMathName(trans.getName())); |
159 | - out.append("};\n"); |
160 | - } |
161 | } |
162 | return out; |
163 | } |
164 | |
165 | + private String handlePlaceAndTransitionLabel(String nameLabelText, String name, boolean isVisible) { |
166 | + if(!isVisible) |
167 | + return ""; |
168 | + |
169 | + String result = ", label={[align=left,label distance=0cm]90:"; |
170 | + result += "$\\mathrm{" + (name.replace("_","\\_")) + "}$"; |
171 | + result += handleNameLabel(nameLabelText); |
172 | + result += "}"; |
173 | + return result; |
174 | + } |
175 | + |
176 | private StringBuffer exportPlacesWithTokens(Place[] places) { |
177 | StringBuffer out = new StringBuffer(); |
178 | |
179 | for (Place place : places) { |
180 | - String invariant = getPlaceInvariantString(place); |
181 | + String invariant = "$" + getPlaceInvariantString(place) + "$"; |
182 | String tokensInPlace = getTokenListStringFor(place); |
183 | |
184 | out.append("\\node[place"); |
185 | + out.append(handlePlaceAndTransitionLabel(place.getNameLabel().getText(), place.getName(), place.getAttributesVisible())); |
186 | out.append("] at ("); |
187 | out.append(place.getPositionX()); |
188 | out.append(','); |
189 | @@ -262,37 +219,38 @@ |
190 | exportPlaceTokens(place, out, ((TimedPlaceComponent) place).underlyingPlace().tokens().size()); |
191 | |
192 | if(((TimedPlaceComponent)place).underlyingPlace().isShared()){ |
193 | - out.append("\\node[sharedplace] at ("); |
194 | + out.append("\\node[sharedplace "); |
195 | + out.append("] at ("); |
196 | out.append(place.getId()); |
197 | out.append(".center) { };\n"); |
198 | } |
199 | - if (place.getAttributesVisible() || !invariant.equals("")){ |
200 | - boolean isLabelAbovePlace = place.getY() > place.getNameLabel().getY(); |
201 | - boolean isLabelBehindPlace = place.getX() < place.getNameLabel().getX(); |
202 | - double xOffset = place.getName().length() > 6 && !isLabelAbovePlace && !isLabelBehindPlace ? place.getLayerOffset() : 0; |
203 | - double yOffset = isLabelAbovePlace ? (place.getNameLabel().getHeight() / 2) : 0; |
204 | - |
205 | - out.append("%% label for place " + place.getName() + "\n"); |
206 | - out.append("\\draw ("); |
207 | - out.append((place.getNameLabel().getX() + xOffset) + "," + ((place.getNameLabel().getY() * -1) + yOffset) +")"); |
208 | - out.append(" node[align=left] "); |
209 | - out.append("{"); |
210 | - if(place.getAttributesVisible()) |
211 | - out.append(exportMathName(place.getName())); |
212 | - if(!invariant.equals("")) { |
213 | - if((place.getAttributesVisible())) |
214 | - out.append("\\\\"); |
215 | - out.append(invariant); |
216 | - }else { |
217 | - out.append("};\n"); |
218 | - } |
219 | - |
220 | - } |
221 | } |
222 | - |
223 | return out; |
224 | } |
225 | |
226 | + private String handleNameLabel(String nameLabel) { |
227 | + String nameLabelsString = ""; |
228 | + String[] labelsInName = nameLabel.split("\n"); |
229 | + for(int i = 0; i < labelsInName.length; i++) { |
230 | + |
231 | + if(labelsInName[i].contains("[")) { |
232 | + nameLabelsString += escapeSpacesInAndOrNot(replaceWithMathLatex(labelsInName[i])); |
233 | + nameLabelsString += "\\\\"; |
234 | + } |
235 | + else if(!labelsInName[i].isEmpty()){ |
236 | + nameLabelsString += escapeSpacesInAndOrNot(replaceWithMathLatex(labelsInName[i])); |
237 | + nameLabelsString += "\\\\"; |
238 | + } else { |
239 | + nameLabelsString += "\\\\"; |
240 | + } |
241 | + } |
242 | + return nameLabelsString; |
243 | + } |
244 | + |
245 | + private String escapeSpacesInAndOrNot(String str) { |
246 | + return str.replace(" and ", "\\ and\\ ").replace(" or", "\\ or\\ ").replace(" not", "\\ not\\ "); |
247 | + } |
248 | + |
249 | private void exportPlaceTokens(Place place, StringBuffer out, int numOfTokens) { |
250 | // Dot radius |
251 | final double tRadius = 1; |
252 | @@ -437,6 +395,124 @@ |
253 | } |
254 | } |
255 | |
256 | + private StringBuffer exportGlobalVariables() { |
257 | + StringBuffer out = new StringBuffer(); |
258 | + |
259 | + Context context = new Context(TAPAALGUI.getCurrentTab()); |
260 | + List<ColorType> listColorTypes = context.network().colorTypes(); |
261 | + List<Constant> constantsList = new ArrayList<>(context.network().constants()); |
262 | + List<Variable> variableList = context.network().variables(); |
263 | + |
264 | + if(!context.network().isColored()) { |
265 | + if(constantsList.isEmpty()) { |
266 | + return out; |
267 | + } |
268 | + out.append("%%Global box which contains global color types, variables and/or constants.\n"); |
269 | + out.append("\\node [globalBox] (globalBox) at (current bounding box.north west) [anchor=south west] {"); |
270 | + exportConstants(constantsList, out); |
271 | + out.append("};"); |
272 | + return out; |
273 | + } |
274 | + |
275 | + if((listColorTypes.isEmpty() && constantsList.isEmpty() && variableList.isEmpty())) |
276 | + return out; |
277 | + |
278 | + out.append("%%Global box which contains global color types, variables and/or constants.\n"); |
279 | + out.append("\\node [globalBox] (globalBox) at (current bounding box.north west) [anchor=south west] {"); |
280 | + |
281 | + exportColorTypes(listColorTypes, out); |
282 | + |
283 | + if(listColorTypes.size() > 0 && (variableList.size() > 0 || constantsList.size() > 0)) { |
284 | + out.append("\\\\"); |
285 | + } |
286 | + |
287 | + exportVariables(variableList, out); |
288 | + |
289 | + if(variableList.size() > 0 && !constantsList.isEmpty()) { |
290 | + out.append("\\\\"); |
291 | + } |
292 | + |
293 | + exportConstants(constantsList, out); |
294 | + |
295 | + out.append("};"); |
296 | + |
297 | + return out; |
298 | + } |
299 | + |
300 | + private void exportColorTypes(List<ColorType> listColorTypes, StringBuffer out) { |
301 | + String stringColorList = ""; |
302 | + for(int i = 0; i < listColorTypes.size(); i++) { |
303 | + if(i == 0) { |
304 | + out.append("Color Types:\\\\"); |
305 | + } |
306 | + out.append("$\\mathit{" + listColorTypes.get(i).getName() + "}$ \\textbf{is} "); |
307 | + |
308 | + if(listColorTypes.get(i).isProductColorType()) { |
309 | + out.append("$\\mathit{<"); |
310 | + for(int x = 0; x < listColorTypes.get(i).getProductColorTypes().size(); x++) { |
311 | + stringColorList += listColorTypes.get(i).getProductColorTypes().get(x).getName().replace("_", "\\_"); |
312 | + |
313 | + if(x != listColorTypes.get(i).getProductColorTypes().size() - 1){ |
314 | + stringColorList += ", "; |
315 | + } |
316 | + } |
317 | + out.append(stringColorList + ">}$\\\\"); |
318 | + stringColorList = ""; |
319 | + |
320 | + } else if(listColorTypes.get(i).isIntegerRange()) { |
321 | + out.append("$\\mathit{"); |
322 | + if(listColorTypes.get(i).size() > 1) { |
323 | + int listSize = listColorTypes.get(i).size(); |
324 | + out.append("[" + listColorTypes.get(i).getColors().get(0).getColorName().replace("_","\\_") + ".." + listColorTypes.get(i).getColors().get(listSize - 1).getColorName().replace("_","\\_") + "]"); |
325 | + } else { |
326 | + out.append("[" + listColorTypes.get(i).getFirstColor().getColorName().replace("_","\\_") + "]"); |
327 | + } |
328 | + out.append("}$\\\\"); |
329 | + |
330 | + } else { |
331 | + out.append("$\\mathit{["); |
332 | + for(int x = 0; x < listColorTypes.get(i).getColors().size(); x++) { |
333 | + stringColorList += listColorTypes.get(i).getColors().get(x).getName().replace("_","\\_"); |
334 | + |
335 | + if(x != listColorTypes.get(i).getColors().size() - 1){ |
336 | + stringColorList += ", "; |
337 | + } |
338 | + } |
339 | + out.append(stringColorList + "]}$\\\\"); |
340 | + stringColorList = ""; |
341 | + } |
342 | + } |
343 | + } |
344 | + |
345 | + private void exportVariables(List<Variable> variableList, StringBuffer out) { |
346 | + String result = ""; |
347 | + for(int i = 0; i < variableList.size(); i++) { |
348 | + if (i == 0) { |
349 | + result += "Variables:\\\\ "; |
350 | + } |
351 | + result += "$\\mathit{" + variableList.get(i).getName().replace("_","\\_") + " \\textbf{ in } " + variableList.get(i).getColorType().getName().replace("_","\\_") + "}$"; |
352 | + if(i != variableList.size() - 1) { |
353 | + result += "\\\\"; |
354 | + } |
355 | + } |
356 | + out.append(result); |
357 | + } |
358 | + |
359 | + private void exportConstants(List<Constant> constantsList, StringBuffer out) { |
360 | + String result = ""; |
361 | + |
362 | + for(int i = 0; i < constantsList.size(); i++) { |
363 | + if(i == 0) { |
364 | + result += "Constants:\\\\"; |
365 | + } |
366 | + result += "$\\mathit{" + constantsList.get(i).toString().replace("_","\\_") + "}$"; |
367 | + if(i != constantsList.size() - 1) { |
368 | + result += "\\\\"; |
369 | + } |
370 | + } |
371 | + out.append(result); |
372 | + } |
373 | + |
374 | protected String getTokenListStringFor(Place place) { |
375 | List<TimedToken> tokens = ((TimedPlaceComponent) place).underlyingPlace().tokens(); |
376 | |
377 | @@ -455,7 +531,7 @@ |
378 | String invariant = ""; |
379 | |
380 | if (!((TimedPlaceComponent) place).getInvariantAsString().contains("inf")) |
381 | - invariant = "$\\mathrm{" + replaceWithMathLatex(((TimedPlaceComponent) place).getInvariantAsString()) + "}$};\n"; |
382 | + invariant = replaceWithMathLatex(((TimedPlaceComponent) place).getInvariantAsString()) + "};\n"; |
383 | return invariant; |
384 | } |
385 | |
386 | @@ -480,12 +556,14 @@ |
387 | StringBuffer out = new StringBuffer(); |
388 | |
389 | out.append("\\begin{tikzpicture}[font=\\scriptsize, xscale=0.45, yscale=0.45, x=1.33pt, y=1.33pt]\n"); |
390 | - out.append("%% the figure can be scaled by changing xscale and yscale\n"); |
391 | + out.append("%% the figure can be scaled by changing xscale and yscale or the size of the x- and y-coordinates\n"); |
392 | out.append("%% positions of place/transition labels that are currently fixed to label=135 degrees\n"); |
393 | - out.append("%% can be adjusted so that they do not cover arcs\n"); |
394 | - out.append("%% similarly the curving of arcs can be done by adjusting bend left/right=XX\n"); |
395 | - out.append("%% labels may be slightly skewed compared to the tapaal drawing due to rounding.\n"); |
396 | - out.append("%% This can be adjusted by tuning the coordinates of the label\n"); |
397 | + out.append("%% these can be adjusted by adjusting either the coordinates, the label distance or the label degree\n"); |
398 | + out.append("%% that is placed right after the 'label-distance'. 90: is above (default), 180 is left, 270 is below etc.\n"); |
399 | + out.append("%% The curving of arcs can be done by adjusting bend left/right=XX\n"); |
400 | + out.append("%% labels may be slightly skewed compared to the Tapaal drawing due to rounding.\n"); |
401 | + out.append("%% This can be adjusted by tuning the coordinates of the label, or the degree (see above)\n"); |
402 | + out.append("%% The box containing global variables can also be moved by adjusting the anchor points / bounding box in the [globalBox] node at the end of the Tikz document\n"); |
403 | out.append("\\tikzstyle{arc}=[->,>=stealth,thick]\n"); |
404 | |
405 | out.append("\\tikzstyle{transportArc}=[->,>=diamond,thick]\n"); |
406 | @@ -496,39 +574,24 @@ |
407 | out.append("\\tikzstyle{every token}=[fill=white,text=black]\n"); |
408 | out.append("\\tikzstyle{sharedplace}=[place,minimum size=7.5mm,dashed,thin]\n"); |
409 | out.append("\\tikzstyle{sharedtransition}=[transition, fill opacity=0, minimum width=3.5mm, minimum height=6.5mm,dashed]\n"); |
410 | - out.append("\\tikzstyle{urgenttransition}=[place,fill=white,minimum size=2.0mm,thin]"); |
411 | - out.append("\\tikzstyle{uncontrollabletransition}=[transition,fill=white,draw=black,very thick]"); |
412 | + out.append("\\tikzstyle{urgenttransition}=[place,fill=white,minimum size=2.0mm,thin]\n"); |
413 | + out.append("\\tikzstyle{uncontrollabletransition}=[transition,fill=white,draw=black,very thick]\n"); |
414 | + out.append("\\tikzstyle{globalBox} = [draw,thick,align=left]"); |
415 | return out; |
416 | } |
417 | |
418 | protected String replaceWithMathLatex(String text) { |
419 | - return text.replace("inf", "\\infty").replace("<=", "\\leq ").replace("*", "\\cdot "); |
420 | - } |
421 | - |
422 | - private String exportMathName(String name) { |
423 | - StringBuilder out = new StringBuilder("$\\mathrm{"); |
424 | - int subscripts = 0; |
425 | - for (int i = 0; i < name.length() - 1; i++) { |
426 | - char c = name.charAt(i); |
427 | - if (c == '_') { |
428 | - out.append("_{"); |
429 | - subscripts++; |
430 | - } else { |
431 | - out.append(c); |
432 | - } |
433 | - } |
434 | - |
435 | - char last = name.charAt(name.length() - 1); |
436 | - if (last == '_') { |
437 | - out.append("\\_"); |
438 | - } else |
439 | - out.append(last); |
440 | - |
441 | - for (int i = 0; i < subscripts; i++) { |
442 | - out.append('}'); |
443 | - } |
444 | - out.append("}$"); |
445 | - return out.toString(); |
446 | - } |
447 | - |
448 | + String[] stringList = text.split(" "); |
449 | + String result = ""; |
450 | + |
451 | + for(int i = 0; i < stringList.length; i++) { |
452 | + result += "$\\mathit{" + replaceSpecialSymbols(stringList[i]) + "}$ "; |
453 | + } |
454 | + return result; |
455 | + } |
456 | + |
457 | + protected String replaceSpecialSymbols(String text) { |
458 | + return text.replace("inf", "\\infty").replace("<=", "\\leq").replace("*", "\\cdot") |
459 | + .replace("\u2192", "\\rightarrow").replace("\u221E", "\\infty"); |
460 | + } |
461 | } |