/** * Parse a raw Wiki link of the form "[[link|text]]", and return a WikiLink object representing * the link. * * @param parserInput Input configuration settings for this parser instance. * @param raw The raw Wiki link text. * @return A WikiLink object that represents the link. */ protected static WikiLink parseWikiLink( ParserInput parserInput, ParserOutput parserOutput, String raw) throws ParserException { if (StringUtils.isBlank(raw)) { return new WikiLink(); } raw = raw.trim(); String suffix = ((!raw.endsWith("]]")) ? raw.substring(raw.lastIndexOf("]]") + 2) : null); // for performance reasons use String methods rather than regex // private static final Pattern WIKI_LINK_PATTERN = // Pattern.compile("\\[\\[\\s*(\\:\\s*)?\\s*(.+?)(\\s*\\|\\s*(.+))?\\s*\\]\\]([a-z]*)"); raw = raw.substring(raw.indexOf("[[") + 2, raw.lastIndexOf("]]")).trim(); // parse in case there is a template or magic word - [[{{PAGENAME}}]] raw = JFlexParserUtil.parseFragment(parserInput, parserOutput, raw, JFlexParser.MODE_TEMPLATE); boolean colon = false; if (raw.startsWith(":")) { colon = true; raw = raw.substring(1).trim(); } String text = null; int pos = raw.indexOf('|'); if (pos != -1 && pos != (raw.length() - 1)) { text = raw.substring(pos + 1).trim(); raw = raw.substring(0, pos).trim(); } String virtualWiki = parserInput.getVirtualWiki(); WikiLink wikiLink = LinkUtil.parseWikiLink(virtualWiki, raw); if (!colon && wikiLink.getNamespace().getId().equals(Namespace.CATEGORY_ID)) { // do not set default text for categories wikiLink.setText(null); } if (wikiLink.getVirtualWiki() != null && !StringUtils.equals(wikiLink.getVirtualWiki().getName(), virtualWiki) && StringUtils.isBlank(wikiLink.getDestination())) { // use the root topic name as the destination wikiLink.setDestination(wikiLink.getVirtualWiki().getRootTopicName()); if (StringUtils.isBlank(wikiLink.getText())) { wikiLink.setText(wikiLink.getVirtualWiki().getName() + Namespace.SEPARATOR); } } if (wikiLink.getInterwiki() != null && StringUtils.isBlank(wikiLink.getDestination()) && StringUtils.isBlank(wikiLink.getText())) { wikiLink.setText(wikiLink.getInterwiki().getInterwikiPrefix() + Namespace.SEPARATOR); } wikiLink.setColon(colon); if (text != null) { wikiLink.setText(text); } if (!StringUtils.isBlank(suffix)) { wikiLink.setText(wikiLink.getText() + suffix); } return wikiLink; }
/** * Parse a raw Wiki link of the form "[[link|text]]", and return a WikiLink object representing * the link. * * @param raw The raw Wiki link text. * @return A WikiLink object that represents the link. */ protected static WikiLink parseWikiLink(String raw) { if (StringUtils.isBlank(raw)) { return new WikiLink(); } Matcher m = WIKI_LINK_PATTERN.matcher(raw.trim()); if (!m.matches()) { return new WikiLink(); } String url = m.group(2); WikiLink wikiLink = LinkUtil.parseWikiLink(url); wikiLink.setColon((m.group(1) != null)); wikiLink.setText(m.group(4)); String suffix = m.group(5); if (!StringUtils.isBlank(suffix)) { if (StringUtils.isBlank(wikiLink.getText())) { wikiLink.setText(wikiLink.getDestination() + suffix); } else { wikiLink.setText(wikiLink.getText() + suffix); } } return wikiLink; }
/** Parse a Mediawiki link of the form "[[topic|text]]" and return the resulting HTML output. */ public String parse(JFlexLexer lexer, String raw, Object... args) throws ParserException { boolean containsNestedLinks = (args.length > 0 && StringUtils.equals(args[0].toString(), "nested")); WikiLink wikiLink = JFlexParserUtil.parseWikiLink(lexer.getParserInput(), raw); if (StringUtils.isBlank(wikiLink.getDestination()) && StringUtils.isBlank(wikiLink.getSection())) { // no destination or section return raw; } if (containsNestedLinks) { // if there is a nested link it must be an image, otherwise the syntax is invalid. if (wikiLink.getColon() || !wikiLink.getNamespace().getId().equals(Namespace.FILE_ID)) { int start = raw.indexOf("[["); int end = raw.lastIndexOf("]]"); String content = raw.substring(start + "[[".length(), end); return "[[" + JFlexParserUtil.parseFragment(lexer.getParserInput(), content, lexer.getMode()) + "]]"; } } raw = this.processLinkMetadata( lexer.getParserInput(), lexer.getParserOutput(), lexer.getMode(), raw, wikiLink); if (lexer.getMode() <= JFlexParser.MODE_PREPROCESS) { // do not parse to HTML when in preprocess mode return raw; } if (!wikiLink.getColon() && wikiLink.getNamespace().getId().equals(Namespace.FILE_ID)) { // parse as an image return lexer.parse(JFlexLexer.TAG_TYPE_IMAGE_LINK, raw); } try { if (!StringUtils.isBlank(wikiLink.getInterWiki())) { // inter-wiki link return LinkUtil.interWiki(wikiLink); } String virtualWiki = lexer.getParserInput().getVirtualWiki(); if (wikiLink.getVirtualWiki() != null) { // link to another virtual wiki virtualWiki = wikiLink.getVirtualWiki().getName(); } if (StringUtils.isBlank(wikiLink.getText()) && !StringUtils.isBlank(wikiLink.getDestination())) { wikiLink.setText(wikiLink.getDestination()); if (!StringUtils.isBlank(wikiLink.getSection())) { wikiLink.setText( wikiLink.getText() + "#" + Utilities.decodeAndEscapeTopicName(wikiLink.getSection(), true)); } } else if (StringUtils.isBlank(wikiLink.getText()) && !StringUtils.isBlank(wikiLink.getSection())) { wikiLink.setText(Utilities.decodeAndEscapeTopicName("#" + wikiLink.getSection(), true)); } else { // pass a parameter via the parserInput to prevent nested links from being generated lexer.getParserInput().getTempParams().put(LINK_CAPTION, true); wikiLink.setText( JFlexParserUtil.parseFragment( lexer.getParserInput(), wikiLink.getText(), lexer.getMode())); lexer.getParserInput().getTempParams().remove(LINK_CAPTION); } if (StringUtils.equals(wikiLink.getDestination(), lexer.getParserInput().getTopicName()) && StringUtils.equals(virtualWiki, lexer.getParserInput().getVirtualWiki()) && StringUtils.isBlank(wikiLink.getSection())) { // same page, bold the text and return return "<b>" + (StringUtils.isBlank(wikiLink.getText()) ? wikiLink.getDestination() : wikiLink.getText()) + "</b>"; } // do not escape text html - already done by parser return LinkUtil.buildInternalLinkHtml( lexer.getParserInput().getContext(), virtualWiki, wikiLink, wikiLink.getText(), null, null, false); } catch (DataAccessException e) { logger.severe("Failure while parsing link " + raw, e); return ""; } catch (ParserException e) { logger.severe("Failure while parsing link " + raw, e); return ""; } }