Author: stephenc Date: Wed Nov 6 14:38:02 2013 New Revision: 1539350 URL: http://svn.apache.org/r1539350 Log: [DOXIA-472] Add support for multimarkdown-style metadata section at the start of a markdown file.
Modified: maven/doxia/doxia/trunk/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java Modified: maven/doxia/doxia/trunk/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java?rev=1539350&r1=1539349&r2=1539350&view=diff ============================================================================== --- maven/doxia/doxia/trunk/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java (original) +++ maven/doxia/doxia/trunk/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java Wed Nov 6 14:38:02 2013 @@ -19,22 +19,24 @@ package org.apache.maven.doxia.module.ma * under the License. */ -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; - +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang.StringUtils; import org.apache.maven.doxia.module.xhtml.XhtmlParser; import org.apache.maven.doxia.parser.ParseException; import org.apache.maven.doxia.parser.Parser; import org.apache.maven.doxia.sink.Sink; - import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.util.IOUtil; - import org.pegdown.Extensions; import org.pegdown.PegDownProcessor; import org.pegdown.ast.RootNode; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * Implementation of {@link org.apache.maven.doxia.parser.Parser} for Markdown documents. * <p/> @@ -59,6 +61,17 @@ public class MarkdownParser protected static final PegDownProcessor PEGDOWN_PROCESSOR = new PegDownProcessor( Extensions.ALL & ~Extensions.HARDWRAPS, Long.MAX_VALUE ); + /** + * Regex that identifies a multimarkdown-style metadata section at the start of the document + */ + private static final String MULTI_MARKDOWN_METADATA_SECTION = + "^((?:[^\\s:][^:]*):(?:.*(?:\r?\n\\s[^\\s].*)*\r?\n))+(?:\\s*\r?\n)"; + + /** + * Regex that captures the key and value of a multimarkdown-style metadata entry. + */ + private static final String MULTI_MARKDOWN_METADATA_ENTRY = "([^\\s:][^:]*):(.*(?:\r?\n\\s[^\\s].*)*)\r?\n"; + /** * {@inheritDoc} @@ -69,9 +82,48 @@ public class MarkdownParser { try { - RootNode rootNode = PEGDOWN_PROCESSOR.parseMarkdown( IOUtil.toString( source ).toCharArray() ); - String markdownAsHtml = new MarkdownToDoxiaHtmlSerializer().toHtml( rootNode ); - super.parse( new StringReader( "<html><body>" + markdownAsHtml + "</body></html>" ), sink ); + String text = IOUtil.toString( source ); + StringBuilder html = new StringBuilder( text.length() * 2 ); + html.append( "<html>" ); + html.append( "<head>" ); + Pattern metadataPattern = Pattern.compile( MULTI_MARKDOWN_METADATA_SECTION, Pattern.MULTILINE ); + Matcher metadataMatcher = metadataPattern.matcher( text ); + if ( metadataMatcher.find() ) + { + metadataPattern = Pattern.compile( MULTI_MARKDOWN_METADATA_ENTRY, Pattern.MULTILINE ); + for ( int i = 1; i <= metadataMatcher.groupCount(); i++ ) + { + String line = metadataMatcher.group( i ); + Matcher lineMatcher = metadataPattern.matcher( line ); + if ( lineMatcher.matches() ) + { + String key = StringUtils.trimToEmpty( lineMatcher.group( 1 ) ); + String value = StringUtils.trimToEmpty( lineMatcher.group( 2 ) ); + if ( "title".equalsIgnoreCase( key ) ) + { + html.append( "<title>" ); + html.append( StringEscapeUtils.escapeXml( value ) ); + html.append( "</title>" ); + } + else + { + html.append( "<meta name=\'" ); + html.append( StringEscapeUtils.escapeXml( key ) ); + html.append( "\' content=\'" ); + html.append( StringEscapeUtils.escapeXml( value ) ); + html.append( "\' />" ); + } + } + } + text = text.substring( metadataMatcher.end() ); + } + html.append( "</head>" ); + html.append( "<body>" ); + RootNode rootNode = PEGDOWN_PROCESSOR.parseMarkdown( text.toCharArray() ); + html.append( new MarkdownToDoxiaHtmlSerializer().toHtml( rootNode ) ); + html.append( "</body>" ); + html.append( "</html>" ); + super.parse( new StringReader( html.toString() ), sink ); } catch ( IOException e ) {