# -*- coding: utf-8 -*- # Copyright © 2016-2017 Hong Xu . # Permission is hereby granted, free of charge, to any # person obtaining a copy of this software and associated # documentation files (the "Software"), to deal in the # Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the # Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice # shall be included in all copies or substantial portions of # the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS # OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import os import sys from docutils import nodes from docutils.parsers.rst import Directive, directives from nikola.plugin_categories import RestExtension from nikola.utils import get_logger, STDERR_HANDLER from pybtex.database import BibliographyData, Entry from pybtex.database.input.bibtex import Parser from pybtex.markup import LaTeXParser from pybtex.style.formatting.unsrt import Style as UnsrtStyle from pybtex.style.template import href, tag LOGGER = get_logger('scan_posts', STDERR_HANDLER) class Style(UnsrtStyle): """The style for publication listing. It hyperlinks the title to the detail page if user sets it. """ def __init__(self, detail_page_url): super().__init__() self.detail_page_url = detail_page_url def format_title(self, e, which_field, as_sentence=True): "Override the UnsrtStyle format_title(), so we have the title hyperlinked." title = tag('strong')[super().format_title(e, which_field, as_sentence)] if self.detail_page_url: url = '/'.join((self.detail_page_url, e.label + '.html')) return href[url, title] else: return title class Plugin(RestExtension): name = "publication_list" def set_site(self, site): self.site = site directives.register_directive('publication_list', PublicationList) PublicationList.site = self.site PublicationList.output_folder = self.site.config['OUTPUT_FOLDER'] return super(Plugin, self).set_site(site) class PublicationList(Directive): """ Directive to list publications. """ has_content = False required_arguments = 1 optional_arguments = sys.maxsize option_spec = { 'bibtex_dir': directives.unchanged, 'detail_page_dir': directives.unchanged, 'highlight_author': directives.unchanged, 'style': directives.unchanged } def run(self): bibtex_dir = self.options.get('bibtex_dir', 'bibtex') detail_page_dir = self.options.get('detail_page_dir', 'papers') highlight_authors = self.options.get('highlight_author', None) if highlight_authors: highlight_authors = highlight_authors.split(';') style = Style(self.site.config['BASE_URL'] + detail_page_dir if detail_page_dir else None) self.state.document.settings.record_dependencies.add(*self.arguments) all_entries = [] labels = set() for a in self.arguments: parser = Parser() for item in parser.parse_file(a).entries.items(): if item[0] in labels: # duplicated entries LOGGER.warning( ("publication_list: BibTeX entries with duplicated labels are found. " "Only the first occurrence will be used.")) continue labels.add(item[0]) all_entries.append(item) # Sort the publication entries by year reversed data = sorted(all_entries, key=lambda e: e[1].fields['year'], reverse=True) html = '
\n' cur_year = None if bibtex_dir: # create the bibtex dir if the option is set try: os.makedirs(os.path.sep.join((self.output_folder, bibtex_dir))) except OSError: # probably because the dir already exists pass if detail_page_dir: # create the detail page dir if the option is set try: os.makedirs(os.path.sep.join((self.output_folder, detail_page_dir))) except OSError: # probably because the dir already exists pass for label, entry in data: # print a year title when year changes if entry.fields['year'] != cur_year: if cur_year is not None: # not first year group html += '' cur_year = entry.fields['year'] html += '

{}

\n' html += '
' return [nodes.raw('', html, format='html'), ]