Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions docs/astro/convert_subworkflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
from jinja2 import Environment, FileSystemLoader, select_autoescape

from docs.astro.formatting import (
escape_mdx,
format_choices,
format_description,
link,
sanitize_html_outside_codeblocks,
sanitize_outside_codeblocks,
)


Expand All @@ -26,15 +27,13 @@ def channel_description_format(description):
try:
_structure = next(filter(lambda x: "Structure:" in x, _descr))
except StopIteration:
return sanitize_html_outside_codeblocks(
" ".join(_descr), table_cell=True
)
return format_description("\n".join(_descr))

_descr.remove(_structure)
_structure = _structure.replace('[', '`[', 1)[::-1].replace(']', ']`', 1)[::-1]
_structure = _structure.replace('[', '`[', 1)[::-1].replace(']', '`]', 1)[::-1]
return "{}<br />{}".format(
format_description('\n'.join(_descr)),
sanitize_html_outside_codeblocks(_structure, table_cell=True)
sanitize_outside_codeblocks(_structure, table_cell=True)
)


Expand Down Expand Up @@ -69,7 +68,8 @@ def main():
'link_tool': link,
'channel_descr': channel_description_format,
'format_choices': format_choices,
'format_description': format_description
'format_description': format_description,
'escape_mdx': escape_mdx
})

with open(f"{args.subworkflow_path}/meta.yml", "r") as f:
Expand Down
22 changes: 12 additions & 10 deletions docs/astro/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,23 @@ def escape_mdx(text):
# ---------------------------------------------------------------------------

#: Characters that must be escaped when rendering markdown inside HTML / MDX.
_HTML_ESCAPE = {
_ESCAPE = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#39;",
"{": "\\{",
"}": "\\}"
}


def sanitize_html_outside_codeblocks(text, table_cell=False):
def sanitize_outside_codeblocks(text, table_cell=False):
"""Escape HTML-sensitive characters in markdown text, preserving code blocks.

Scans the text character by character, tracking whether we're inside
an inline code span (``...``) or a fenced code block (````` ... `````).
Only escapes ``&``, ``<``, ``>``, ``"`` and ``'`` when outside of code
Only escapes ``&``, ``<``, ``>``, ``"``, ``'``, ``{`` and ``}`` when outside of code
regions.

When *table_cell* is ``True`` (for content inside markdown table cells):
Expand Down Expand Up @@ -78,13 +80,13 @@ def sanitize_html_outside_codeblocks(text, table_cell=False):
content = content[first_nl + 1:]
content = content.rstrip("\n")
# Escape HTML inside <code> so it renders literally
for char, entity in _HTML_ESCAPE.items():
for char, entity in _ESCAPE.items():
content = content.replace(char, entity)
content = content.replace("\n", "<br />")
tags = ""
if lang:
tags = f'lang="{lang}"'
result.append(f"<pre><code {tags}>{escape_mdx(content)}</code></pre>")
result.append(f"<pre><code {tags}>{content}</code></pre>")
else:
result.append(text[i : end + 3])
i = end + 3
Expand All @@ -98,13 +100,13 @@ def sanitize_html_outside_codeblocks(text, table_cell=False):
lang = content[:first_nl]
content = content[first_nl + 1:]
content = content.rstrip("\n")
for char, entity in _HTML_ESCAPE.items():
for char, entity in _ESCAPE.items():
content = content.replace(char, entity)
content = content.replace("\n", "<br />")
tags = ""
if lang:
tags = f'lang="{lang}"'
result.append(f"<pre><code {tags}>{escape_mdx(content)}</code></pre>")
result.append(f"<pre><code {tags}>{content}</code></pre>")
else:
result.append(text[i:])
break
Expand All @@ -126,7 +128,7 @@ def sanitize_html_outside_codeblocks(text, table_cell=False):

# -- Regular character: escape when outside code --------------------
else:
result.append(_HTML_ESCAPE.get(text[i], text[i]))
result.append(_ESCAPE.get(text[i], text[i]))
i += 1

return "".join(result)
Expand Down Expand Up @@ -247,7 +249,7 @@ def format_description(description):
"""
if not description:
return ""
return sanitize_html_outside_codeblocks(
return sanitize_outside_codeblocks(
collapse_line_returns(str(description)), table_cell=True
)

Expand All @@ -259,5 +261,5 @@ def format_choices(choices):
choices = [c.strip() for c in choices.split(",")]

return "<br />".join(
[li(sanitize_html_outside_codeblocks(str(c))) for c in choices]
[li(sanitize_outside_codeblocks(str(c))) for c in choices]
) if choices else ""
4 changes: 2 additions & 2 deletions docs/astro/templates/subworkflow.md.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ head:

{%- for channel in input %}
{% for name, content in channel.items() -%}
| {{ name }} | {{ content.type }} | {{ content.description | channel_descr }} | {{ content.mandatory | default(True) }} | {% if content.pattern %} `{{ content.pattern }}` {% endif %} |
| {{ name }} | {{ content.type }} | {{ content.description | channel_descr }} | {{ content.mandatory | default(True) }} | {% if content.pattern %} `{{ content.pattern | escape_mdx }}` {% endif %} |
{%- endfor %}
{%- endfor %}
</div>
Expand All @@ -48,7 +48,7 @@ head:

{%- for channel in output %}
{% for name, content in channel.items() -%}
| {{ name }} | {{ content.type }} | {{ content.description | channel_descr }} | {{ content.mandatory | default(True) }} | {% if content.pattern %} `{{ content.pattern }}` {% endif %} |
| {{ name }} | {{ content.type }} | {{ content.description | channel_descr }} | {{ content.mandatory | default(True) }} | {% if content.pattern %} `{{ content.pattern | escape_mdx }}` {% endif %} |
{%- endfor %}
{%- endfor %}
</div>
Expand Down
19 changes: 11 additions & 8 deletions modules/nf-neuro/harmonization/clinicalcombat/meta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,21 @@ output:
JSON files used to properly plot the harmonization results in a downstream MultiQC report.
These files contain the regression curves and the percentiles computed before and after
harmonization for all bundles of a given metric. The files have the following structure:

```json
{
"bundle_name_1": {
"metric1": {
"plot_1": { ... },
"plot_2": { ... },
"bundle_name_1": {
"metric1": {
"plot_1": { ... },
"plot_2": { ... },
},
"bundle_name_2": {
"metric1": {
"plot_1": { ... },
"plot_2": { ... },
"bundle_name_2": {
"metric1": {
"plot_1": { ... },
"plot_2": { ... },
}
}
```
pattern: "*.json"
versions:
- versions.yml:
Expand Down