diff --git a/course/content.py b/course/content.py index 68dead5e757370f70f17691dd24b6078caf82404..ca2197eb96004207bb1ed1e6c915e9e7800d72a6 100644 --- a/course/content.py +++ b/course/content.py @@ -252,7 +252,12 @@ JINJA_YAML_RE = re.compile( r"^\[JINJA\]\s*$(.*?)^\[\/JINJA\]\s*$", re.MULTILINE | re.DOTALL) YAML_BLOCK_START_SCALAR_RE = re.compile( - r":\s*[|>](?:[0-9][-+]?|[-+][0-9]?)?(?:\s*\#.*)?$") + r"(:\s*[|>])" + "(J?)" + "((?:[0-9][-+]?|[-+][0-9]?)?)" + "(?:\s*\#.*)?" + "$") + GROUP_COMMENT_START = re.compile(r"^\s*#\s*\{\{\{") LEADING_SPACES_RE = re.compile(r"^( *)") @@ -266,14 +271,14 @@ def process_yaml_for_expansion(yaml_str): while i < line_count: l = lines[i] - if GROUP_COMMENT_START.match(l): - jinja_lines.append("{% raw %}") - jinja_lines.append(l) - jinja_lines.append("{% endraw %}") - i += 1 + yaml_block_scalar_match = YAML_BLOCK_START_SCALAR_RE.search(l) - elif YAML_BLOCK_START_SCALAR_RE.search(l): + if yaml_block_scalar_match is not None: unprocessed_block_lines = [] + allow_jinja = bool(yaml_block_scalar_match.group(2)) + l = YAML_BLOCK_START_SCALAR_RE.sub( + r"\1\3", l) + unprocessed_block_lines.append(l) block_start_indent = len(LEADING_SPACES_RE.match(l).group(1)) @@ -295,9 +300,17 @@ def process_yaml_for_expansion(yaml_str): unprocessed_block_lines.append(l) i += 1 - jinja_lines.append("{% raw %}") + if not allow_jinja: + jinja_lines.append("{% raw %}") jinja_lines.extend(unprocessed_block_lines) + if not allow_jinja: + jinja_lines.append("{% endraw %}") + + elif GROUP_COMMENT_START.match(l): + jinja_lines.append("{% raw %}") + jinja_lines.append(l) jinja_lines.append("{% endraw %}") + i += 1 else: jinja_lines.append(l) diff --git a/doc/content.rst b/doc/content.rst index 24ab30fa523639809cc151247ce97339fd8fdf52..b75c76fd858af391f5cd8843824849c11d95479c 100644 --- a/doc/content.rst +++ b/doc/content.rst @@ -86,7 +86,37 @@ Here's an example: credit_percent: 0 ... -TODO: Macro expansion in YAML +Macros in YAML +^^^^^^^^^^^^^^ + +Repetitive text in YAML (such as for example :ref:`flow-rules` that are +repeated for each instance of a given type of assignment, with very minor +modifications) can be abbreviated through the use of the +`Jinja <http://jinja.pocoo.org/docs/dev/templates/>`_ templating language. +Jinja expansion takes place everywhere in YAML code except for block +literals:: + + # Jinja usable here + + correct_code: | + + # No Jinja here + +:ref:`markup` does its own Jinja expansion though, so such block literals +*can* use Jinja. + +.. comment:: + + (Let's keep this undocumented for now.) + + Jinja expansion *can* be enabled for a block literal by mentioning a + letter "J" immediately after the character introducing the block scalar:: + + # Jinja usable here + + correct_code: |J + + # Jinja also usable here On system lock-in ----------------- @@ -294,12 +324,7 @@ Macros Repetitive text (such as the fairly long video inclusion snippet above) can be abbreviated through the use of the `Jinja <http://jinja.pocoo.org/docs/dev/templates/>`_ -templating language. To enable this support, make sure to use the line:: - - [JINJA] - -as the first line of your bulk text. From that point, you may use all features -of Jinja. For example, you could have a file :file:`macros.jinja` in the root +templating language. For example, you could have a file :file:`macros.jinja` in the root of your :ref:`git-repo` containing the following text:: {% macro youtube(id) -%} @@ -309,19 +334,15 @@ of your :ref:`git-repo` containing the following text:: This could then be used from wherever RELATE markup is allowed:: - [JINJA] - Some text... More text... {% from "macros.jinja" import youtube %} - {{ youtube("QH2-TGUlwu4") }} Some text... More text... to embed a YouTube player. (YouTube is a registered trademark.) - .. _course_yml: The Main Course Page File