📄 jspwikimarkupparser.java
字号:
* When given a link to a WikiName, we just return * a proper HTML link for it. The local link mutator * chain is also called. */ private Element makeCamelCaseLink( String wikiname ) { String matchedLink; callMutatorChain( m_localLinkMutatorChain, wikiname ); if( (matchedLink = linkExists( wikiname )) != null ) { makeLink( READ, matchedLink, wikiname, null, null ); } else { makeLink( EDIT, wikiname, wikiname, null, null ); } return m_currentElement; } /** Holds the image URL for the duration of this parser */ private String m_outlinkImageURL = null; /** * Returns an element for the external link image (out.png). However, * this method caches the URL for the lifetime of this MarkupParser, * because it's commonly used, and we'll end up with possibly hundreds * our thousands of references to it... It's a lot faster, too. * * @return An element containing the HTML for the outlink image. */ private Element outlinkImage() { Element el = null; if( m_useOutlinkImage ) { if( m_outlinkImageURL == null ) { m_outlinkImageURL = m_context.getURL( WikiContext.NONE, OUTLINK_IMAGE ); } el = new Element("img").setAttribute("class", "outlink"); el.setAttribute( "src", m_outlinkImageURL ); el.setAttribute("alt",""); } return el; } /** * Takes an URL and turns it into a regular wiki link. Unfortunately, * because of the way that flushPlainText() works, it already encodes * all of the XML entities. But so does WikiContext.getURL(), so we * have to do a reverse-replace here, so that it can again be replaced in makeLink. * <p> * What a crappy problem. * * @param url * @return An anchor Element containing the link. */ private Element makeDirectURILink( String url ) { Element result; String last = null; if( url.endsWith(",") || url.endsWith(".") ) { last = url.substring( url.length()-1 ); url = url.substring( 0, url.length()-1 ); } callMutatorChain( m_externalLinkMutatorChain, url ); if( isImageLink( url ) ) { result = handleImageLink( StringUtils.replace(url,"&","&"), url, false ); } else { result = makeLink( EXTERNAL, StringUtils.replace(url,"&","&"), url, null, null ); addElement( outlinkImage() ); } if( last != null ) { m_plainTextBuf.append(last); } return result; } /** * Image links are handled differently: * 1. If the text is a WikiName of an existing page, * it gets linked. * 2. If the text is an external link, then it is inlined. * 3. Otherwise it becomes an ALT text. * * @param reallink The link to the image. * @param link Link text portion, may be a link to somewhere else. * @param hasLinkText If true, then the defined link had a link text available. * This means that the link text may be a link to a wiki page, * or an external resource. */ // FIXME: isExternalLink() is called twice. private Element handleImageLink( String reallink, String link, boolean hasLinkText ) { String possiblePage = MarkupParser.cleanLink( link ); if( isExternalLink( link ) && hasLinkText ) { return makeLink( IMAGELINK, reallink, link, null, null ); } else if( ( linkExists( possiblePage ) ) != null && hasLinkText ) { // System.out.println("Orig="+link+", Matched: "+matchedLink); callMutatorChain( m_localLinkMutatorChain, possiblePage ); return makeLink( IMAGEWIKILINK, reallink, link, null, null ); } else { return makeLink( IMAGE, reallink, link, null, null ); } } private Element handleAccessRule( String ruleLine ) { if( m_wysiwygEditorMode ) { m_currentElement.addContent( "[" + ruleLine + "]" ); } if( !m_parseAccessRules ) return m_currentElement; Acl acl; WikiPage page = m_context.getRealPage(); // UserDatabase db = m_context.getEngine().getUserDatabase(); if( ruleLine.startsWith( "{" ) ) ruleLine = ruleLine.substring( 1 ); if( ruleLine.endsWith( "}" ) ) ruleLine = ruleLine.substring( 0, ruleLine.length() - 1 ); if( log.isDebugEnabled() ) log.debug("page="+page.getName()+", ACL = "+ruleLine); try { acl = m_engine.getAclManager().parseAcl( page, ruleLine ); page.setAcl( acl ); if( log.isDebugEnabled() ) log.debug( acl.toString() ); } catch( WikiSecurityException wse ) { return makeError( wse.getMessage() ); } return m_currentElement; } /** * Handles metadata setting [{SET foo=bar}] */ private Element handleMetadata( String link ) { if( m_wysiwygEditorMode ) { m_currentElement.addContent( "[" + link + "]" ); } try { String args = link.substring( link.indexOf(' '), link.length()-1 ); String name = args.substring( 0, args.indexOf('=') ); String val = args.substring( args.indexOf('=')+1, args.length() ); name = name.trim(); val = val.trim(); if( val.startsWith("'") ) val = val.substring( 1 ); if( val.endsWith("'") ) val = val.substring( 0, val.length()-1 ); // log.debug("SET name='"+name+"', value='"+val+"'."); if( name.length() > 0 && val.length() > 0 ) { val = m_engine.getVariableManager().expandVariables( m_context, val ); m_context.getPage().setAttribute( name, val ); } } catch( Exception e ) { ResourceBundle rb = m_context.getBundle(InternationalizationManager.CORE_BUNDLE); Object[] args = { link }; return makeError( MessageFormat.format( rb.getString( "markupparser.error.invalidset" ), args ) ); } return m_currentElement; } /** * Emits a processing instruction that will disable markup escaping. This is * very useful if you want to emit HTML directly into the stream. * */ private void disableOutputEscaping() { addElement( new ProcessingInstruction(Result.PI_DISABLE_OUTPUT_ESCAPING, "") ); } /** * Gobbles up all hyperlinks that are encased in square brackets. */ private Element handleHyperlinks( String linktext, int pos ) { ResourceBundle rb = m_context.getBundle(InternationalizationManager.CORE_BUNDLE); StringBuilder sb = new StringBuilder(linktext.length()+80); if( isAccessRule( linktext ) ) { return handleAccessRule( linktext ); } if( isMetadata( linktext ) ) { return handleMetadata( linktext ); } if( PluginManager.isPluginLink( linktext ) ) { try { PluginContent pluginContent = m_engine.getPluginManager().parsePluginLine( m_context, linktext, pos ); // // This might sometimes fail, especially if there is something which looks // like a plugin invocation but is really not. // if( pluginContent != null ) { addElement( pluginContent ); pluginContent.executeParse( m_context ); } } catch( PluginException e ) { log.info( "Failed to insert plugin: "+e.getMessage() ); //log.info( "Root cause:",e.getRootThrowable() ); if( !m_wysiwygEditorMode ) { ResourceBundle rbPlugin = m_context.getBundle(WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE); Object[] args = { e.getMessage() }; return addElement( makeError( MessageFormat.format( rbPlugin.getString( "plugin.error.insertionfailed" ), args ) ) ); } } return m_currentElement; } try { LinkParser.Link link = m_linkParser.parse(linktext); linktext = link.getText(); String linkref = link.getReference(); // // Yes, we now have the components separated. // linktext = the text the link should have // linkref = the url or page name. // // In many cases these are the same. [linktext|linkref]. // if( VariableManager.isVariableLink( linktext ) ) { Content el = new VariableContent(linktext); addElement( el ); } else if( isExternalLink( linkref ) ) { // It's an external link, out of this Wiki callMutatorChain( m_externalLinkMutatorChain, linkref ); if( isImageLink( linkref ) ) { handleImageLink( linkref, linktext, link.hasReference() ); } else { makeLink( EXTERNAL, linkref, linktext, null, link.getAttributes() ); addElement( outlinkImage() ); } } else if( link.isInterwikiLink() ) { // It's an interwiki link // InterWiki links also get added to external link chain // after the links have been resolved. // FIXME: There is an interesting issue here: We probably should // URLEncode the wikiPage, but we can't since some of the // Wikis use slashes (/), which won't survive URLEncoding. // Besides, we don't know which character set the other Wiki // is using, so you'll have to write the entire name as it appears // in the URL. Bugger. String extWiki = link.getExternalWiki(); String wikiPage = link.getExternalWikiPage(); if( m_wysiwygEditorMode ) { makeLink( INTERWIKI, extWiki + ":" + wikiPage, linktext, null, link.getAttributes() ); } else { String urlReference = m_engine.getInterWikiURL( extWiki ); if( urlReference != null ) { urlReference = TextUtil.replaceString( urlReference, "%s", wikiPage ); urlReference = callMutatorChain( m_externalLinkMutatorChain, urlReference ); if( isImageLink(urlReference) ) { handleImageLink( urlReference, linktext, link.hasReference() ); } else { makeLink( INTERWIKI, urlReference, linktext, null, link.getAttributes() ); } if( isExternalLink(urlReference) ) { addElement( outlinkImage() ); } } else { Object[] args = { extWiki }; addElement( makeError( MessageFormat.format( rb.getString( "markupparser.error.nointerwikiref" ), args ) ) ); } } } else if( linkref.startsWith("#") ) { // It defines a local footnote makeLink( LOCAL, linkref, linktext, null, link.getAttributes() ); } else if( TextUtil.isNumber( linkref ) ) { // It defines a reference to a local footnote makeLink( LOCALREF, linkref, linktext, null, link.getAttributes() ); } else { int hashMark = -1; // // Internal wiki link, but is it an attachment link? // String attachment = findAttachment( linkref ); if( attachment != null ) { callMutatorChain( m_attachmentLinkMutatorChain, attachment ); if( isImageLink( linkref ) ) { attachment = m_context.getURL( WikiContext.ATTACH, attachment ); sb.append( handleImageLink( attachment, linktext, link.hasReference() ) ); } else { makeLink( ATTACHMENT, attachment, linktext, null, link.getAttributes() ); } } else if( (hashMark = linkref.indexOf('#')) != -1 ) { // It's an internal Wiki link, but to a named section String namedSection = linkref.substring( hashMark+1 ); linkref = linkref.substring( 0, hashMark ); linkref = MarkupParser.cleanLink( linkref ); callMutatorChain( m_localLinkMutatorChain, linkref ); String matchedLink; if( (matchedLink = linkExists( linkref )) != null ) { String sectref = "section-"+m_engine.encodeName(matchedLink)+"-"+wikifyLink(namedSection); sectref = sectref.replace('%', '_'); makeLink( READ, matchedLink, linktext, sectref, link.getAttributes() ); } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -