Source code for hed.schema.schema_io.schema2wiki
"""Allows output of HedSchema objects as MEDIAWIKI format"""
import pandas as pd
from hed.schema.hed_schema_constants import HedSectionKey
from hed.schema.schema_io import wiki_constants, df_constants
from hed.schema.schema_io.schema2base import Schema2Base
[docs]
class Schema2Wiki(Schema2Base):
"""Converts a HedSchema to MediaWiki-format text output."""
def __init__(self):
super().__init__()
self.current_tag_string = ""
self.current_tag_extra = ""
# =========================================
# Required baseclass function
# =========================================
def _initialize_output(self):
self.current_tag_string = ""
self.current_tag_extra = ""
self.output = []
def _output_header(self, attributes):
hed_attrib_string = self._get_attribs_string_from_schema(attributes)
self.current_tag_string = f"{wiki_constants.HEADER_LINE_STRING} {hed_attrib_string}"
self._flush_current_tag()
def _output_prologue(self, prologue):
self._add_blank_line()
self.current_tag_string = wiki_constants.PROLOGUE_SECTION_ELEMENT
self._flush_current_tag()
if prologue:
self.current_tag_string += prologue
self._flush_current_tag()
def _output_annotations(self, hed_schema):
pass
def _output_extras(self, hed_schema):
"""Add additional sections if needed.
Parameters:
hed_schema (H: The schema object to output.
This is a placeholder for any additional output that needs to be done after the main sections.
"""
# In the base class, we do nothing, but subclasses can override this method.
self._output_extra(hed_schema, df_constants.SOURCES_KEY, wiki_constants.SOURCES_SECTION_ELEMENT)
self._output_extra(hed_schema, df_constants.PREFIXES_KEY, wiki_constants.PREFIXES_SECTION_ELEMENT)
self._output_extra(
hed_schema, df_constants.EXTERNAL_ANNOTATION_KEY, wiki_constants.EXTERNAL_ANNOTATION_SECTION_ELEMENT
)
def _output_extra(self, hed_schema, section_key, wiki_key):
"""Add additional section if needed.
Parameters:
hed_schema (HedSchema): The schema object to output.
section_key (string): The key in the extras dictionary of the schema.
wiki_key (string): The key in the wiki constants for the section.
"""
extra = hed_schema.get_extras(section_key)
if extra is None or extra.empty:
return
self._add_blank_line()
self.current_tag_string = wiki_key
self._flush_current_tag()
for _, row in extra.iterrows():
self.current_tag_string += "*"
# Build column string from all columns
column_strings = []
for col in extra.columns:
if pd.notna(row[col]) and row[col] != "":
column_strings.append(f"{col}={row[col]}")
self.current_tag_extra = ",".join(column_strings)
self._flush_current_tag()
def _output_epilogue(self, epilogue):
self._add_blank_line()
self.current_tag_string = wiki_constants.EPILOGUE_SECTION_ELEMENT
self._flush_current_tag()
self.current_tag_string += epilogue
self._flush_current_tag()
def _output_footer(self):
self._add_blank_line()
self.current_tag_string = wiki_constants.END_HED_STRING
self._flush_current_tag()
def _start_section(self, key_class):
self._add_blank_line()
self.current_tag_string += wiki_constants.wiki_section_headers[key_class]
self._flush_current_tag()
def _end_tag_section(self):
self._add_blank_line()
self._add_blank_line()
self.current_tag_string = wiki_constants.END_SCHEMA_STRING
self._flush_current_tag()
def _end_units_section(self):
pass
def _end_section(self, section_key):
pass
def _write_tag_entry(self, tag_entry, parent_node=None, level=0):
tag = tag_entry.name
if level == 0:
if "/" in tag:
tag = tag_entry.short_tag_name
self._add_blank_line()
self.current_tag_string += f"'''{tag}'''"
else:
short_tag = tag.split("/")[-1]
tab_char = "" # GitHub mangles these, so remove spacing for now.
# takes value tags should appear after the nowiki tag.
if short_tag.endswith("#"):
self.current_tag_string += f"{tab_char * level}{'*' * level} "
self.current_tag_extra += short_tag + " "
else:
self.current_tag_string += f"{tab_char * level}{'*' * level} {short_tag}"
self.current_tag_extra += self._format_props_and_desc(tag_entry)
self._flush_current_tag()
def _write_entry(self, entry, parent_node, include_props=True):
entry_name = entry.name
depth = 1
if entry.section_key == HedSectionKey.Units:
depth = 2
self.current_tag_string += f"{'*' * depth} {entry_name}"
if include_props:
self.current_tag_extra += self._format_props_and_desc(entry)
self._flush_current_tag()
# =========================================
# Helper functions to write out lines
# =========================================
def _flush_current_tag(self):
if self.current_tag_string or self.current_tag_extra:
if self.current_tag_extra:
new_tag = f"{self.current_tag_string} <nowiki>{self.current_tag_extra}</nowiki>"
else:
new_tag = self.current_tag_string
self.output.append(new_tag)
self.current_tag_string = ""
self.current_tag_extra = ""
def _add_blank_line(self):
self.output.append("")
def _format_props_and_desc(self, schema_entry):
extras_string = ""
attribute_string = self._format_tag_attributes(schema_entry.attributes)
if attribute_string:
extras_string += f"{{{attribute_string}}}"
desc = schema_entry.description
if desc:
if attribute_string:
extras_string += " "
extras_string += f"[{desc}]"
return extras_string