diff --git a/pokedex/db/markdown.py b/pokedex/db/markdown.py index 725f931..7e16c5d 100644 --- a/pokedex/db/markdown.py +++ b/pokedex/db/markdown.py @@ -47,19 +47,17 @@ class MarkdownString(object): def __html__(self): return self.as_html() - def as_html(self, object_url=None, identifier_url=None, make_link=None): + def as_html(self, extension_cls=None): """Returns the string as HTML. - If given, the optional arguments will be used instead of those in the - session's pokedex_link_maker. See MarkdownLinkMaker for documentation. + Pass a custom `extension_cls` to use your own class to generate links. + The default (and recommended superclass) is `PokedexLinkExtension`, + described below. """ - extension = self.session.pokedex_link_maker.get_extension( - self.language, - object_url=object_url, - identifier_url=identifier_url, - make_link=make_link, - ) + if extension_cls is None: + extension_cls = self.session.markdown_extension_class + extension = extension_cls(self.session) md = markdown.Markdown( extensions=['extra', extension], @@ -78,8 +76,8 @@ class MarkdownString(object): # the links by their text. # XXX: The tables get unaligned - link_maker = MarkdownLinkMaker(self.session) - pattern = PokedexLinkPattern(link_maker, self.language) + link_maker = PokedexLinkExtension(self.session) + pattern = PokedexLinkPattern(link_maker, self.session, self.language) regex = '()%s()' % pattern.regex def handleMatch(m): return pattern.handleMatch(m).text @@ -130,6 +128,7 @@ class MoveEffectPropertyMap(MoveEffectProperty): newdict[key] = _markdownify_effect_text(obj, newdict[key], key) return newdict + class PokedexLinkPattern(markdown.inlinepatterns.Pattern): """Matches [label]{category:target}. @@ -137,10 +136,10 @@ class PokedexLinkPattern(markdown.inlinepatterns.Pattern): """ regex = ur'(?x) \[ ([^]]*) \] \{ ([-a-z0-9]+) : ([-a-z0-9]+) \}' - def __init__(self, factory, string_language, game_language=None): + def __init__(self, factory, session, string_language=None, game_language=None): markdown.inlinepatterns.Pattern.__init__(self, self.regex) self.factory = factory - self.session = factory.session + self.session = session self.string_language = string_language self.game_language = game_language @@ -167,7 +166,7 @@ class PokedexLinkPattern(markdown.inlinepatterns.Pattern): name = None # Translations can be incomplete; in which case we want to use a # fallback. - if table in [tables.Type]: + if table in [tables.Type] and self.string_language: # Type wants to be localized to the same language as the text name = obj.name_map.get(self.string_language) if not name and self.game_language: @@ -181,31 +180,19 @@ class PokedexLinkPattern(markdown.inlinepatterns.Pattern): el.text = markdown.AtomicString(label or name) return el -class MarkdownLinkMaker(object): - """Creates Markdown extensions for handling links for the given session. +class PokedexLinkExtension(markdown.Extension): + u"""Markdown extension that translates the syntax used in effect text: - There are two ways to customize the link handling: either override the - *_url methods in a subclass, or give them as arguments to get_extension - (or MarkdownString.as_html). + `[label]{category:identifier}` is treated as a link to a Pokédex object, + where `category` is the table's singular name, and `label` is an optional + link title that defaults to the object's name in the current language. """ - def __init__(self, session=None): + def __init__(self, session): self.session = session - def get_extension(self, language=None, object_url=None, identifier_url=None, - make_link=None): - """Get a Markdown extension that handles links using the given language. - """ - link_maker = self - class LinkExtension(markdown.Extension): - def extendMarkdown(self, md, md_globals): - self.identifier_url = identifier_url or link_maker.identifier_url - self.object_url = object_url or link_maker.object_url - self.make_link = make_link or link_maker.make_link - self.session = link_maker.session - pattern = PokedexLinkPattern(self, language) - md.inlinePatterns['pokedex-link'] = pattern - - return LinkExtension() + def extendMarkdown(self, md, md_globals): + pattern = PokedexLinkPattern(self, self.session) + md.inlinePatterns['pokedex-link'] = pattern def make_link(self, category, obj, url, text): """Make an element @@ -218,17 +205,17 @@ class MarkdownLinkMaker(object): return el def identifier_url(self, category, identifier): - """Return the URL for the given {category:identifier} link + """Return the URL for the given {category:identifier} link. For ORM + objects, object_url is tried first. - For ORM objects, object_url is tried first - - Returns None by default, which causes to be used in place of + Returns None by default, which causes to be used in place of + . """ return None def object_url(self, category, obj): - """Return the URL for the ORM object obj + """Return the URL for the ORM object `obj`. - Returns None by default, which causes identifier_url to be used + Returns None by default, which causes identifier_url to be tried. """ return None diff --git a/pokedex/db/multilang.py b/pokedex/db/multilang.py index 5b3ecbb..642619a 100644 --- a/pokedex/db/multilang.py +++ b/pokedex/db/multilang.py @@ -193,12 +193,14 @@ class MultilangSession(Session): Needs to be used with `MultilangScopedSession`, below. """ default_language_id = None + markdown_extension_class = markdown.PokedexLinkExtension def __init__(self, *args, **kwargs): if 'default_language_id' in kwargs: self.default_language_id = kwargs.pop('default_language_id') - self.pokedex_link_maker = markdown.MarkdownLinkMaker(self) + if 'markdown_extension_class' in kwargs: + self.markdown_extension_class = kwargs.pop('markdown_extension_class') kwargs.setdefault('query_cls', MultilangQuery) @@ -218,7 +220,5 @@ class MultilangScopedSession(ScopedSession): self.registry().default_language_id = new @property - def pokedex_link_maker(self): - """Passes the new link maker through to the current session. - """ - return self.registry().pokedex_link_maker + def markdown_extension_class(self): + return self.registry().markdown_extension_class diff --git a/pokedex/tests/test_strings.py b/pokedex/tests/test_strings.py index 03ca60d..075bd2b 100644 --- a/pokedex/tests/test_strings.py +++ b/pokedex/tests/test_strings.py @@ -95,10 +95,18 @@ def test_markdown_string(): md = markdown.MarkdownString('[]{move:thunderbolt} [paralyzes]{mechanic:paralysis}', connection, en) assert unicode(md) == 'Thunderbolt paralyzes' assert md.as_html() == '

Thunderbolt paralyzes

' - assert md.as_html(object_url=lambda category, obj: "%s/%s" % (category, obj.identifier)) == ( + + class ObjectTestExtension(markdown.PokedexLinkExtension): + def object_url(self, category, obj): + return "%s/%s" % (category, obj.identifier) + + class IdentifierTestExtension(markdown.PokedexLinkExtension): + def identifier_url(self, category, ident): + return "%s/%s" % (category, ident) + + assert md.as_html(extension_cls=ObjectTestExtension) == ( '

Thunderbolt paralyzes

') - print md.as_html(identifier_url=lambda category, ident: "%s/%s" % (category, ident)) - assert md.as_html(identifier_url=lambda category, ident: "%s/%s" % (category, ident)) == ( + assert md.as_html(extension_cls=IdentifierTestExtension) == ( '

Thunderbolt paralyzes

') def markdown_column_params():