diff options
author | Daniel Schadt <kingdread@gmx.de> | 2021-08-17 01:42:45 +0200 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2021-08-17 01:42:45 +0200 |
commit | 1543a13c880bf22037466109cbd77b2d0c9f21c3 (patch) | |
tree | 3a3033cff52e12d84e923ec7810b32abc6799067 /wikimini/templates | |
parent | 02f21a9ca9f9842502f8b89cf77aafc05082bcf1 (diff) | |
download | wikimini-1543a13c880bf22037466109cbd77b2d0c9f21c3.tar.gz wikimini-1543a13c880bf22037466109cbd77b2d0c9f21c3.tar.bz2 wikimini-1543a13c880bf22037466109cbd77b2d0c9f21c3.zip |
Reorganize code
Cramming everything into a single file is not necessarily good, so this
patch splits it up a bit. Furthermore, the templates are no longer
hardcoded, but managed through a registry.
This breaks the lang-ar implementation, which was a weird special case
anyway. Properly fixing it would be to include all country codes.
Diffstat (limited to 'wikimini/templates')
-rw-r--r-- | wikimini/templates/__init__.py | 58 | ||||
-rw-r--r-- | wikimini/templates/cite.py | 36 | ||||
-rw-r--r-- | wikimini/templates/convert.py | 21 | ||||
-rw-r--r-- | wikimini/templates/language.py | 19 | ||||
-rw-r--r-- | wikimini/templates/mainlinks.py | 15 | ||||
-rw-r--r-- | wikimini/templates/quotes.py | 27 | ||||
-rw-r--r-- | wikimini/templates/various.py | 19 |
7 files changed, 195 insertions, 0 deletions
diff --git a/wikimini/templates/__init__.py b/wikimini/templates/__init__.py new file mode 100644 index 0000000..9e983e1 --- /dev/null +++ b/wikimini/templates/__init__.py @@ -0,0 +1,58 @@ +"""Template substitution for Wikimini. + +This module contains functions that mimic Wikipedia's templates. + +A template is a function that takes the :class:`~wikimini.Wikimini` instance and the +:class:`~mwparserfromhell.nodes.template.Template` node to convert, and returns +a string with the template output (see :const:`Template`). +""" +from typing import Callable, Optional + +import mwparserfromhell as mwp + +from .. import Wikimini + + +#: The type of a template render function. +Template = Callable[[Wikimini, mwp.nodes.template.Template], str] + + +class Registry: + """A container for all available templates.""" + def __init__(self): + self.templates = {} + + def get(self, name: str) -> Optional[Template]: + """Retrieves the template with the given name. + + Args: + name: The name of the template. + + Returns: + The template if found, or :any:`None`. + """ + # Are templates case-sensitive? + # Yes, except usually the first letter. + # (https://en.wikipedia.org/wiki/Help:A_quick_guide_to_templates#FAQ) + template = self.templates.get(name) + if template is None: + template = self.templates.get(name[0].swapcase() + name[1:]) + return template + + def insert(self, name: str, template: Template): + """Insert the given template into the registry. + + Args: + name: The name of the template. + template: The template to insert. + """ + self.templates[name] = template + + +#: The global template registry. +registry = Registry() + + +from . import ( # pylint: disable=wrong-import-position + convert, mainlinks, quotes, various, cite, language +) diff --git a/wikimini/templates/cite.py b/wikimini/templates/cite.py new file mode 100644 index 0000000..ac4f597 --- /dev/null +++ b/wikimini/templates/cite.py @@ -0,0 +1,36 @@ +"""Citation related templates.""" +from . import registry + + +def tmpl_citation(wikimini, obj): + """Renders the ``{{citation|...}}`` template.""" + title = obj.get("title", None) + if title: + title = title.value.strip_code().strip() + else: + title = "Untitled" + names = [] + for idx in ["%", "%1", "%2", "%3", "%4", "%5", "editor1-%"]: + last = obj.get(idx.replace("%", "last"), None) + if last: + last = last.value.strip_code().strip() + first = obj.get(idx.replace("%", "first"), None) + if first: + first = first.value.strip_code().strip() + if last and first: + names.append(f"{last}, {first}") + elif last: + names.append(last) + elif first: + names.append(first) + return "{} ({})".format(title, "; ".join(names)) + + +for name in ["cite", "citation", "cite arXiv", "cite AV media", "cite book", + "cite conference", "cite encyclopedia", "cite episode", + "cite interview", "cite journal", "cite magazine", + "cite mailing list", "cite map", "cite news", "cite newsgroup", + "cite podcast", "cite press release", "cite report", + "cite serial", "cite sign", "cite speech", "cite techreport", + "cite thesis", "cite web"]: + registry.insert(name, tmpl_citation) diff --git a/wikimini/templates/convert.py b/wikimini/templates/convert.py new file mode 100644 index 0000000..a7a3f44 --- /dev/null +++ b/wikimini/templates/convert.py @@ -0,0 +1,21 @@ +"""Implementations for the unit conversion templates.""" +from . import registry + + +def tmpl_convert(wikimini, obj): + """Renders the ``{{convert|...}}`` template.""" + if str(obj.params[1]) in {"-", "to"}: + return "{0}{3} {1} {2}{3}".format( + obj.params[0].value.strip_code(), + obj.params[1].value.strip_code(), + obj.params[2].value.strip_code(), + obj.params[3].value.strip_code(), + ) + return "{}{}".format( + obj.params[0].value.strip_code(), + obj.params[1].value.strip_code(), + ) + + +registry.insert("convert", tmpl_convert) +registry.insert("cvt", tmpl_convert) diff --git a/wikimini/templates/language.py b/wikimini/templates/language.py new file mode 100644 index 0000000..052b7f0 --- /dev/null +++ b/wikimini/templates/language.py @@ -0,0 +1,19 @@ +"""Language related templates.""" +from . import registry + + +def tmpl_ipa(wikimini, obj): + """Renders the ``{{IPA|...}}`` template.""" + return "pronounced [{}]".format(wikimini._convert(obj.params[0].value)) + + +registry.insert("IPA", tmpl_ipa) + + +def tmpl_lang(wikimini, obj): + """Renders the ``{{Lang|...}}`` template.""" + return wikimini._convert(obj.params[1].value) + + +registry.insert("lang", tmpl_lang) +registry.insert("script", tmpl_lang) diff --git a/wikimini/templates/mainlinks.py b/wikimini/templates/mainlinks.py new file mode 100644 index 0000000..ffcbc5e --- /dev/null +++ b/wikimini/templates/mainlinks.py @@ -0,0 +1,15 @@ +"""Renders templates that link to further articles.""" +from . import registry + + +def tmpl_main(wikimini, obj): + """Renders the ``{{main|...}}`` template.""" + links = [ + "=> {} {}".format(wikimini.page_url(str(t.value)), t.value) + for t in obj.params + ] + return "Main articles:\n{}\n".format("\n".join(links)) + + +registry.insert("main", tmpl_main) +registry.insert("main article", tmpl_main) diff --git a/wikimini/templates/quotes.py b/wikimini/templates/quotes.py new file mode 100644 index 0000000..7c1429d --- /dev/null +++ b/wikimini/templates/quotes.py @@ -0,0 +1,27 @@ +"""Renders various quote related templates.""" +from . import registry + + +def tmpl_quote(wikimini, obj): + """Renders the ``{{blockquote|...}}`` template.""" + text = obj.get("text", None) + if not text: + return "" + content = text.value.strip_code() + lines = content.split("\n") + return "\n".join(f"> {line}" for line in lines) + + +registry.insert("blockquote", tmpl_quote) +registry.insert("quote", tmpl_quote) + + +def tmpl_cquote(wikimini, obj): + """Renders the ``{{cquote|...}}`` template.""" + text = obj.params[0] + content = text.value.strip_code() + lines = content.split("\n") + return "\n".join(f"> {line}" for line in lines) + + +registry.insert("cquote", tmpl_cquote) diff --git a/wikimini/templates/various.py b/wikimini/templates/various.py new file mode 100644 index 0000000..8c6e0d5 --- /dev/null +++ b/wikimini/templates/various.py @@ -0,0 +1,19 @@ +"""Various small templates.""" +from . import registry + + +def tmpl_reign(wikimini, obj): + """Renders the ``{{reign|...}}`` template.""" + if not obj.params: + return "r. " + first = obj.params[0].value.strip_code().strip() or "?" + second = "" + if len(obj.params) > 1: + second = obj.params[1].value.strip_code().strip() + return f"r. {first} – {second}" + + +registry.insert("reign", tmpl_reign) +registry.insert("ruled", tmpl_reign) +registry.insert("rexit", tmpl_reign) +registry.insert("r.", tmpl_reign) |