23andMe / Yamale

A schema and validator for YAML.
MIT License
670 stars 88 forks source link

Documentation for nodes #169

Closed erdalkaraca closed 2 years ago

erdalkaraca commented 2 years ago

Is there a way to inline documentation strings for nodes? For example:

book:
  title: str(doc='the title of the book')

I would like generate an interactive and human readable (html) doc of the schema but need to also provide brief (maybe also multiline) descriptions for each node in the schema.

mildebrandt commented 2 years ago

Hi @erdalkaraca , thanks for your interest in Yamale.

Since the schema is just another YAML file, you can put inline comments:

book:
  title: str() # the title of the book

Then you can use a parser that preserves comments (like ruamel) to parse the comments along with the attributes for your doc generation:

$ python
Python 3.9.6 (default, Jun 29 2021, 05:25:02) 
[Clang 12.0.5 (clang-1205.0.22.9)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ruamel.yaml as yaml
>>> schema_str = """
... # The schema
... book: # The book
...   title: str() # the title of the book
... """
>>> schema = yaml.round_trip_load(schema_str)
>>> schema.ca
Comment(
  start=[None, [CommentToken('# The schema\n', line: 1, col: 0)]],
  items={
    book: [None, None, CommentToken('# The book\n', line: 2, col: 6), None]
  })
>>> schema.ca.comment[1][0].value
'# The schema\n'
>>> schema['book'].ca
Comment(
  start=[CommentToken('# The book\n', line: 2, col: 6), None],
  items={
    title: [None, None, CommentToken('# the title of the book\n', line: 3, col: 15), None]
  })
>>> schema['book'].ca.comment[0].value
'# The book\n'
>>> schema['book'].ca.items['title'][2]
CommentToken('# the title of the book\n', line: 3, col: 15)
>>> schema['book'].ca.items['title'][2].value
'# the title of the book\n'

I hope that helps, good luck!

erdalkaraca commented 2 years ago

@mildebrandt thanks for the suggestion!

As I need some more flexibility, I will try implementing a preprocessor for yamale schemas with additional features (code generation for the types).

Example:

book:
  .extends: item
  title:
    .rule: str()
    .doc: >
      the title is
      a short description
      of the book
---
item:
  isbn: str()

will become:

book:
  title: str()
---
item:
  isbn: str()

So, after preprocessing, I have the meta data stripped off and stored somewhere else for further processing.

Code generation would produce something like:

class Item:
  def __init__(self):
    self.isbn : str = None

class Book(Item):
  def __init__(self):
    self.title : str = None
    """the title is
      a short description
      of the book"""
mildebrandt commented 2 years ago

I'm glad you have another route to take. I'll close this for now, but please open if you have another question.