12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- '''
- 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 = tags[0]
- min_count = tags[-1]
- 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 - min_count + 1)
- / (math.log(max_count - min_count + 1) 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':
- tag_cloud.sort(key=lambda elem: elem[0].name)
- 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)
|