publist

managing my list of publications, talks, reviews
git clone https://a3nm.net/git/publist/
Log | Files | Refs | README | LICENSE

maketex.py (8920B)


      1 #!/usr/bin/python3
      2 # arguments: maketex.py LANGUAGE [FORMAT [PUBLICATION [FOLDER]]]
      3 # LANGUAGE is "en" (default) or "fr"
      4 # FORMAT is "tex" (default) or "bib"
      5 # PUBLICATION is the id of the publication to compile, or:
      6 # - "all" for all publications
      7 # - "all_formal" for all publications with formal details
      8 # - "cv" for all CV publications: all publications that are main, reviewed, not
      9 #   hidden (default)
     10 # FOLDER is where to find "publis" "venues" "authors", default is script dir
     11 
     12 from parserec import parse, getvenue, isurlrel, absurl, getyear, endswithpunct, authorname, stz
     13 import os
     14 import sys
     15 import argparse
     16 
     17 SITEURL="https://a3nm.net"
     18 LOCALURL=SITEURL+"/publications/"
     19 
     20 
     21 parser = argparse.ArgumentParser()
     22 parser.add_argument('lang', nargs='?', default='en', help="Language (default: 'en').")
     23 parser.add_argument('fmt', nargs='?', default='tex', help="Format (can be 'tex' for cvitems or 'bib' for bibtex, default: 'tex').")
     24 parser.add_argument('thepubli', nargs='?', default="all", help="ID of the specific publication to generate (default: 'all'; can also be 'cv').")
     25 parser.add_argument('--formal', action='store_true', help="Add full venue names and page numbers")
     26 
     27 # Parse arguments
     28 args = parser.parse_args()
     29 
     30 # Assign to global variables to maintain compatibility
     31 lang = args.lang
     32 fmt = args.fmt
     33 thepubli = args.thepubli
     34 formal_mode = args.formal
     35 
     36 # http://stackoverflow.com/a/1432949
     37 abspath = os.path.abspath(__file__)
     38 dname = os.path.dirname(abspath)
     39 
     40 folder = dname
     41 try:
     42     folder = sys.argv[4]
     43 except IndexError:
     44     pass
     45 os.chdir(dname)
     46 
     47 authorsz = dict((x['id'], x) for x in parse('authors'))
     48 venuesz = dict((x['id'], x) for x in parse('venues'))
     49 
     50 def mklinktex(text, url, sep=""):
     51     global SITEURL, LOCALURL
     52     if not url or url.lower() == "none":
     53         return (text)
     54     url = url.replace("_", "\\_").replace("%", "\\%") # naive escaping
     55     return ('\\href{%s}%s{%s}' % (absurl(url, SITEURL, LOCALURL), sep, text))
     56 
     57 def authortotex(author, withurl=False, sepnames=False):
     58     if withurl:
     59         return mklinktex(authorname(author, sepnames=sepnames), author['url'])
     60     else:
     61         return authorname(author, sepnames=sepnames)
     62 
     63 def venuetotex(venue, url, issue, dropyear=False):
     64     if dropyear and "'" in venue:
     65         # cut conf'1942, but beware of ' in titles
     66         venue_s = venue.split("'")
     67         if len(venue_s) == 2:
     68             if venue_s[1].isdigit():
     69                 venue = venue_s[0]
     70     try:
     71         if dropyear and venue[-4:].isdigit() and venue[-5] == ' ':
     72             venue = venue[:-5]
     73     except IndexError:
     74         pass
     75     if issue and not dropyear:
     76         venue += ', %s' % issue
     77     l = mklinktex(venue, url)
     78     if ' ' not in venue:
     79         return '\\mbox{%s}' % l
     80     return l
     81 
     82 def publitotex(publi, lang, venuesz, authorsz):
     83     name, fullname, typ, url, issue, oa, keywords = getvenue(publi, lang, venuesz, True)
     84     authors = ', '.join(authortotex(authorsz[author], withurl=True)
     85             for author in publi['authors'].split(' '))
     86     return("\\cvitem{\\bfseries %s}{%s.\\newline\\emph{%s}%s%s}" % (venuetotex(name, url,
     87         issue), authors, mklinktex(publi['title'], publi['url']), "" if
     88         endswithpunct(publi) else ".", "\\newline "
     89             + (publi['awardtex'] if 'awardtex' in publi.keys() else publi['award']) if 'award' in publi.keys() else ''))
     90 
     91 typetobibtype = {
     92         'journal': 'article',
     93         'newsletter': 'article',
     94         'conference': 'inproceedings',
     95         'patent': 'misc',
     96         'draft': 'unpublished',
     97         'phdthesis': 'phdthesis',
     98         'habilitationthesis': 'phdthesis',
     99         'mscthesis': 'mastersthesis',
    100         'demo': 'inproceedings',
    101         'spotlight': 'inproceedings',
    102         'posterpaper': 'inproceedings',
    103         'shortpaper': 'inproceedings',
    104         'note': 'unpublished',
    105         'submitted': 'unpublished',
    106         }
    107 typetoobjtype = {
    108         'journal': 'journal',
    109         'newsletter': 'journal',
    110         'conference': 'booktitle',
    111         'demo': 'booktitle',
    112         'spotlight': 'booktitle',
    113         'posterpaper': 'booktitle',
    114         'shortpaper': 'booktitle',
    115         'patent': 'howpublished',
    116         'draft': 'howpublished',
    117         'note': 'howpublished',
    118         'submitted': 'note',
    119         }
    120 legaltypes = ['phdthesis', 'habilitationthesis', 'patent', 'mscthesis', 'journal', 'conference',
    121         'note', 'demo', 'posterpaper', 'shortpaper', 'spotlight', 'book',
    122         'newsletter', 'draft', 'submitted']
    123 informaltypes = ['phdthesis', 'habilitationthesis', 'mscthesis', 'note', 'book', 'newsletter']
    124 
    125 def publitobib(publi, lang, venuesz, authorsz):
    126     global typetobibtype, typetoobjtype, legaltypes, SITEURL, LOCALURL
    127     global informaltypes
    128     global stz
    129     name, fullname, typ2, url, issue, oa, keywords = getvenue(publi, lang, venuesz)
    130     s = ""
    131     typ = publi.get('type', None)
    132     if typ == None or len(typ) == 0:
    133         if typ2 == None or len(typ2) == 0:
    134             typ = 'conference'
    135         else:
    136             typ = typ2
    137     assert(typ in legaltypes)
    138     if publi.get('status', None) == 'draft':
    139         typ = "draft"
    140     if publi.get('status', None) == 'submitted':
    141         typ = "submitted"
    142     knowntype = False
    143     for k in keywords:
    144         if k.startswith("TYPE"):
    145             knowntype = True
    146             if k[5:] in informaltypes:
    147                 keywords.add("informal")
    148     if not knowntype:
    149         keywords.add("TYPE" + typ)
    150         if typ in informaltypes:
    151             keywords.add("informal")
    152     if 'reviewed' in publi.keys() and publi['reviewed'] == 'yes':
    153         keywords.add('peer')
    154     if 'status' in publi.keys() and publi['status'] == 'submitted':
    155         keywords.add('underreview')
    156     if 'venue' in publi.keys():
    157         keywords.add('published')
    158     s += '@%s{%s,\n' % (typetobibtype[typ], publi['id'])
    159     authors = ' and '.join(authortotex(authorsz[author], sepnames=True) for author in
    160     publi['authors'].split(' '))
    161     s += '  author = {%s},\n' % authors
    162     s += '  title = {%s},\n' % mklinktex(publi['title'],
    163         publi['url'], sep="\n    ")
    164     s += '  year = {%s},\n' % str(getyear(publi))
    165     did_note = False
    166     if typ == "draft":
    167         assert (not did_note)
    168         did_note = True
    169         if 'url' in publi.keys() and publi['url'] != "none":
    170             s += '  note = {Preprint: \\url{%s}},\n' % (absurl(publi['url'], SITEURL, LOCALURL))
    171     elif typ in ["phdthesis", "mscthesis", "habilitationthesis"]:
    172         s += '  school = {%s},\n' % (mklinktex(publi['school'],
    173         publi['schoolurl']))
    174     else:
    175         s += '  %s = {%s},\n' % (typetoobjtype[typ], venuetotex(fullname if formal_mode else name, url, issue,
    176             True))
    177     if typ in ["demo", "posterpaper", "shortpaper", "spotlight", "habilitationthesis"]:
    178         assert (not did_note)
    179         did_note = True
    180         s += '  note = {%s},\n' % (stz[typ][lang])
    181     #if 'issue' in publi.keys():
    182     #    s += '  number = {%s},\n' % publi['issue']
    183     if formal_mode:
    184         for related in ['journalversion', 'conferenceversion']:
    185             if related in publi.keys():
    186                 assert (not did_note)
    187                 did_note = True
    188                 s += ('  note = {%s~\\cite{%s}},\n' %
    189                     (stz[related+"_explain"][lang], publi[related]))
    190     if 'doi' in publi.keys() and publi['doi'].lower() != 'none':
    191         s += '  doi = {%s},\n' % publi['doi']
    192     s += '  keywords = {' + ','.join(sorted(keywords)) + '},\n'
    193     if formal_mode:
    194         if 'extra' in publi.keys():
    195             s += publi['extra']
    196     s += '}\n\n'
    197     return s
    198 
    199 fmtdict = {
    200         'tex': publitotex,
    201         'bib': publitobib,
    202         }
    203 
    204 if __name__ == '__main__':
    205     seen = set()
    206     for publi in parse('publis'):
    207         assert (publi['id'] not in seen)
    208         seen.add(publi['id'])
    209         if thepubli not in ["all"]:
    210             if thepubli == "cv" or not thepubli:
    211                 if publi.get('reviewed', "no") == "no":
    212                     # only reviewed publis
    213                     continue
    214                 if publi.get('main', "no") == "no" and not publi.get('addcv', "no") == "yes":
    215                     # only main publis
    216                     continue
    217                 if publi.get('hidecv', "no") == "yes" or publi.get('oldcv',
    218                         "no") == "yes":
    219                     # hide some publis: hidecv are the ones I don't want, oldcv
    220                     # are the ones I'd want except they are too old
    221                     continue
    222             else:
    223                 # just one publi
    224                 if thepubli and publi['id'] != thepubli:
    225                     continue
    226         name, fullname, typ2, url, issue, oa, keywords = getvenue(publi, lang, venuesz)
    227         if fmt == 'tex' and typ2 == 'journal' and publi.get('issue', "none").lower() == "none":
    228             # in latex, no journal articles without an issue number yet
    229             continue
    230         print(fmtdict[fmt](publi, lang, venuesz, authorsz))
    231 
    232