2 u
"""Implements the markup used for description and effect text in the database.
4 The language used is a variation of Markdown and Markdown Extra. There are
5 docs for each at http://daringfireball.net/projects/markdown/ and
6 http://michelf.com/projects/php-markdown/extra/ respectively.
8 Pokédex links are represented with the extended syntax `[name]{type}`, e.g.,
9 `[Eevee]{pokemon}`. The actual code that parses these is in spline-pokedex.
11 from __future__
import absolute_import
14 import sqlalchemy
.types
16 class MarkdownString(object):
17 """Wraps a Markdown string. Stringifies to the original text, but .as_html
18 will return an HTML rendering.
20 To add extensions to the rendering (which is necessary for rendering links
21 correctly, and which spline-pokedex does), you must append to this class's
22 `markdown_extensions` list. Yep, that's gross.
25 markdown_extensions
= ['extra']
27 def __init__(self
, source_text
):
28 self
.source_text
= source_text
31 def __unicode__(self
):
32 return self
.source_text
36 """Returns the string as HTML4."""
41 md
= markdown
.Markdown(
42 extensions
=self
.markdown_extensions
,
44 output_format
='xhtml1',
47 self
._as_html
= md
.convert(self
.source_text
)
53 """Returns the string in a plaintext-friendly form.
55 At the moment, this is just the original source text.
57 return self
.source_text
60 class _MoveEffects(object):
61 def __init__(self
, effect_column
, move
):
62 self
.effect_column
= effect_column
65 def __contains__(self
, lang
):
66 return lang
in self
.move
.move_effect
.prose
68 def __getitem__(self
, lang
):
70 effect_text
= getattr(self
.move
.move_effect
.prose
[lang
], self
.effect_column
)
71 except AttributeError:
73 effect_text
= effect_text
.replace(
75 unicode(self
.move
.effect_chance
),
78 return MarkdownString(effect_text
)
80 class MoveEffectProperty(object):
81 """Property that wraps a move effect. Used like this:
83 MoveClass.effect = MoveEffectProperty('effect')
85 some_move.effect # returns a MarkdownString
86 some_move.effect.as_html # returns a chunk of HTML
88 This class also performs simple substitution on the effect, replacing
89 `$effect_chance` with the move's actual effect chance.
92 def __init__(self
, effect_column
):
93 self
.effect_column
= effect_column
95 def __get__(self
, move
, move_class
):
97 # Don't crash with getattr on the class
99 return _MoveEffects(self
.effect_column
, move
)['en']
101 class MoveEffectsProperty(object):
102 """Property that wraps move effects. Used like this:
104 MoveClass.effects = MoveEffectProperty('effect')
106 some_move.effects[lang] # returns a MarkdownString
107 some_move.effects[lang].as_html # returns a chunk of HTML
109 This class also performs simple substitution on the effect, replacing
110 `$effect_chance` with the move's actual effect chance.
113 def __init__(self
, effect_column
):
114 self
.effect_column
= effect_column
116 def __get__(self
, move
, move_class
):
117 return _MoveEffects(self
.effect_column
, move
)
119 class MarkdownColumn(sqlalchemy
.types
.TypeDecorator
):
120 """Generic SQLAlchemy column type for Markdown text.
122 Do NOT use this for move effects! They need to know what move they belong
123 to so they can fill in, e.g., effect chances. Use the MoveEffectProperty
124 property class above.
126 impl
= sqlalchemy
.types
.Unicode
128 def process_bind_param(self
, value
, dialect
):
129 if not isinstance(value
, basestring
):
130 # Can't assign, e.g., MarkdownString objects yet
131 raise NotImplementedError
133 return unicode(value
)
135 def process_result_value(self
, value
, dialect
):
136 return MarkdownString(value
)