publist

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

maketex.py (9240B)


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