Skip to content

Commit

Permalink
Revert "[ENH] Link to filename element definitions in filename templa…
Browse files Browse the repository at this point in the history
…tes (#1228)"

This reverts commit ea25a5f.
  • Loading branch information
effigies authored Aug 23, 2022
1 parent ea25a5f commit fcb3c2d
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 246 deletions.
11 changes: 3 additions & 8 deletions pdf_build_src/process_markdowns.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
well.
"""

from datetime import datetime
import json
import os
import posixpath
import re
import subprocess
import sys
from datetime import datetime

import numpy as np

Expand Down Expand Up @@ -626,14 +626,9 @@ def process_macros(duplicated_src_dir_path):
# switch "use_pipe" flag OFF to render examples
if "make_filetree_example" in function_string:
function_string = function_string.replace(
")",
", False)",
")",
", False)"
)

# switch "pdf_format" ON to render filename templates
if "make_filename_template" in function_string:
function_string = function_string.replace(")", ", pdf_format=True)")

# Run the function to get the output
new = eval(function_string)
# Replace the code snippet with the function output
Expand Down
17 changes: 4 additions & 13 deletions tools/mkdocs_macros_bids/macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,12 @@ def _get_source_path(level=1):
return caller.f_locals["_Context__self"]["page"].file.src_path


def make_filename_template(pdf_format=False, **kwargs):
"""Generate a filename template snippet from the schema, based on specific filters.
def make_filename_template(**kwargs):
"""Generate a filename template snippet from the schema, based on specific
filters.
Parameters
----------
pdf_format : bool, optional
If True, the filename template will be compiled as a standard markdown code block,
without any hyperlinks, so that the specification's PDF build will look right.
If False, the filename template will use HTML and include hyperlinks.
This works on the website.
Default is False.
kwargs : dict
Keyword arguments used to filter the schema.
Example kwargs that may be used include: "suffixes", "datatypes",
Expand All @@ -84,11 +79,7 @@ def make_filename_template(pdf_format=False, **kwargs):
in the schema, after filtering.
"""
schema_obj = schema.load_schema()
codeblock = render.make_filename_template(
schema_obj,
pdf_format=pdf_format,
**kwargs,
)
codeblock = render.make_filename_template(schema_obj, **kwargs)
return codeblock


Expand Down
167 changes: 21 additions & 146 deletions tools/schemacode/bidsschematools/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from tabulate import tabulate

from . import utils
from .schema import BIDSSchemaError, Namespace, filter_schema, load_schema
from .schema import BIDSSchemaError, Namespace, filter_schema

lgr = utils.get_logger()
# Basic settings for output, for now just basic
Expand Down Expand Up @@ -239,35 +239,17 @@ def _add_entity(filename_template, entity_pattern, requirement_level):
return filename_template


def make_filename_template(
schema=None,
src_path=None,
n_dupes_to_combine=6,
pdf_format=False,
**kwargs,
):
def make_filename_template(schema, n_dupes_to_combine=6, **kwargs):
"""Create codeblocks containing example filename patterns for a given datatype.
By default, this function uses HTML, instead of direct Markdown codeblocks,
so that it can embed hyperlinks within the filenames.
Parameters
----------
schema : dict
The schema object, which is a dictionary with nested dictionaries and
lists stored within it.
src_path : str | None
The file where this macro is called, which may be explicitly provided
by the "page.file.src_path" variable.
n_dupes_to_combine : int
The minimum number of suffixes/extensions to combine in the template as
<suffix>/<extension>.
pdf_format : bool, optional
If True, the filename template will be compiled as a standard markdown code block,
without any hyperlinks, so that the specification's PDF build will look right.
If False, the filename template will use HTML and include hyperlinks.
This works on the website.
Default is False.
kwargs : dict
Keyword arguments used to filter the schema.
Example kwargs that may be used include: "suffixes", "datatypes",
Expand All @@ -278,104 +260,49 @@ def make_filename_template(
codeblock : str
A multiline string containing the filename templates for file types
in the schema, after filtering.
Notes
-----
This function doesn't use src_path, because the hyperlinks use absolute paths to HTML files.
It would be nice, at some point, to use src_path in conjunction with paths to markdown files,
like other functions do, instead.
"""
if not schema:
schema = load_schema()

schema = Namespace(filter_schema(schema.to_dict(), **kwargs))
entity_order = schema["rules"]["entities"]
entities_path = "/99-appendices/09-entities.html"
glossary_path = "/99-appendices/14-glossary.html"

paragraph = ""
# Parent directories
sub_string = (
f'{schema["objects"]["entities"]["subject"]["name"]}-'
f'<{schema["objects"]["entities"]["subject"]["format"]}>'
paragraph += "{}-<{}>/\n\t[{}-<{}>/]\n".format(
schema["objects"]["entities"]["subject"]["name"],
schema["objects"]["entities"]["subject"]["format"],
schema["objects"]["entities"]["session"]["name"],
schema["objects"]["entities"]["session"]["format"],
)
paragraph += utils._link_with_html(
sub_string,
html_path=entities_path,
heading="sub",
pdf_format=pdf_format,
)
paragraph += "/\n\t["
ses_string = (
f'{schema["objects"]["entities"]["session"]["name"]}-'
f'<{schema["objects"]["entities"]["session"]["format"]}>'
)
paragraph += utils._link_with_html(
ses_string,
html_path=entities_path,
heading="ses",
pdf_format=pdf_format,
)
paragraph += "/]\n"

datatypes = schema.rules.datatypes

for datatype in datatypes:
# NOTE: We should have a full rethink of the schema hierarchy
# so that derivatives aren't treated like a "datatype"
# XXX We should have a full rethink of the schema hierarchy...
if datatype == "derivatives":
continue

paragraph += "\t\t"
paragraph += utils._link_with_html(
datatype,
html_path=glossary_path,
heading=f"{datatype.lower()}-datatypes",
pdf_format=pdf_format,
)
paragraph += "/\n"
paragraph += "\t\t{}/\n".format(datatype)

# Unique filename patterns
for group in datatypes[datatype].values():
string = "\t\t\t"
for ent in entity_order:
if "enum" in schema["objects"]["entities"][ent].keys():
# Entity key-value pattern with specific allowed values
ent_format = (
f'{schema["objects"]["entities"][ent]["name"]}-'
f'<{"|".join(schema["objects"]["entities"][ent]["enum"])}>'
)
ent_format = utils._link_with_html(
ent_format,
html_path=entities_path,
heading=schema["objects"]["entities"][ent]["name"],
pdf_format=pdf_format,
ent_format = "{}-<{}>".format(
schema["objects"]["entities"][ent]["name"],
"|".join(schema["objects"]["entities"][ent]["enum"]),
)
else:
# Standard entity key-value pattern with simple label/index
ent_format = utils._link_with_html(
ent_format = "{}-<{}>".format(
schema["objects"]["entities"][ent]["name"],
html_path=entities_path,
heading=schema["objects"]["entities"][ent]["name"],
pdf_format=pdf_format,
)
ent_format += "-"
ent_format += "<" if pdf_format else "&lt;"
ent_format += utils._link_with_html(
schema["objects"]["entities"][ent].get("format", "label"),
html_path=glossary_path,
heading=(
f'{schema["objects"]["entities"][ent].get("format", "label")}-formats'
),
pdf_format=pdf_format,
)
ent_format += ">" if pdf_format else "&gt;"

if ent in group["entities"]:
if isinstance(group["entities"][ent], dict):
if "enum" in group["entities"][ent].keys():
# Overwrite the filename pattern using valid values
ent_format = "{}-&lt;{}&gt;".format(
# Overwrite the filename pattern based on the valid values
ent_format = "{}-<{}>".format(
schema["objects"]["entities"][ent]["name"],
"|".join(group["entities"][ent]["enum"]),
)
Expand All @@ -391,88 +318,36 @@ def make_filename_template(
# In cases of large numbers of suffixes,
# we use the "suffix" variable and expect a table later in the spec
if len(group["suffixes"]) >= n_dupes_to_combine:
string += "_"
string += "<" if pdf_format else "&lt;"
string += utils._link_with_html(
"suffix",
html_path=glossary_path,
heading="suffix-common_principles",
pdf_format=pdf_format,
)
string += ">" if pdf_format else "&gt;"
suffix = "_<suffix>"
string += suffix
strings = [string]
else:
strings = []
for suffix in group["suffixes"]:
# The glossary indexes by the suffix identifier (TwoPE instead of 2PE),
# but the rules reference the actual suffix string (2PE instead of TwoPE),
# so we need to look it up.
suffix_id = [
k for k, v in schema["objects"]["suffixes"].items() if v["value"] == suffix
][0]

suffix_string = utils._link_with_html(
suffix,
html_path=glossary_path,
heading=f"{suffix_id.lower()}-suffixes",
pdf_format=pdf_format,
)
strings.append(f"{string}_{suffix_string}")
strings = [string + "_" + suffix for suffix in group["suffixes"]]

# Add extensions
full_strings = []
extensions = group["extensions"]
extensions = [ext if ext != "*" else ".<extension>" for ext in extensions]
extensions = utils.combine_extensions(extensions)
if len(extensions) >= n_dupes_to_combine:
# Combine exts when there are many, but keep JSON separate
if ".json" in extensions:
extensions = [".<extension>", ".json"]
else:
extensions = [".<extension>"]

ext_headings = []
for extension in extensions:
# The glossary indexes by the extension identifier (niigz instead of .nii.gz),
# but the rules reference the actual suffix string (.nii.gz instead of niigz),
# so we need to look it up.
ext_id = [
k
for k, v in schema["objects"]["extensions"].items()
if v["value"] == extension
]
if ext_id:
ext_id = ext_id[0]
ext_headings.append(f"{ext_id.lower()}-extensions")
else:
ext_headings.append("extension-common_principles")

extensions = utils.combine_extensions(
extensions,
html_path=glossary_path,
heading_lst=ext_headings,
pdf_format=pdf_format,
)

for extension in extensions:
for string in strings:
new_string = f"{string}{extension}"
new_string = string + extension
full_strings.append(new_string)

full_strings = sorted(full_strings)
if full_strings:
paragraph += "\n".join(full_strings) + "\n"

paragraph = paragraph.rstrip()
if pdf_format:
codeblock = f"Template:\n```Text\n{paragraph}\n```"
else:
codeblock = (
f'Template:\n<div class="highlight"><pre><code>{paragraph}\n</code></pre></div>'
)

codeblock = "Template:\n```Text\n" + paragraph + "\n```"
codeblock = codeblock.expandtabs(4)
codeblock = codeblock.replace("SPEC_ROOT", get_relpath(src_path))

return codeblock


Expand Down
2 changes: 1 addition & 1 deletion tools/schemacode/bidsschematools/tests/test_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def test_make_filename_template(schema_obj, schema_dir):
* all files under the datatype rules subdirectory have corresponding entries.
This may need to be updated for schema hierarchy changes.
"""
filename_template = render.make_filename_template(schema_obj, pdf_format=True)
filename_template = render.make_filename_template(schema_obj)

# Test predefined substrings
expected_template_part = """
Expand Down
2 changes: 1 addition & 1 deletion tools/schemacode/bidsschematools/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ def test_combine_extensions():
"""A unit test for utils.combine_extensions."""
test_extensions = ["nii.gz", "nii", "json"]
target_combined = ["nii[.gz]", "json"]
test_combined = utils.combine_extensions(test_extensions, pdf_format=True)
test_combined = utils.combine_extensions(test_extensions)
assert test_combined == target_combined


Expand Down
Loading

0 comments on commit fcb3c2d

Please sign in to comment.