diff --git a/tools/check.py b/tools/check.py
index d15c5210ba686af2a4a3c7b564538269da2d0d70..1c1fc59ce02c2e97bfcae81c0ea1f0e024ae16bd 100755
--- a/tools/check.py
+++ b/tools/check.py
@@ -13,6 +13,7 @@ Call at command line with flag -h to see options and usage instructions.
 
 import argparse
 import collections
+import functools
 import glob
 import hashlib
 import logging
@@ -25,6 +26,19 @@ import yaml
 
 import validation_helpers as vh
 
+NUMBER_OF_ERRORS = 0
+
+def incr_error(func):
+    """Wrapper to count the number of errors"""
+    @functools.wraps(func)
+    def wrapper(*args, **kwargs):
+        global NUMBER_OF_ERRORS
+        NUMBER_OF_ERRORS += 1
+        return func(*args, **kwargs)
+    return wrapper
+
+logging.error = incr_error(logging.error)
+
 
 class MarkdownValidator(object):
     """Base class for Markdown validation
@@ -37,7 +51,7 @@ class MarkdownValidator(object):
     # Dict of tuples for each callout type: {style: (title, min, max)}
     CALLOUTS = {}
 
-    WARN_ON_EXTRA_HEADINGS = True  # Warn when other headings are present?
+    WARN_ON_EXTRA_HEADINGS = False  # Warn when other headings are present?
 
     # Validate YAML doc headers: dict of {header text: validation_func}
     DOC_HEADERS = {}
@@ -456,7 +470,8 @@ class IndexPageValidator(MarkdownValidator):
     DOC_HEADERS = {'layout': vh.is_str,
                    'title': vh.is_str}
 
-    CALLOUTS = {'prereq': ("Prerequisites", 1, 1)}
+    CALLOUTS = {'prereq': ("Prerequisites", 1, 1),
+                'getready': ("Getting ready", 1, 1)}
 
     def _partition_links(self):
         """Check the text of every link in index.md"""
@@ -500,17 +515,16 @@ class TopicPageValidator(MarkdownValidator):
         The top-level document has no headings indicating subtopics.
         The only valid subheadings are nested in blockquote elements"""
         heading_nodes = self.ast.get_section_headings()
-        if len(heading_nodes) == 0:
-            return True
+        if len(heading_nodes) != 0:
+            # Individual heading msgs are logged by validate_section_heading_order
+            logging.warning(
+                "In {0}: "
+                "Sub-headings are often a sign "
+                "a lesson needs to be split into multiple topics. "
+                "Please make sure this subsection doesn't belong "
+                "in a separate lesson.".format(self.filename))
 
-        # Individual heading msgs are logged by validate_section_heading_order
-        logging.error(
-            "In {0}: "
-            "The topic page should not have sub-headings "
-            "outside of special blocks. "
-            "If a topic needs sub-headings, "
-            "it should be broken into multiple topics.".format(self.filename))
-        return False
+        return True
 
     def _run_tests(self):
         parent_tests = super(TopicPageValidator, self)._run_tests()
@@ -822,12 +836,11 @@ def main(parsed_args_obj):
 
     if all_valid is True:
         logging.debug("All Markdown files successfully passed validation.")
-        sys.exit(0)
     else:
         logging.warning(
-            "Some errors were encountered during validation. "
-            "See log for details.")
-        sys.exit(1)
+            "{0} errors were encountered during validation. "
+            "See log for details.".format(NUMBER_OF_ERRORS))
+    sys.exit(NUMBER_OF_ERRORS)
 
 
 if __name__ == "__main__":
diff --git a/tools/filters/blockquote2div.py b/tools/filters/blockquote2div.py
index 485b77082848e76496dad30a29b5d580d3b32e2a..3ea39f779432bd6b2da54b080663c6c5d258326f 100755
--- a/tools/filters/blockquote2div.py
+++ b/tools/filters/blockquote2div.py
@@ -52,6 +52,7 @@ SPECIAL_CLASSES = {
     "callout": ("panel-info", "glyphicon-pushpin"),
     "challenge": ("panel-success", "glyphicon-pencil"),
     "prereq": ("panel-warning", "glyphicon-education"),
+    "getready": ("panel-warning", "glyphicon-check"),
     "objectives": ("panel-warning", "glyphicon-certificate"),
 }
 
@@ -113,7 +114,16 @@ def blockquote2div(key, value, format, meta):
 
             # a blockquote is just a list of blocks, so it can be
             # passed directly to Div, which expects Div(attr, blocks)
-            return pf.Div((id, classes, kvs), [panel_header, panel_body])
+            if classes[0] == "callout":
+                return [{"t": "RawBlock", "c": [ "html", "<aside class=\"{0}\">".format(' '.join(classes)) ]},
+                        panel_header,
+                        panel_body,
+                        {"t": "RawBlock", "c": [ "html", "</aside>" ]}]
+            else:
+                return [{"t": "RawBlock", "c": [ "html", "<section class=\"{0}\">".format(' '.join(classes)) ]},
+                        panel_header,
+                        panel_body,
+                        {"t": "RawBlock", "c": [ "html", "</section>" ]}]
 
 
 if __name__ == '__main__':