--- /dev/null
+# from https://github.com/getpelican/pelican-plugins as of f4d717ff
+
+# but with a fix to the alphabetical sorting
+
+'''
+tag_cloud
+===================================
+
+This plugin generates a tag cloud from available tags
+'''
+from __future__ import unicode_literals
+
+from collections import defaultdict
+from operator import itemgetter
+
+import logging
+import math
+import random
+
+from pelican import signals
+
+logger = logging.getLogger(__name__)
+
+
+def set_default_settings(settings):
+ settings.setdefault('TAG_CLOUD_STEPS', 4)
+ settings.setdefault('TAG_CLOUD_MAX_ITEMS', 100)
+ settings.setdefault('TAG_CLOUD_SORTING', 'random')
+ settings.setdefault('TAG_CLOUD_BADGE', False)
+
+
+def init_default_config(pelican):
+ from pelican.settings import DEFAULT_CONFIG
+ set_default_settings(DEFAULT_CONFIG)
+ if(pelican):
+ set_default_settings(pelican.settings)
+
+
+def generate_tag_cloud(generator):
+ tag_cloud = defaultdict(int)
+ for article in generator.articles:
+ for tag in getattr(article, 'tags', []):
+ tag_cloud[tag] += 1
+
+ tag_cloud = sorted(tag_cloud.items(), key=itemgetter(1), reverse=True)
+ tag_cloud = tag_cloud[:generator.settings.get('TAG_CLOUD_MAX_ITEMS')]
+
+ tags = list(map(itemgetter(1), tag_cloud))
+ if tags:
+ max_count = max(tags)
+ steps = generator.settings.get('TAG_CLOUD_STEPS')
+
+ # calculate word sizes
+ def generate_tag(tag, count):
+ tag = (
+ tag,
+ int(math.floor(steps - (steps - 1) * math.log(count)
+ / (math.log(max_count)or 1)))
+ )
+ if generator.settings.get('TAG_CLOUD_BADGE'):
+ tag += (count,)
+ return tag
+
+ tag_cloud = [
+ generate_tag(tag, count)
+ for tag, count in tag_cloud
+ ]
+
+ sorting = generator.settings.get('TAG_CLOUD_SORTING')
+
+ if sorting == 'alphabetically':
+ # `.lower()` to avoid putting all uppercase tags lexicographically
+ # before lowercase tags —ZMD
+ tag_cloud.sort(key=lambda elem: elem[0].name.lower())
+ elif sorting == 'alphabetically-rev':
+ tag_cloud.sort(key=lambda elem: elem[0].name, reverse=True)
+ elif sorting == 'size':
+ tag_cloud.sort(key=lambda elem: elem[1])
+ elif sorting == 'size-rev':
+ tag_cloud.sort(key=lambda elem: elem[1], reverse=True)
+ elif sorting == 'random':
+ random.shuffle(tag_cloud)
+ else:
+ logger.warning("setting for TAG_CLOUD_SORTING not recognized: %s, "
+ "falling back to 'random'", sorting)
+ random.shuffle(tag_cloud)
+
+ # make available in context
+ generator.tag_cloud = tag_cloud
+ generator._update_context(['tag_cloud'])
+
+
+def register():
+ signals.initialized.connect(init_default_config)
+ signals.article_generator_finalized.connect(generate_tag_cloud)