1 # from https://github.com/getpelican/pelican-plugins as of f4d717ff
3 # but with a fix to the alphabetical sorting
7 ===================================
9 This plugin generates a tag cloud from available tags
11 from __future__ import unicode_literals
13 from collections import defaultdict
14 from operator import itemgetter
20 from pelican import signals
22 logger = logging.getLogger(__name__)
25 def set_default_settings(settings):
26 settings.setdefault('TAG_CLOUD_STEPS', 4)
27 settings.setdefault('TAG_CLOUD_MAX_ITEMS', 100)
28 settings.setdefault('TAG_CLOUD_SORTING', 'random')
29 settings.setdefault('TAG_CLOUD_BADGE', False)
32 def init_default_config(pelican):
33 from pelican.settings import DEFAULT_CONFIG
34 set_default_settings(DEFAULT_CONFIG)
36 set_default_settings(pelican.settings)
39 def alphabetic_sort_key(element):
41 if tag[0] == "æ": # exceptional case
43 # `.lower()` to avoid putting all uppercase tags lexicographically
44 # before lowercase tags —ZMD
48 def generate_tag_cloud(generator):
49 tag_cloud = defaultdict(int)
50 for article in generator.articles:
51 for tag in getattr(article, 'tags', []):
54 tag_cloud = sorted(tag_cloud.items(), key=itemgetter(1), reverse=True)
55 tag_cloud = tag_cloud[:generator.settings.get('TAG_CLOUD_MAX_ITEMS')]
57 tags = list(map(itemgetter(1), tag_cloud))
60 steps = generator.settings.get('TAG_CLOUD_STEPS')
62 # calculate word sizes
63 def generate_tag(tag, count):
66 int(math.floor(steps - (steps - 1) * math.log(count)
67 / (math.log(max_count)or 1)))
69 if generator.settings.get('TAG_CLOUD_BADGE'):
74 generate_tag(tag, count)
75 for tag, count in tag_cloud
78 sorting = generator.settings.get('TAG_CLOUD_SORTING')
80 if sorting == 'alphabetically':
81 tag_cloud.sort(key=alphabetic_sort_key)
82 elif sorting == 'alphabetically-rev':
83 tag_cloud.sort(key=lambda elem: elem[0].name, reverse=True)
84 elif sorting == 'size':
85 tag_cloud.sort(key=lambda elem: elem[1])
86 elif sorting == 'size-rev':
87 tag_cloud.sort(key=lambda elem: elem[1], reverse=True)
88 elif sorting == 'random':
89 random.shuffle(tag_cloud)
91 logger.warning("setting for TAG_CLOUD_SORTING not recognized: %s, "
92 "falling back to 'random'", sorting)
93 random.shuffle(tag_cloud)
95 # make available in context
96 generator.tag_cloud = tag_cloud
97 generator._update_context(['tag_cloud'])
101 signals.initialized.connect(init_default_config)
102 signals.article_generator_finalized.connect(generate_tag_cloud)