[DOXIA-472] Add support for multimarkdown-style metadata section at the start of a markdown file.
git-svn-id: https://svn.apache.org/repos/asf/maven/doxia/doxia/trunk@1539350 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java
index 7913a2e..d46fab6 100644
--- a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java
+++ b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownParser.java
@@ -19,22 +19,24 @@
* 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 @@
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 @@
{
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 )
{