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