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