Skip to content

Better YAML front matter parsing in commonmark-ext-yaml-front-matter - #445

Open
zyxist wants to merge 2 commits into
commonmark:mainfrom
zyxist:yaml-front-matter-extractors
Open

Better YAML front matter parsing in commonmark-ext-yaml-front-matter#445
zyxist wants to merge 2 commits into
commonmark:mainfrom
zyxist:yaml-front-matter-extractors

Conversation

@zyxist

@zyxist zyxist commented Aug 1, 2026

Copy link
Copy Markdown

Last year, I reported the issue #391 - I found some time to turn it into the contribution, based on the outcome of the discussion. I will be happy to discuss the approach and apply any improvements, if necessary.

Summary

The PR splits the YAML front matter processing into two parts:

  1. Finding front matter delimiters
  2. Processing the captured front matter content with the new concept of YamlFrontMatterExtractor.

I moved the existing built-in parser of YAML subset into one of the two extractors: YamlDataExtractor. The other extractor is YamlContentExtractor that extracts the front matter as a string for further processing with other tools.

Compatibility

The changes are backward-compatible. YamlDataExtractor is the default extractor, and one must explicitly initialize the extension with YamlContentExtractor to get the string content. The visitor and Markdown renderer support both modes.

Naming

For the existing parser, I strived to keep consistent naming to help understand the connection: YamlFrontMatterVisitor.getData() (existing method) => YamlDataExtractor.

@robinst robinst left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! I have a few things I'd like to see changed but the direction is good.

Comment thread README.md Outdated
Map<String, List<String>> frontMatter = YamlFrontMatterVisitor.readData(document);
```

Alternatively, you can use initialize the extension with `YamlContentExtractor` that saves the YAML front matter content

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo "use initialize"


import org.commonmark.node.CustomNode;

public class YamlFrontMatterContent extends CustomNode {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the existing one is called YamlFrontMatterNode. I'm not sure if just "Content" is enough to distinguish the two. What do you think about naming this one YamlFrontMatterRawContent (and the method getLiteral() (like what code blocks call their content)? Also, can you add some Javadoc here and for YamlFrontMatterNode?


import org.commonmark.parser.block.BlockContinue;

public interface YamlFrontMatterExtractor {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm not sure about calling this an "extractor", it feels like what the visitor does sounds more like extracting. We already have a good word for turning some input into nodes, which is a parser. Should we just call this FrontMatterParser?

For the name of the implementations I have similar concerns (them not being specific enough). With the above change, they would be:

  • BasicYamlParser
  • RawContentParser

(Note that the raw content parser could also be used for e.g. TOML or other syntax of front matter.)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I struggled to find the right naming here. I initially rejected "parser", because I had a very similar name YamlFrontMatterBlockParser next to it, but the term is perfect here. I will take a look :)

public interface YamlFrontMatterExtractor {
void onNextLine(YamlFrontMatterBlock block, CharSequence line);

BlockContinue onBlockEnd(YamlFrontMatterBlock block);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove the return type here, as anything else than BlockContinue.finished() doesn't make sense.

@zyxist zyxist Aug 2, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it allows the parser to handle the following use case described here, if someone needs it:

#391 (comment)

But this is a minor issue with easy workaround, so I can either simplify the interface or document the purpose in the javadoc.

import org.commonmark.parser.block.BlockContinue;

public interface YamlFrontMatterExtractor {
void onNextLine(YamlFrontMatterBlock block, CharSequence line);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change the line to SourceLine instead (which is what parserState.getLine() returns)?

/**
* Reads the YAML Front Matter metadata as a string, if the Markdown
* document has the YAML Front Matter and the extension uses
* {@link YamlContentExtractor} (default).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* {@link YamlContentExtractor} (default).
* {@link YamlContentExtractor}.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants