diff --git a/client/galaxy/scripts/components/Markdown/Markdown.vue b/client/galaxy/scripts/components/Markdown/Markdown.vue
index 03a43e27969..5d49d1fcac4 100644
--- a/client/galaxy/scripts/components/Markdown/Markdown.vue
+++ b/client/galaxy/scripts/components/Markdown/Markdown.vue
@@ -17,16 +17,12 @@ import JOB_STATES_MODEL from "mvc/history/job-states-model";
import HDCAModel from "mvc/history/hdca-model";
import HDCAListItemEdit from "mvc/history/hdca-li-edit";
-const galaxy_blocks = /{galaxy_(\w+)(.*)}/;
+const FUNCTION_CALL_LINE_TEMPLATE = /\s*(\w+)\s*\((\s*\w+\s*=\s*\w+\s*)\)\s*/m;
const md = MarkdownIt();
const default_fence = md.renderer.rules.fence;
-function render_fenced_div(action, args, content) {
- return `
\n`;
-}
-
const RENDER_FUNCTIONS = {
history_dataset_display: (action, args, content) => {
const history_dataset_id = args.history_dataset_id;
@@ -82,10 +78,22 @@ const RENDER_FUNCTIONS = {
const history_dataset_id = args.history_dataset_id;
return `
`;
},
- history_dataset_peek: render_fenced_div,
- history_dataset_info: render_fenced_div,
- tool_stdout: render_fenced_div,
- tool_stderr: render_fenced_div,
+ history_dataset_peek: (action, args, content) => {
+ const history_dataset_id = args.history_dataset_id;
+ return ``;
+ },
+ history_dataset_info: (action, args, content) => {
+ const history_dataset_id = args.history_dataset_id;
+ return ``;
+ },
+ tool_stdout: (action, args, content) => {
+ const jobId = args.job_id;
+ return ``;
+ },
+ tool_stderr: (action, args, content) => {
+ const jobId = args.job_id;
+ return ``;
+ },
job_metrics: (action, args, content) => {
const jobId = args.job_id;
return ``;
@@ -100,8 +108,8 @@ md.renderer.rules.fence = function(tokens, idx, options, env, slf) {
const token = tokens[idx],
info = token.info ? token.info.trim() : "",
content = token.content;
- const arr = galaxy_blocks.exec(info);
- if (arr) {
+ if (info == "galaxy") {
+ const arr = FUNCTION_CALL_LINE_TEMPLATE.exec(content);
const action = arr[1];
const arguments_str = arr[2].trim();
const args = {};
@@ -109,7 +117,7 @@ md.renderer.rules.fence = function(tokens, idx, options, env, slf) {
const parts = arguments_str.split(/(\s+)/);
for (const part of parts) {
const [key, val] = part.split("=");
- args[key] = val;
+ args[key.trim()] = val.trim();
}
}
return RENDER_FUNCTIONS[action](action, args, content);
@@ -118,6 +126,16 @@ md.renderer.rules.fence = function(tokens, idx, options, env, slf) {
}
};
+function render_fenced_output(tag, objects, idAttr, metadataKey) {
+ $("." + tag).each((i, el) => {
+ const objectId = $(el).attr(idAttr);
+ const meta = objects[objectId][metadataKey];
+ $(el)
+ .find("code")
+ .text(meta);
+ });
+}
+
export default {
props: {
markdownConfig: {
@@ -129,7 +147,8 @@ export default {
markdownRendered: "",
historyDatasets: {},
historyDatasetCollections: {},
- workflows: {}
+ workflows: {},
+ jobs: {}
};
},
watch: {
@@ -139,6 +158,7 @@ export default {
this.historyDatasets = mConfig.history_datasets || {};
this.historyDatasetCollections = mConfig.history_dataset_collections || {};
this.workflows = mConfig.workflows || {};
+ this.jobs = mConfig.jobs || {};
this.$nextTick(() => {
render_embedded_items();
@@ -155,6 +175,11 @@ export default {
}
});
+ render_fenced_output("tool-stdout", this.jobs, "job_id", "tool_stdout");
+ render_fenced_output("tool-stderr", this.jobs, "job_id", "tool_stderr");
+ render_fenced_output("dataset-peek", this.historyDatasets, "history_dataset_id", "peek");
+ render_fenced_output("dataset-info", this.historyDatasets, "history_dataset_id", "info");
+
$(".dataset-collection").each((i, el) => {
const Galaxy = getGalaxyInstance();
const hdcaId = $(el).attr("history_dataset_collection_id");
diff --git a/client/galaxy/scripts/mvc/workflow/workflow-manager.js b/client/galaxy/scripts/mvc/workflow/workflow-manager.js
index 9391a564bb5..67eb4b87625 100644
--- a/client/galaxy/scripts/mvc/workflow/workflow-manager.js
+++ b/client/galaxy/scripts/mvc/workflow/workflow-manager.js
@@ -9,16 +9,19 @@ const DEFAULT_INVOCATION_REPORT = `
# Workflow Execution Report
## Workflow Inputs
-::: invocation_inputs
-:::
+\`\`\`galaxy
+invocation_inputs()
+\`\`\`
## Workflow Outputs
-::: invocation_outputs
-:::
+\`\`\`galaxy
+invocation_outputs()
+\`\`\`
## Workflow
-::: workflow_display
-:::
+\`\`\`galaxy
+workflow_display()
+\`\`\`
`;
class Workflow {
diff --git a/lib/galaxy/managers/markdown_util.py b/lib/galaxy/managers/markdown_util.py
index 6ce369994ba..be4144804e8 100644
--- a/lib/galaxy/managers/markdown_util.py
+++ b/lib/galaxy/managers/markdown_util.py
@@ -37,8 +37,12 @@ INVOCATION_SECTIONS = [
"invocation_inputs",
"invocation_outputs",
]
-GALAXY_FLAVORED_MARKDOWN_CONTAINER_REGEX = "(%s)" % "|".join(GALAXY_FLAVORED_MARKDOWN_CONTAINERS)
-INVOCATION_SECTION_MARKDOWN_CONTAINER_REGEX = "(%s)" % "|".join(INVOCATION_SECTIONS)
+ALL_CONTAINER_TYPES = GALAXY_FLAVORED_MARKDOWN_CONTAINERS + INVOCATION_SECTIONS
+GALAXY_FLAVORED_MARKDOWN_CONTAINER_REGEX = "(%s)" % "|".join(ALL_CONTAINER_TYPES)
+
+FUNCTION_ARG = r'\s*\w+\s*=\s*\w+\s*'
+FUNCTION_CALL_LINE_TEMPLATE = r'\s*%s\s*\((?:' + FUNCTION_ARG + r')?\)\s*'
+GALAXY_MARKDOWN_FUNCTION_CALL_LINE = re.compile(FUNCTION_CALL_LINE_TEMPLATE % GALAXY_FLAVORED_MARKDOWN_CONTAINER_REGEX)
BLOCK_FENCE_START = re.compile(r'```.*')
BLOCK_FENCE_END = re.compile(r'```[\s]*')
@@ -49,14 +53,12 @@ INPUT_LABEL_PATTERN = re.compile(r'input=([\w_\-]+)')
STEP_LABEL_PATTERN = re.compile(r'step=([\w_\-]+)')
ID_PATTERN = re.compile(r'(workflow_id|history_dataset_id|history_dataset_collection_id|job_id)=([\d]+)')
GALAXY_FLAVORED_MARKDOWN_CONTAINER_LINE_PATTERN = re.compile(
- r"```\s*\{galaxy_%s.*\}\s*" % GALAXY_FLAVORED_MARKDOWN_CONTAINER_REGEX
-)
-FENCED_MARKDOWN_CONTAINER_LINE_PATTERN = re.compile(
- r"```\s*\{.*"
+ r"```\s*galaxy\s*"
)
INVOCATION_SECTION_MARKDOWN_CONTAINER_LINE_PATTERN = re.compile(
- r"```\s*\{galaxy_%s.*\}\s*" % INVOCATION_SECTION_MARKDOWN_CONTAINER_REGEX
+ r"```\s*galaxy\s*"
)
+GALAXY_FENCED_BLOCK = re.compile(r'^```\s*galaxy\s*(.*?)^```', re.MULTILINE ^ re.DOTALL)
VALID_CONTAINER_START_PATTERN = re.compile(r"^```\s+[\w]+.*$")
VALID_CONTAINER_END_PATTERN = re.compile(r"^```\s*$")
WHITE_SPACE_ONLY_PATTERN = re.compile(r"^[\s]+$")
@@ -75,7 +77,6 @@ def ready_galaxy_markdown_for_export(trans, internal_galaxy_markdown):
extra_rendering_data = {}
def _remap(container, line):
- remap_lines = []
id_match = re.search(ID_PATTERN, line)
object_id = None
encoded_id = None
@@ -83,44 +84,37 @@ def ready_galaxy_markdown_for_export(trans, internal_galaxy_markdown):
object_id = int(id_match.group(2))
encoded_id = trans.security.encode_id(object_id)
line = line.replace(id_match.group(), "%s=%s" % (id_match.group(1), encoded_id))
- remap_lines.append(line)
- def remap_with_fenced_output(output, default):
- if output:
- for line in output.splitlines(True):
- if not line.endswith("\n"):
- line += "\n"
- remap_lines.append(line)
- else:
- # TODO: handle this better... shouldn't be part of code block
- # ideally.
- remap_lines.append("%s\n" % default)
+ def ensure_rendering_data_for(object_type, encoded_id):
+ if object_type not in extra_rendering_data:
+ extra_rendering_data[object_type] = {}
+ object_type_data = extra_rendering_data[object_type]
+ if encoded_id not in object_type_data:
+ object_type_data[encoded_id] = {}
+ return object_type_data[encoded_id]
+
+ def extend_history_dataset_rendering_data(key, val, default_val):
+ ensure_rendering_data_for("history_datasets", encoded_id)[key] = val or default_val
if container == "history_dataset_display":
assert object_id is not None
hda = hdas_manager.get_accessible(object_id, trans.user)
if "history_datasets" not in extra_rendering_data:
extra_rendering_data["history_datasets"] = {}
- extra_rendering_data["history_datasets"][encoded_id] = {
- "name": hda.name,
- }
+ extend_history_dataset_rendering_data("name", hda.name, "")
elif container == "history_dataset_peek":
assert object_id is not None
hda = hdas_manager.get_accessible(object_id, trans.user)
peek = hda.peek
- remap_with_fenced_output(peek, "*No Dataset Peek Available*")
+ extend_history_dataset_rendering_data("peek", peek, "*No Dataset Peek Available*")
elif container == "history_dataset_info":
hda = hdas_manager.get_accessible(object_id, trans.user)
info = hda.info
- remap_with_fenced_output(info, "*No Dataset Info Available*")
+ extend_history_dataset_rendering_data("info", info, "*No Dataset Peek Available*")
elif container == "workflow_display":
# TODO: should be workflow id...
stored_workflow = workflows_manager.get_stored_accessible_workflow(trans, encoded_id)
- if "workflows" not in extra_rendering_data:
- extra_rendering_data["workflows"] = {}
- extra_rendering_data["workflows"][encoded_id] = {
- "name": stored_workflow.name,
- }
+ ensure_rendering_data_for("workflows", encoded_id)["name"] = stored_workflow.name
elif container == "history_dataset_collection_display":
collection_manager = DatasetCollectionManager(trans.app)
hdca = collection_manager.get_dataset_collection_instance(trans, "history", encoded_id)
@@ -130,18 +124,18 @@ def ready_galaxy_markdown_for_export(trans, internal_galaxy_markdown):
)
if "history_dataset_collections" not in extra_rendering_data:
extra_rendering_data["history_dataset_collections"] = {}
- extra_rendering_data["history_dataset_collections"][encoded_id] = hdca_view
+ ensure_rendering_data_for("history_dataset_collections", encoded_id).update(hdca_view)
elif container == "tool_stdout":
job_manager = JobManager(trans.app)
job = job_manager.get_accessible_job(trans, object_id)
- remap_with_fenced_output(job.tool_stdout, "*No Standard Output Available*")
+ ensure_rendering_data_for("jobs", encoded_id)["tool_stdout"] = job.tool_stdout or "*No Standard Output Available*"
elif container == "tool_stderr":
job_manager = JobManager(trans.app)
job = job_manager.get_accessible_job(trans, object_id)
- remap_with_fenced_output(job.tool_stderr, "*No Standard Error Available*")
- return remap_lines
+ ensure_rendering_data_for("jobs", encoded_id)["tool_stderr"] = job.tool_stderr or "*No Standard Error Available*"
+ return (line, False)
- export_markdown = _remap_galaxy_markdown_containers(_remap, internal_galaxy_markdown)
+ export_markdown = _remap_galaxy_markdown_calls(_remap, internal_galaxy_markdown)
return export_markdown, extra_rendering_data
@@ -171,12 +165,14 @@ def resolve_invocation_markdown(trans, invocation, workflow_markdown):
if output_assoc.history_content_type == "dataset":
section_markdown += """#### Output Dataset: %s
-```{galaxy_history_dataset_display output=%s}
+```galaxy
+history_dataset_display(output=%s)
```
""" % (output_assoc.workflow_output.label, output_assoc.workflow_output.label)
else:
section_markdown += """#### Output Dataset Collection: %s
-```{galaxy_history_dataset_collection_display output=%s}
+```galaxy
+history_dataset_collection_display(output=%s)
```
""" % (output_assoc.workflow_output.label)
elif container == "invocation_inputs":
@@ -186,21 +182,25 @@ def resolve_invocation_markdown(trans, invocation, workflow_markdown):
if input_assoc.history_content_type == "dataset":
section_markdown += """#### Input Dataset: %s
-```{galaxy_history_dataset_display input=%s}
+```galaxy
+history_dataset_display(input=%s)
```
""" % (input_assoc.workflow_step.label, input_assoc.workflow_step.label)
else:
section_markdown += """#### Input Dataset Collection: %s
-```{galaxy_history_dataset_collection_display input=%s}
+```galaxy
+history_dataset_collection_display(input=%s)
```
""" % (input_assoc.workflow_step.label, input_assoc.workflow_step.label)
- return section_markdown
+ else:
+ return line, False
+ return section_markdown, True
def _remap(container, line):
if container == "workflow_display":
# TODO: this really should be workflow id not stored workflow id but the API
# it consumes wants the stored id.
- return "```{galaxy_workflow_display workflow_id=%s}\n" % invocation.workflow.stored_workflow.id
+ return ("workflow_display(workflow_id=%s)\n" % invocation.workflow.stored_workflow.id, False)
ref_object_type = None
output_match = re.search(OUTPUT_LABEL_PATTERN, line)
input_match = re.search(INPUT_LABEL_PATTERN, line)
@@ -228,16 +228,14 @@ def resolve_invocation_markdown(trans, invocation, workflow_markdown):
else:
ref_object_type = "history_dataset_collection"
line = line.replace(target_match.group(), "%s_id=%s" % (ref_object_type, ref_object.id))
- return line
+ return (line, False)
log.debug("workflow markdown is \n%s" % workflow_markdown)
- workflow_markdown = _remap_galaxy_markdown_containers(
+ workflow_markdown = _remap_galaxy_markdown_calls(
_section_remap,
workflow_markdown,
- container_pattern=INVOCATION_SECTION_MARKDOWN_CONTAINER_LINE_PATTERN,
- replace_whole_container=True
)
- galaxy_markdown = _remap_galaxy_markdown_containers(_remap, workflow_markdown)
+ galaxy_markdown = _remap_galaxy_markdown_calls(_remap, workflow_markdown)
log.debug("galaxy markdown is \n%s" % galaxy_markdown)
return galaxy_markdown
@@ -245,6 +243,7 @@ def resolve_invocation_markdown(trans, invocation, workflow_markdown):
def validate_galaxy_markdown(galaxy_markdown, internal=True):
expecting_container_close_for = None
last_line_no = 0
+ function_calls = 0
for (line, fenced, open_fence, line_no) in _split_markdown_lines(galaxy_markdown):
last_line_no = line_no
@@ -261,7 +260,7 @@ def validate_galaxy_markdown(galaxy_markdown, internal=True):
continue
elif fenced and expecting_container_close and BLOCK_FENCE_END.match(line):
expecting_container_close_for = None
- elif open_fence and FENCED_MARKDOWN_CONTAINER_LINE_PATTERN.match(line):
+ elif open_fence and GALAXY_FLAVORED_MARKDOWN_CONTAINER_LINE_PATTERN.match(line):
if expecting_container_close:
if not VALID_CONTAINER_END_PATTERN.match(line):
invalid_line("Invalid command close line [{line}] for [{expected_for}]", line=line, expected_for=expecting_container_close_for)
@@ -269,11 +268,16 @@ def validate_galaxy_markdown(galaxy_markdown, internal=True):
expecting_container_close_for = None
continue
- if not GALAXY_FLAVORED_MARKDOWN_CONTAINER_LINE_PATTERN.match(line):
- invalid_line("Invalid markdown command line [{line}]", line=line)
- # TODO: check IDs and attributes and stuff...
expecting_container_close_for = line
continue
+ elif fenced and line and expecting_container_close_for:
+ if GALAXY_MARKDOWN_FUNCTION_CALL_LINE.match(line):
+ function_calls += 1
+ if function_calls > 1:
+ invalid_line("Only one Galaxy directive is allowed per fenced Galaxy block (```galaxy)")
+ continue
+ else:
+ invalid_line("Invalid embedded Galaxy markup line [{line}]", line=line)
# Markdown unrelated to Galaxy object containers.
continue
@@ -282,26 +286,47 @@ def validate_galaxy_markdown(galaxy_markdown, internal=True):
raise Exception("Invalid line %d: %s" % (last_line_no, "close of block for [{expected_for}] expected".format(expected_for=expecting_container_close_for)))
-def _remap_galaxy_markdown_containers(func, markdown, container_pattern=GALAXY_FLAVORED_MARKDOWN_CONTAINER_LINE_PATTERN, replace_whole_container=False):
- remapped_lines = []
- replaced_container = False
- for (line, fenced, open_fence, _) in _split_markdown_lines(markdown):
- if replaced_container:
- # Replaced whole container, no need to keep container close.
- assert line.startswith("```")
- replaced_container = False
- continue
- container_match = container_pattern.match(line)
- if container_match:
- remap_line = func(container_match.group(1), line)
- if not isinstance(remap_line, list):
- remap_line = [remap_line]
- remapped_lines.extend(remap_line)
- replaced_container = replace_whole_container
+def _remap_galaxy_markdown_containers(func, markdown):
+ new_markdown = markdown
+
+ searching_from = 0
+ while True:
+ from_markdown = new_markdown[searching_from:]
+ match = re.search(GALAXY_FENCED_BLOCK, from_markdown)
+ if match is not None:
+ (replacement, whole_block) = func(match.group(1))
+ if whole_block:
+ start_pos = match.start()
+ end_pos = match.end()
+ else:
+ start_pos = match.start(1)
+ end_pos = match.end(1)
+ start_pos = start_pos + searching_from
+ end_pos = end_pos + searching_from
+
+ new_markdown = new_markdown[:start_pos] + replacement + new_markdown[end_pos:]
+ searching_from = end_pos
else:
- remapped_lines.append(line)
- rval = "".join(remapped_lines)
- return rval
+ break
+
+ return new_markdown
+
+
+def _remap_galaxy_markdown_calls(func, markdown):
+
+ def _remap_container(container):
+ matching_line = None
+ for line in container.splitlines():
+ if GALAXY_MARKDOWN_FUNCTION_CALL_LINE.match(line):
+ assert matching_line is None
+ matching_line = line
+
+ assert matching_line, "Failed to find func call line in [%s]" % container
+ match = GALAXY_MARKDOWN_FUNCTION_CALL_LINE.match(line)
+
+ return func(match.group(1), matching_line + "\n")
+
+ return _remap_galaxy_markdown_containers(_remap_container, markdown)
def _split_markdown_lines(markdown):
diff --git a/lib/galaxy/workflow/reports/generators/markdown.py b/lib/galaxy/workflow/reports/generators/markdown.py
index a17466cecdf..4f735274d43 100644
--- a/lib/galaxy/workflow/reports/generators/markdown.py
+++ b/lib/galaxy/workflow/reports/generators/markdown.py
@@ -11,16 +11,19 @@ DEFAULT_MARKDOWN = """
# ${title}
## Workflow Inputs
-::: invocation_inputs
-:::
+```galaxy
+invocation_inputs()
+```
## Workflow Outputs
-::: invocation_outputs
-:::
+```galaxy
+invocation_outputs()
+```
## Workflow
-::: workflow_display
-:::
+```galaxy
+workflow_display()
+```
"""
diff --git a/test/api/test_workflows.py b/test/api/test_workflows.py
index a4ad8069be8..e1a063278e8 100644
--- a/test/api/test_workflows.py
+++ b/test/api/test_workflows.py
@@ -1284,7 +1284,7 @@ steps:
assert report_json["render_format"] == "markdown"
markdown_content = report_json["markdown"]
assert "## Workflow Outputs" in markdown_content
- assert "\n```{galaxy_history_dataset_display history_dataset_id=" in markdown_content
+ assert "\n```galaxy\nhistory_dataset_display(history_dataset_id=" in markdown_content
assert "## Workflow Inputs" in markdown_content
assert "## About This Report" in markdown_content
diff --git a/test/base/workflow_fixtures.py b/test/base/workflow_fixtures.py
index 941f5813477..55de9ccc7e7 100644
--- a/test/base/workflow_fixtures.py
+++ b/test/base/workflow_fixtures.py
@@ -500,19 +500,23 @@ report:
in the default workflow invocation report template.
## Workflow Inputs
- ```{galaxy_invocation_inputs}
+ ```galaxy
+ invocation_inputs()
```
## Workflow Outputs
- ```{galaxy_invocation_outputs}
+ ```galaxy
+ invocation_outputs()
```
## Workflow Inputs
- ```{galaxy_invocation_inputs}
+ ```galaxy
+ invocation_inputs()
```
## Workflow Outputs
- ```{galaxy_invocation_outputs}
+ ```galaxy
+ invocation_outputs()
```
The auto-generated sections could be hand-crafted from workflow markdown also,
@@ -530,28 +534,34 @@ report:
Once can reference an output and embed a display of it as follows:
- ```{galaxy_history_dataset_display output=output_1}
+ ```galaxy
+ history_dataset_display(output=output_1)
```
- ```{galaxy_history_dataset_display output=output_1}
+ ```galaxy
+ history_dataset_display(output=output_1)
```
Inputs can be referenced and displayed the same way:
- ```{galaxy_history_dataset_display input=input_1}
+ ```galaxy
+ history_dataset_display(input=input_1)
```
- ```{galaxy_history_dataset_display input=input_1}
+ ```galaxy
+ history_dataset_display(input=input_1)
```
---
Images can be embedded directly into the report as follows:
- ```{galaxy_history_dataset_as_image output=output_image}
+ ```galaxy
+ history_dataset_as_image(output=output_image)
```
- ```{galaxy_history_dataset_as_image output=output_image}
+ ```galaxy
+ history_dataset_as_image(output=output_image)
```
---
@@ -559,30 +569,36 @@ report:
Dataset peek content can be displayed to quickly provided an embedded
summary of an input or output:
- ```{galaxy_history_dataset_peek output=output_1}
+ ```galaxy
+ history_dataset_peek(output=output_1)
```
- ```{galaxy_history_dataset_peek output=output_1}
+ ```galaxy
+ history_dataset_peek(output=output_1)
```
---
Dataset "info" content can be displayed as well:
- ```{galaxy_history_dataset_info input=input_1}
+ ```galaxy
+ history_dataset_info(input=input_1)
```
- ```{galaxy_history_dataset_info input=input_1}
+ ```galaxy
+ history_dataset_info(input=input_1)
```
---
Collections can be displayed:
- ```{galaxy_history_dataset_collection_display input=input_list}
+ ```galaxy
+ history_dataset_collection_display(input=input_list)
```
- ```{galaxy_history_dataset_collection_display input=input_list}
+ ```galaxy
+ history_dataset_collection_display(input=input_list)
```
---
@@ -590,46 +606,56 @@ report:
The whole workflow can be embedded to provide some context and display
annotations and steps.
- ```{galaxy_workflow_display}
+ ```galaxy
+ workflow_display()
```
- ```{galaxy_workflow_display}
+ ```galaxy
+ workflow_display()
```
---
Job parameters can be summarized:
- ```{galaxy_job_parameters step=qc_step}
+ ```galaxy
+ job_parameters(step=qc_step)
```
- ```{galaxy_job_parameters step=qc_step}
+ ```galaxy
+ job_parameters(step=qc_step)
```
---
Job metrics can be summarized as well:
- ```{galaxy_job_metrics step=image_cat}
+ ```galaxy
+ job_metrics(step=image_cat)
```
- ```{galaxy_job_metrics step=image_cat}
+ ```galaxy
+ job_metrics(step=image_cat)
```
---
Tool standard out and error are also available for steps.
- ```{galaxy_tool_stdout step=qc_step}
+ ```galaxy
+ tool_stdout(step=qc_step)
```
- ```{galaxy_tool_stdout step=qc_step}
+ ```galaxy
+ tool_stdout(step=qc_step)
```
- ```{galaxy_tool_stderr step=qc_step}
+ ```galaxy
+ tool_stderr(step=qc_step)
```
- ```{galaxy_tool_stderr step=qc_step}
+ ```galaxy
+ tool_stderr(step=qc_step)
```
---
diff --git a/test/unit/test_markdown_validate.py b/test/unit/test_markdown_validate.py
index 681fb163eac..1dc5561bf4b 100644
--- a/test/unit/test_markdown_validate.py
+++ b/test/unit/test_markdown_validate.py
@@ -32,26 +32,40 @@ printf('hello')
""")
# assert valid container is fine.
assert_markdown_valid("""
-```{galaxy_job_metrics job_id=THISFAKEID}
+```galaxy
+job_metrics(job_id=THISFAKEID)
```
""")
- # assert valid container is fine.
+ # assert valid container is fine at end of document.
assert_markdown_valid("""
-```{galaxy_job_metrics job_id=THISFAKEID}
+```galaxy
+job_metrics(job_id=THISFAKEID)
```""")
# assert valid containers require container close
assert_markdown_invalid("""
-```{galaxy_job_metrics job_id=THISFAKEID}
-foo
+```galaxy
+job_metrics(job_id=THISFAKEID)
""", at_line=1)
# assert valid containers require container close, even at end...
assert_markdown_invalid("""
-```{galaxy_job_metrics job_id=THISFAKEID""")
-
- # assert valid containers require container close, even at end...
+```galaxy
+job_metrics(job_id=THISFAKEID)""")
+ # assert only one command allowed
assert_markdown_invalid("""
-```{galaxy_not_a_command}
-```""")
+```galaxy
+job_metrics(job_id=THISFAKEID)
+job_metrics(job_id=THISFAKEID2)
+```
+""")
+ # assert command paren is closed
assert_markdown_invalid("""
-```{not_a_command}
-```""")
+```galaxy
+job_metrics(job_id=THISFAKEID
+```
+""")
+ # assert command arg is named.
+ assert_markdown_invalid("""
+```galaxy
+job_metrics(THISFAKEID)
+```
+""")
diff --git a/test/unit/workflows/test_workflow_markdown.py b/test/unit/workflows/test_workflow_markdown.py
index f286731450c..742d557b451 100644
--- a/test/unit/workflows/test_workflow_markdown.py
+++ b/test/unit/workflows/test_workflow_markdown.py
@@ -1,5 +1,5 @@
from galaxy import model
-from galaxy.managers.markdown_util import resolve_invocation_markdown
+from galaxy.managers.markdown_util import resolve_invocation_markdown, validate_galaxy_markdown
from .test_workflow_progress import TEST_WORKFLOW_YAML
from .workflow_support import MockTrans, yaml_to_model
@@ -7,63 +7,69 @@ from .workflow_support import MockTrans, yaml_to_model
def test_workflow_section_expansion():
workflow_markdown = """
## Workflow
-```{galaxy_workflow_display}
+```galaxy
+workflow_display()
```
"""
galaxy_markdown = resolved_markdown(workflow_markdown)
assert "## Workflow\n" in galaxy_markdown
- assert "```{galaxy_workflow_display workflow_id=342}\n```\n" in galaxy_markdown
+ assert "```galaxy\nworkflow_display(workflow_id=342)\n```\n" in galaxy_markdown
def test_inputs_section_expansion():
workflow_markdown = """
## Workflow Inputs
-```{galaxy_invocation_inputs}
+```galaxy
+invocation_inputs()
```
"""
galaxy_markdown = resolved_markdown(workflow_markdown)
assert "## Workflow Inputs" in galaxy_markdown
- assert "```{galaxy_history_dataset_display history_dataset_id=567}" in galaxy_markdown
+ assert "```galaxy\nhistory_dataset_display(history_dataset_id=567)\n" in galaxy_markdown
assert len(galaxy_markdown.split("```")) == 3
def test_outputs_section_expansion():
workflow_markdown = """
## Workflow Outputs
-```{galaxy_invocation_outputs}
+```galaxy
+invocation_outputs()
```
"""
galaxy_markdown = resolved_markdown(workflow_markdown)
assert "## Workflow Outputs" in galaxy_markdown
- assert "```{galaxy_history_dataset_display history_dataset_id=563}" in galaxy_markdown
+ assert "```galaxy\nhistory_dataset_display(history_dataset_id=563)" in galaxy_markdown
def test_input_reference_mapping():
workflow_markdown = """
And outputs...
-```{galaxy_history_dataset_peek input=input1}
+```galaxy
+history_dataset_peek(input=input1)
```
"""
galaxy_markdown = resolved_markdown(workflow_markdown)
- assert "```{galaxy_history_dataset_peek history_dataset_id=567}\n```" in galaxy_markdown
+ assert "```galaxy\nhistory_dataset_peek(history_dataset_id=567)\n```" in galaxy_markdown
def test_output_reference_mapping():
workflow_markdown = """
And outputs...
-```{galaxy_history_dataset_as_image output=output_label}
+```galaxy
+history_dataset_as_image(output=output_label)
```
"""
galaxy_markdown = resolved_markdown(workflow_markdown)
- assert "```{galaxy_history_dataset_as_image history_dataset_id=563}" in galaxy_markdown
+ assert "```galaxy\nhistory_dataset_as_image(history_dataset_id=563)\n```" in galaxy_markdown
def resolved_markdown(workflow_markdown):
# Convert workflow markdown to internal Galaxy markdown with object id references
# and with sections expanded.
trans = MockTrans()
+ validate_galaxy_markdown(workflow_markdown)
galaxy_markdown = resolve_invocation_markdown(trans, example_invocation(trans), workflow_markdown)
return galaxy_markdown