Publications markdown generator for academicpages

Takes a TSV of publications with metadata and converts them for use with academicpages.github.io. This is an interactive Jupyter notebook (see more info here). The core python code is also in publications.py. Run either from the markdown_generator folder after replacing publications.tsv with one containing your data.

TODO: Make this work with BibTex and other databases of citations, rather than Stuart's non-standard TSV format and citation style.

Data format

The TSV needs to have the following columns: pub_date, title, venue, excerpt, citation, site_url, and paper_url, with a header at the top.

  • excerpt and paper_url can be blank, but the others must have values.
  • pub_date must be formatted as YYYY-MM-DD.
  • url_slug will be the descriptive part of the .md file and the permalink URL for the page about the paper. The .md file will be YYYY-MM-DD-[url_slug].md and the permalink will be https://[yourdomain]/publications/YYYY-MM-DD-[url_slug]

This is how the raw file looks (it doesn't look pretty, use a spreadsheet or other program to edit and create).


In [22]:
!cat publications.tsv


authors	pub_year	title	conference	location	paper_url	accepted	submitted	video_url
Phani Vadrevu, Babak Rahbarinia, Roberto Perdisci, Kang Li, Manos Antonakakis	2013	Measuring and detecting malware downloads in live network traffic	European Symposium on Research in Computer Security (ESORICS)	Egham, U.K.	/files/papers/amico.pdf	43	242	-
Phani Vadrevu, Roberto Perdisci	2016	MAXS: Scaling malware execution with sequential multi-hypothesis testing	11th ACM on Asia Conference on Computer and Communications Security (AsiaCCS)	Xi'an, China	/files/papers/maxs.pdf	73	350	-
Phani Vadrevu, Jienan Liu, Bo Li, Babak Rahbarinia, Kyu Hyung Lee, Roberto Perdisci	2017	Enabling Reconstruction of Attacks on Users via Efficient Browsing Snapshots	24th Annual Network and Distributed System Security Symposium (NDSS)	San Diego, U.S.A.	/files/papers/chromepic.pdf	68	423	https://www.youtube.com/watch?v=iIgTjHr1w0o
Bo Li, Phani Vadrevu, Kyu Hyung Lee, Roberto Perdisci	2018	JSgraph: Enabling Reconstruction of Web Attacks via Efficient Tracking of Live In-Browser JavaScript Executions	25th Annual Network and Distributed System Security Symposium (NDSS)	San Diego, U.S.A.	/files/papers/jsgraph.pdf	71	331 https://www.youtube.com/watch?v=pZU1RIxTMUs
Phani Vadrevu, Roberto Perdisci	2019	What You See is NOT What You Get: Discovering and Tracking Ad-Driven Social Engineering 10 Attack Campaigns	19th ACM Internet Measurement Conference (IMC)	Amsterdam, Netherlands	/files/papers/seacma.pdf	38	197	https://vimeo.com/showcase/6531379/video/369121670#t=3018s
Karthika Subramani, Xingzi Yuan, Omid Setayeshfar, Phani Vadrevu, Kyu Hyung Lee, Roberto Perdisci	2020	Measuring Abuse in Web Push Advertising	arXiv preprint	-	/files/papers/pushads.pdf	-	-	-

Import pandas

We are using the very handy pandas library for dataframes.


In [3]:
import pandas as pd

Import TSV

Pandas makes this easy with the read_csv function. We are using a TSV, so we specify the separator as a tab, or \t.

I found it important to put this data in a tab-separated values format, because there are a lot of commas in this kind of data and comma-separated values can get messed up. However, you can modify the import statement, as pandas also has read_excel(), read_json(), and others.


In [32]:
publications = pd.read_csv("publications.tsv", sep="\t", header=0)
publications


Out[32]:
authors pub_year title conference location paper_url accepted submitted video_url
0 Phani Vadrevu, Babak Rahbarinia, Roberto Perdi... 2013 Measuring and detecting malware downloads in l... European Symposium on Research in Computer Sec... Egham, U.K. /files/papers/amico.pdf 43 242 -
1 Phani Vadrevu, Roberto Perdisci 2016 MAXS: Scaling malware execution with sequentia... 11th ACM on Asia Conference on Computer and Co... Xi'an, China /files/papers/maxs.pdf 73 350 -
2 Phani Vadrevu, Jienan Liu, Bo Li, Babak Rahbar... 2017 Enabling Reconstruction of Attacks on Users vi... 24th Annual Network and Distributed System Sec... San Diego, U.S.A. /files/papers/chromepic.pdf 68 423 https://www.youtube.com/watch?v=iIgTjHr1w0o
3 Bo Li, Phani Vadrevu, Kyu Hyung Lee, Roberto P... 2018 JSgraph: Enabling Reconstruction of Web Attack... 25th Annual Network and Distributed System Sec... San Diego, U.S.A. /files/papers/jsgraph.pdf 71 331 https://www.youtube.com/watch?v=pZU1RIxTMUs
4 Phani Vadrevu, Roberto Perdisci 2019 What You See is NOT What You Get: Discovering ... 19th ACM Internet Measurement Conference (IMC) Amsterdam, Netherlands /files/papers/seacma.pdf 38 197 https://vimeo.com/showcase/6531379/video/36912...
5 Karthika Subramani, Xingzi Yuan, Omid Setayesh... 2020 Measuring Abuse in Web Push Advertising arXiv preprint - /files/papers/pushads.pdf - - -

In [34]:
publications.columns


Out[34]:
Index([u'authors', u'pub_year', u'title', u'conference', u'location',
       u'paper_url', u'accepted', u'submitted', u'video_url'],
      dtype='object')

Escape special characters

YAML is very picky about how it takes a valid string, so we are replacing single and double quotes (and ampersands) with their HTML encoded equivilents. This makes them look not so readable in raw format, but they are parsed and rendered nicely.


In [14]:
html_escape_table = {
    "&": "&",
    '"': """,
    "'": "'"
    }

def html_escape(text):
    """Produce entities within text."""
    return "".join(html_escape_table.get(c,c) for c in text)

Creating the markdown files

This is where the heavy lifting is done. This loops through all the rows in the TSV dataframe, then starts to concatentate a big string (md) that contains the markdown for each type. It does the YAML metadata first, then does the description for the individual page.


In [35]:
import os
for row, item in publications.iterrows():
    
    paper_name = item.paper_url.rsplit('/', 1)[1].split('.')[0]
    md_filename = str(item.pub_year) + "-" + paper_name + ".md"
    html_filename = str(item.pub_year) + "-" + paper_name
    ## YAML variables
    
    md = "---\ntitle: \""   + item.title + '"\n'
    
    md += """collection: publications"""
    
    md += """\npermalink: /publication/""" + html_filename
    
    md += "\nyear: " + str(item.pub_year) 
    
    md += "\nconference: '" + html_escape(item.conference) + "'"
    
    md += "\nauthors: " + "[" + ", ".join(["'" + a + "'" for a in item.authors.split(', ')]) + "]"

    md += "\nlocation: '" + html_escape(item.location) + "'"

    md += "\naccepted: '" + str(item.accepted) + "'"
    
    md += "\nsubmitted: '" + str(item.submitted) + "'"
    
    if len(str(item.paper_url)) > 5:
        md += "\npaper_url: '" + item.paper_url + "'"
        
    if item.video_url != '-':
        md += "\nvideo_url: '" + item.video_url + "'"
        
    md += "\n---"
    
    ## Markdown description for individual page
        
    #if len(str(item.paper_url)) > 5:
    #    md += "\n[Download paper here](" + item.paper_url + ")\n" 
            
    md_filename = os.path.basename(md_filename)
       
    with open("../_publications/" + md_filename, 'w') as f:
        f.write(md)

These files are in the publications directory, one directory below where we're working from.


In [36]:
!ls ../_publications/


2013-amico.md     2017-chromepic.md 2019-seacma.md
2016-maxs.md      2018-jsgraph.md   2020-pushads.md

In [39]:
!cat ../_publications/2019-seacma.md


---
title: "What You See is NOT What You Get: Discovering and Tracking Ad-Driven Social Engineering 10 Attack Campaigns"
collection: publications
permalink: /publication/2019-seacma
year: 2019
conference: '19th ACM Internet Measurement Conference (IMC)'
authors: ['Phani Vadrevu', 'Roberto Perdisci']
location: 'Amsterdam, Netherlands'
accepted: '38'
submitted: '197'
paper_url: '/files/papers/seacma.pdf'
video_url: 'https://vimeo.com/showcase/6531379/video/369121670#t=3018s'
---

In [ ]: