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 }