gnunetbib

Bibliography (BibTeX, based on AnonBib)
Log | Files | Refs | README | LICENSE

writeHTML.py (9204B)


      1 #!/usr/bin/python3
      2 # Copyright 2003-2008, Nick Mathewson.  See LICENSE for licensing info.
      3 # Copyright 2018, 2019 ng0 <ng0@n0.is>
      4 
      5 """
      6 Generate indices by author, topic, date, and BibTeX key.
      7 """
      8 
      9 from future.utils import raise_with_traceback
     10 from io import BytesIO ## for Python 3
     11 import sys
     12 import re
     13 import os
     14 import json
     15 import BibTeX
     16 import config
     17 
     18 
     19 assert sys.version_info[:3] >= (2, 2, 0)
     20 os.umask(0o22)
     21 
     22 def getTemplate(name):
     23     template_file = open(name)
     24     template = template_file.read()
     25     template_file.close()
     26     template_s, template_e = template.split("%(entries)s")
     27     return template_s, template_e
     28 
     29 def pathLength(s):
     30     n = 0
     31     while s:
     32         parent, leaf = os.path.split(s)
     33         if leaf != '' and leaf != '.':
     34             n += 1
     35         s = parent
     36     return n
     37 
     38 def writeBody(target_file, sections, section_urls, cache_path, base_url):
     39     """
     40     target_file: an open file
     41     sections: list of (sectionname, [list of BibTeXEntry])
     42     section_urls: map from sectionname to external url
     43     """
     44     for s, entries in sections:
     45         u = section_urls.get(s)
     46         sDisp = re.sub(r'\s+', ' ', s.strip())
     47         sDisp = sDisp.replace(" ", "&nbsp;")
     48         print("<section class='item-preview'>", file=target_file)
     49         if u:
     50             print(('<h3><a name="%s"></a><a href="%s">%s</a></h3>'
     51                    %((BibTeX.url_untranslate(s), u, sDisp))),
     52                   file=target_file)
     53         else:
     54             print(('<h3><a name="%s">%s</a></h3>'
     55                    %(BibTeX.url_untranslate(s), sDisp)),
     56                   file=target_file)
     57         #print("<section class='item-preview'>", file=target_file)
     58         for e in entries:
     59             print(e.to_html(cache_path=cache_path, base_url=base_url),
     60                   file=target_file)
     61         print("</section>", file=target_file)
     62 
     63 def writeHTML(f, sections, sectionType, fieldName, choices,
     64               tag, config, cache_url_path, section_urls={}):
     65     """
     66     sections: list of (sectionname, [list of BibTeXEntry])'''
     67     sectionType: str
     68     fieldName: str
     69     choices: list of (choice, url)
     70     """
     71 
     72     title = config.TAG_TITLES[tag]
     73     short_title = config.TAG_SHORT_TITLES[tag]
     74     # what used to be the sidebar:
     75     secStr = []
     76     for s, _ in sections:
     77         hts = re.sub(r'\s+', ' ', s.strip())
     78         hts = s.replace(" ", "&nbsp;")
     79         secStr.append("<li class='bar-item'><a class='bar-link' href='#%s'>%s</a></li>\n"%
     80                       ((BibTeX.url_untranslate(s), hts)))
     81     secStr = "".join(secStr)
     82 
     83     #
     84     tagListStr = []
     85     st = list(config.TAG_SHORT_TITLES.keys())
     86     st.sort()
     87     root = "../"*pathLength(config.TAG_DIRECTORIES[tag])
     88     if root == "": root = "."
     89     for t in st:
     90         name = config.TAG_SHORT_TITLES[t]
     91         if t == tag:
     92             tagListStr.append(name)
     93         else:
     94             url = BibTeX.smartJoin(root, config.TAG_DIRECTORIES[t], "date.html")
     95             tagListStr.append("<a href='%s'>%s</a>"%(url, name))
     96     tagListStr = "&nbsp;|&nbsp;".join(tagListStr)
     97 
     98     #
     99     choiceStr = []
    100     for choice, url in choices:
    101         if url:
    102             choiceStr.append("<a href='%s'>%s</a>"%(url, choice))
    103         else:
    104             choiceStr.append(choice)
    105 
    106     choiceStr = ("&nbsp;|&nbsp;".join(choiceStr))
    107 
    108     fields = {'command_line' :  "",
    109               'sectiontypes' :  sectionType,
    110               'choices' : choiceStr,
    111               'field': fieldName,
    112               'sections' : secStr,
    113               'otherbibs' : tagListStr,
    114               'title': title,
    115               'short_title': short_title,
    116               "root" : root,}
    117 
    118     header, footer = getTemplate(config.TEMPLATE_FILE)
    119     print(header%fields, file=f)
    120     writeBody(f, sections, section_urls, cache_path=cache_url_path,
    121               base_url=root)
    122     print(footer%fields, file=f)
    123 
    124 def jsonDumper(obj):
    125     if isinstance(obj, BibTeX.BibTeXEntry):
    126         e = obj.entries.copy()
    127         e['key'] = obj.key
    128         return e
    129     else:
    130         raise_with_traceback(TypeError("Do not know how to serialize %s"%(obj.__class,)))
    131 
    132 def writePageSet(config, bib, tag):
    133     if tag:
    134         bib_entries = [b for b in bib.entries
    135                        if tag in b.get('www_tags', "").split()]
    136     else:
    137         bib_entries = bib.entries[:]
    138 
    139     if not bib_entries:
    140         print("No entries with tag %r; skipping"%tag, file=sys.stderr)
    141         return
    142 
    143     tagdir = config.TAG_DIRECTORIES[tag]
    144     outdir = os.path.join(config.OUTPUT_DIR, tagdir)
    145     cache_url_path = BibTeX.smartJoin("../"*pathLength(tagdir),
    146                                       config.CACHE_DIR)
    147     if not os.path.exists(outdir):
    148         os.makedirs(outdir, 0o755)
    149     ##### Sorted views:
    150 
    151     ## By topic.
    152 
    153     entries = BibTeX.sortEntriesBy(bib_entries, "www_section", "ZZZZZZZZZZZZZZ")
    154     entries = BibTeX.splitSortedEntriesBy(entries, "www_section")
    155     if entries[-1][0].startswith("<span class='bad'>"):
    156         entries[-1] = ("Miscellaneous", entries[-1][1])
    157 
    158     entries = [(s, BibTeX.sortEntriesByDate(ents))
    159                for s, ents in entries]
    160 
    161     f = open(os.path.join(outdir, "topic.html"), 'w')
    162     writeHTML(f, entries, "Topics", "topic",
    163               (("By topic", None),
    164                ("By date", "./date.html"),
    165                ("By author", "./author.html")),
    166               tag=tag, config=config,
    167               cache_url_path=cache_url_path)
    168     f.close()
    169 
    170     ## By date.
    171 
    172     entries = BibTeX.sortEntriesByDate(bib_entries)
    173     entries = BibTeX.splitSortedEntriesBy(entries, 'year')
    174     for idx in -1, -2:
    175         try:
    176             if entries[idx][0].startswith("<span class='bad'>"):
    177                 entries[idx] = ("Unknown", entries[idx][1])
    178             elif entries[idx][0].startswith("forthcoming"):
    179                 entries[idx] = ("Forthcoming", entries[idx][1])
    180         except IndexError:
    181             continue
    182     sections = [ent[0] for ent in entries]
    183 
    184     first_year = int(entries[0][1][0]['year'])
    185     try:
    186         last_year = int(entries[-1][1][0].get('year'))
    187     except ValueError:
    188         last_year = int(entries[-2][1][0].get('year'))
    189 
    190     years = list(map(str, list(range(first_year, last_year+1))))
    191     if entries[-1][0] == 'Unknown':
    192         years.append("Unknown")
    193 
    194     date_file = open(os.path.join(outdir, "date.html"), 'w')
    195     writeHTML(date_file, entries, "Years", "date",
    196               (("By topic", "./topic.html"),
    197                ("By date", None),
    198                ("By author", "./author.html")),
    199               tag=tag, config=config,
    200               cache_url_path=cache_url_path)
    201     date_file.close()
    202 
    203     ## By author
    204     entries, url_map = BibTeX.splitEntriesByAuthor(bib_entries)
    205 
    206     author_file = open(os.path.join(outdir, "author.html"), 'w')
    207     writeHTML(author_file, entries, "Authors", "author",
    208               (("By topic", "./topic.html"),
    209                ("By date", "./date.html"),
    210                ("By author", None),),
    211               tag=tag, config=config,
    212               cache_url_path=cache_url_path,
    213               section_urls=url_map)
    214     author_file.close()
    215 
    216     ## The big BibTeX file
    217 
    218     entries = bib_entries[:]
    219     entries = [(ent.key, ent) for ent in entries]
    220     entries.sort()
    221     entries = [ent[1] for ent in entries]
    222 
    223     ## Finding the root directory is done by writeHTML(), but
    224     ## the BibTeX file doesn't use that, so repeat the code here
    225     root = "../"*pathLength(config.TAG_DIRECTORIES[tag])
    226     if root == "":
    227         root = "."
    228 
    229     header, footer = getTemplate(config.BIBTEX_TEMPLATE_FILE)
    230     bibtex_file = open(os.path.join(outdir, "bibtex.html"), 'w')
    231     print(header%{'command_line' : "",
    232                   'title': config.TAG_TITLES[tag],
    233                   'root': root},
    234           file=bibtex_file)
    235     for ent in entries:
    236         print((("<tr><td class='bibtex'><a name='%s'>%s</a>"
    237                 "<pre class='bibtex'>%s</pre></td></tr>")
    238                % (BibTeX.url_untranslate(ent.key),
    239                   ent.key,
    240                   ent.format(90, 8, 1))),
    241               file=bibtex_file)
    242     print(footer, file=bibtex_file)
    243     bibtex_file.close()
    244 
    245     bibtex_json_file = open(os.path.join(outdir, "bibtex.json"), 'w')
    246     json.dump(entries, bibtex_json_file, default=jsonDumper)
    247     bibtex_json_file.close()
    248 
    249     # Produce NAME with EXTENSION 'bib' as a FILE holding one
    250     # bib record.
    251     bibdir = config.BIB_DIRECTORY
    252     biboutdir = os.path.join(config.OUTPUT_DIR, bibdir)
    253     for ent in entries:
    254         bib_file_dir = os.path.join(biboutdir, ent.key)
    255         if not os.path.exists(bib_file_dir):
    256             os.makedirs(bib_file_dir, 0o755)
    257         single_bib_file = open(os.path.join(bib_file_dir,
    258                                             "record.bib"),
    259                                'w')
    260         print("%s" % ent.format(90, 8, 1), file=single_bib_file)
    261         single_bib_file.close()
    262 
    263 if __name__ == '__main__':
    264     if len(sys.argv) == 2:
    265         print("Loading from %s"%sys.argv[1])
    266     else:
    267         print("Expected a single configuration file as an argument",
    268               file=sys.stderr)
    269         sys.exit(1)
    270     config.load(sys.argv[1])
    271 
    272     bib = BibTeX.parseFile(config.MASTER_BIB)
    273 
    274     for tag in list(config.TAG_DIRECTORIES.keys()):
    275         writePageSet(config, bib, tag)