Explorar o código

Enable multiple lines in value of metadata

 Now we can do some thing like summary in multiple line. From
 the many options in YAML only this is supported:

 key: >
     value spreads
     on multiple lines
Oz N Tiram %!s(int64=8) %!d(string=hai) anos
pai
achega
6b73ee359b
Modificáronse 1 ficheiros con 56 adicións e 4 borrados
  1. 56 4
      blogit/blogit.py

+ 56 - 4
blogit/blogit.py

@@ -41,6 +41,49 @@ try:
 except DistributionNotFound:  # pragma: no cover
     __version__ = '0.2'
 
+
+class Markdown(md2.Markdown):
+    _metadata_pat = re.compile("^---\W(?P<metadata>[\S+:\S+\s]+\n)---\n")
+    _key_val_pat = re.compile("^\w+:(?! >)\s*(?:[ \t].*\n?)+", re.MULTILINE)
+    # this allows key: >
+    #                   value
+    #                   conutiues over multiple lines
+    _key_val_block_pat = re.compile(
+        "(\w+:\s+>\n\s+[\S\s]+?)(?=\n\w+\s*:\s*\w+\n|\Z)")
+
+    def _extract_metadata(self, text):
+        # fast test
+        if not text.startswith("---"):
+            return text
+        match = self._metadata_pat.match(text)
+        if not match:
+            return text
+        tail = text[len(match.group(0)):]
+        metadata_str = match.groupdict()['metadata']
+
+        kv = re.findall(self._key_val_pat, metadata_str)
+        kvm = re.findall(self._key_val_block_pat, metadata_str)
+
+        for item in kv:
+            k, v = item.split(":", 1)
+            self.metadata[k.strip()] = v.strip()
+
+        for item in kvm:
+            k, v = item.split(": >", 1)
+            self.metadata[k.strip()] = " ".join(v.split())
+
+        return tail
+
+
+def markdown(text, html4tags=False, tab_width=4,
+             safe_mode=None, extras=None, link_patterns=None,
+             use_file_vars=False):
+    return Markdown(html4tags=html4tags, tab_width=tab_width,
+                    safe_mode=safe_mode, extras=extras,
+                    link_patterns=link_patterns,
+                    use_file_vars=use_file_vars).convert(text)
+
+
 logger = logging.getLogger(__name__)
 logger.setLevel(logging.DEBUG)
 ch = logging.StreamHandler()
@@ -56,8 +99,12 @@ try:
     jinja_env = Environment(lstrip_blocks=True, trim_blocks=True,
                             loader=FileSystemLoader(CONFIG['templates']))
 
-    jinja_env.filters['markdown'] = lambda text: Markup(md2.markdown(
-        text, extras=['fenced-code-blocks', 'hilite', 'tables', 'metadata']))
+    def s2md(text):
+        return Markup(markdown(text,
+                               extras=['fenced-code-blocks',
+                                       'hilite', 'tables']))
+
+    jinja_env.filters['markdown'] = s2md
 
     class DataBase(object):  # pragma: no coverage
 
@@ -273,15 +320,19 @@ class Entry(object):
 
     def prepare(self):
 
-        self.body_html = md2.markdown(
+        self.body_html = markdown(
             codecs.open(self.abspath, 'r').read(),
             extras=['fenced-code-blocks', 'hilite', 'tables', 'metadata'])
 
         self.header = self.body_html.metadata
+        """a blog post without tags causes an error ..."""
         if 'tags' in self.header:  # pages can lack tags
             self.header['tags'] = [t.strip().lower() for t in
                                    self.header['tags'].split(',')]
 
+        else:
+            self.header['tags'] = ("",)
+
         self.date = self.header.get('published', datetime.datetime.now())
 
         if isinstance(self.date, str):
@@ -398,8 +449,9 @@ def update_index(entries):
 
 
 def _filter_none_public(entries):
+    """by default entries are public, but one can hide them"""
     for e in entries:
-        if e.header.get('public').lower() in ('true', 'yes'):
+        if e.header.get('public', 'yes').lower() in ('true', 'yes'):
             yield e