Clover Coverage Report
Coverage timestamp: Fri May 24 2013 13:47:27 UTC
../../../../../../img/srcFileCovDistChart9.png 45% of files have more coverage
254   630   89   11.04
102   429   0.35   1.53
23     3.87  
15    
 
  Element2LatexImpl       Line # 38 68 11 97.6% 0.9756098
  Element2LatexImpl.ListType       Line # 215 0 0 - -1.0
  Element2LatexImpl.Predvar       Line # 231 11 4 100% 1.0
  Element2LatexImpl.Funvar       Line # 253 11 4 100% 1.0
  Element2LatexImpl.Predcon       Line # 275 32 13 83% 0.8301887
  Element2LatexImpl.Funcon       Line # 340 32 13 60.4% 0.6037736
  Element2LatexImpl.Var       Line # 406 22 10 92% 0.92
  Element2LatexImpl.BinaryLogical       Line # 442 12 6 100% 1.0
  Element2LatexImpl.Quantifier       Line # 479 11 9 100% 1.0
  Element2LatexImpl.Not       Line # 514 6 2 100% 1.0
  Element2LatexImpl.Class       Line # 529 9 3 100% 1.0
  Element2LatexImpl.Classlist       Line # 548 9 3 100% 1.0
  Element2LatexImpl.QuantorIntersection       Line # 567 11 4 0% 0.0
  Element2LatexImpl.QuantorUnion       Line # 590 11 4 0% 0.0
  Element2LatexImpl.Unknown       Line # 613 9 3 100% 1.0
 
  (105)
 
1    /* This file is part of the project "Hilbert II" - http://www.qedeq.org
2    *
3    * Copyright 2000-2013, Michael Meyling <mime@qedeq.org>.
4    *
5    * "Hilbert II" is free software; you can redistribute
6    * it and/or modify it under the terms of the GNU General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10    * This program 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
13    * GNU General Public License for more details.
14    */
15   
16    package org.qedeq.kernel.bo.service.control;
17   
18    import java.util.HashMap;
19    import java.util.Map;
20   
21    import org.qedeq.base.utility.StringUtility;
22    import org.qedeq.kernel.bo.common.Element2Latex;
23    import org.qedeq.kernel.bo.logic.common.ExistenceChecker;
24    import org.qedeq.kernel.bo.module.ModuleLabels;
25    import org.qedeq.kernel.se.base.list.Element;
26    import org.qedeq.kernel.se.base.list.ElementList;
27    import org.qedeq.kernel.se.base.module.FunctionDefinition;
28    import org.qedeq.kernel.se.base.module.PredicateDefinition;
29    import org.qedeq.kernel.se.dto.module.FunctionDefinitionVo;
30    import org.qedeq.kernel.se.dto.module.PredicateDefinitionVo;
31   
32   
33    /**
34    * Transfer a QEDEQ formulas into LaTeX text.
35    *
36    * @author Michael Meyling
37    */
 
