Bladeren bron

Liquid Tags: line numbers for include_code

Lion Krischer 10 jaren geleden
bovenliggende
commit
97e2d7549b
2 gewijzigde bestanden met toevoegingen van 45 en 10 verwijderingen
  1. 9 1
      liquid_tags/Readme.md
  2. 36 9
      liquid_tags/include_code.py

+ 9 - 1
liquid_tags/Readme.md

@@ -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
 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:
 this default location can be changed by specifying

+ 36 - 9
liquid_tags/include_code.py

@@ -34,12 +34,24 @@ import os
 from .mdx_liquid_tags import LiquidTags
 
 
-SYNTAX = "{% include_code /path/to/code.py [lang:python] [title] %}"
-FORMAT = re.compile(r"""^(?:\s+)?(?P<src>\S+)(?:\s+)?(?:(?:lang:)(?P<lang>\S+))?(?:\s+)?(?P<title>.+)?$""")
+SYNTAX = "{% include_code /path/to/code.py [lang:python] [lines:X-Y] [:hidefilename:] [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')
 def include_code(preprocessor, tag, markup):
+
     title = None
     lang = None
     src = None
@@ -47,8 +59,12 @@ def include_code(preprocessor, tag, markup):
     match = FORMAT.search(markup)
     if match:
         argdict = match.groupdict()
-        title = argdict['title']
+        title = argdict['title'] or ""
         lang = argdict['lang']
+        lines = argdict['lines']
+        hide_filename = bool(argdict['hidefilename'])
+        if lines:
+            first_line, last_line = map(int, lines.split("-"))
         src = argdict['src']
 
     if not src:
@@ -62,12 +78,23 @@ def include_code(preprocessor, tag, markup):
     if not os.path.exists(code_path):
         raise ValueError("File {0} could not be found".format(code_path))
 
-    code = open(code_path).read()
-
-    if title:
-        title = "{0} {1}".format(title, os.path.basename(src))
-    else:
-        title = os.path.basename(src)
+    with open(code_path) as fh:
+        if lines:
+            code = fh.readlines()[first_line - 1: last_line]
+            code[-1] = code[-1].rstrip()
+            code = "".join(code)
+        else:
+            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 = re.sub('/+', '/', url)