001
014
015 package com.liferay.portlet.wiki.engines.antlrwiki.translator;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.util.ArrayUtil;
020 import com.liferay.portal.kernel.util.HtmlUtil;
021 import com.liferay.portal.kernel.util.StringBundler;
022 import com.liferay.portal.kernel.util.StringPool;
023 import com.liferay.portal.kernel.util.StringUtil;
024 import com.liferay.portal.kernel.util.TreeNode;
025 import com.liferay.portal.parsers.creole.ast.CollectionNode;
026 import com.liferay.portal.parsers.creole.ast.HeadingNode;
027 import com.liferay.portal.parsers.creole.ast.ImageNode;
028 import com.liferay.portal.parsers.creole.ast.WikiPageNode;
029 import com.liferay.portal.parsers.creole.ast.extension.TableOfContentsNode;
030 import com.liferay.portal.parsers.creole.ast.link.LinkNode;
031 import com.liferay.portal.parsers.creole.visitor.impl.XhtmlTranslationVisitor;
032 import com.liferay.portlet.wiki.NoSuchPageException;
033 import com.liferay.portlet.wiki.engines.antlrwiki.translator.internal.UnformattedHeadingTextVisitor;
034 import com.liferay.portlet.wiki.engines.antlrwiki.translator.internal.UnformattedLinksTextVisitor;
035 import com.liferay.portlet.wiki.model.WikiPage;
036 import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
037
038 import java.util.List;
039
040 import javax.portlet.PortletURL;
041
042
045 public class XhtmlTranslator extends XhtmlTranslationVisitor {
046
047 public String translate(
048 WikiPage wikiPage, PortletURL viewPageURL, PortletURL editPageURL,
049 String attachmentURLPrefix, WikiPageNode wikiPageNode) {
050
051 _wikiPage = wikiPage;
052 _viewPageURL = viewPageURL;
053 _editPageURL = editPageURL;
054 _attachmentURLPrefix = attachmentURLPrefix;
055 _rootWikiPageNode = wikiPageNode;
056
057 return super.translate(wikiPageNode);
058 }
059
060 @Override
061 public void visit(HeadingNode headingNode) {
062 append("<h");
063 append(headingNode.getLevel());
064
065 String unformattedText = getUnformattedHeadingText(headingNode);
066
067 String markup = getHeadingMarkup(_wikiPage.getTitle(), unformattedText);
068
069 append(" id=\"");
070 append(markup);
071 append("\">");
072
073 traverse(headingNode.getChildASTNodes());
074
075 append("<a class=\"hashlink\" href=\"");
076
077 if (_viewPageURL != null) {
078 append(_viewPageURL.toString());
079 }
080
081 append(StringPool.POUND);
082 append(markup);
083 append("\">#</a></h");
084 append(headingNode.getLevel());
085 append(">");
086 }
087
088 @Override
089 public void visit(ImageNode imageNode) {
090 append("<img");
091
092 if (imageNode.hasAltCollectionNode()) {
093 append(" alt=\"");
094
095 CollectionNode altCollectionNode = imageNode.getAltNode();
096
097 traverse(altCollectionNode.getASTNodes());
098
099 append(StringPool.QUOTE);
100 }
101
102 append(" src=\"");
103
104 if (imageNode.isAbsoluteLink()) {
105 append(imageNode.getLink());
106 }
107 else {
108 append(_attachmentURLPrefix);
109 append(imageNode.getLink());
110 }
111
112 append("\" />");
113 }
114
115 @Override
116 public void visit(LinkNode linkNode) {
117 append("<a href=\"");
118
119 appendHref(linkNode);
120
121 append("\">");
122
123 if (linkNode.hasAltCollectionNode()) {
124 CollectionNode altCollectionNode = linkNode.getAltCollectionNode();
125
126 traverse(altCollectionNode.getASTNodes());
127 }
128 else {
129 append(HtmlUtil.escape(linkNode.getLink()));
130 }
131
132 append("</a>");
133 }
134
135 @Override
136 public void visit(TableOfContentsNode tableOfContentsNode) {
137 TableOfContentsVisitor tableOfContentsVisitor =
138 new TableOfContentsVisitor();
139
140 TreeNode<HeadingNode> tableOfContents = tableOfContentsVisitor.compose(
141 _rootWikiPageNode);
142
143 append("<div class=\"toc\">");
144 append("<div class=\"collapsebox\">");
145 append("<h4>");
146
147 String title = tableOfContentsNode.getTitle();
148
149 if (title == null) {
150 title = "Table of Contents";
151 }
152
153 append(title);
154
155 append(StringPool.NBSP);
156 append("<a class=\"toc-trigger\" href=\"javascript:;\">[-]</a></h4>");
157 append("<div class=\"toc-index\">");
158
159 appendTableOfContents(tableOfContents, 1);
160
161 append("</div>");
162 append("</div>");
163 append("</div>");
164 }
165
166 protected void appendAbsoluteHref(LinkNode linkNode) {
167 append(HtmlUtil.escape(linkNode.getLink()));
168 }
169
170 protected void appendHref(LinkNode linkNode) {
171 if (linkNode.getLink() == null) {
172 UnformattedLinksTextVisitor unformattedLinksTextVisitor =
173 new UnformattedLinksTextVisitor();
174
175 linkNode.setLink(
176 unformattedLinksTextVisitor.getUnformattedText(linkNode));
177 }
178
179 if (linkNode.isAbsoluteLink()) {
180 appendAbsoluteHref(linkNode);
181 }
182 else {
183 appendWikiHref(linkNode);
184 }
185 }
186
187 protected void appendTableOfContents(
188 TreeNode<HeadingNode> tableOfContents, int depth) {
189
190 append("<ol>");
191
192 List<TreeNode<HeadingNode>> treeNodes = tableOfContents.getChildNodes();
193
194 if (treeNodes != null) {
195 for (TreeNode<HeadingNode> treeNode : treeNodes) {
196 append("<li class=\"toc-level-");
197 append(depth);
198 append("\">");
199
200 HeadingNode headingNode = treeNode.getValue();
201
202 String content = getUnformattedHeadingText(headingNode);
203
204 append("<a class=\"wikipage\" href=\"");
205
206 if (_viewPageURL != null) {
207 append(_viewPageURL.toString());
208 }
209
210 append(StringPool.POUND);
211 append(getHeadingMarkup(_wikiPage.getTitle(), content));
212 append("\">");
213 append(content);
214 append("</a>");
215
216 appendTableOfContents(treeNode, depth + 1);
217
218 append("</li>");
219 }
220 }
221
222 append("</ol>");
223 }
224
225 protected void appendWikiHref(LinkNode linkNode) {
226 WikiPage page = null;
227
228 try {
229 page = WikiPageLocalServiceUtil.getPage(
230 _wikiPage.getNodeId(), linkNode.getLink());
231 }
232 catch (NoSuchPageException nspe) {
233 }
234 catch (Exception e) {
235 _log.error(e, e);
236 }
237
238 String attachmentLink = searchLinkInAttachments(linkNode);
239
240 if (attachmentLink != null) {
241
242
243
244 append(_attachmentURLPrefix + attachmentLink);
245
246 return;
247 }
248
249 String pageTitle = linkNode.getLink();
250
251 if ((page != null) && (_viewPageURL != null)) {
252 _viewPageURL.setParameter("title", pageTitle);
253
254 append(_viewPageURL.toString());
255
256 _viewPageURL.setParameter("title", _wikiPage.getTitle());
257 }
258 else if (_editPageURL != null) {
259 _editPageURL.setParameter("title", pageTitle);
260
261 append(_editPageURL.toString());
262
263 _editPageURL.setParameter("title", _wikiPage.getTitle());
264 }
265 }
266
267 protected String getHeadingMarkup(String prefix, String text) {
268 StringBundler sb = new StringBundler(5);
269
270 sb.append(_HEADING_ANCHOR_PREFIX);
271 sb.append(prefix);
272 sb.append(StringPool.DASH);
273 sb.append(text.trim());
274
275 return StringUtil.replace(
276 sb.toString(), StringPool.SPACE, StringPool.PLUS);
277 }
278
279 protected String getUnformattedHeadingText(HeadingNode headingNode) {
280 UnformattedHeadingTextVisitor unformattedHeadingTextVisitor =
281 new UnformattedHeadingTextVisitor();
282
283 return unformattedHeadingTextVisitor.getUnformattedText(headingNode);
284 }
285
286 protected String searchLinkInAttachments(LinkNode linkNode) {
287 String[] attachments = null;
288
289 try {
290 attachments = _wikiPage.getAttachmentsFiles();
291 }
292 catch (Exception e) {
293 return null;
294 }
295
296 String link =
297 StringPool.SLASH + _wikiPage.getAttachmentsDir() +
298 StringPool.SLASH + linkNode.getLink();
299
300 if (ArrayUtil.contains(attachments, link)) {
301 int pos = link.lastIndexOf(StringPool.SLASH);
302
303 return link.substring(pos + 1);
304 }
305
306 return null;
307 }
308
309 private static final String _HEADING_ANCHOR_PREFIX = "section-";
310
311 private static Log _log = LogFactoryUtil.getLog(XhtmlTranslator.class);
312
313 private String _attachmentURLPrefix;
314 private PortletURL _editPageURL;
315 private WikiPageNode _rootWikiPageNode;
316 private PortletURL _viewPageURL;
317 private WikiPage _wikiPage;
318
319 }