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