Merge remote branch 'veekun/media-reorganization'
[zzz-pokedex.git] / pokedex / db / markdown.py
index dd86746..1ad304c 100644 (file)
@@ -5,8 +5,9 @@ The language used is a variation of Markdown and Markdown Extra.  There are
 docs for each at http://daringfireball.net/projects/markdown/ and
 http://michelf.com/projects/php-markdown/extra/ respectively.
 
-Pokédex links are represented with the extended syntax `[name]{type}`, e.g.,
-`[Eevee]{pokemon}`.  The actual code that parses these is in spline-pokedex.
+Pokédex links are represented with the syntax `[text]{type:identifier}`, e.g.,
+`[Eevee]{pokemon:eevee}`.  The actual code that parses these is in
+spline-pokedex.
 """
 from __future__ import absolute_import
 
@@ -31,11 +32,17 @@ class MarkdownString(object):
     def __unicode__(self):
         return self.source_text
 
+    def __str__(self):
+        return unicode(self.source_text).encode()
+
+    def __html__(self):
+        return self.as_html
+
     @property
     def as_html(self):
         """Returns the string as HTML4."""
 
-        if self._as_html:
+        if self._as_html is not None:
             return self._as_html
 
         md = markdown.Markdown(
@@ -72,12 +79,10 @@ class MoveEffectProperty(object):
         some_move.effect            # returns a MarkdownString
         some_move.effect.as_html    # returns a chunk of HTML
 
-    This class attempts to detect if the wrapped property is a dict-based
-    association proxy, and will act like such a dict if so.  Don't rely on it
-    for querying, of course.
-
     This class also performs simple substitution on the effect, replacing
     `$effect_chance` with the move's actual effect chance.
+
+    Use `MoveEffectPropertyMap` for dict-like association proxies.
     """
 
     def __init__(self, effect_column):
@@ -85,16 +90,19 @@ class MoveEffectProperty(object):
 
     def __get__(self, obj, cls):
         prop = getattr(obj.move_effect, self.effect_column)
-        if isinstance(prop, dict):
-            # Looks like a dict proxy; markdownify everyone
-            newdict = dict(prop)
-            for key in newdict:
-                newdict[key] = _markdownify_effect_text(obj, newdict[key])
-            return newdict
-
-        # Otherwise, scalar prop.  Boring
         return _markdownify_effect_text(obj, prop)
 
+class MoveEffectPropertyMap(MoveEffectProperty):
+    """Similar to `MoveEffectProperty`, but works on dict-like association
+    proxies.
+    """
+    def __get__(self, obj, cls):
+        prop = getattr(obj.move_effect, self.effect_column)
+        newdict = dict(prop)
+        for key in newdict:
+            newdict[key] = _markdownify_effect_text(obj, newdict[key])
+        return newdict
+
 class MarkdownColumn(sqlalchemy.types.TypeDecorator):
     """Generic SQLAlchemy column type for Markdown text.
 
@@ -105,6 +113,9 @@ class MarkdownColumn(sqlalchemy.types.TypeDecorator):
     impl = sqlalchemy.types.Unicode
 
     def process_bind_param(self, value, dialect):
+        if value is None:
+            return None
+
         if not isinstance(value, basestring):
             # Can't assign, e.g., MarkdownString objects yet
             raise NotImplementedError
@@ -112,4 +123,7 @@ class MarkdownColumn(sqlalchemy.types.TypeDecorator):
         return unicode(value)
 
     def process_result_value(self, value, dialect):
+        if value is None:
+            return None
+
         return MarkdownString(value)