Liquid Tags: line numbers for include_code

This commit is contained in:
Lion Krischer
2014-05-01 01:11:53 +02:00
parent 1d4d19aca5
commit 97e2d7549b
2 changed files with 44 additions and 9 deletions

View File

@@ -61,7 +61,15 @@ To include code from a file in your document with a link to the original
file, enable the ``liquid_tags.include_code`` plugin, and add to your file, enable the ``liquid_tags.include_code`` plugin, and add to your
document: document:
{% include_code myscript.py [Title text] %} {% include_code /path/to/code.py [lang:python] [lines:X-Y] [:hidefilename:] [title] %}
All arguments are optional but their order must be kept. `:hidefilename:` is
only allowed if a title is also given.
{% include_code /path/to/code.py lines:1-10 :hidefilename: Test Example %}
This example will show the first 10 lines of the file while hiding the actual
filename.
The script must be in the ``code`` subdirectory of your content folder: The script must be in the ``code`` subdirectory of your content folder:
this default location can be changed by specifying this default location can be changed by specifying

View File

@@ -34,12 +34,24 @@ import os
from .mdx_liquid_tags import LiquidTags from .mdx_liquid_tags import LiquidTags
SYNTAX = "{% include_code /path/to/code.py [lang:python] [title] %}" SYNTAX = "{% include_code /path/to/code.py [lang:python] [lines:X-Y] [:hidefilename:] [title] %}"
FORMAT = re.compile(r"""^(?:\s+)?(?P<src>\S+)(?:\s+)?(?:(?:lang:)(?P<lang>\S+))?(?:\s+)?(?P<title>.+)?$""") FORMAT = re.compile(r"""
^(?:\s+)? # Allow whitespace at beginning
(?P<src>\S+) # Find the path
(?:\s+)? # Whitespace
(?:(?:lang:)(?P<lang>\S+))? # Optional language
(?:\s+)? # Whitespace
(?:(?:lines:)(?P<lines>\d+-\d+))? # Optional lines
(?:\s+)? # Whitespace
(?P<hidefilename>:hidefilename:)? # Hidefilename flag
(?:\s+)? # Whitespace
(?P<title>.+)?$ # Optional title
""", re.VERBOSE)
@LiquidTags.register('include_code') @LiquidTags.register('include_code')
def include_code(preprocessor, tag, markup): def include_code(preprocessor, tag, markup):
title = None title = None
lang = None lang = None
src = None src = None
@@ -47,8 +59,12 @@ def include_code(preprocessor, tag, markup):
match = FORMAT.search(markup) match = FORMAT.search(markup)
if match: if match:
argdict = match.groupdict() argdict = match.groupdict()
title = argdict['title'] title = argdict['title'] or ""
lang = argdict['lang'] lang = argdict['lang']
lines = argdict['lines']
hide_filename = bool(argdict['hidefilename'])
if lines:
first_line, last_line = map(int, lines.split("-"))
src = argdict['src'] src = argdict['src']
if not src: if not src:
@@ -62,12 +78,23 @@ def include_code(preprocessor, tag, markup):
if not os.path.exists(code_path): if not os.path.exists(code_path):
raise ValueError("File {0} could not be found".format(code_path)) raise ValueError("File {0} could not be found".format(code_path))
code = open(code_path).read() with open(code_path) as fh:
if lines:
if title: code = fh.readlines()[first_line - 1: last_line]
title = "{0} {1}".format(title, os.path.basename(src)) code[-1] = code[-1].rstrip()
code = "".join(code)
else: else:
title = os.path.basename(src) code = fh.read()
if not title and hide_filename:
raise ValueError("Either title must be specified or filename must "
"be available")
if not hide_filename:
title += " %s" % os.path.basename(src)
if lines:
title += " [Lines %s]" % lines
title = title.strip()
url = '/{0}/{1}'.format(code_dir, src) url = '/{0}/{1}'.format(code_dir, src)
url = re.sub('/+', '/', url) url = re.sub('/+', '/', url)