summaryrefslogtreecommitdiff
path: root/wikimini/templates
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2021-08-17 01:42:45 +0200
committerDaniel Schadt <kingdread@gmx.de>2021-08-17 01:42:45 +0200
commit1543a13c880bf22037466109cbd77b2d0c9f21c3 (patch)
tree3a3033cff52e12d84e923ec7810b32abc6799067 /wikimini/templates
parent02f21a9ca9f9842502f8b89cf77aafc05082bcf1 (diff)
downloadwikimini-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__.py58
-rw-r--r--wikimini/templates/cite.py36
-rw-r--r--wikimini/templates/convert.py21
-rw-r--r--wikimini/templates/language.py19
-rw-r--r--wikimini/templates/mainlinks.py15
-rw-r--r--wikimini/templates/quotes.py27
-rw-r--r--wikimini/templates/various.py19
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)