Skip to content

Support For Comments

Mihai edited this page Jun 6, 2021 · 6 revisions

Support For Comments

Comments can be added when building a YAML and they are also read, if they exist. The basic rule for comments is "The One Above", meaning the comment referring to a YAML Node is the first one above it, with the exception of Scalars: comments referring to scalars should be on the same line, right after the value.

Another special case is the comment referring to the overall YAML: this is found right at the beginning, before the start marker (---).

Building with Comments:

The following YAML:

# Project Info. This comment refers to the whole document.
---
# architects of the project
architects:
  - mihai
  - sherif
# all the contributors
developers:
  - rultor
  - salikjan
  - sherif
name: "eo-yaml" # name of the project

Can be built as follows (all the build() methods are overloaded to also accept comments):

final YamlMapping commented = Yaml.createYamlMappingBuilder()
    .add(
        "architects",
        Yaml.createYamlSequenceBuilder()
            .add("mihai")
            .add("sherif")
            .build("architects of the project")
    )
    .add(
        "developers",
        Yaml.createYamlSequenceBuilder()
            .add("rultor")
            .add("salikjan")
            .add("sherif")
            .build("all the contributors")
    )
    .add(
        "name",
        Yaml.createYamlScalarBuilder()
            .addLine("eo-yaml")
            .buildPlainScalar("name of the project")
    )
    .build("Project Info. This comment refers to the whole document.");

Reading Comments:

Put the above YAML in a file called project.yml and read it:

final YamlMapping project = Yaml.createYamlMappingReader(
    new File("project.yml")
).readYamlMapping();
final String info = project.comment().value();//"Project Info. This comment refers to the whole document."
final String arch = project.yamlSequence("architects").comment().value();//"architects of the project"
final String devs = project.yamlSequence("developers").comment().value();//"all the contributors"
final String name = project.value("name").comment().value();//"name of the project"

The comment() methods are returning a Comment which has a value() and can also tell you which node it refers to via the yamlNode() method. So if a Comment gets "lost" around your codebase, you'll always know where it came from.

Special Case: Scalar Comments

Mappings and sequences can have a single comment, the one above them. However, scalars can have two comments: one above and one inline.

# Project Info. This comment refers to the whole document.
---
# architects of the project
architects:
  - mihai
  - sherif
# all the contributors
developers:
  - rultor
  - salikjan
  - sherif
# name of the project
name: "eo-yaml" # simple name, without the repo

In this case, the two comments are concatenated with newLine:

final Comment comment = project.value("name").comment();
System.out.println(comment.value());

"name of the project
simple name, without the repo"

You can also access the two comments independently, if you cast the Comment to ScalarComment:

final ScalarComment comment = (ScalarComment) project.value("name").comment();
System.out.println(comment.above().value()); //"name of the project"
System.out.println(comment.inline().value()); //"simple name, without the repo"

Can be built as follows (all the build() methods are overloaded to also accept comments):

final YamlMapping commented = Yaml.createYamlMappingBuilder()
    .add(
        "architects",
        Yaml.createYamlSequenceBuilder()
            .add("mihai")
            .add("sherif")
            .build("architects of the project")
    )
    .add(
        "developers",
        Yaml.createYamlSequenceBuilder()
            .add("rultor")
            .add("salikjan")
            .add("sherif")
            .build("all the contributors")
    )
    .add(
        "name",
        Yaml.createYamlScalarBuilder()
            .addLine("eo-yaml")
            .buildPlainScalar(
                "name of the project",            //comment above the scalar
                "simple name, without the repo"   //comment inline with the scalar
            )
    )
    .build("Project Info. This comment refers to the whole document.");