Bläddra i källkod

Create the glossary plugin, which creates a 'definitions' variable to page templates, containing all information on definition lists found on articles and pages.

Add the source object to the dict, instead of just passing the title.

Add example usage.
Leonardo 7 år sedan
förälder
incheckning
6298afc2f5
4 ändrade filer med 142 tillägg och 0 borttagningar
  1. 2 0
      Readme.rst
  2. 1 0
      glossary/__init__.py
  3. 64 0
      glossary/glossary.py
  4. 75 0
      glossary/readme.md

+ 2 - 0
Readme.rst

@@ -100,6 +100,8 @@ GitHub activity           On the template side, you just have to iterate over th
 
 Global license            Allows you to define a ``LICENSE`` setting and adds the contents of that license variable to the article's context
 
+Glossary                  Adds a variable containing definitions extracted from definition lists in articles and pages. This variable is visible to all page templates.
+
 Goodreads activity        Lists books from your Goodreads shelves
 
 GooglePlus comments       Adds GooglePlus comments to Pelican

+ 1 - 0
glossary/__init__.py

@@ -0,0 +1 @@
+from .glossary import *

+ 64 - 0
glossary/glossary.py

@@ -0,0 +1,64 @@
+"""
+Builds a glossary page containing definition lists found in articles
+and pages, and adds a `definitions` variable visible to all page templates.
+
+"""
+
+from pelican import signals, contents
+from bs4 import BeautifulSoup
+
+
+class Definitions():
+    definitions = []
+    exclude = ['Hint']
+
+
+def extract_definitions(content):
+    soup = BeautifulSoup(content.content, 'html.parser')
+
+    for def_list in soup.find_all('dl'):
+        defns = []
+        for def_title in def_list.find_all('dt'):
+            if def_title.text not in Definitions.exclude:
+                defns.append(
+                    {'title': get_title(def_title),
+                     'link': get_link(def_title, content.url),
+                     'definition': get_def(def_title),
+                     'source': content})
+
+        for defn in defns:
+            defn['see_also'] = [also for also in defns if also is not defn]
+
+        Definitions.definitions += defns
+
+
+def get_title(def_title):
+    return def_title.text
+
+
+def get_link(def_title, url):
+    a_tag = def_title.findChild('a')
+    if a_tag and a_tag['href']:
+        return url + a_tag['href']
+    else:
+        return None
+
+
+def get_def(def_title):
+    return ''.join(str(t) for t in def_title.find_next('dd').contents)
+
+
+def parse_content(content):
+    if isinstance(content, contents.Static) or not content.content:
+        return
+    else:
+        return extract_definitions(content)
+
+
+def set_definitions(generator, metadata):
+    generator.context['definitions'] = Definitions.definitions
+
+
+def register():
+    signals.content_object_init.connect(parse_content)
+    signals.page_generator_context.connect(set_definitions)

+ 75 - 0
glossary/readme.md

@@ -0,0 +1,75 @@
+# Glossary
+
+Builds a glossary page containing definition lists found in articles and
+pages.
+
+If you have an article or page that generates the following:
+
+file `defns.html` titled "My definitions"
+```
+<dl>
+  <dt><a href="some-link.html">My Term</a></dt>
+  <dd>This is definition for My Term.</dd>
+  <dt>Another Term</dt>
+  <dd>And another definition.</dd>
+</dl>
+```
+
+This plugin will extract all such definitions and put them inside the
+`definitions` variable in the pelican context. It will be seen by all page
+templates.
+
+The `definitions` variable will have the following attributes:
++ `title`, the definition title, inside <dt> tags,
++ `definition`, the definition, inside <dd> tags,
++ `link`, if the <dt> tags enclose a <a> tag, it will be stored here, or
+  None,
++ `source`, the article or page that contains this definition list,
++ `see_also`, containing a list of dicts just like this, made from other
+  definitions in the same list.
+
+For example, for the above html code, the `definitions` variable would look
+like the following:
+
+```
+definitions = [dict1, dict2]
+dict1.title = "My Term"
+dict1.definition = "This is definition for My Term."
+dict1.link = 'some-link.html'
+dict1.source = <content Object referring to "My definitions">
+dict1.see_also = [dict2]
+
+dict2.title = "Another Term"
+dict2.definition = "And another definition."
+dict2.link = None
+dict2.source = <content Object referring to "My definitions">
+dict2.see_also = [dict1]
+```
+
+Note the `link` attribute does not necessarily point to `source.url`.
+
+Next is an example usage of the `definitions` variable.
+
+```
+{% for def in definitions | sort(attribute='title') %}
+<dl>
+  <dt>{{ def.title }}</dt>
+  <dd>
+    <p>{{ def.definition }}</p>
+    <p>
+    Defined in:
+    {% if def.link %}<a href="{{ def.link }}">{% endif %}
+    {{ def.source.title }}
+    {% if def.link %}</a>{% endif %}.
+
+    {% if def.see_also %}
+    See also:
+    {% for also in def.see_also %}
+    <a href="{{ also.link }}">{{ also.title }}</a>
+    {% endfor%}
+    {% endif %}
+    </p>
+  </dd>
+</dl>
+{% endfor %}
+```