Skip to content

Is it possible to create standalone comments? #159

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
cmoesel opened this issue Apr 24, 2020 · 5 comments
Closed

Is it possible to create standalone comments? #159

cmoesel opened this issue Apr 24, 2020 · 5 comments

Comments

@cmoesel
Copy link

cmoesel commented Apr 24, 2020

This is partially related to the above, so I hope you don't mind me asking here, but is there a way to create a standalone comment without attaching it to a specific sequence, map, or pair in the doc?

My use case is that I am generating a YAML file one field at a time based a different configuration data source. For each field, I want to either add it as a pair to the document or add a commented out pair to the document.

E.g., a very simplified example:

// assumes 'legacyConfig' var (JSON) and 'yamlDoc' var (YAML Document)
const supportedFields = ['name', 'id', 'url'];
supportedFields.forEach(f => {
  if (legacyConfig[f] != null) {
    yamlDoc.add(new Pair(f, legacyConfig[f]));
  } else {
    yamlDoc.add(new Comment(`${f}: ${f) value`)); // <-- this is what I want to do
  }
});

resulting in YAML like so (if the legacy config has only name and url):

name: Foo
#id: id value
url: http://example.org/foo

I guess I can do that today by keeping a reference to the last added pair and appending the new comment to the last added pair's comment value, but something like above would be much cleaner.

BONUS:
I'm really asking to see if anything like this exists now, but if it's something that needs to be developed, then it would be really cool if I could do something like this:

const myPair = new Pair('foo', 'bar');
myPair.commentOut = true;
doc.add(myPair);

// or

doc.add((new Pair('foo', 'bar')).commentedOut());

This would make adding commented out sections of more complex YAML even easier!

@eemeli
Copy link
Owner

eemeli commented Apr 25, 2020

Standalone comments do not currently exist in yaml at the AST level. The lower-level CST does parse comments into separate nodes, but when parsing that into the AST they're assigned to node properties. I would not recommend working with the CST for this; it's not really meant to be used to create new content.

I think the easiest way to get what you want is to extend the Pair class and override its toString(ctx, onComment, onChompKeep) method with something like this (untested code):

import { Pair } from 'yaml/types'

class CommentPair extends Pair {
  toString(ctx, onComment, onChompKeep) {
    const str = super.toString(ctx, onComment, onChompKeep)
    return str.replace(new RegExp(`^(${ctx.indent})?`, 'gm'), '$&# ')
  }
}

In case it's not clear, that should add an appropriate-indented '# ' for each line of the stringified output of Pair.toString(). Adding a CommentPair to a mapping should otherwise work exactly like normal pairs do.

@cmoesel
Copy link
Author

cmoesel commented Apr 30, 2020

I'll give that a try! Thanks!

@cmoesel
Copy link
Author

cmoesel commented May 4, 2020

Yes, I can confirm, that works well, thank you!

One note for any TypeScript users looking at this, here is the typed implementation:

class CommentPair extends Pair {
  toString(ctx: Schema.StringifyContext, onComment?: () => void, onChompKeep?: () => void) {
    // @ts-ignore the Pair (super) type doesn't declare the 3-arg toString overload
    const str = super.toString(ctx, onComment, onChompKeep);
    return str.replace(new RegExp(`^(${ctx.indent})?`, 'gm'), '$&# ');
  }
}

@eemeli - if you do any future work on types, and if this sort of use is expected to be common, you may want to consider putting the 3-arg toString overload in the type definitions.

@eemeli
Copy link
Owner

eemeli commented May 16, 2020

Closing, as the original issue is hopefully solved and the missing method typings will be included in the next release.

@eemeli eemeli closed this as completed May 16, 2020
@cmoesel
Copy link
Author

cmoesel commented May 18, 2020

Thanks again, @eemeli!

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

No branches or pull requests

2 participants