38    public final class Element2LatexImpl implements Element2Latex {
39   
40    /** Knows about labels, definitions and external QEDEQ module references. */
41    private ModuleLabels labels;
42   
43    /** Maps operator strings to {@link ElementList} to LaTeX mappers. */
44    private final Map elementList2ListType = new HashMap();
45   
46    /** For mapping an unknown operator. */
47    private final ListType unknown = new Unknown();
48   
49    /** Maps predicate identifiers to {@link PredicateDefinition}s. Contains default definitions
50    * as a fallback.*/
51    private final Map backupPredicateDefinitions = new HashMap();
52   
53    /** Maps function identifiers to {@link FunctionDefinition}s. Contains default definitions. */
54    private final Map backupFunctionDefinitions = new HashMap();
55   
56    /**
57    * Constructor.
58    *
59    * @param labels Knows about labels, definitions and external QEDEQ module references.
60    */
 
61  595 toggle public Element2LatexImpl(final ModuleLabels labels) {
62  595 this.labels = labels;
63   
64  595 this.elementList2ListType.put("PREDVAR", new Predvar());
65  595 this.elementList2ListType.put("FUNVAR", new Funvar());
66  595 this.elementList2ListType.put("PREDCON", new Predcon());
67  595 this.elementList2ListType.put("FUNCON", new Funcon());
68  595 this.elementList2ListType.put("VAR", new Var());
69   
70  595 this.elementList2ListType.put("AND", new BinaryLogical("\\land"));
71  595 this.elementList2ListType.put("OR", new BinaryLogical("\\lor"));
72  595 this.elementList2ListType.put("IMPL", new BinaryLogical("\\rightarrow"));
73  595 this.elementList2ListType.put("EQUI", new BinaryLogical("\\leftrightarrow"));
74   
75  595 this.elementList2ListType.put("FORALL", new Quantifier("\\forall"));
76  595 this.elementList2ListType.put("EXISTS", new Quantifier("\\exists"));
77  595 this.elementList2ListType.put("EXISTSU", new Quantifier("\\exists!"));
78   
79  595 this.elementList2ListType.put("NOT", new Not());
80  595 this.elementList2ListType.put("CLASS", new Class());
81  595 this.elementList2ListType.put("CLASSLIST", new Classlist());
82   
83    // TODO mime 20080126: wrong spelled and not used any longer (?)
84  595 this.elementList2ListType.put("QUANTOR_INTERSECTION", new QuantorIntersection());
85  595 this.elementList2ListType.put("QUANTOR_UNION", new QuantorUnion());
86   
87  595 fillBackup();
88   
89    }
90   
91    /**
92    * Fill backup predicate list (if required modules could not be loaded, or the predicate is
93    * not yet defined.
94    */
 
95  595 toggle private void fillBackup() {
96    // logical identity operator
97  595 addBackupPredicate(ExistenceChecker.NAME_EQUAL, "2", "#1 \\ = \\ #2");
98   
99    // negation of the logical identity operator
100  595 addBackupPredicate("notEqual", "2", "#1 \\ \\neq \\ #2");
101   
102  595 addBackupPredicate("in", "2", "#1 \\in #2");
103  595 addBackupPredicate("notIn", "2", "#1 \\notin #2");
104  595 addBackupPredicate("isSet", "1", "\\mathfrak{M}(#1)");
105  595 addBackupPredicate("subclass", "2", "#1 \\ \\subseteq \\ #2");
106  595 addBackupPredicate("isOrderedPair", "1", "\\mbox{isOrderedPair}(#1)");
107  595 addBackupPredicate("isRelation", "1", "\\mathfrak{Rel}(#1)");
108  595 addBackupPredicate("isFunction", "1", "\\mathfrak{Funct}(#1)");
109   
110  595 addBackupFunction("RussellClass", "0", "\\mathfrak{Ru}");
111  595 addBackupFunction("universalClass", "0", "\\mathfrak{V}");
112  595 addBackupFunction("emptySet", "0", "\\emptyset");
113  595 addBackupFunction("union", "2", "(#1 \\cup #2)");
114  595 addBackupFunction("intersection", "2", "(#1 \\cap #2)");
115  595 addBackupFunction("complement", "1", "\\overline{#1}");
116  595 addBackupFunction("classList", "1", "\\{ #1 \\}");
117  595 addBackupFunction("classList", "2", "\\{ #1, #2 \\}");
118  595 addBackupFunction("setProduct", "1", "\\bigcap \\ #1");
119  595 addBackupFunction("setSum", "1", "\\bigcup \\ #1");
120  595 addBackupFunction("power", "1", "\\mathfrak{P}(#1)");
121  595 addBackupFunction("orderedPair", "2", "\\langle #1, #2 \\rangle");
122  595 addBackupFunction("cartesianProduct", "2", "( #1 \\times #2)");
123  595 addBackupFunction("domain", "1", "\\mathfrak{Dom}(#1)");
124  595 addBackupFunction("range", "1", "\\mathfrak{Rng}(#1)");
125  595 addBackupFunction("successor", "1", "#1'");
126   
127    }
128   
129    /**
130    * Add predicate to backup list.
131    *
132    * @param name Predicate name.
133    * @param argNumber Number of arguments.
134    * @param latexPattern This is the latex presentation. Variables are marked by "#1", "#2"
135    * and so on.
136    */
 
137  5355 toggle private void addBackupPredicate(final String name, final String argNumber,
138    final String latexPattern) {
139  5355 final String key = name + "_" + argNumber;
140  5355 final PredicateDefinitionVo predicate = new PredicateDefinitionVo();
141  5355 predicate.setArgumentNumber(argNumber);
142  5355 predicate.setName(name);
143  5355 predicate.setLatexPattern(latexPattern);
144  5355 backupPredicateDefinitions.put(key, predicate);
145    }
146   
147    /**
148    * Add function to backup list.
149    *
150    * @param name Function name.
151    * @param argNumber Number of arguments.
152    * @param latexPattern This is the LaTex presentation. Variables are marked by "#1", "#2"
153    * and so on.
154    */
 
155  9520 toggle private void addBackupFunction(final String name, final String argNumber,
156    final String latexPattern) {
157  9520 final String key = name + "_" + argNumber;
158  9520 final FunctionDefinitionVo function = new FunctionDefinitionVo();
159  9520 function.setArgumentNumber(argNumber);
160  9520 function.setName(name);
161  9520 function.setLatexPattern(latexPattern);
162  9520 backupFunctionDefinitions.put(key, function);
163    }
164   
 
165  8190 toggle public String getLatex(final Element element) {
166  8190 return getLatex(element, true);
167    }
168   
169    /**
170    * Get LaTeX element presentation.
171    *
172    * @param element Print this element.
173    * @param first First level?
174    * @return LaTeX form of element.
175    */
 
176  53287 toggle String getLatex(final Element element, final boolean first) {
177  53287 if (element == null) {
178  0 return "";
179    }
180  53287 if (element.isAtom()) {
181  10 return element.getAtom().getString();
182    }
183  53277 final ElementList list = element.getList();
184   
185  53277 ListType converter = (ListType) elementList2ListType.get(list.getOperator());
186   
187  53277 if (converter == null) {
188  4 converter = this.unknown;
189    }
190  53277 return converter.getLatex(list, first);
191   
192    }
193   
194    /**
195    * Get default definition mapping of predicate definitions. Our last hope.
196    *
197    * @return Mapping of predicate definitions.
198    */
 
199  1213 toggle Map getBackupPredicateDefinitions() {
200  1213 return this.backupPredicateDefinitions;
201    }
202   
203    /**
204    * Get default definition mapping of function definitions. Our last hope.
205    *
206    * @return Mapping of predicate definitions.
207    */
 
208  2 toggle Map getBackupFunctionDefinitions() {
209  2 return this.backupFunctionDefinitions;
210    }
211   
212    /**
213    * Describes the interface for an {@link ElementList} to LaTeX converter.
214    */
 
215    interface ListType {
216   
217    /**
218    * Transform list into LaTeX.
219    *
220    * @param list This list shall be transformed.
221    * @param first Is the resulting LaTeX formula or term at top level? If so we possibly
222    * can omit some brackets.
223    * @return LaTeX formula or term.
224    */
225    public String getLatex(ElementList list, boolean first);
226    }
227   
228    /**
229    * Transformer for a predicate variable.
230    */
 
231    class Predvar implements ListType {
 
232  20918 toggle public String getLatex(final ElementList list, final boolean first) {
233  20918 final StringBuffer buffer = new StringBuffer();
234  20918 final String identifier = list.getElement(0).getAtom().getString();
235  20918 buffer.append(identifier);
236  20918 if (list.size() > 1) {
237  2321 buffer.append("(");
238  5590 for (int i = 1; i < list.size(); i++) {
239  3269 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
240  3269 if (i + 1 < list.size()) {
241  948 buffer.append(", ");
242    }
243    }
244  2321 buffer.append(")");
245    }
246  20918 return buffer.toString();
247    }
248    }
249   
250    /**
251    * Transformer for a function variable.
252    */
 
253    class Funvar implements ListType {
 
254  141 toggle public String getLatex(final ElementList list, final boolean first) {
255  141 final StringBuffer buffer = new StringBuffer();
256  141 final String identifier = list.getElement(0).getAtom().getString();
257  141 buffer.append(identifier);
258  141 if (list.size() > 1) {
259  140 buffer.append("(");
260  293 for (int i = 1; i < list.size(); i++) {
261  153 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
262  153 if (i + 1 < list.size()) {
263  13 buffer.append(", ");
264    }
265    }
266  140 buffer.append(")");
267    }
268  141 return buffer.toString();
269    }
270    }
271   
272    /**
273    * Transformer for a predicate constant.
274    */
 
275    class Predcon implements ListType {
 
276  2315 toggle public String getLatex(final ElementList list, final boolean first) {
277  2315 final StringBuffer buffer = new StringBuffer();
278  2315 final String name = list.getElement(0).getAtom().getString();
279  2315 final int arguments = list.size() - 1;
280  2315 String identifier = name + "_" + (arguments);
281    // LATER 20060922 m31: is only working for definition name + argument number
282    // if argument length is dynamic this dosen't work
283  2315 PredicateDefinition definition = (PredicateDefinition)
284    Element2LatexImpl.this.labels.getPredicateDefinitions().get(identifier);
285  2315 if (definition == null) {
286    // try external modules
287  1249 try {
288  1249 final int external = name.indexOf(".");
289  1249 if (external >= 0) {
290  652 final String shortName = name.substring(external + 1);
291  652 identifier = shortName + "_" + (arguments);
292  652 if (Element2LatexImpl.this.labels.getReferences() != null
293    && Element2LatexImpl.this.labels.getReferences().size() > 0) {
294  652 final String label = name.substring(0, external);
295  652 final DefaultKernelQedeqBo newProp = (DefaultKernelQedeqBo)
296    Element2LatexImpl.this.labels.getReferences().getQedeqBo(label);
297  652 if (newProp != null) {
298  652 if (newProp.getExistenceChecker().predicateExists(shortName,
299    arguments)) {
300  652 definition = newProp.getLabels()
301    .getPredicate(shortName, arguments);
302    }
303    }
304    }
305    }
306    } catch (Exception e) {
307    // try failed...
308    }
309    }
310    // we try our backup
311  2315 if (definition == null) {
312  1213 definition = (PredicateDefinition) Element2LatexImpl.this.getBackupPredicateDefinitions()
313    .get(identifier);
314    }
315  2315 if (definition != null) {
316  2313 final StringBuffer define = new StringBuffer(definition.getLatexPattern());
317  6112 for (int i = list.size() - 1; i >= 1; i--) {
318  3799 StringUtility.replace(define, "#" + i, Element2LatexImpl.this.getLatex(
319    list.getElement(i), false));
320    }
321  2313 buffer.append(define);
322    } else {
323  2 buffer.append(identifier);
324  2 buffer.append("(");
325  2 for (int i = 1; i < list.size(); i++) {
326  0 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
327  0 if (i + 1 < list.size()) {
328  0 buffer.append(", ");
329    }
330    }
331  2 buffer.append(")");
332    }
333  2315 return buffer.toString();
334    }
335    }
336   
337    /**
338    * Transformer for a function constant.
339    */
 
340    class Funcon implements ListType {
341   
 
342  1538 toggle public String getLatex(final ElementList list, final boolean first) {
343  1538 final StringBuffer buffer = new StringBuffer();
344  1538 final String name = list.getElement(0).getAtom().getString();
345  1538 final int arguments = list.size() - 1;
346  1538 String identifier = name + "_" + (arguments);
347    // LATER 20060922 m31: is only working for definition name + argument number
348    // if argument length is dynamic this dosen't work
349  1538 FunctionDefinition definition = (FunctionDefinition)
350    Element2LatexImpl.this.labels.getFunctionDefinitions().get(identifier);
351  1538 if (definition == null) {
352    // try external modules
353  2 try {
354  2 final int external = name.indexOf(".");
355  2 if (external >= 0) {
356  0 final String shortName = name.substring(external + 1);
357  0 identifier = shortName + "_" + (arguments);
358  0 if (Element2LatexImpl.this.labels.getReferences() != null
359    && Element2LatexImpl.this.labels.getReferences().size() > 0) {
360  0 final String label = name.substring(0, external);
361  0 final DefaultKernelQedeqBo newProp = (DefaultKernelQedeqBo)
362    Element2LatexImpl.this.labels.getReferences().getQedeqBo(label);
363  0 if (newProp != null) {
364  0 if (newProp.getExistenceChecker().functionExists(shortName,
365    arguments)) {
366  0 definition = newProp.getLabels()
367    .getFunction(shortName, arguments);
368    }
369    }
370    }
371    }
372    } catch (Exception e) {
373    // try failed...
374    }
375    }
376    // we try our backup
377  1538 if (definition == null) {
378  2 definition = (FunctionDefinition) Element2LatexImpl.this.getBackupFunctionDefinitions()
379    .get(identifier);
380    }
381  1538 if (definition != null) {
382  1537 final StringBuffer define = new StringBuffer(definition.getLatexPattern());
383  3343 for (int i = list.size() - 1; i >= 1; i--) {
384  1806 StringUtility.replace(define, "#" + i, Element2LatexImpl.this.
385    getLatex(list.getElement(i), false));
386    }
387  1537 buffer.append(define);
388    } else {
389  1 buffer.append(identifier);
390  1 buffer.append("(");
391  1 for (int i = 1; i < list.size(); i++) {
392  0 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
393  0 if (i + 1 < list.size()) {
394  0 buffer.append(", ");
395    }
396    }
397  1 buffer.append(")");
398    }
399  1538 return buffer.toString();
400    }
401    }
402   
403    /**
404    * Transformer for a subject variable.
405    */
 
406    static class Var implements ListType {
 
407  9719 toggle public String getLatex(final ElementList list, final boolean first) {
408  9719 final String text = list.getElement(0).getAtom().getString();
409    // interpret variable identifier as number
410  9719 try {
411  9719 final int index = Integer.parseInt(text);
412  9 final String newText = "" + index;
413  9 if (!text.equals(newText) || newText.startsWith("-")) {
414  0 throw new NumberFormatException("This is no allowed number: " + text);
415    }
416  9 switch (index) {
417  2 case 1:
418  2 return "x";
419  1 case 2:
420  1 return "y";
421  1 case 3:
422  1 return "z";
423  1 case 4:
424  1 return "u";
425  1 case 5:
426  1 return "v";
427  1 case 6:
428  1 return "w";
429  2 default:
430  2 return "x_" + (index - 6);
431    }
432    } catch (NumberFormatException e) {
433    // variable identifier is no number, just take it as it is
434  9710 return text;
435    }
436    }
437    }
438   
439    /**
440    * Transformer for a binary logical operator written in infix notation.
441    */
 
442    class BinaryLogical implements ListType {
443   
444    /** LaTeX for operator. */
445    private final String latex;
446   
447    /**
448    * Constructor.
449    *
450    * @param latex LaTeX for operator.
451    */
 
452  2380 toggle BinaryLogical(final String latex) {
453  2380 this.latex = latex;
454    }
455   
 
456  15095 toggle public String getLatex(final ElementList list, final boolean first) {
457  15095 final StringBuffer buffer = new StringBuffer();
458  15095 final String infix = "\\ " + latex + "\\ ";
459  15095 if (!first) {
460  10036 buffer.append("(");
461    }
462    // we also handle it if it has not exactly two operands
463  45323 for (int i = 0; i < list.size(); i++) {
464  30228 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
465  30228 if (i + 1 < list.size()) {
466  15133 buffer.append(infix);
467    }
468    }
469  15095 if (!first) {
470  10036 buffer.append(")");
471    }
472  15095 return buffer.toString();
473    }
474    }
475   
476    /**
477    * Transformer for a quantifier operator.
478    */
 
479    class Quantifier implements ListType {
480   
481    /** LaTeX for quantifier. */
482    private final String latex;
483   
484    /**
485    * Constructor.
486    *
487    * @param latex LaTeX for quantifier.
488    */
 
489  1785 toggle Quantifier(final String latex) {
490  1785 this.latex = latex;
491    }
492   
 
493  2068 toggle public String getLatex(final ElementList list, final boolean first) {
494  2068 final StringBuffer buffer = new StringBuffer();
495  2068 buffer.append(latex + " ");
496  6260 for (int i = 0; i < list.size(); i++) {
497  4192 if (i != 0 || (i == 0 && list.size() <= 2)) {
498  4136 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
499    }
500  4192 if (i + 1 < list.size()) {
501  2124 buffer.append("\\ ");
502    }
503  4192 if (list.size() > 2 && i == 1) {
504  56 buffer.append("\\ ");
505    }
506    }
507  2068 return buffer.toString();
508    }
509    }
510   
511    /**
512    * Transformer for negation.
513    */
 
514    class Not implements ListType {
 
515  1272 toggle public String getLatex(final ElementList list, final boolean first) {
516  1272 final StringBuffer buffer = new StringBuffer();
517  1272 final String prefix = "\\neg ";
518  1272 buffer.append(prefix);
519  2544 for (int i = 0; i < list.size(); i++) {
520  1272 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
521    }
522  1272 return buffer.toString();
523    }
524    }
525   
526    /**
527    * Transformer for a class operator.
528    */
 
529    class Class implements ListType {
 
530  204 toggle public String getLatex(final ElementList list, final boolean first) {
531  204 final StringBuffer buffer = new StringBuffer();
532  204 final String prefix = "\\{ ";
533  204 buffer.append(prefix);
534  612 for (int i = 0; i < list.size(); i++) {
535  408 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
536  408 if (i + 1 < list.size()) {
537  204 buffer.append(" \\ | \\ ");
538    }
539    }
540  204 buffer.append(" \\} ");
541  204 return buffer.toString();
542    }
543    }
544   
545    /**
546    * Transformer for class list operator.
547    */
 
548    class Classlist implements ListType {
 
549  3 toggle public String getLatex(final ElementList list, final boolean first) {
550  3 final StringBuffer buffer = new StringBuffer();
551  3 final String prefix = "\\{ ";
552  3 buffer.append(prefix);
553  12 for (int i = 0; i < list.size(); i++) {
554  9 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
555  9 if (i + 1 < list.size()) {
556  6 buffer.append(", \\ ");
557    }
558    }
559  3 buffer.append(" \\} ");
560  3 return buffer.toString();
561    }
562    }
563   
564    /**
565    * Transformer for a quantifier intersection.
566    */
 
567    class QuantorIntersection implements ListType {
 
568  0 toggle public String getLatex(final ElementList list, final boolean first) {
569  0 final StringBuffer buffer = new StringBuffer();
570  0 final String prefix = "\\bigcap";
571  0 buffer.append(prefix);
572  0 if (0 < list.size()) {
573  0 buffer.append("{").append(Element2LatexImpl.this.getLatex(list.getElement(0), false))
574    .append("}");
575    }
576  0 for (int i = 1; i < list.size(); i++) {
577  0 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
578  0 if (i + 1 < list.size()) {
579  0 buffer.append(" \\ \\ ");
580    }
581    }
582  0 buffer.append(" \\} ");
583  0 return buffer.toString();
584    }
585    }
586   
587    /**
588    * LATER mime 20080126: needed?
589    */
 
590    class QuantorUnion implements ListType {
 
591  0 toggle public String getLatex(final ElementList list, final boolean first) {
592  0 final StringBuffer buffer = new StringBuffer();
593  0 final String prefix = "\\bigcup";
594  0 buffer.append(prefix);
595  0 if (0 < list.size()) {
596  0 buffer.append("{").append(Element2LatexImpl.this.getLatex(list.getElement(0), false))
597    .append("}");
598    }
599  0 for (int i = 1; i < list.size(); i++) {
600  0 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
601  0 if (i + 1 < list.size()) {
602  0 buffer.append(" \\ \\ ");
603    }
604    }
605  0 buffer.append(" \\} ");
606  0 return buffer.toString();
607    }
608    }
609   
610    /**
611    * If we don't now what kind of type we have we do this.
612    */
 
613    class Unknown implements ListType {
 
614  4 toggle public String getLatex(final ElementList list, final boolean first) {
615  4 final StringBuffer buffer = new StringBuffer();
616  4 buffer.append(list.getOperator());
617  4 buffer.append("(");
618  16 for (int i = 0; i < list.size(); i++) {
619  12 buffer.append(Element2LatexImpl.this.getLatex(list.getElement(i), false));
620  12 if (i + 1 < list.size()) {
621  8 buffer.append(", ");
622    }
623    }
624  4 buffer.append(")");
625  4 return buffer.toString();
626    }
627    }
628   
629   
630    }