View Javadoc

1   /*
2    * Copyright 2002 - 2009 JEuclid, http://jeuclid.sf.net
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* $Id: Mfenced.java,v 34009469c57a 2009/08/07 13:21:37 max $ */
18  
19  package net.sourceforge.jeuclid.elements.presentation.general;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import net.sourceforge.jeuclid.Constants;
25  import net.sourceforge.jeuclid.elements.AbstractElementWithDelegates;
26  import net.sourceforge.jeuclid.elements.AbstractJEuclidElement;
27  import net.sourceforge.jeuclid.elements.presentation.token.Mo;
28  import net.sourceforge.jeuclid.elements.support.operatordict.OperatorDictionary;
29  import net.sourceforge.jeuclid.layout.LayoutableNode;
30  
31  import org.apache.batik.dom.AbstractDocument;
32  import org.w3c.dom.Node;
33  import org.w3c.dom.mathml.MathMLFencedElement;
34  
35  /**
36   * The class represents the mfenced element.
37   * 
38   * @version $Revision: 34009469c57a $
39   */
40  public final class Mfenced extends AbstractElementWithDelegates implements
41          MathMLFencedElement {
42  
43      /** The separators attribute. */
44      public static final String ATTR_SEPARATORS = "separators";
45  
46      /** The close attribute. */
47      public static final String ATTR_CLOSE = "close";
48  
49      /** The open attribute. */
50      public static final String ATTR_OPEN = "open";
51  
52      /**
53       * The XML element from this class.
54       */
55      public static final String ELEMENT = "mfenced";
56  
57      private static final String FENCE_SPACE = "0.2em";
58  
59      private static final long serialVersionUID = 1L;
60  
61      /**
62       * Default constructor. Sets MathML Namespace.
63       * 
64       * @param qname
65       *            Qualified name.
66       * @param odoc
67       *            Owner Document.
68       */
69      public Mfenced(final String qname, final AbstractDocument odoc) {
70          super(qname, odoc);
71          this.setDefaultMathAttribute(Mfenced.ATTR_OPEN, "(");
72          this.setDefaultMathAttribute(Mfenced.ATTR_CLOSE, ")");
73          this.setDefaultMathAttribute(Mfenced.ATTR_SEPARATORS, ",");
74      }
75  
76      /** {@inheritDoc} */
77      @Override
78      protected Node newNode() {
79          return new Mfenced(this.nodeName, this.ownerDocument);
80      }
81  
82      /**
83       * @return opening delimiter
84       */
85      public String getOpen() {
86          return this.getMathAttribute(Mfenced.ATTR_OPEN);
87      }
88  
89      /**
90       * Set the opening delimiter.
91       * 
92       * @param open
93       *            Delimiter
94       */
95      public void setOpen(final String open) {
96          this.setAttribute(Mfenced.ATTR_OPEN, open);
97      }
98  
99      /**
100      * @return Return the closing delimiter
101      */
102     public String getClose() {
103         return this.getMathAttribute(Mfenced.ATTR_CLOSE);
104     }
105 
106     /**
107      * Set the closing delimiter.
108      * 
109      * @param close
110      *            New close delimeter
111      */
112     public void setClose(final String close) {
113         this.setAttribute(Mfenced.ATTR_CLOSE, close);
114     }
115 
116     /**
117      * Return the separators.
118      * 
119      * @return separators
120      */
121     public String getSeparators() {
122         final StringBuilder retVal = new StringBuilder();
123         final String attValue = this.getMathAttribute(Mfenced.ATTR_SEPARATORS);
124         if (attValue != null) {
125             for (int i = 0; i < attValue.length(); i++) {
126                 final char c = attValue.charAt(i);
127                 if (c > AbstractJEuclidElement.TRIVIAL_SPACE_MAX) {
128                     retVal.append(c);
129                 }
130             }
131         }
132         return retVal.toString();
133     }
134 
135     /**
136      * Set the separators.
137      * 
138      * @param separators
139      *            New separators
140      */
141     public void setSeparators(final String separators) {
142         this.setAttribute(Mfenced.ATTR_SEPARATORS, separators);
143     }
144 
145     /** {@inheritDoc} */
146     @Override
147     protected List<LayoutableNode> createDelegates() {
148         final int contentCount = this.getMathElementCount();
149         final List<LayoutableNode> retVal = new ArrayList<LayoutableNode>(
150                 2 * contentCount + 1);
151 
152         final Mo opOpen = this.createFenceOperator();
153         opOpen.setForm(OperatorDictionary.FORM_PREFIX);
154         opOpen.setTextContent(this.getOpen());
155 
156         retVal.add(opOpen);
157         final String sep = this.getSeparators();
158         final boolean haveSep = (sep != null) && (sep.length() > 0);
159 
160         for (int i = 0; i < contentCount; i++) {
161             retVal.add(this.getMathElement(i));
162 
163             if (haveSep && (i < (contentCount - 1))) {
164                 final Mo opSep = (Mo) this.getOwnerDocument().createElement(
165                         Mo.ELEMENT);
166                 opSep.setSeparator(Constants.TRUE);
167                 if (i < sep.length()) {
168                     opSep.setTextContent(String.valueOf(sep.charAt(i)));
169                 } else {
170                     opSep.setTextContent(String.valueOf(sep
171                             .charAt(sep.length() - 1)));
172                 }
173                 retVal.add(opSep);
174             }
175         }
176         final Mo opClose = this.createFenceOperator();
177         opClose.setForm(OperatorDictionary.FORM_POSTFIX);
178         opClose.setTextContent(this.getClose());
179         retVal.add(opClose);
180 
181         return retVal;
182     }
183 
184     private Mo createFenceOperator() {
185         final Mo opOpen = (Mo) this.getOwnerDocument()
186                 .createElement(Mo.ELEMENT);
187         opOpen.setFence(Constants.TRUE);
188         opOpen.setStretchy(Constants.TRUE);
189         opOpen.setRspace(Mfenced.FENCE_SPACE);
190         opOpen.setLspace(Mfenced.FENCE_SPACE);
191         opOpen.setSymmetric(Constants.FALSE);
192         return opOpen;
193     }
194 
195 }