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    }