001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2001-2002 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006: This program is free software; you can redistribute it and/or modify
007: it under the terms of the GNU Lesser General Public License as published by
008: the Free Software Foundation; either version 2.1 of the License, or
009: (at your option) any later version.
010:
011: This program is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public License
017: along with this program; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package com.ecyrd.jspwiki.render;
021:
022: import java.io.IOException;
023: import java.util.ArrayList;
024: import java.util.Iterator;
025: import java.util.List;
026:
027: import org.jdom.Content;
028: import org.jdom.Element;
029: import org.jdom.Text;
030:
031: import com.ecyrd.jspwiki.WikiContext;
032: import com.ecyrd.jspwiki.parser.PluginContent;
033: import com.ecyrd.jspwiki.parser.WikiDocument;
034:
035: /**
036: * Implements DOM-to-Creole rendering.
037: * <p>
038: * FIXME: This class is not yet completely done.
039: *
040: * @author Janne Jalkanen
041: */
042: public class CreoleRenderer extends WikiRenderer {
043: private static final String IMG_START = "{{";
044: private static final String IMG_END = "}}";
045: private static final String PLUGIN_START = "<<";
046: private static final String PLUGIN_END = ">>";
047: private static final String HREF_START = "[[";
048: private static final String HREF_DELIMITER = "|";
049: private static final String HREF_END = "]]";
050: private static final String PRE_START = "{{{";
051: private static final String PRE_END = "}}}";
052: private static final String PLUGIN_IMAGE = "Image";
053: private static final String PARAM_SRC = "src";
054: private static final String HREF_ATTRIBUTE = "href";
055: private static final String ONE_SPACE = " ";
056: private static final String EMPTY_STRING = "";
057: private static final String LINEBREAK = "\n";
058: private static final String LI = "li";
059: private static final String UL = "ul";
060: private static final String OL = "ol";
061: private static final String P = "p";
062: private static final String A = "a";
063: private static final String PRE = "pre";
064:
065: /**
066: * Contains element, start markup, end markup
067: */
068: private static final String[] ELEMENTS = { "i", "//", "//", "b",
069: "**", "**", "h2", "== ", " ==", "h3", "=== ", " ===", "h4",
070: "==== ", " ====", "hr", "----", EMPTY_STRING, "tt",
071: "<<{{>>", "<<}}>>" };
072:
073: private int m_listCount = 0;
074: private char m_listChar = 'x';
075:
076: private List m_plugins = new ArrayList();
077:
078: public CreoleRenderer(WikiContext ctx, WikiDocument doc) {
079: super (ctx, doc);
080: }
081:
082: /**
083: * Renders an element into the StringBuffer given
084: * @param ce
085: * @param sb
086: */
087: private void renderElement(Element ce, StringBuffer sb) {
088: String endEl = EMPTY_STRING;
089: for (int i = 0; i < ELEMENTS.length; i += 3) {
090: if (ELEMENTS[i].equals(ce.getName())) {
091: sb.append(ELEMENTS[i + 1]);
092: endEl = ELEMENTS[i + 2];
093: }
094: }
095:
096: if (UL.equals(ce.getName())) {
097: m_listCount++;
098: m_listChar = '*';
099: } else if (OL.equals(ce.getName())) {
100: m_listCount++;
101: m_listChar = '#';
102: } else if (LI.equals(ce.getName())) {
103: for (int i = 0; i < m_listCount; i++)
104: sb.append(m_listChar);
105: sb.append(ONE_SPACE);
106: } else if (A.equals(ce.getName())) {
107: String href = ce.getAttributeValue(HREF_ATTRIBUTE);
108: String text = ce.getText();
109:
110: if (href.equals(text)) {
111: sb.append(HREF_START + href + HREF_END);
112: } else {
113: sb.append(HREF_START + href + HREF_DELIMITER + text
114: + HREF_END);
115: }
116: // Do not render anything else
117: return;
118: } else if (PRE.equals(ce.getName())) {
119: sb.append(PRE_START);
120: sb.append(ce.getText());
121: sb.append(PRE_END);
122:
123: return;
124: }
125:
126: //
127: // Go through the children
128: //
129: for (Iterator i = ce.getContent().iterator(); i.hasNext();) {
130: Content c = (Content) i.next();
131:
132: if (c instanceof PluginContent) {
133: PluginContent pc = (PluginContent) c;
134:
135: if (pc.getPluginName().equals(PLUGIN_IMAGE)) {
136: sb.append(IMG_START + pc.getParameter(PARAM_SRC)
137: + IMG_END);
138: } else {
139: m_plugins.add(pc);
140: sb
141: .append(PLUGIN_START + pc.getPluginName()
142: + ONE_SPACE + m_plugins.size()
143: + PLUGIN_END);
144: }
145: } else if (c instanceof Text) {
146: sb.append(((Text) c).getText());
147: } else if (c instanceof Element) {
148: renderElement((Element) c, sb);
149: }
150: }
151:
152: if (UL.equals(ce.getName()) || OL.equals(ce.getName())) {
153: m_listCount--;
154: } else if (P.equals(ce.getName())) {
155: sb.append(LINEBREAK);
156: }
157:
158: sb.append(endEl);
159: }
160:
161: public String getString() throws IOException {
162: StringBuffer sb = new StringBuffer(1000);
163:
164: Element ce = m_document.getRootElement();
165:
166: //
167: // Traverse through the entire tree of everything.
168: //
169:
170: renderElement(ce, sb);
171:
172: return sb.toString();
173: }
174:
175: }
|