diff --git a/CHANGELOG.md b/CHANGELOG.md index bc3b7a332..9761edb2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html), with the exception that 0.x versions can break between minor versions. +## Unreleased +### Added +- YAML front matter extension: Limited support for single and double + quoted string values (#260) + ## [0.18.2] - 2022-02-24 ### Changed - Test against Java 17 diff --git a/commonmark-ext-yaml-front-matter/src/main/java/org/commonmark/ext/front/matter/internal/YamlFrontMatterBlockParser.java b/commonmark-ext-yaml-front-matter/src/main/java/org/commonmark/ext/front/matter/internal/YamlFrontMatterBlockParser.java index e9d0901b6..2010b4f71 100644 --- a/commonmark-ext-yaml-front-matter/src/main/java/org/commonmark/ext/front/matter/internal/YamlFrontMatterBlockParser.java +++ b/commonmark-ext-yaml-front-matter/src/main/java/org/commonmark/ext/front/matter/internal/YamlFrontMatterBlockParser.java @@ -61,10 +61,11 @@ public BlockContinue tryContinue(ParserState parserState) { inLiteral = false; currentKey = matcher.group(1); currentValues = new ArrayList<>(); - if ("|".equals(matcher.group(2))) { + String value = matcher.group(2); + if ("|".equals(value)) { inLiteral = true; - } else if (!"".equals(matcher.group(2))) { - currentValues.add(matcher.group(2)); + } else if (!"".equals(value)) { + currentValues.add(parseString(value)); } return BlockContinue.atIndex(parserState.getIndex()); @@ -81,7 +82,8 @@ public BlockContinue tryContinue(ParserState parserState) { } else { matcher = REGEX_METADATA_LIST.matcher(line); if (matcher.matches()) { - currentValues.add(matcher.group(1)); + String value = matcher.group(1); + currentValues.add(parseString(value)); } } @@ -93,6 +95,24 @@ public BlockContinue tryContinue(ParserState parserState) { public void parseInlines(InlineParser inlineParser) { } + private static String parseString(String s) { + // Limited parsing of https://yaml.org/spec/1.2.2/#73-flow-scalar-styles + // We assume input is well-formed and otherwise treat it as a plain string. In a real + // parser, e.g. `'foo` would be invalid because it's missing a trailing `'`. + if (s.startsWith("'") && s.endsWith("'")) { + String inner = s.substring(1, s.length() - 1); + return inner.replace("''", "'"); + } else if (s.startsWith("\"") && s.endsWith("\"")) { + String inner = s.substring(1, s.length() - 1); + // Only support escaped `\` and `"`, nothing else. + return inner + .replace("\\\"", "\"") + .replace("\\\\", "\\"); + } else { + return s; + } + } + public static class Factory extends AbstractBlockParserFactory { @Override public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser) { diff --git a/commonmark-ext-yaml-front-matter/src/test/java/org/commonmark/ext/front/matter/YamlFrontMatterTest.java b/commonmark-ext-yaml-front-matter/src/test/java/org/commonmark/ext/front/matter/YamlFrontMatterTest.java index 251b1c15f..a5f203b97 100644 --- a/commonmark-ext-yaml-front-matter/src/test/java/org/commonmark/ext/front/matter/YamlFrontMatterTest.java +++ b/commonmark-ext-yaml-front-matter/src/test/java/org/commonmark/ext/front/matter/YamlFrontMatterTest.java @@ -30,11 +30,7 @@ public void simpleValue() { "\ngreat"; final String rendered = "
great
\n"; - YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor(); - Node document = PARSER.parse(input); - document.accept(visitor); - - Mapgreat
\n"; - YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor(); - Node document = PARSER.parse(input); - document.accept(visitor); - - Mapgreat
\n"; - YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor(); - Node document = PARSER.parse(input); - document.accept(visitor); - - Mapgreat
\n"; - YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor(); - Node document = PARSER.parse(input); - document.accept(visitor); - - Mapgreat
\n"; - YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor(); - Node document = PARSER.parse(input); - document.accept(visitor); - - Mapgreat
\n"; - YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor(); - Node document = PARSER.parse(input); - document.accept(visitor); - - Maptest
\n"; - YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor(); - Node document = PARSER.parse(input); - document.accept(visitor); - - Maphello
\ntest
\n"; - YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor(); - Node document = PARSER.parse(input); - document.accept(visitor); - - Maptest
\n"; - YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor(); - Node document = PARSER.parse(input); - document.accept(visitor); - - Map