WIP local fonts
[Ultimately_Untrue_Thought.git] / plugins / tag_cloud.py
1 # from https://github.com/getpelican/pelican-plugins as of f4d717ff
2
3 # but with a fix to the alphabetical sorting
4
5 '''
6 tag_cloud
7 ===================================
8
9 This plugin generates a tag cloud from available tags
10 '''
11 from __future__ import unicode_literals
12
13 from collections import defaultdict
14 from operator import itemgetter
15
16 import logging
17 import math
18 import random
19
20 from pelican import signals
21
22 logger = logging.getLogger(__name__)
23
24
25 def set_default_settings(settings):
26     print(settings)
27     settings.setdefault('TAG_CLOUD_STEPS', 4)
28     settings.setdefault('TAG_CLOUD_MAX_ITEMS', 100)
29     settings.setdefault('TAG_CLOUD_SORTING', 'random')
30     settings.setdefault('TAG_CLOUD_BADGE', False)
31
32
33 def init_default_config(pelican):
34     from pelican.settings import DEFAULT_CONFIG
35     set_default_settings(DEFAULT_CONFIG)
36     if(pelican):
37             set_default_settings(pelican.settings)
38
39
40 def generate_tag_cloud(generator):
41     tag_cloud = defaultdict(int)
42     for article in generator.articles:
43         for tag in getattr(article, 'tags', []):
44             tag_cloud[tag] += 1
45
46     tag_cloud = sorted(tag_cloud.items(), key=itemgetter(1), reverse=True)
47     tag_cloud = tag_cloud[:generator.settings.get('TAG_CLOUD_MAX_ITEMS')]
48
49     tags = list(map(itemgetter(1), tag_cloud))
50     if tags:
51         max_count = max(tags)
52     steps = generator.settings.get('TAG_CLOUD_STEPS')
53
54     # calculate word sizes
55     def generate_tag(tag, count):
56         tag = (
57             tag,
58             int(math.floor(steps - (steps - 1) * math.log(count)
59                 / (math.log(max_count)or 1)))
60         )
61         if generator.settings.get('TAG_CLOUD_BADGE'):
62             tag += (count,)
63         return tag
64
65     tag_cloud = [
66         generate_tag(tag, count)
67         for tag, count in tag_cloud
68     ]
69
70     sorting = generator.settings.get('TAG_CLOUD_SORTING')
71
72     if sorting == 'alphabetically':
73         # `.lower()` to avoid putting all uppercase tags lexicographically
74         # before lowercase tags —ZMD
75         tag_cloud.sort(key=lambda elem: elem[0].name.lower())
76     elif sorting == 'alphabetically-rev':
77         tag_cloud.sort(key=lambda elem: elem[0].name, reverse=True)
78     elif sorting == 'size':
79         tag_cloud.sort(key=lambda elem: elem[1])
80     elif sorting == 'size-rev':
81         tag_cloud.sort(key=lambda elem: elem[1], reverse=True)
82     elif sorting == 'random':
83         random.shuffle(tag_cloud)
84     else:
85         logger.warning("setting for TAG_CLOUD_SORTING not recognized: %s, "
86                        "falling back to 'random'", sorting)
87         random.shuffle(tag_cloud)
88
89     # make available in context
90     generator.tag_cloud = tag_cloud
91     generator._update_context(['tag_cloud'])
92
93
94 def register():
95     signals.initialized.connect(init_default_config)
96     signals.article_generator_finalized.connect(generate_tag_cloud)