You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kw...@apache.org on 2023/02/02 18:59:20 UTC
[maven-doxia] branch master updated: [DOXIA-690] Improved support of metadata (both YAML front matter and MultiMarkdown) (#141)
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-doxia.git
The following commit(s) were added to refs/heads/master by this push:
new ab13591c [DOXIA-690] Improved support of metadata (both YAML front matter and MultiMarkdown) (#141)
ab13591c is described below
commit ab13591cdd02f121e90c3a0332ec2c71a1cbe531
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Thu Feb 2 19:59:14 2023 +0100
[DOXIA-690] Improved support of metadata (both YAML front matter and MultiMarkdown) (#141)
Properly support multiline values in sink and parser.
Always emit with normalized separators.
---
doxia-modules/doxia-module-markdown/pom.xml | 5 +
.../doxia/module/markdown/MarkdownParser.java | 148 +++++++++++++++------
.../maven/doxia/module/markdown/MarkdownSink.java | 25 ++--
.../module/markdown/YamlFrontMatterVisitor.java | 40 ++++++
.../doxia-module-markdown/src/site/apt/index.apt | 11 +-
.../doxia/module/markdown/MarkdownParserTest.java | 84 ++++++++++--
.../doxia/module/markdown/MarkdownSinkTest.java | 24 ++++
.../src/test/resources/metadata-yaml.md | 9 +-
.../src/test/resources/metadata.md | 5 +-
9 files changed, 288 insertions(+), 63 deletions(-)
diff --git a/doxia-modules/doxia-module-markdown/pom.xml b/doxia-modules/doxia-module-markdown/pom.xml
index b65f292a..e32ba64d 100644
--- a/doxia-modules/doxia-module-markdown/pom.xml
+++ b/doxia-modules/doxia-module-markdown/pom.xml
@@ -116,6 +116,11 @@ under the License.
<artifactId>flexmark-ext-wikilink</artifactId>
<version>${flexmarkVersion}</version>
</dependency>
+ <dependency>
+ <groupId>com.vladsch.flexmark</groupId>
+ <artifactId>flexmark-ext-yaml-front-matter</artifactId>
+ <version>${flexmarkVersion}</version>
+ </dependency>
<dependency>
<groupId>org.jetbrains</groupId>
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 2b454ed1..eb9f25d9 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
@@ -25,8 +25,14 @@ import javax.inject.Singleton;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import com.vladsch.flexmark.ast.Heading;
import com.vladsch.flexmark.ast.HtmlCommentBlock;
@@ -39,6 +45,7 @@ import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension;
import com.vladsch.flexmark.ext.tables.TablesExtension;
import com.vladsch.flexmark.ext.typographic.TypographicExtension;
import com.vladsch.flexmark.ext.wikilink.WikiLinkExtension;
+import com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.util.ast.Node;
import com.vladsch.flexmark.util.data.MutableDataSet;
@@ -76,19 +83,23 @@ public class MarkdownParser extends AbstractTextParser implements TextMarkup {
* In order to ensure that we have minimal risk of false positives when slurping metadata sections, the
* first key in the metadata section must be one of these standard keys or else the entire metadata section is
* ignored.
+ * @see <a href="https://fletcher.github.io/MultiMarkdown-5/metadata.html">Multimarkdown Metadata</a>
*/
private static final Pattern METADATA_SECTION_PATTERN = Pattern.compile(
- "\\A^\\s*"
+ "\\A^"
+ "(?:title|author|date|address|affiliation|copyright|email|keywords|language|phone|subtitle)"
- + "[ \\t]*:[ \\t]*[^\\r\\n]*[ \\t]*$[\\r\\n]+"
- + "(?:^[ \\t]*[^:\\r\\n]+[ \\t]*:[ \\t]*[^\\r\\n]*[ \\t]*$[\\r\\n]+)*",
+ + "[ \\t]*:[\\S\\s]+?^[ \\t]*$",
Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
/**
* Regex that captures the key and value of a multimarkdown-style metadata entry.
+ * Group 1 captures the key, group 2 captures the value. Multivalues are not supported in the syntax!
+ * Multiline values need to be normalized
+ * @see <a href="https://fletcher.github.io/MultiMarkdown-5/metadata.html">Multimarkdown Metadata</a>
+ *
*/
- private static final Pattern METADATA_ENTRY_PATTERN =
- Pattern.compile("^[ \\t]*([^:\\r\\n]+?)[ \\t]*:[ \\t]*([^\\r\\n]*)[ \\t]*$", Pattern.MULTILINE);
+ private static final Pattern METADATA_ENTRY_PATTERN = Pattern.compile(
+ "^([^:\\r\\n]+?)[ \\t]*:([\\S\\s]+?)(?=(?:^(?:[^:\\r\\n]+?)[ \\t]*:)|^[ \\t]*$)", Pattern.MULTILINE);
/**
* The parser of the HTML produced by Flexmark, that we will
@@ -102,6 +113,11 @@ public class MarkdownParser extends AbstractTextParser implements TextMarkup {
*/
private static final com.vladsch.flexmark.parser.Parser FLEXMARK_PARSER;
+ /**
+ * Flexmark's Markdown Metadata parser
+ */
+ private static final com.vladsch.flexmark.parser.Parser FLEXMARK_METADATA_PARSER;
+
/**
* Flexmark's HTML renderer (its output will be re-parsed and converted to Sink events)
*/
@@ -136,6 +152,12 @@ public class MarkdownParser extends AbstractTextParser implements TextMarkup {
FLEXMARK_PARSER =
com.vladsch.flexmark.parser.Parser.builder(flexmarkOptions).build();
+ MutableDataSet flexmarkMetadataOptions = new MutableDataSet();
+ flexmarkMetadataOptions.set(
+ com.vladsch.flexmark.parser.Parser.EXTENSIONS, Arrays.asList(YamlFrontMatterExtension.create()));
+ FLEXMARK_METADATA_PARSER = com.vladsch.flexmark.parser.Parser.builder(flexmarkMetadataOptions)
+ .build();
+
// Build the HTML renderer
FLEXMARK_HTML_RENDERER = HtmlRenderer.builder(flexmarkOptions)
.linkResolverFactory(new FlexmarkDoxiaLinkResolver.Factory())
@@ -156,6 +178,86 @@ public class MarkdownParser extends AbstractTextParser implements TextMarkup {
}
}
+ private boolean processMetadataForHtml(StringBuilder html, StringBuilder source) {
+ final Map<String, List<String>> metadata;
+ final int endOffset; // end of metadata within source
+ // support two types of metadata:
+ if (source.toString().startsWith("---")) {
+ // 1. YAML front matter (https://github.com/vsch/flexmark-java/wiki/Extensions#yaml-front-matter)
+ Node documentRoot = FLEXMARK_METADATA_PARSER.parse(source.toString());
+ YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor();
+ visitor.visit(documentRoot);
+ metadata = visitor.getData();
+ endOffset = visitor.getEndOffset();
+ } else {
+ // 2. Multimarkdown metadata (https://fletcher.github.io/MultiMarkdown-5/metadata.html), not yet supported
+ // by Flexmark (https://github.com/vsch/flexmark-java/issues/550)
+ metadata = new LinkedHashMap<>();
+ Matcher metadataMatcher = METADATA_SECTION_PATTERN.matcher(source);
+ if (metadataMatcher.find()) {
+ String entry = metadataMatcher.group(0) + EOL;
+ Matcher entryMatcher = METADATA_ENTRY_PATTERN.matcher(entry);
+ while (entryMatcher.find()) {
+ String key = entryMatcher.group(1);
+ String value = normalizeMultilineValue(entryMatcher.group(2));
+ metadata.put(key, Collections.singletonList(value));
+ }
+ endOffset = metadataMatcher.end(0);
+ } else {
+ endOffset = 0;
+ }
+ }
+ if (endOffset > 0) {
+ // Trim the metadata from the source
+ source.delete(0, endOffset);
+ }
+ return writeHtmlMetadata(html, metadata);
+ }
+
+ static String normalizeMultilineValue(String value) {
+ return value.trim().replaceAll("[ \\t]*[\\r\\n]+[ \\t]*", " ");
+ }
+
+ private boolean writeHtmlMetadata(StringBuilder html, Map<String, List<String>> data) {
+ boolean containsTitle = false;
+ for (Entry<String, List<String>> entry : data.entrySet()) {
+ if (writeHtmlMetadata(html, entry.getKey(), entry.getValue())) {
+ containsTitle = true;
+ }
+ }
+ return containsTitle;
+ }
+
+ private boolean writeHtmlMetadata(StringBuilder html, String key, List<String> values) {
+ if ("title".equalsIgnoreCase(key)) {
+ html.append("<title>");
+ html.append(HtmlTools.escapeHTML(values.stream().collect(Collectors.joining(", ")), false));
+ html.append("</title>");
+ return true;
+ } else {
+ if (key.equalsIgnoreCase("author") && values.size() > 1) {
+ // for multiple authors emit multiple meta tags
+ for (String value : values) {
+ writeHtmlMetadata(html, key, Collections.singletonList(value));
+ }
+ } else {
+ // every other multi-value should just be concatenated and emitted in a single meta tag
+ final String separator;
+ if (key.equalsIgnoreCase("keywords")) {
+ separator = ",";
+ } else {
+ separator = EOL;
+ }
+ html.append("<meta name='");
+ html.append(HtmlTools.escapeHTML(key));
+ html.append("' content='");
+ html.append(HtmlTools.escapeHTML(values.stream().collect(Collectors.joining(separator))));
+ html.append("' />");
+ }
+ return false;
+ }
+ }
+
/**
* uses flexmark-java library to parse content and generate HTML output.
*
@@ -165,48 +267,18 @@ public class MarkdownParser extends AbstractTextParser implements TextMarkup {
*/
String toHtml(Reader source) throws IOException {
// Read the source
- String text = IOUtil.toString(source);
+ StringBuilder markdownText = new StringBuilder(IOUtil.toString(source));
// Now, build the HTML document
StringBuilder html = new StringBuilder(1000);
html.append("<html>");
html.append("<head>");
- // detect yaml style metadata
- if (text.startsWith("---")) {
- // remove the enclosing --- to get back to classical metadata
- text = text.replaceFirst("---", "").replaceFirst("---", "");
- }
-
- // First, we interpret the "metadata" section of the document and add the corresponding HTML headers
- Matcher metadataMatcher = METADATA_SECTION_PATTERN.matcher(text);
- boolean haveTitle = false;
- if (metadataMatcher.find()) {
- Matcher entryMatcher = METADATA_ENTRY_PATTERN.matcher(metadataMatcher.group(0));
- while (entryMatcher.find()) {
- String key = entryMatcher.group(1);
- String value = entryMatcher.group(2);
- if ("title".equalsIgnoreCase(key)) {
- haveTitle = true;
- html.append("<title>");
- html.append(HtmlTools.escapeHTML(value, false));
- html.append("</title>");
- } else {
- html.append("<meta name='");
- html.append(HtmlTools.escapeHTML(key));
- html.append("' content='");
- html.append(HtmlTools.escapeHTML(value));
- html.append("' />");
- }
- }
-
- // Trim the metadata from the source
- text = text.substring(metadataMatcher.end(0));
- }
+ boolean haveTitle = processMetadataForHtml(html, markdownText);
// Now is the time to parse the Markdown document
// (after we've trimmed out the metadatas, and before we check for its headings)
- Node documentRoot = FLEXMARK_PARSER.parse(text);
+ Node documentRoot = FLEXMARK_PARSER.parse(markdownText.toString());
// Special trick: if there is no title specified as a metadata in the header, we will use the first
// heading as the document title
diff --git a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownSink.java b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownSink.java
index 740a2593..c5c7dcb1 100644
--- a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownSink.java
+++ b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/MarkdownSink.java
@@ -21,6 +21,8 @@ package org.apache.maven.doxia.module.markdown;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
@@ -50,7 +52,7 @@ public class MarkdownSink extends AbstractTextSink implements MarkdownMarkup {
private StringBuilder tableCaptionBuffer;
/** author. */
- private String author;
+ private Collection<String> authors;
/** title. */
private String title;
@@ -154,7 +156,7 @@ public class MarkdownSink extends AbstractTextSink implements MarkdownMarkup {
this.tableCaptionBuffer = new StringBuilder();
this.listNestingIndent = "";
- this.author = null;
+ this.authors = new LinkedList<>();
this.title = null;
this.date = null;
this.linkName = null;
@@ -205,21 +207,24 @@ public class MarkdownSink extends AbstractTextSink implements MarkdownMarkup {
public void head_() {
headerFlag = false;
- if (!startFlag) {
- write(EOL);
+ // only write head block if really necessary
+ if (title == null && authors.isEmpty() && date == null) {
+ return;
}
- // TODO add --- once DOXIA-617 implemented
- // write(METADATA_MARKUP + EOL);
+ write(METADATA_MARKUP + EOL);
if (title != null) {
write("title: " + title + EOL);
}
- if (author != null) {
- write("author: " + author + EOL);
+ if (!authors.isEmpty()) {
+ write("author: " + EOL);
+ for (String author : authors) {
+ write(" - " + author + EOL);
+ }
}
if (date != null) {
write("date: " + date + EOL);
}
- // write(METADATA_MARKUP + EOL);
+ write(METADATA_MARKUP + EOL);
}
/**
@@ -237,7 +242,7 @@ public class MarkdownSink extends AbstractTextSink implements MarkdownMarkup {
*/
public void author_() {
if (buffer.length() > 0) {
- author = buffer.toString();
+ authors.add(buffer.toString());
resetBuffer();
}
}
diff --git a/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/YamlFrontMatterVisitor.java b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/YamlFrontMatterVisitor.java
new file mode 100644
index 00000000..b02c156e
--- /dev/null
+++ b/doxia-modules/doxia-module-markdown/src/main/java/org/apache/maven/doxia/module/markdown/YamlFrontMatterVisitor.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.doxia.module.markdown;
+
+import com.vladsch.flexmark.ext.yaml.front.matter.AbstractYamlFrontMatterVisitor;
+import com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterBlock;
+
+public class YamlFrontMatterVisitor extends AbstractYamlFrontMatterVisitor {
+
+ int endOffset = 0;
+
+ @Override
+ public void visit(YamlFrontMatterBlock node) {
+ endOffset = node.getContentChars().getEndOffset();
+ super.visit(node);
+ }
+
+ /**
+ * @return the end of the YAML front matter metadata in the input source
+ */
+ public int getEndOffset() {
+ return endOffset;
+ }
+}
diff --git a/doxia-modules/doxia-module-markdown/src/site/apt/index.apt b/doxia-modules/doxia-module-markdown/src/site/apt/index.apt
index b896ffc9..b83bf1ca 100644
--- a/doxia-modules/doxia-module-markdown/src/site/apt/index.apt
+++ b/doxia-modules/doxia-module-markdown/src/site/apt/index.apt
@@ -30,7 +30,16 @@ doxia-module-markdown
Markdown is a popular lightweight markup language, easy to read and easy to write.
It is supported by a large panel of websites, text editors/IDEs and converter tools.
- Markdown format is only supported as Doxia source format.
+ Markdown format is supported both as source (parser) and destination (sink), the latter only since version 1.12.0.
+
+* Metadata
+
+ Although metadata was not part of the original Markdown format it is now widely supported through multiple extensions.
+ This modules supports the following two metadata formats:
+
+ * {{{http://fletcher.github.io/MultiMarkdown-5/metadata.html}MultiMarkdown Metadata}}
+
+ * {{{https://github.com/vsch/flexmark-java/wiki/Extensions#yaml-front-matter}YAML front matter}}
* References
diff --git a/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownParserTest.java b/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownParserTest.java
index c6362665..9d716de0 100644
--- a/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownParserTest.java
+++ b/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownParserTest.java
@@ -376,7 +376,69 @@ public class MarkdownParserTest extends AbstractParserTest {
*/
@Test
public void testMetadataSinkEvent() throws Exception {
- testMetadataSinkEvent("metadata");
+ List<SinkEventElement> eventList =
+ parseFileToEventTestingSink("metadata").getEventList();
+ Iterator<SinkEventElement> it = eventList.iterator();
+
+ assertSinkEquals(
+ it,
+ "head",
+ "title",
+ "text",
+ "text",
+ "text",
+ "title_",
+ "author",
+ "text",
+ "author_",
+ "date",
+ "text",
+ "date_",
+ "unknown",
+ "head_",
+ "body",
+ "section1",
+ "sectionTitle1",
+ "text",
+ "sectionTitle1_",
+ "paragraph",
+ "text",
+ "paragraph_",
+ "section2",
+ "sectionTitle2",
+ "text",
+ "sectionTitle2_",
+ "paragraph",
+ "text",
+ "paragraph_",
+ "section2_",
+ "section1_",
+ "body_");
+
+ assertFalse(it.hasNext());
+
+ // Title must be "A Title & a Test"
+ assertEquals("A Title ", eventList.get(2).getArgs()[0]);
+ assertEquals("&", eventList.get(3).getArgs()[0]);
+ assertEquals(" a 'Test'", eventList.get(4).getArgs()[0]);
+
+ // Authors on multiple lines are just normalized in terms of whitespaces (i.e. space newline space is replaced
+ // by space)
+ assertEquals(
+ "Somebody 'Nickname' Great <so...@somewhere.org>, another author",
+ eventList.get(7).getArgs()[0]);
+
+ // Date must be "2013 © Copyleft"
+ assertEquals("2013 \u00A9 Copyleft", eventList.get(10).getArgs()[0]);
+
+ // * META element must be an "unknown" Sink event that specifies:
+ // * name = "keywords" and content = "maven,doxia,markdown"
+ SinkEventElement meta = eventList.get(12);
+ assertEquals("unknown", meta.getName());
+ assertEquals("meta", meta.getArgs()[0]);
+ SinkEventAttributeSet metaAtts = (SinkEventAttributeSet) meta.getArgs()[2];
+ assertTrue(metaAtts.containsAttribute(SinkEventAttributes.NAME, "keywords"));
+ assertTrue(metaAtts.containsAttribute("content", "maven,doxia,markdown"));
}
/**
@@ -384,12 +446,10 @@ public class MarkdownParserTest extends AbstractParserTest {
*
* @throws Exception if the event list is not correct when parsing the document
*/
+ @Test
public void testMetadataYamlSinkEvent() throws Exception {
- testMetadataSinkEvent("metadata-yaml");
- }
-
- private void testMetadataSinkEvent(String doc) throws Exception {
- List<SinkEventElement> eventList = parseFileToEventTestingSink(doc).getEventList();
+ List<SinkEventElement> eventList =
+ parseFileToEventTestingSink("metadata-yaml").getEventList();
Iterator<SinkEventElement> it = eventList.iterator();
assertSinkEquals(
@@ -403,6 +463,9 @@ public class MarkdownParserTest extends AbstractParserTest {
"author",
"text",
"author_",
+ "author",
+ "text",
+ "author_",
"date",
"text",
"date_",
@@ -434,17 +497,20 @@ public class MarkdownParserTest extends AbstractParserTest {
assertEquals("&", eventList.get(3).getArgs()[0]);
assertEquals(" a 'Test'", eventList.get(4).getArgs()[0]);
- // Author must be "Somebody <so...@somewhere.org>"
+ // first author must be "Somebody <so...@somewhere.org>"
assertEquals(
"Somebody 'Nickname' Great <so...@somewhere.org>",
eventList.get(7).getArgs()[0]);
+ // second author must be "another author"
+ assertEquals("another author", eventList.get(10).getArgs()[0]);
+
// Date must be "2013 © Copyleft"
- assertEquals("2013 \u00A9 Copyleft", eventList.get(10).getArgs()[0]);
+ assertEquals("2013 \u00A9 Copyleft", eventList.get(13).getArgs()[0]);
// * META element must be an "unknown" Sink event that specifies:
// * name = "keywords" and content = "maven,doxia,markdown"
- SinkEventElement meta = eventList.get(12);
+ SinkEventElement meta = eventList.get(15);
assertEquals("unknown", meta.getName());
assertEquals("meta", meta.getArgs()[0]);
SinkEventAttributeSet metaAtts = (SinkEventAttributeSet) meta.getArgs()[2];
diff --git a/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownSinkTest.java b/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownSinkTest.java
index 4cd8b75b..cac89ac5 100644
--- a/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownSinkTest.java
+++ b/doxia-modules/doxia-module-markdown/src/test/java/org/apache/maven/doxia/module/markdown/MarkdownSinkTest.java
@@ -24,6 +24,7 @@ import org.apache.maven.doxia.markup.Markup;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.impl.AbstractSinkTest;
import org.codehaus.plexus.util.StringUtils;
+import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -340,6 +341,29 @@ public class MarkdownSinkTest extends AbstractSinkTest {
return "<!-- " + text + " -->";
}
+ @Test
+ public void testMultipleAuthors() {
+ final Sink sink = getSink();
+ sink.head();
+ sink.author();
+ sink.text("first author");
+ sink.author_();
+ sink.author();
+ sink.text("second author");
+ sink.author_();
+ sink.head_();
+ sink.flush();
+ sink.close();
+
+ String expected = MarkdownMarkup.METADATA_MARKUP + EOL
+ + "author: " + EOL
+ + " - first author" + EOL
+ + " - second author" + EOL
+ + MarkdownMarkup.METADATA_MARKUP + EOL;
+
+ assertEquals(expected, getSinkContent(), "Wrong metadata section");
+ }
+
/**
* test for DOXIA-497.
*/
diff --git a/doxia-modules/doxia-module-markdown/src/test/resources/metadata-yaml.md b/doxia-modules/doxia-module-markdown/src/test/resources/metadata-yaml.md
index 406c74ff..2f7679c6 100644
--- a/doxia-modules/doxia-module-markdown/src/test/resources/metadata-yaml.md
+++ b/doxia-modules/doxia-module-markdown/src/test/resources/metadata-yaml.md
@@ -1,8 +1,13 @@
---
title: A Title & a 'Test'
-author: Somebody 'Nickname' Great <so...@somewhere.org>
+author:
+ - Somebody 'Nickname' Great <so...@somewhere.org>
+ - another author
date: 2013 © Copyleft
-keywords: maven,doxia,markdown
+keywords:
+ - maven
+ - doxia
+ - markdown
---
# The document with look-alike header
diff --git a/doxia-modules/doxia-module-markdown/src/test/resources/metadata.md b/doxia-modules/doxia-module-markdown/src/test/resources/metadata.md
index 97ce7f11..f3ed4542 100644
--- a/doxia-modules/doxia-module-markdown/src/test/resources/metadata.md
+++ b/doxia-modules/doxia-module-markdown/src/test/resources/metadata.md
@@ -1,7 +1,6 @@
-
title: A Title & a 'Test'
-author: Somebody 'Nickname' Great <so...@somewhere.org>
-
+author: Somebody 'Nickname' Great <so...@somewhere.org>,
+another author
date: 2013 © Copyleft
keywords: maven,doxia,markdown