aboutsummaryrefslogtreecommitdiffstats
path: root/filters/html-converters/md2html
diff options
context:
space:
mode:
Diffstat (limited to 'filters/html-converters/md2html')
-rwxr-xr-xfilters/html-converters/md2html27
1 files changed, 25 insertions, 2 deletions
diff --git a/filters/html-converters/md2html b/filters/html-converters/md2html
index 79d4a17..d2906ec 100755
--- a/filters/html-converters/md2html
+++ b/filters/html-converters/md2html
@@ -31,6 +31,13 @@ _MD_ANYITEM = re.compile(r'^ {0,3}(?:[-*+]|\d{1,9}[.)])[ \t]')
class _ListInterruptPreprocessor(Preprocessor):
def run(self, lines):
out, in_fence, fence = [], False, None
+ # Track whether we're already inside a list. A bullet that merely
+ # continues an existing list must NOT get a blank line inserted before
+ # it: that would turn a tight list into a loose one (every item wrapped
+ # in <p>), which is exactly what happens when a preceding item wraps onto
+ # an indented continuation line and we mistake the next bullet for a
+ # paragraph->list transition. We only want to interrupt a real paragraph.
+ in_list = False
for line in lines:
m = _MD_FENCE.match(line)
if m:
@@ -41,12 +48,28 @@ class _ListInterruptPreprocessor(Preprocessor):
in_fence, fence = False, None
out.append(line)
continue
- if not in_fence and out:
+ if in_fence:
+ out.append(line)
+ continue
+ if not line.strip():
+ # a blank line doesn't end a list (loose lists / lazy
+ # continuation), so leave in_list untouched
+ out.append(line)
+ continue
+ is_item = bool(_MD_ANYITEM.match(line))
+ indented = line[:1] in (' ', '\t')
+ # a non-indented, non-item line after a list closes that list
+ if in_list and not is_item and not indented:
+ in_list = False
+ if out:
prev = out[-1]
- if (prev.strip() and not _MD_ANYITEM.match(prev)
+ if (prev.strip() and not in_list
+ and not _MD_ANYITEM.match(prev)
and not prev.startswith((' ', '\t'))
and (_MD_BULLET.match(line) or _MD_ORDERED1.match(line))):
out.append('')
+ if is_item:
+ in_list = True
out.append(line)
return out