publist

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

maketex.py (8767B)


      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         s += '  note = {Preprint: \\url{%s}},\n' % (absurl(publi['url'], SITEURL, LOCALURL))
    170     elif typ in ["phdthesis", "mscthesis", "habilitationthesis"]:
    171         s += '  school = {%s},\n' % (mklinktex(publi['school'],
    172         publi['schoolurl']))
    173     else:
    174         s += '  %s = {%s},\n' % (typetoobjtype[typ], venuetotex(fullname if formal_mode else name, url, issue,
    175             True))
    176     if typ in ["demo", "posterpaper", "shortpaper", "spotlight", "habilitationthesis"]:
    177         assert (not did_note)
    178         did_note = True
    179         s += '  note = {%s},\n' % (stz[typ][lang])
    180     #if 'issue' in publi.keys():
    181     #    s += '  number = {%s},\n' % publi['issue']
    182     if formal_mode:
    183         for related in ['journalversion', 'conferenceversion']:
    184             if related in publi.keys():
    185                 assert (not did_note)
    186                 did_note = True
    187                 s += ('  note = {%s~\\cite{%s}},\n' %
    188                     (stz[related+"_explain"][lang], publi[related]))
    189     if 'doi' in publi.keys() and publi['doi'].lower() != 'none':
    190         s += '  doi = {%s},\n' % publi['doi']
    191     s += '  keywords = {' + ','.join(sorted(keywords)) + '},\n'
    192     if formal_mode:
    193         if 'extra' in publi.keys():
    194             s += publi['extra']
    195     s += '}\n\n'
    196     return s
    197 
    198 fmtdict = {
    199         'tex': publitotex,
    200         'bib': publitobib,
    201         }
    202 
    203 if __name__ == '__main__':
    204     for publi in parse('publis'):
    205         if thepubli not in ["all"]:
    206             if thepubli == "cv" or not thepubli:
    207                 if publi.get('reviewed', "no") == "no":
    208                     # only reviewed publis
    209                     continue
    210                 if publi.get('main', "no") == "no" and not publi.get('addcv', "no") == "yes":
    211                     # only main publis
    212                     continue
    213                 if publi.get('hidecv', "no") == "yes" or publi.get('oldcv',
    214                         "no") == "yes":
    215                     # hide some publis: hidecv are the ones I don't want, oldcv
    216                     # are the ones I'd want except they are too old
    217                     continue
    218             else:
    219                 # just one publi
    220                 if thepubli and publi['id'] != thepubli:
    221                     continue
    222         name, fullname, typ2, url, issue, oa, keywords = getvenue(publi, lang, venuesz)
    223         if fmt == 'tex' and typ2 == 'journal' and publi.get('issue', "none").lower() == "none":
    224             # in latex, no journal articles without an issue number yet
    225             continue
    226         print(fmtdict[fmt](publi, lang, venuesz, authorsz))
    227 
    228