Skip to content

Commit

Permalink
[STY] Improve object formatting in the glossary (#1235)
Browse files Browse the repository at this point in the history
* Improve glossary

* Update render.py

* Update render.py

* Update render.py

* More improvements.

* Update test_render.py
  • Loading branch information
tsalo authored Aug 19, 2022
1 parent 99a4f51 commit df45cee
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 40 deletions.
91 changes: 67 additions & 24 deletions tools/schemacode/bidsschematools/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from collections.abc import Mapping

import pandas as pd
import yaml
from tabulate import tabulate

from . import utils
Expand All @@ -16,6 +17,19 @@
utils.set_logger_level(lgr, os.environ.get("BIDS_SCHEMA_LOG_LEVEL", logging.INFO))
logging.basicConfig(format="%(asctime)-15s [%(levelname)8s] %(message)s")

TYPE_CONVERTER = {
"associated_data": "associated data",
"columns": "column",
"common_principles": "common principle",
"datatypes": "datatype",
"entities": "entity",
"extensions": "extension",
"formats": "format",
"metadata": "metadata",
"top_level_files": "top level file",
"suffixes": "suffix",
}


def get_relpath(src_path):
"""Retrieve relative path to the source root from the perspective of a Markdown file.
Expand Down Expand Up @@ -77,24 +91,29 @@ def make_entity_definitions(schema, src_path=None):
text = ""
for entity in entity_order:
entity_info = entity_definitions[entity]
entity_shorthand = entity_info["name"]
text += "\n"
text += "## {}".format(entity_shorthand)
text += "\n\n"
text += "Full name: {}".format(entity_info["display_name"])
text += "\n\n"
text += "Format: `{}-<{}>`".format(
entity_info["name"],
entity_info.get("format", "label"),
)
entity_text = _make_entity_definition(entity, entity_info, src_path)
text += "\n" + entity_text

return text


def _make_entity_definition(entity, entity_info, src_path):
"""Describe an entity."""
entity_shorthand = entity_info["name"]
text = ""
text += "## {}".format(entity_shorthand)
text += "\n\n"
text += f"**Full name**: {entity_info['display_name']}"
text += "\n\n"
text += f"**Format**: `{entity_info['name']}-<{entity_info.get('format', 'label')}>`"
text += "\n\n"
if "enum" in entity_info.keys():
text += f"**Allowed values**: `{'`, `'.join(entity_info['enum'])}`"
text += "\n\n"
if "enum" in entity_info.keys():
text += "Allowed values: `{}`".format("`, `".join(entity_info["enum"]))
text += "\n\n"

description = entity_info["description"]
description = description.replace("SPEC_ROOT", get_relpath(src_path))
text += "Definition: {}".format(description)
description = entity_info["description"]
description = description.replace("SPEC_ROOT", get_relpath(src_path))
text += f"**Definition**: {description}"
return text


Expand All @@ -117,14 +136,16 @@ def make_glossary(schema, src_path=None):
information about the entities in the schema.
"""
all_objects = {}
schema = schema.to_dict()

for group, group_objects in schema["objects"].items():
group_obj_keys = list(group_objects.keys())
# Remove private objects

# Do not include private objects in the glossary
group_obj_keys = [k for k in group_obj_keys if not k.startswith("_")]

# Identify multi-sense objects (multiple entries, indicated by __ in key)
multi_sense_objects = []
# Identify multi-sense objects (multiple entries, some with __ in them)
for key in group_obj_keys:
if "__" in key:
temp_key = key.split("__")[0]
Expand All @@ -149,14 +170,16 @@ def make_glossary(schema, src_path=None):
new_name = f"{new_name} ({group})"
all_objects[new_name] = {}
all_objects[new_name]["key"] = f"objects.{group}.{key}"
all_objects[new_name]["type"] = TYPE_CONVERTER.get(group, group)
all_objects[new_name]["definition"] = group_objects[key]

text = ""
for obj_key in sorted(all_objects.keys()):
obj = all_objects[obj_key]
obj_marker = obj["key"]
obj_def = obj["definition"]
obj_name = obj_def["display_name"]

# Clean up the text description
obj_desc = obj_def["description"]
# A backslash before a newline means continue a string
obj_desc = obj_desc.replace("\\\n", "")
Expand All @@ -169,11 +192,31 @@ def make_glossary(schema, src_path=None):

text += f'\n<a name="{obj_marker}"></a>'
text += f"\n## {obj_key}\n\n"
text += f"name: {obj_name}\n\n"
text += f"description:\n>{obj_desc}\n\n"

temp_obj_def = {k: v for k, v in obj_def.items() if k not in ("description", "name")}
text += f"schema information:\n```yaml\n{temp_obj_def}\n```"
text += f"**Name**: {obj_def['display_name']}\n\n"
text += f"**Type**: {obj['type'].title()}\n\n"

if obj["type"] == "suffix":
text += f"**Format**: `<entities>_{obj_def['value']}.<extension>`\n\n"
elif obj["type"] == "extension":
text += f"**Format**: `<entities>_<suffix>{obj_def['value']}`\n\n"
elif obj["type"] == "format":
text += f"**Regular expression**: `{obj_def['pattern']}`\n\n"

if "enum" in obj_def.keys():
allowed_vals = [f"`{enum}`" for enum in obj_def["enum"]]
text += f"**Allowed values**: {', '.join(allowed_vals)}\n\n"

text += f"**Description**:\n{obj_desc}\n\n"

temp_obj_def = {
k: v
for k, v in obj_def.items()
if k not in ("description", "display_name", "name", "value", "enum", "pattern")
}

if temp_obj_def:
temp_obj_def = yaml.dump(temp_obj_def)
text += f"**Schema information**:\n```yaml\n{temp_obj_def}\n```"

return text

Expand Down
32 changes: 16 additions & 16 deletions tools/schemacode/bidsschematools/tests/test_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ def test_make_entity_definitions(schema_obj):
"""
schema_text = render.make_entity_definitions(schema_obj)
expected_formats = [
"Format: `sub-<label>`",
"Format: `ses-<label>`",
"Format: `sample-<label>`",
"Format: `task-<label>`",
"Format: `acq-<label>`",
"Format: `ce-<label>`",
"Format: `trc-<label>`",
"Format: `stain-<label>`",
"Format: `rec-<label>`",
"Format: `dir-<label>`",
"Format: `run-<index>`",
"Format: `mod-<label>`",
"Format: `echo-<index>`",
"Format: `flip-<index>`",
"Format: `inv-<index>`",
"Format: `mt-<label>`",
"**Format**: `sub-<label>`",
"**Format**: `ses-<label>`",
"**Format**: `sample-<label>`",
"**Format**: `task-<label>`",
"**Format**: `acq-<label>`",
"**Format**: `ce-<label>`",
"**Format**: `trc-<label>`",
"**Format**: `stain-<label>`",
"**Format**: `rec-<label>`",
"**Format**: `dir-<label>`",
"**Format**: `run-<index>`",
"**Format**: `mod-<label>`",
"**Format**: `echo-<index>`",
"**Format**: `flip-<index>`",
"**Format**: `inv-<index>`",
"**Format**: `mt-<label>`",
]
for expected_format in expected_formats:
assert expected_format in schema_text
Expand Down

0 comments on commit df45cee

Please sign in to comment.