Files
template/src/front-matter.js
T

327 lines
9.3 KiB
JavaScript

const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
const months = ['Jan.', 'Feb.', 'March', 'April', 'May', 'June', 'July', 'Aug.', 'Sept.', 'Oct.', 'Nov.', 'Dec.'];
const zeroPad = n => n < 10 ? '0' + n : n;
const RFC = function(date) {
const day = days[date.getDay()].substring(0, 3);
const paddedDate = zeroPad(date.getDate());
const month = months[date.getMonth()].substring(0,3);
const year = date.getFullYear().toString();
const hours = date.getUTCHours().toString();
const minutes = date.getUTCMinutes().toString();
const seconds = date.getUTCSeconds().toString();
return `${day}, ${paddedDate} ${month} ${year} ${hours}:${minutes}:${seconds} Z`;
};
const objectFromMap = function(map) {
const object = Array.from(map).reduce((object, [key, value]) => (
Object.assign(object, { [key]: value }) // Be careful! Maps can have non-String keys; object literals can't.
), {});
return object;
};
const mapFromObject = function(object) {
const map = new Map();
for (var property in object) {
if (object.hasOwnProperty(property)) {
map.set(property, object[property]);
}
}
return map;
};
class Author {
// constructor(name='', personalURL='', affiliation='', affiliationURL='') {
// this.name = name; // 'Chris Olah'
// this.personalURL = personalURL; // 'https://colah.github.io'
// this.affiliation = affiliation; // 'Google Brain'
// this.affiliationURL = affiliationURL; // 'https://g.co/brain'
// }
constructor(object) {
this.name = object.author; // 'Chris Olah'
this.personalURL = object.authorURL; // 'https://colah.github.io'
this.affiliation = object.affiliation; // 'Google Brain'
this.affiliationURL = object.affiliationURL; // 'https://g.co/brain'
}
// 'Chris'
get firstName() {
const names = this.name.split(' ');
return names.slice(0, names.length - 1).join(' ');
}
// 'Olah'
get lastName() {
const names = this.name.split(' ');
return names[names.length -1];
}
}
export function mergeFromYMLFrontmatter(target, source) {
target.title = source.title;
if (source.published) {
if (source.published instanceof Date) {
target.publishedDate = source.published;
} else if (source.published.constructor === String) {
target.publishedDate = new Date(source.published);
}
}
if (source.publishedDate) {
if (source.publishedDate instanceof Date) {
target.publishedDate = source.publishedDate;
} else if (source.publishedDate.constructor === String) {
target.publishedDate = new Date(source.publishedDate);
} else {
console.error('Don\'t know what to do with published date: ' + source.publishedDate);
}
}
target.description = source.description;
target.authors = source.authors.map( (authorObject) => new Author(authorObject));
target.katex = source.katex;
target.password = source.password;
}
export class FrontMatter {
constructor() {
this.title = 'unnamed article'; // 'Attention and Augmented Recurrent Neural Networks'
this.description = ''; // 'A visual overview of neural attention...'
this.authors = []; // Array of Author(s)
this.bibliography = new Map();
this.bibliographyParsed = false;
// {
// 'gregor2015draw': {
// 'title': 'DRAW: A recurrent neural network for image generation',
// 'author': 'Gregor, Karol and Danihelka, Ivo and Graves, Alex and Rezende, Danilo Jimenez and Wierstra, Daan',
// 'journal': 'arXiv preprint arXiv:1502.04623',
// 'year': '2015',
// 'url': 'https://arxiv.org/pdf/1502.04623.pdf',
// 'type': 'article'
// },
// }
// Citation keys should be listed in the order that they are appear in the document.
// Each key refers to a key in the bibliography dictionary.
this.citations = []; // [ 'gregor2015draw', 'mercier2011humans' ]
this.citationsCollected = false;
//
// Assigned from posts.csv
//
// publishedDate: 2016-09-08T07:00:00.000Z,
// tags: [ 'rnn' ],
// distillPath: '2016/augmented-rnns',
// githubPath: 'distillpub/post--augmented-rnns',
// doiSuffix: 1,
//
// Assigned from journal
//
this.journal = {};
// journal: {
// 'title': 'Distill',
// 'full_title': 'Distill',
// 'abbrev_title': 'Distill',
// 'url': 'http://distill.pub',
// 'doi': '10.23915/distill',
// 'publisherName': 'Distill Working Group',
// 'publisherEmail': 'admin@distill.pub',
// 'issn': '2476-0757',
// 'editors': [...],
// 'committee': [...]
// }
// volume: 1,
// issue: 9,
this.katex = {};
//
// Assigned from publishing process
//
// githubCompareUpdatesUrl: 'https://github.com/distillpub/post--augmented-rnns/compare/1596e094d8943d2dc0ea445d92071129c6419c59...3bd9209e0c24d020f87cf6152dcecc6017cbc193',
// updatedDate: 2017-03-21T07:13:16.000Z,
// doi: '10.23915/distill.00001',
this.publishedDate = undefined;
}
// Example:
// title: Demo Title Attention and Augmented Recurrent Neural Networks
// published: Jan 10, 2017
// authors:
// - Chris Olah:
// - Shan Carter: http://shancarter.com
// affiliations:
// - Google Brain:
// - Google Brain: http://g.co/brain
//
// Computed Properties
//
// 'http://distill.pub/2016/augmented-rnns',
set url(value) {
this._url = value;
}
get url() {
if (this._url) {
return this._url;
} else if (this.distillPath && this.journal.url) {
return this.journal.url + '/' + this.distillPath;
} else if (this.journal.url) {
return this.journal.url;
}
}
// 'https://github.com/distillpub/post--augmented-rnns',
get githubUrl() {
if (this.githubPath) {
return 'https://github.com/' + this.githubPath;
} else {
return undefined;
}
}
// TODO resolve differences in naming of URL/Url/url.
// 'http://distill.pub/2016/augmented-rnns/thumbnail.jpg',
set previewURL(value) {
this._previewURL = value;
}
get previewURL() {
return this._previewURL ? this._previewURL : this.url + '/thumbnail.jpg';
}
// 'Thu, 08 Sep 2016 00:00:00 -0700',
get publishedDateRFC() {
return RFC(this.publishedDate);
}
// 'Thu, 08 Sep 2016 00:00:00 -0700',
get updatedDateRFC() {
return RFC(this.updatedDate);
}
// 2016,
get publishedYear() {
return this.publishedDate.getFullYear();
}
// 'Sept',
get publishedMonth() {
return months[this.publishedDate.getMonth()];
}
// 8,
get publishedDay() {
return this.publishedDate.getDate();
}
// '09',
get publishedMonthPadded() {
return zeroPad(this.publishedDate.getMonth() + 1);
}
// '08',
get publishedDayPadded() {
return zeroPad(this.publishedDate.getDate());
}
get publishedISODateOnly() {
return this.publishedDate.toISOString().split('T')[0];
}
get volume() {
const volume = this.publishedYear - 2015;
if (volume < 1) {
throw new Error('Invalid publish date detected during computing volume');
}
return volume;
}
get issue() {
return this.publishedDate.getMonth() + 1;
}
// 'Olah & Carter',
get concatenatedAuthors() {
if (this.authors.length > 2) {
return this.authors[0].lastName + ', et al.';
} else if (this.authors.length === 2) {
return this.authors[0].lastName + ' & ' + this.authors[1].lastName;
} else if (this.authors.length === 1) {
return this.authors[0].lastName;
}
}
// 'Olah, Chris and Carter, Shan',
get bibtexAuthors() {
return this.authors.map(author => {
return author.lastName + ', ' + author.firstName;
}).join(' and ');
}
// 'olah2016attention'
get slug() {
let slug = '';
if (this.authors.length) {
slug += this.authors[0].lastName.toLowerCase();
slug += this.publishedYear;
slug += this.title.split(' ')[0].toLowerCase();
}
return slug || 'Untitled';
}
get bibliographyEntries() {
return new Map(this.citations.map( citationKey => {
const entry = this.bibliography.get(citationKey);
return [citationKey, entry];
}));
}
set bibliography(bibliography) {
if (bibliography instanceof Map) {
this._bibliography = bibliography;
} else if (typeof bibliography === 'object') {
this._bibliography = mapFromObject(bibliography);
}
}
get bibliography() {
return this._bibliography;
}
static fromObject(source) {
const frontMatter = new FrontMatter();
Object.assign(frontMatter, source);
return frontMatter;
}
assignToObject(target) {
Object.assign(target, this);
target.bibliography = objectFromMap(this.bibliographyEntries);
target.url = this.url;
target.githubUrl = this.githubUrl;
target.previewURL = this.previewURL;
if (this.publishedDate) {
target.volume = this.volume;
target.issue = this.issue;
target.publishedDateRFC = this.publishedDateRFC;
target.publishedYear = this.publishedYear;
target.publishedMonth = this.publishedMonth;
target.publishedDay = this.publishedDay;
target.publishedMonthPadded = this.publishedMonthPadded;
target.publishedDayPadded = this.publishedDayPadded;
}
if (this.updatedDate) {
target.updatedDateRFC = this.updatedDateRFC;
}
target.concatenatedAuthors = this.concatenatedAuthors;
target.bibtexAuthors = this.bibtexAuthors;
target.slug = this.slug;
}
}