001
014
015 package com.liferay.portal.parsers.creole.visitor.impl;
016
017 import com.liferay.portal.kernel.util.HtmlUtil;
018 import com.liferay.portal.kernel.util.StringBundler;
019 import com.liferay.portal.kernel.util.StringPool;
020 import com.liferay.portal.parsers.creole.ast.ASTNode;
021 import com.liferay.portal.parsers.creole.ast.BoldTextNode;
022 import com.liferay.portal.parsers.creole.ast.CollectionNode;
023 import com.liferay.portal.parsers.creole.ast.ForcedEndOfLineNode;
024 import com.liferay.portal.parsers.creole.ast.FormattedTextNode;
025 import com.liferay.portal.parsers.creole.ast.HeadingNode;
026 import com.liferay.portal.parsers.creole.ast.HorizontalNode;
027 import com.liferay.portal.parsers.creole.ast.ImageNode;
028 import com.liferay.portal.parsers.creole.ast.ItalicTextNode;
029 import com.liferay.portal.parsers.creole.ast.LineNode;
030 import com.liferay.portal.parsers.creole.ast.ListNode;
031 import com.liferay.portal.parsers.creole.ast.NoWikiSectionNode;
032 import com.liferay.portal.parsers.creole.ast.OrderedListItemNode;
033 import com.liferay.portal.parsers.creole.ast.OrderedListNode;
034 import com.liferay.portal.parsers.creole.ast.ParagraphNode;
035 import com.liferay.portal.parsers.creole.ast.ScapedNode;
036 import com.liferay.portal.parsers.creole.ast.UnformattedTextNode;
037 import com.liferay.portal.parsers.creole.ast.UnorderedListItemNode;
038 import com.liferay.portal.parsers.creole.ast.UnorderedListNode;
039 import com.liferay.portal.parsers.creole.ast.WikiPageNode;
040 import com.liferay.portal.parsers.creole.ast.extension.TableOfContentsNode;
041 import com.liferay.portal.parsers.creole.ast.link.LinkNode;
042 import com.liferay.portal.parsers.creole.ast.table.TableDataNode;
043 import com.liferay.portal.parsers.creole.ast.table.TableHeaderNode;
044 import com.liferay.portal.parsers.creole.ast.table.TableNode;
045 import com.liferay.portal.parsers.creole.visitor.ASTVisitor;
046
047 import java.util.List;
048 import java.util.Stack;
049
050
053 public class XhtmlTranslationVisitor implements ASTVisitor {
054
055 public String translate(WikiPageNode wikiPageNode) {
056 _sb.setIndex(0);
057
058 visit(wikiPageNode);
059
060 return _sb.toString();
061 }
062
063 @Override
064 public void visit(BoldTextNode boldTextNode) {
065 append("<strong>");
066
067 if (boldTextNode.hasContent()) {
068 traverse(boldTextNode.getChildASTNodes());
069 }
070
071 append("</strong>");
072 }
073
074 @Override
075 public void visit(CollectionNode collectionNode) {
076 for (ASTNode astNode : collectionNode.getASTNodes()) {
077 astNode.accept(this);
078 }
079 }
080
081 @Override
082 public void visit(ForcedEndOfLineNode forcedEndOfLineNode) {
083 append("<br/>");
084 }
085
086 @Override
087 public void visit(FormattedTextNode formattedTextNode) {
088 if (formattedTextNode.getContent() != null) {
089 append(HtmlUtil.escape(formattedTextNode.getContent()));
090 }
091 else {
092 traverse(formattedTextNode.getChildASTNodes());
093 }
094 }
095
096 @Override
097 public void visit(HeadingNode headingNode) {
098 int level = headingNode.getLevel();
099
100 append("<h");
101 append(level);
102 append(">");
103
104 traverse(headingNode.getChildASTNodes());
105
106 append("</h");
107 append(level);
108 append(">");
109 }
110
111 @Override
112 public void visit(HorizontalNode horizontalNode) {
113 append("<hr/>");
114 }
115
116 @Override
117 public void visit(ImageNode imageNode) {
118 append("<img src=\"");
119 append(HtmlUtil.escape(imageNode.getLink()));
120 append("\" ");
121
122 if (imageNode.hasAltCollectionNode()) {
123 append("alt=\"");
124
125 CollectionNode altCollectionNode = imageNode.getAltNode();
126
127 traverse(altCollectionNode.getASTNodes());
128
129 append("\"");
130 }
131
132 append("/>");
133 }
134
135 @Override
136 public void visit(ItalicTextNode italicTextNode) {
137 append("<em>");
138
139 if (italicTextNode.hasContent()) {
140 traverse(italicTextNode.getChildASTNodes());
141 }
142
143 append("</em>");
144 }
145
146 @Override
147 public void visit(LineNode lineNode) {
148 traverse(lineNode.getChildASTNodes(), null, StringPool.SPACE);
149 }
150
151 @Override
152 public void visit(LinkNode linkNode) {
153 append("<a href=\"");
154 append(HtmlUtil.escape(linkNode.getLink()));
155 append("\">");
156
157 if (linkNode.hasAltCollectionNode()) {
158 CollectionNode altCollectionNode = linkNode.getAltCollectionNode();
159
160 traverse(altCollectionNode.getASTNodes());
161 }
162 else {
163 append(HtmlUtil.escape(linkNode.getLink()));
164 }
165
166 append("</a>");
167 }
168
169 @Override
170 public void visit(ListNode listNode) {
171 traverse(listNode.getChildASTNodes());
172 }
173
174 @Override
175 public void visit(NoWikiSectionNode noWikiSectionNode) {
176 append("<pre>");
177 append(HtmlUtil.escape(noWikiSectionNode.getContent()));
178 append("</pre>");
179 }
180
181 @Override
182 public void visit(OrderedListItemNode orderedListItemNode) {
183 traverse(orderedListItemNode.getChildASTNodes(), "<li>", "</li>");
184 }
185
186 @Override
187 public void visit(OrderedListNode orderedListNode) {
188 append("<ol>");
189
190 traverse(orderedListNode.getChildASTNodes());
191
192 append("</ol>");
193 }
194
195 @Override
196 public void visit(ParagraphNode paragraphNode) {
197 traverse(paragraphNode.getChildASTNodes(), "<p>", "</p>");
198 }
199
200 @Override
201 public void visit(ScapedNode scapedNode) {
202 append(HtmlUtil.escape(scapedNode.getContent()));
203 }
204
205 @Override
206 public void visit(TableDataNode tableDataNode) {
207 traverse(tableDataNode.getChildASTNodes(), "<td>", "</td>");
208 }
209
210 @Override
211 public void visit(TableHeaderNode tableHeaderNode) {
212 traverse(tableHeaderNode.getChildASTNodes(), "<th>", "</th>");
213 }
214
215 @Override
216 public void visit(TableNode tableNode) {
217 append("<table>");
218
219 traverseAndWriteForEach(tableNode.getChildASTNodes(), "<tr>", "</tr>");
220
221 append("</table>");
222 }
223
224 @Override
225 public void visit(TableOfContentsNode tableOfContentsNode) {
226 }
227
228 @Override
229 public void visit(UnformattedTextNode unformattedTextNode) {
230 if (unformattedTextNode.hasContent()) {
231 append(HtmlUtil.escape(unformattedTextNode.getContent()));
232 }
233 else {
234 traverse(unformattedTextNode.getChildASTNodes());
235 }
236 }
237
238 @Override
239 public void visit(UnorderedListItemNode unorderedListItemNode) {
240 traverse(unorderedListItemNode.getChildASTNodes(), "<li>", "</li>");
241 }
242
243 @Override
244 public void visit(UnorderedListNode unorderedListNode) {
245 append("<ul>");
246
247 traverse(unorderedListNode.getChildASTNodes());
248
249 append("</ul>");
250 }
251
252 @Override
253 public void visit(WikiPageNode wikiPageNode) {
254 traverse(wikiPageNode.getChildASTNodes());
255 }
256
257 protected void append(Object object) {
258 if (object != null) {
259 _sb.append(object);
260 }
261 }
262
263 protected void appendLevelTags(int nodeLevel, boolean ordered) {
264 int diff = nodeLevel - _currentNodeLevel.pop();
265
266 if (diff > 0) {
267 for (int i = 0; i < diff; i++) {
268 if (ordered) {
269 append("<ol>");
270 }
271 else {
272 append("<ul>");
273 }
274 }
275 }
276 else if (diff < 0) {
277 for (int i = 0; i > diff; i--) {
278 if (ordered) {
279 append("</ol>");
280 }
281 else {
282 append("</ul>");
283 }
284 }
285 }
286
287 _currentNodeLevel.push(nodeLevel);
288 }
289
290 protected void traverse(List<ASTNode> astNodes) {
291 if (astNodes != null) {
292 for (ASTNode astNode : astNodes) {
293 if (astNode != null) {
294 astNode.accept(this);
295 }
296 }
297 }
298 }
299
300 protected void traverse(List<ASTNode> astNodes, String open, String close) {
301 append(open);
302
303 traverse(astNodes);
304
305 append(close);
306 }
307
308 protected void traverseAndWriteForEach(
309 List<ASTNode> astNodes, String open, String close) {
310
311 for (ASTNode curNode : astNodes) {
312 append(open);
313
314 if (curNode != null) {
315 curNode.accept(this);
316 }
317
318 append(close);
319 }
320 }
321
322 private Stack<Integer> _currentNodeLevel = new Stack<Integer>();
323 private StringBundler _sb = new StringBundler();
324
325 }