Skip to content
Snippets Groups Projects
Commit 0e63ea95 authored by Greg Wilson's avatar Greg Wilson
Browse files

Merge branch '2016-06' of github.com:swcarpentry/styles into 2016-06

parents f752c51c 3c28d16e
Branches
Tags
No related merge requests found
......@@ -98,6 +98,10 @@ def parse_args():
"""Parse command-line arguments."""
parser = OptionParser()
parser.add_option('-l', '--linelen',
default=False,
dest='line_len',
help='Check line lengths')
parser.add_option('-p', '--parser',
default=None,
dest='parser',
......@@ -127,7 +131,9 @@ def check_config(args):
def read_all_markdown(args, source_dir):
"""Read source files, returning {path : {'metadta':yaml, 'text':text, 'doc':doc}}."""
"""Read source files, returning
{path : {'metadata':yaml, 'metadata_len':N, 'text':text, 'lines':[(i, line, len)], 'doc':doc}}
"""
all_dirs = [os.path.join(source_dir, d) for d in SOURCE_DIRS]
all_patterns = [os.path.join(d, '*.md') for d in all_dirs]
......@@ -160,17 +166,22 @@ def check_fileset(source_dir, reporter, filenames_present):
else:
reporter.add(None, 'Episode {0} has badly-formatted filename', filename)
# Check episode filename numbering.
# Check for duplicate episode numbers.
reporter.check(len(seen) == len(set(seen)),
None,
'Duplicate episode numbers {0} vs {1}',
sorted(seen), sorted(set(seen)))
# Check that numbers are consecutive.
seen = [int(s) for s in seen]
seen.sort()
reporter.check(all([i+1 == n for (i, n) in enumerate(seen)]),
None,
'Missing or non-consecutive episode numbers {0}',
seen)
clean = True
for i in range(len(seen) - 1):
clean = clean and ((seen[i+1] - seen[i]) == 1)
reporter.check(clean,
None,
'Missing or non-consecutive episode numbers {0}',
seen)
def create_checker(args, filename, info):
......@@ -192,7 +203,7 @@ def require(condition, message):
class CheckBase(object):
"""Base class for checking Markdown files."""
def __init__(self, args, filename, metadata, metadata_len, text, doc):
def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
"""Cache arguments for checking."""
super(CheckBase, self).__init__()
......@@ -202,6 +213,7 @@ class CheckBase(object):
self.metadata = metadata
self.metadata_len = metadata_len
self.text = text
self.lines = lines
self.doc = doc
self.layout = None
......@@ -230,15 +242,12 @@ class CheckBase(object):
def check_text(self):
"""Check the raw text of the lesson body."""
offset = 0
if self.metadata_len is not None:
offset = self.metadata_len
lines = [(offset+i+1, l, len(l)) for (i, l) in enumerate(self.text.split('\n'))]
over = [i for (i, l, n) in lines if (n > MAX_LINE_LEN) and (not l.startswith('!'))]
self.reporter.check(not over,
self.filename,
'Line(s) are too long: {0}',
', '.join([str(i) for i in over]))
if self.args.line_len:
over = [i for (i, l, n) in self.lines if (n > MAX_LINE_LEN) and (not l.startswith('!'))]
self.reporter.check(not over,
self.filename,
'Line(s) are too long: {0}',
', '.join([str(i) for i in over]))
def check_blockquote_classes(self):
......@@ -315,8 +324,8 @@ class CheckBase(object):
class CheckNonJekyll(CheckBase):
"""Check a file that isn't translated by Jekyll."""
def __init__(self, args, filename, metadata, metadata_len, text, doc):
super(CheckNonJekyll, self).__init__(args, filename, metadata, metadata_len, text, doc)
def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
super(CheckNonJekyll, self).__init__(args, filename, metadata, metadata_len, text, lines, doc)
def check_metadata(self):
......@@ -328,16 +337,16 @@ class CheckNonJekyll(CheckBase):
class CheckIndex(CheckBase):
"""Check the main index page."""
def __init__(self, args, filename, metadata, metadata_len, text, doc):
super(CheckIndex, self).__init__(args, filename, metadata, metadata_len, text, doc)
def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
super(CheckIndex, self).__init__(args, filename, metadata, metadata_len, text, lines, doc)
self.layout = 'lesson'
class CheckEpisode(CheckBase):
"""Check an episode page."""
def __init__(self, args, filename, metadata, metadata_len, text, doc):
super(CheckEpisode, self).__init__(args, filename, metadata, metadata_len, text, doc)
def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
super(CheckEpisode, self).__init__(args, filename, metadata, metadata_len, text, lines, doc)
def check_metadata(self):
super(CheckEpisode, self).check_metadata()
......@@ -352,16 +361,16 @@ class CheckEpisode(CheckBase):
class CheckReference(CheckBase):
"""Check the reference page."""
def __init__(self, args, filename, metadata, metadata_len, text, doc):
super(CheckReference, self).__init__(args, filename, metadata, metadata_len, text, doc)
def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
super(CheckReference, self).__init__(args, filename, metadata, metadata_len, text, lines, doc)
self.layout = 'reference'
class CheckGeneric(CheckBase):
"""Check a generic page."""
def __init__(self, args, filename, metadata, metadata_len, text, doc):
super(CheckGeneric, self).__init__(args, filename, metadata, metadata_len, text, doc)
def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
super(CheckGeneric, self).__init__(args, filename, metadata, metadata_len, text, lines, doc)
self.layout = 'page'
......
......@@ -56,7 +56,10 @@ class Reporter(object):
def read_markdown(parser, path):
"""Get YAML and AST for Markdown file, returning {'metadata':yaml, 'text': text, 'doc':doc}."""
"""
Get YAML and AST for Markdown file, returning
{'metadata':yaml, 'metadata_len':N, 'text':text, 'lines':[(i, line, len)], 'doc':doc}.
"""
# Split and extract YAML (if present).
metadata = None
......@@ -73,6 +76,10 @@ def read_markdown(parser, path):
metadata_len = pieces[1].count('\n')
body = pieces[2]
# Split into lines.
offset = 0 if metadata_len is None else metadata_len
lines = [(offset+i+1, l, len(l)) for (i, l) in enumerate(body.split('\n'))]
# Parse Markdown.
cmd = 'ruby {0}'.format(parser)
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, close_fds=True, universal_newlines=True)
......@@ -83,5 +90,6 @@ def read_markdown(parser, path):
'metadata': metadata,
'metadata_len': metadata_len,
'text': body,
'lines': lines,
'doc': doc
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment