/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.wiki.engine.creole.internal.antlrwiki.translator;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.HtmlUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.TreeNode;
import com.liferay.wiki.engine.creole.internal.antlrwiki.translator.internal.UnformattedHeadingTextVisitor;
import com.liferay.wiki.engine.creole.internal.antlrwiki.translator.internal.UnformattedLinksTextVisitor;
import com.liferay.wiki.engine.creole.internal.parser.ast.CollectionNode;
import com.liferay.wiki.engine.creole.internal.parser.ast.HeadingNode;
import com.liferay.wiki.engine.creole.internal.parser.ast.ImageNode;
import com.liferay.wiki.engine.creole.internal.parser.ast.WikiPageNode;
import com.liferay.wiki.engine.creole.internal.parser.ast.extension.TableOfContentsNode;
import com.liferay.wiki.engine.creole.internal.parser.ast.link.LinkNode;
import com.liferay.wiki.engine.creole.internal.parser.visitor.XhtmlTranslationVisitor;
import com.liferay.wiki.exception.NoSuchPageException;
import com.liferay.wiki.model.WikiPage;
import com.liferay.wiki.service.WikiPageLocalServiceUtil;
import java.util.List;
import javax.portlet.PortletURL;
/**
* @author Miguel Pastor
*/
public class XhtmlTranslator extends XhtmlTranslationVisitor {
public String translate(
WikiPage page, PortletURL viewPageURL, PortletURL editPageURL,
String attachmentURLPrefix, WikiPageNode wikiPageNode) {
_page = page;
_viewPageURL = viewPageURL;
_editPageURL = editPageURL;
_attachmentURLPrefix = attachmentURLPrefix;
_rootWikiPageNode = wikiPageNode;
return super.translate(wikiPageNode);
}
@Override
public void visit(HeadingNode headingNode) {
append("<h");
append(headingNode.getLevel());
String unformattedText = getUnformattedHeadingText(headingNode);
String markup = getHeadingMarkup(_page.getTitle(), unformattedText);
append(" id=\"");
append(markup);
append("\">");
traverse(headingNode.getChildASTNodes());
append("</h");
append(headingNode.getLevel());
append(">");
}
@Override
public void visit(ImageNode imageNode) {
append("<img");
if (imageNode.hasAltCollectionNode()) {
append(" alt=\"");
CollectionNode altCollectionNode = imageNode.getAltNode();
traverse(altCollectionNode.getASTNodes());
append(StringPool.QUOTE);
}
append(" src=\"");
if (imageNode.isAbsoluteLink()) {
append(imageNode.getLink());
}
else {
append(_attachmentURLPrefix);
append(imageNode.getLink());
}
append("\" />");
}
@Override
public void visit(LinkNode linkNode) {
append("<a href=\"");
appendHref(linkNode);
append("\">");
if (linkNode.hasAltCollectionNode()) {
CollectionNode altCollectionNode = linkNode.getAltCollectionNode();
traverse(altCollectionNode.getASTNodes());
}
else {
append(HtmlUtil.escape(linkNode.getLink()));
}
append("</a>");
}
@Override
public void visit(TableOfContentsNode tableOfContentsNode) {
TableOfContentsVisitor tableOfContentsVisitor =
new TableOfContentsVisitor();
TreeNode<HeadingNode> tableOfContents = tableOfContentsVisitor.compose(
_rootWikiPageNode);
append("<div class=\"toc\">");
append("<div class=\"collapsebox\">");
append("<h4>");
String title = tableOfContentsNode.getTitle();
if (title == null) {
title = "Table of Contents";
}
append(title);
append(StringPool.NBSP);
append("<a class=\"toc-trigger\" href=\"javascript:;\">[-]</a></h4>");
append("<div class=\"toc-index\">");
appendTableOfContents(tableOfContents, 1);
append("</div>");
append("</div>");
append("</div>");
}
protected void appendAbsoluteHref(LinkNode linkNode) {
append(HtmlUtil.escape(linkNode.getLink()));
}
protected void appendHref(LinkNode linkNode) {
if (linkNode.getLink() == null) {
UnformattedLinksTextVisitor unformattedLinksTextVisitor =
new UnformattedLinksTextVisitor();
linkNode.setLink(
unformattedLinksTextVisitor.getUnformattedText(linkNode));
}
if (linkNode.isAbsoluteLink()) {
appendAbsoluteHref(linkNode);
}
else {
appendWikiHref(linkNode);
}
}
protected void appendTableOfContents(
TreeNode<HeadingNode> tableOfContents, int depth) {
List<TreeNode<HeadingNode>> treeNodes = tableOfContents.getChildNodes();
if ((treeNodes == null) || treeNodes.isEmpty()) {
return;
}
append("<ol>");
for (TreeNode<HeadingNode> treeNode : treeNodes) {
append("<li class=\"toc-level-");
append(depth);
append("\">");
HeadingNode headingNode = treeNode.getValue();
String content = getUnformattedHeadingText(headingNode);
append("<a class=\"wikipage\" href=\"");
if (_viewPageURL != null) {
String viewPageURLString = _viewPageURL.toString();
int index = viewPageURLString.indexOf(StringPool.POUND);
if (index != -1) {
viewPageURLString = viewPageURLString.substring(0, index);
}
append(viewPageURLString);
}
append(StringPool.POUND);
append(getHeadingMarkup(_page.getTitle(), content));
append("\">");
append(content);
append("</a>");
appendTableOfContents(treeNode, depth + 1);
append("</li>");
}
append("</ol>");
}
protected void appendWikiHref(LinkNode linkNode) {
WikiPage page = null;
try {
page = WikiPageLocalServiceUtil.getPage(
_page.getNodeId(), linkNode.getLink());
}
catch (NoSuchPageException nspe) {
}
catch (Exception e) {
_log.error(e, e);
}
String attachmentLink = searchLinkInAttachments(linkNode);
if (attachmentLink != null) {
// Attachment links take precedence over pages
append(_attachmentURLPrefix + attachmentLink);
return;
}
String pageTitle = linkNode.getLink();
if ((page != null) && (_viewPageURL != null)) {
_viewPageURL.setParameter("title", pageTitle);
append(_viewPageURL.toString());
_viewPageURL.setParameter("title", _page.getTitle());
}
else if (_editPageURL != null) {
_editPageURL.setParameter("title", pageTitle);
append(_editPageURL.toString());
_editPageURL.setParameter("title", _page.getTitle());
}
}
protected String getHeadingMarkup(String prefix, String text) {
StringBundler sb = new StringBundler(4);
sb.append(_HEADING_ANCHOR_PREFIX);
sb.append(prefix);
sb.append(StringPool.DASH);
sb.append(text.trim());
return StringUtil.replace(sb.toString(), CharPool.SPACE, CharPool.PLUS);
}
protected String getUnformattedHeadingText(HeadingNode headingNode) {
UnformattedHeadingTextVisitor unformattedHeadingTextVisitor =
new UnformattedHeadingTextVisitor();
return unformattedHeadingTextVisitor.getUnformattedText(headingNode);
}
protected String searchLinkInAttachments(LinkNode linkNode) {
try {
for (FileEntry fileEntry : _page.getAttachmentsFileEntries()) {
String title = fileEntry.getTitle();
if (title.equals(linkNode.getLink())) {
return title;
}
}
}
catch (Exception e) {
}
return null;
}
private static final String _HEADING_ANCHOR_PREFIX = "section-";
private static final Log _log = LogFactoryUtil.getLog(
XhtmlTranslator.class);
private String _attachmentURLPrefix;
private PortletURL _editPageURL;
private WikiPage _page;
private WikiPageNode _rootWikiPageNode;
private PortletURL _viewPageURL;
}