+ reporter.check_field(config_file, 'configuration',
+ config, 'kind', 'lesson')
+ reporter.check_field(config_file, 'configuration',
+ config, 'carpentry', ('swc', 'dc', 'lc', 'cp'))
+ reporter.check_field(config_file, 'configuration', config, 'title')
+ reporter.check_field(config_file, 'configuration', config, 'email')
+
+ for defaults in [
+ {'values': {'root': '.', 'layout': 'page'}},
+ {'values': {'root': '..', 'layout': 'episode'}, 'scope': {'type': 'episodes', 'path': ''}},
+ {'values': {'root': '..', 'layout': 'page'}, 'scope': {'type': 'extras', 'path': ''}}
+ ]:
+ reporter.check(defaults in config.get('defaults', []),
+ 'configuration',
+ '"root" not set to "." in configuration')
+
+def check_source_rmd(reporter, source_dir, parser):
+ """Check that Rmd episode files include `source: Rmd`"""
+
+ episode_rmd_dir = [os.path.join(source_dir, d) for d in SOURCE_RMD_DIRS]
+ episode_rmd_files = [os.path.join(d, '*.Rmd') for d in episode_rmd_dir]
+ results = {}
+ for pat in episode_rmd_files:
+ for f in glob.glob(pat):
+ data = read_markdown(parser, f)
+ dy = data['metadata']
+ if dy:
+ reporter.check_field(f, 'episode_rmd',
+ dy, 'source', 'Rmd')
+
+def read_references(reporter, ref_path):
+ """Read shared file of reference links, returning dictionary of valid references
+ {symbolic_name : URL}
+ """
+
+ result = {}
+ urls_seen = set()
+ if ref_path:
+ with open(ref_path, 'r') as reader:
+ for (num, line) in enumerate(reader):
+ line_num = num + 1
+ m = P_INTERNAL_LINK_DEF.search(line)
+ require(m,
+ '{0}:{1} not valid reference:\n{2}'.format(ref_path, line_num, line.rstrip()))
+ name = m.group(1)
+ url = m.group(2)
+ require(name,
+ 'Empty reference at {0}:{1}'.format(ref_path, line_num))
+ reporter.check(name not in result,
+ ref_path,
+ 'Duplicate reference {0} at line {1}',
+ name, line_num)
+ reporter.check(url not in urls_seen,
+ ref_path,
+ 'Duplicate definition of URL {0} at line {1}',
+ url, line_num)
+ result[name] = url
+ urls_seen.add(url)
+ return result