001 /*
002 Licensed to the Apache Software Foundation (ASF) under one
003 or more contributor license agreements. See the NOTICE file
004 distributed with this work for additional information
005 regarding copyright ownership. The ASF licenses this file
006 to you under the Apache License, Version 2.0 (the
007 "License"); you may not use this file except in compliance
008 with the License. You may obtain a copy of the License at
009
010 http://www.apache.org/licenses/LICENSE-2.0
011
012 Unless required by applicable law or agreed to in writing,
013 software distributed under the License is distributed on an
014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 KIND, either express or implied. See the License for the
016 specific language governing permissions and limitations
017 under the License.
018 */
019 package org.apache.wiki.render;
020
021 import java.io.IOException;
022 import java.util.ArrayList;
023 import java.util.Iterator;
024 import java.util.List;
025
026 import org.jdom2.Content;
027 import org.jdom2.Element;
028 import org.jdom2.Text;
029
030 import org.apache.wiki.WikiContext;
031 import org.apache.wiki.parser.PluginContent;
032 import org.apache.wiki.parser.WikiDocument;
033
034 /**
035 * Implements DOM-to-Creole rendering.
036 * <p>
037 * FIXME: This class is not yet completely done.
038 *
039 */
040 public class CreoleRenderer extends WikiRenderer
041 {
042 private static final String IMG_START = "{{";
043 private static final String IMG_END = "}}";
044 private static final String PLUGIN_START = "<<";
045 private static final String PLUGIN_END = ">>";
046 private static final String HREF_START = "[[";
047 private static final String HREF_DELIMITER = "|";
048 private static final String HREF_END = "]]";
049 private static final String PRE_START = "{{{";
050 private static final String PRE_END = "}}}";
051 private static final String PLUGIN_IMAGE = "Image";
052 private static final String PARAM_SRC = "src";
053 private static final String HREF_ATTRIBUTE = "href";
054 private static final String ONE_SPACE = " ";
055 private static final String EMPTY_STRING = "";
056 private static final String LINEBREAK = "\n";
057 private static final String LI = "li";
058 private static final String UL = "ul";
059 private static final String OL = "ol";
060 private static final String P = "p";
061 private static final String A = "a";
062 private static final String PRE = "pre";
063
064 /**
065 * Contains element, start markup, end markup
066 */
067 private static final String[] ELEMENTS = {
068 "i" , "//" , "//",
069 "b" , "**" , "**",
070 "h2", "== " , " ==",
071 "h3", "=== " , " ===",
072 "h4", "==== " , " ====",
073 "hr", "----" , EMPTY_STRING,
074 "tt", "<<{{>>", "<<}}>>"
075 };
076
077 private int m_listCount = 0;
078 private char m_listChar = 'x';
079
080 private List<PluginContent> m_plugins = new ArrayList<PluginContent>();
081
082 /**
083 * Creates a new Creole Renderer.
084 *
085 */
086 public CreoleRenderer( WikiContext ctx, WikiDocument doc )
087 {
088 super( ctx, doc );
089 }
090
091 /**
092 * Renders an element into the StringBuffer given
093 * @param ce
094 * @param sb
095 */
096 private void renderElement( Element ce, StringBuffer sb )
097 {
098 String endEl = EMPTY_STRING;
099 for( int i = 0; i < ELEMENTS.length; i+=3 )
100 {
101 if( ELEMENTS[i].equals(ce.getName()) )
102 {
103 sb.append( ELEMENTS[i+1] );
104 endEl = ELEMENTS[i+2];
105 }
106 }
107
108 if( UL.equals(ce.getName()) )
109 {
110 m_listCount++;
111 m_listChar = '*';
112 }
113 else if( OL.equals(ce.getName()) )
114 {
115 m_listCount++;
116 m_listChar = '#';
117 }
118 else if( LI.equals(ce.getName()) )
119 {
120 for(int i = 0; i < m_listCount; i++ ) sb.append( m_listChar );
121 sb.append( ONE_SPACE );
122 }
123 else if( A.equals(ce.getName()) )
124 {
125 String href = ce.getAttributeValue( HREF_ATTRIBUTE );
126 String text = ce.getText();
127
128 if( href.equals(text) )
129 {
130 sb.append( HREF_START + href + HREF_END );
131 }
132 else
133 {
134 sb.append( HREF_START + href+ HREF_DELIMITER + text +HREF_END);
135 }
136 // Do not render anything else
137 return;
138 }
139 else if( PRE.equals(ce.getName()) )
140 {
141 sb.append( PRE_START );
142 sb.append( ce.getText() );
143 sb.append( PRE_END );
144
145 return;
146 }
147
148 //
149 // Go through the children
150 //
151 for( Iterator i = ce.getContent().iterator(); i.hasNext(); )
152 {
153 Content c = (Content)i.next();
154
155 if( c instanceof PluginContent )
156 {
157 PluginContent pc = (PluginContent)c;
158
159 if( pc.getPluginName().equals( PLUGIN_IMAGE ) )
160 {
161 sb.append( IMG_START + pc.getParameter( PARAM_SRC ) + IMG_END );
162 }
163 else
164 {
165 m_plugins.add(pc);
166 sb.append( PLUGIN_START + pc.getPluginName() + ONE_SPACE + m_plugins.size() + PLUGIN_END );
167 }
168 }
169 else if( c instanceof Text )
170 {
171 sb.append( ((Text)c).getText() );
172 }
173 else if( c instanceof Element )
174 {
175 renderElement( (Element)c, sb );
176 }
177 }
178
179 if( UL.equals( ce.getName() ) || OL.equals( ce.getName() ) )
180 {
181 m_listCount--;
182 }
183 else if( P.equals( ce.getName() ) )
184 {
185 sb.append( LINEBREAK );
186 }
187
188 sb.append(endEl);
189 }
190
191 /**
192 * {@inheritDoc}
193 */
194 public String getString() throws IOException
195 {
196 StringBuffer sb = new StringBuffer(1000);
197
198 Element ce = m_document.getRootElement();
199
200 //
201 // Traverse through the entire tree of everything.
202 //
203
204 renderElement( ce, sb );
205
206 return sb.toString();
207 }
208
209 }