mirror of
https://github.com/wassname/template.git
synced 2026-08-04 13:23:33 +08:00
Project reorganization, add editorconfig and linter
This commit is contained in:
@@ -0,0 +1 @@
|
||||
node_modules/
|
||||
@@ -0,0 +1,89 @@
|
||||
const html = `
|
||||
<style>
|
||||
dt-appendix {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
margin-bottom: 0;
|
||||
border-top: 1px solid rgba(0,0,0,0.1);
|
||||
color: rgba(0,0,0,0.5);
|
||||
background: rgb(250, 250, 250);
|
||||
padding-top: 36px;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
dt-appendix h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-top: 18px;
|
||||
margin-bottom: 18px;
|
||||
color: rgba(0,0,0,0.65);
|
||||
}
|
||||
dt-appendix .citation {
|
||||
font-size: 11px;
|
||||
line-height: 15px;
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding-left: 18px;
|
||||
border: 1px solid rgba(0,0,0,0.1);
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
padding: 10px 18px;
|
||||
border-radius: 3px;
|
||||
color: rgba(150, 150, 150, 1);
|
||||
overflow: hidden;
|
||||
margin-top: -12px;
|
||||
}
|
||||
dt-appendix .references {
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
dt-appendix a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
dt-appendix ol,
|
||||
dt-appendix ul {
|
||||
padding-left: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="l-body">
|
||||
<h3>References</h3>
|
||||
<dt-bibliography></dt-bibliography>
|
||||
<h3 id="citation">Errors, Reuse, and Citation</h3>
|
||||
<p>If you see mistakes or want to suggest changes, please <a class="github-issue">create an issue on GitHub</a>.</p>
|
||||
<p>Diagrams and text are licensed under Creative Commons Attribution <a href="https://creativecommons.org/licenses/by/2.0/">CC-BY 2.0</a>, unless noted otherwise, with the <a class="github">source available on GitHub</a>. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: “Figure from …”.</p>
|
||||
<p>For attribution in academic contexts, please cite this work as</p>
|
||||
<pre class="citation short"></pre>
|
||||
<p>BibTeX citation</p>
|
||||
<pre class="citation long"></pre>
|
||||
</div>
|
||||
`;
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector('dt-appendix')
|
||||
if (el) {
|
||||
let oldHtml = el.innerHTML;
|
||||
el.innerHTML = html;
|
||||
let div = el.querySelector("div.l-body")
|
||||
|
||||
if (dom.querySelector("dt-fn")) {
|
||||
div.innerHTML = `<h3>Footnotes</h3><dt-fn-list></dt-fn-list>` + div.innerHTML;
|
||||
}
|
||||
|
||||
div.innerHTML = oldHtml + div.innerHTML;
|
||||
if (data.githubCompareUpdatesUrl) {
|
||||
div.innerHTML = `<h3>Updates</h3><p><a href="${data.githubCompareUpdatesUrl}">View all changes</a> to this article since it was first published.</p>` + div.innerHTML;
|
||||
}
|
||||
|
||||
el.querySelector("a.github").setAttribute("href", data.githubUrl);
|
||||
el.querySelector("a.github-issue").setAttribute("href", data.githubUrl + "/issues/new");
|
||||
el.querySelector(".citation.short").textContent = data.concatenatedAuthors + ", " + '"' + data.title + '", Distill, ' + data.publishedYear + ".";
|
||||
var bibtex = "@article{" + data.slug + ",\n";
|
||||
bibtex += " author = {" + data.bibtexAuthors + "},\n";
|
||||
bibtex += " title = {" + data.title + "},\n";
|
||||
bibtex += " journal = {Distill},\n";
|
||||
bibtex += " year = {" + data.publishedYear + "},\n";
|
||||
bibtex += " note = {" + data.url + "}\n";
|
||||
bibtex += "}";
|
||||
el.querySelector(".citation.long").textContent = bibtex;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
const html = `
|
||||
<style>
|
||||
dt-banner {
|
||||
background: #FFF59D;
|
||||
display: block;
|
||||
text-align: center;
|
||||
color: black;
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
}
|
||||
</style>
|
||||
<div>This article is a draft, awaiting review for publication in Distill</div>
|
||||
`;
|
||||
|
||||
export default function(dom, data) {
|
||||
let banner = dom.createElement("dt-banner");
|
||||
banner.innerHTML = html;
|
||||
let b = dom.querySelector("body");
|
||||
b.insertBefore(banner, b.firstChild);
|
||||
banner.addEventListener("click", function() {
|
||||
banner.style.display = "none";
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import bibtexParse from "bibtex-parse-js";
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector('script[type="text/bibliography"]');
|
||||
let citations = [];
|
||||
let bibliography = {};
|
||||
//TODO If we don't have a local element, make a request for the document.
|
||||
if (el) {
|
||||
let rawBib = el.textContent;
|
||||
let parsed = bibtexParse.toJSON(rawBib);
|
||||
if(parsed) {
|
||||
parsed.forEach(e => {
|
||||
for (var k in e.entryTags){
|
||||
var val = e.entryTags[k];
|
||||
val = val.replace(/[\t\n ]+/g, " ");
|
||||
val = val.replace(/{\\["^`\.'acu~Hvs]( )?([a-zA-Z])}/g,
|
||||
(full, x, char) => char);
|
||||
val = val.replace(/{\\([a-zA-Z])}/g,
|
||||
(full, char) => char);
|
||||
e.entryTags[k] = val;
|
||||
}
|
||||
bibliography[e.citationKey] = e.entryTags;
|
||||
bibliography[e.citationKey].type = e.entryType;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var citeTags = [].slice.apply(dom.querySelectorAll("dt-cite"));
|
||||
citeTags.forEach(el => {
|
||||
let key = el.getAttribute("key");
|
||||
if (key) {
|
||||
let citationKeys = key.split(",");
|
||||
citationKeys.forEach(key => {
|
||||
if (citations.indexOf(key) == -1){
|
||||
citations.push(key);
|
||||
if (!(key in bibliography)){
|
||||
console.warn("No bibliography entry found for: " + key);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
data.bibliography = bibliography;
|
||||
data.citations = citations;
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
import mustache from "mustache";
|
||||
|
||||
const html = `
|
||||
<style>
|
||||
dt-byline {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
display: block;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
min-height: 90px;
|
||||
|
||||
}
|
||||
dt-article.centered dt-byline {
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
dt-byline a,
|
||||
dt-article dt-byline a {
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
dt-article dt-byline a:hover {
|
||||
text-decoration: underline;
|
||||
border-bottom: none;
|
||||
}
|
||||
dt-byline .authors {
|
||||
text-align: left;
|
||||
}
|
||||
dt-byline .name {
|
||||
display: inline;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
dt-byline .affiliation {
|
||||
display: inline;
|
||||
}
|
||||
dt-byline .date {
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
dt-byline .year, dt-byline .month {
|
||||
display: inline;
|
||||
}
|
||||
dt-byline .citation {
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
dt-byline .citation div {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@media(min-width: 768px) {
|
||||
dt-byline {
|
||||
}
|
||||
}
|
||||
|
||||
@media(min-width: 1080px) {
|
||||
dt-byline {
|
||||
border-bottom: none;
|
||||
margin-bottom: 70px;
|
||||
}
|
||||
|
||||
dt-byline a:hover {
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
dt-byline .authors {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
dt-byline .author {
|
||||
display: inline-block;
|
||||
margin-right: 12px;
|
||||
/*padding-left: 20px;*/
|
||||
/*border-left: 1px solid #ddd;*/
|
||||
}
|
||||
|
||||
dt-byline .affiliation {
|
||||
display: block;
|
||||
}
|
||||
|
||||
dt-byline .author:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
dt-byline .name {
|
||||
display: block;
|
||||
}
|
||||
|
||||
dt-byline .date {
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding-left: 15px;
|
||||
margin-left: 15px;
|
||||
display: inline-block;
|
||||
}
|
||||
dt-byline .year, dt-byline .month {
|
||||
display: block;
|
||||
}
|
||||
|
||||
dt-byline .citation {
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.15);
|
||||
padding-left: 15px;
|
||||
margin-left: 15px;
|
||||
display: inline-block;
|
||||
}
|
||||
dt-byline .citation div {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
`;
|
||||
|
||||
const template = `
|
||||
<div class="byline">
|
||||
<div class="authors">
|
||||
{{#authors}}
|
||||
<div class="author">
|
||||
{{#personalURL}}
|
||||
<a class="name" href="{{personalURL}}">{{name}}</a>
|
||||
{{/personalURL}}
|
||||
{{^personalURL}}
|
||||
<div class="name">{{name}}</div>
|
||||
{{/personalURL}}
|
||||
{{#affiliation}}
|
||||
{{#affiliationURL}}
|
||||
<a class="affiliation" href="{{affiliationURL}}">{{affiliation}}</a>
|
||||
{{/affiliationURL}}
|
||||
{{^affiliationURL}}
|
||||
<div class="affiliation">{{affiliation}}</div>
|
||||
{{/affiliationURL}}
|
||||
{{/affiliation}}
|
||||
</div>
|
||||
{{/authors}}
|
||||
</div>
|
||||
<div class="date">
|
||||
<div class="month">{{publishedMonth}}. {{publishedDay}}</div>
|
||||
<div class="year">{{publishedYear}}</div>
|
||||
</div>
|
||||
<a class="citation" href="#citation">
|
||||
<div>Citation:</div>
|
||||
<div>{{concatenatedAuthors}}, {{publishedYear}}</div>
|
||||
</a>
|
||||
</div>
|
||||
`
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector('dt-byline');
|
||||
if (el) {
|
||||
el.innerHTML = html + mustache.render(template, data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
export default function(dom, data) {
|
||||
let css = `
|
||||
dt-cite {
|
||||
color: hsla(206, 90%, 20%, 0.7);
|
||||
}
|
||||
dt-cite .citation-number {
|
||||
cursor: default;
|
||||
white-space: nowrap;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Roboto", Helvetica, sans-serif;
|
||||
font-size: 75%;
|
||||
color: hsla(206, 90%, 20%, 0.7);
|
||||
display: inline-block;
|
||||
line-height: 1.1em;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
figcaption dt-cite .citation-number {
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
top: -2px;
|
||||
line-height: 1em;
|
||||
}
|
||||
`;
|
||||
|
||||
let style = dom.createElement("style");
|
||||
style.textContent = css;
|
||||
dom.querySelector("body").appendChild(style);
|
||||
|
||||
let citations = data.citations;
|
||||
/*if (data.citations) {
|
||||
citations = Object.keys(data.citations).map(c => data.citations[c]);
|
||||
citations.sort((a, b) => {
|
||||
return a.author.localeCompare(b.author);
|
||||
});
|
||||
}*/
|
||||
|
||||
var citeTags = [].slice.apply(dom.querySelectorAll("dt-cite"));
|
||||
citeTags.forEach((el,n) => {
|
||||
var key = el.getAttribute("key");
|
||||
if (key) {
|
||||
var keys = key.split(",");
|
||||
var cite_string = inline_cite_short(keys);
|
||||
var cite_hover_str = "";
|
||||
keys.map((key,n) => {
|
||||
if (n>0) cite_hover_str += "<br><br>";
|
||||
cite_hover_str += hover_cite(data.bibliography[key]);
|
||||
});
|
||||
cite_hover_str = cite_hover_str.replace(/"/g, "'")
|
||||
var orig_string = el.innerHTML;
|
||||
if (orig_string != "") orig_string += " ";
|
||||
el.innerHTML = `<span id="citation-${n}" data-hover="${cite_hover_str}">${orig_string}<span class="citation-number">${cite_string}</span></span>`;
|
||||
}
|
||||
});
|
||||
|
||||
let bibEl = dom.querySelector("dt-bibliography");
|
||||
if (bibEl) {
|
||||
let ol = dom.createElement("ol");
|
||||
citations.forEach(key => {
|
||||
let el = dom.createElement("li");
|
||||
el.innerHTML = bibliography_cite(data.bibliography[key]);
|
||||
ol.appendChild(el);
|
||||
})
|
||||
bibEl.appendChild(ol);
|
||||
}
|
||||
|
||||
function inline_cite_short(keys){
|
||||
function cite_string(key){
|
||||
if (key in data.bibliography){
|
||||
var n = data.citations.indexOf(key)+1;
|
||||
return ""+n;
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
return "["+keys.map(cite_string).join(", ")+"]";
|
||||
}
|
||||
|
||||
function inline_cite_long(keys){
|
||||
function cite_string(key){
|
||||
if (key in data.bibliography){
|
||||
var ent = data.bibliography[key];
|
||||
var names = ent.author.split(" and ");
|
||||
names = names.map(name => name.split(",")[0].trim())
|
||||
var year = ent.year;
|
||||
if (names.length == 1) return names[0] + ", " + year;
|
||||
if (names.length == 2) return names[0] + " & " + names[1] + ", " + year;
|
||||
if (names.length > 2) return names[0] + ", et al., " + year;
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
return keys.map(cite_string).join(", ");
|
||||
}
|
||||
|
||||
function author_string(ent, template, sep, finalSep){
|
||||
var names = ent.author.split(" and ");
|
||||
let name_strings = names.map(name => {
|
||||
name = name.trim();
|
||||
if (name.indexOf(",") != -1){
|
||||
var last = name.split(",")[0].trim();
|
||||
var firsts = name.split(",")[1];
|
||||
} else {
|
||||
var last = name.split(" ").slice(-1)[0].trim();
|
||||
var firsts = name.split(" ").slice(0,-1).join(" ");
|
||||
}
|
||||
var initials = "";
|
||||
if (firsts != undefined) {
|
||||
initials = firsts.trim().split(" ").map(s => s.trim()[0]);
|
||||
initials = initials.join(".")+".";
|
||||
}
|
||||
return template.replace("${F}", firsts)
|
||||
.replace("${L}", last)
|
||||
.replace("${I}", initials);
|
||||
});
|
||||
if (names.length > 1) {
|
||||
var str = name_strings.slice(0, names.length-1).join(sep);
|
||||
str += (finalSep || sep) + name_strings[names.length-1];
|
||||
return str;
|
||||
} else {
|
||||
return name_strings[0];
|
||||
}
|
||||
}
|
||||
|
||||
function venue_string(ent) {
|
||||
var cite = (ent.journal || ent.booktitle || "")
|
||||
if ("volume" in ent){
|
||||
var issue = ent.issue || ent.number;
|
||||
issue = (issue != undefined)? "("+issue+")" : "";
|
||||
cite += ", Vol " + ent.volume + issue;
|
||||
}
|
||||
if ("pages" in ent){
|
||||
cite += ", pp. " + ent.pages
|
||||
}
|
||||
if (cite != "") cite += ". "
|
||||
if ("publisher" in ent){
|
||||
cite += ent.publisher;
|
||||
if (cite[cite.length-1] != ".") cite += ".";
|
||||
}
|
||||
return cite;
|
||||
}
|
||||
|
||||
function link_string(ent){
|
||||
if ("url" in ent){
|
||||
var url = ent.url;
|
||||
var arxiv_match = (/arxiv\.org\/abs\/([0-9\.]*)/).exec(url);
|
||||
if (arxiv_match != null){
|
||||
url = `http://arxiv.org/pdf/${arxiv_match[1]}.pdf`;
|
||||
}
|
||||
|
||||
if (url.slice(-4) == ".pdf"){
|
||||
var label = "PDF";
|
||||
} else if (url.slice(-5) == ".html") {
|
||||
var label = "HTML";
|
||||
}
|
||||
return `  <a href="${url}">[${label||"link"}]</a>`;
|
||||
}/* else if ("doi" in ent){
|
||||
return `  <a href="https://doi.org/${ent.doi}" >[DOI]</a>`;
|
||||
}*/ else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
function doi_string(ent, new_line){
|
||||
if ("doi" in ent) {
|
||||
return `${new_line?"<br>":""} <a href="https://doi.org/${ent.doi}" style="text-decoration:inherit;">DOI: ${ent.doi}</a>`;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function bibliography_cite(ent, fancy){
|
||||
if (ent){
|
||||
var cite = "<b>" + ent.title + "</b> "
|
||||
cite += link_string(ent) + "<br>";
|
||||
cite += author_string(ent, "${L}, ${I}", ", ", " and ");
|
||||
if (ent.year || ent.date){
|
||||
cite += ", " + (ent.year || ent.date) + ". "
|
||||
} else {
|
||||
cite += ". "
|
||||
}
|
||||
cite += venue_string(ent);
|
||||
cite += doi_string(ent);
|
||||
return cite
|
||||
/*var cite = author_string(ent, "${L}, ${I}", ", ", " and ");
|
||||
if (ent.year || ent.date){
|
||||
cite += ", " + (ent.year || ent.date) + ". "
|
||||
} else {
|
||||
cite += ". "
|
||||
}
|
||||
cite += "<b>" + ent.title + "</b>. ";
|
||||
cite += venue_string(ent);
|
||||
cite += doi_string(ent);
|
||||
cite += link_string(ent);
|
||||
return cite*/
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
function hover_cite(ent){
|
||||
if (ent){
|
||||
var cite = "";
|
||||
cite += "<b>" + ent.title + "</b>";
|
||||
cite += link_string(ent);
|
||||
cite += "<br>"
|
||||
|
||||
var a_str = author_string(ent, "${I} ${L}", ", ") + ".";
|
||||
var v_str = venue_string(ent).trim() + " " + ent.year + ". " + doi_string(ent, true);
|
||||
|
||||
if ((a_str+v_str).length < Math.min(40, ent.title.length)) {
|
||||
cite += a_str + " " + v_str;
|
||||
} else {
|
||||
cite += a_str + "<br>" + v_str;
|
||||
}
|
||||
return cite;
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//https://scholar.google.com/scholar?q=allintitle%3ADocument+author%3Aolah
|
||||
function get_GS_URL(ent){
|
||||
if (ent){
|
||||
var names = ent.author.split(" and ");
|
||||
names = names.map(name => name.split(",")[0].trim())
|
||||
var title = ent.title.split(" ")//.replace(/[,:]/, "")
|
||||
var url = "http://search.labs.crossref.org/dois?"//""https://scholar.google.com/scholar?"
|
||||
url += uris({q: names.join(" ") + " " + title.join(" ")})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import Prism from "prismjs";
|
||||
|
||||
export default function(dom, data) {
|
||||
let codeElements = [].slice.call(dom.querySelectorAll("dt-code"));
|
||||
codeElements.forEach(el => {
|
||||
let content = el.textContent;
|
||||
el.innerHTML = "";
|
||||
let language = el.getAttribute("language");
|
||||
let c = dom.createElement("code");
|
||||
if (el.getAttribute("block") === "") {
|
||||
// Let's normalize the tab indents
|
||||
content = content.replace(/\n/, "");
|
||||
let tabs = content.match(/\s*/);
|
||||
content = content.replace(new RegExp("\n" + tabs, "g"), "\n");
|
||||
content = content.trim();
|
||||
let p = dom.createElement("pre");
|
||||
p.appendChild(c);
|
||||
el.appendChild(p);
|
||||
} else {
|
||||
el.appendChild(c);
|
||||
}
|
||||
let highlighted = content;
|
||||
if (Prism.languages[language]) {
|
||||
c.setAttribute("class", "language-" + language);
|
||||
highlighted = Prism.highlight(content, Prism.languages[language]);
|
||||
}
|
||||
c.innerHTML = highlighted;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA99JREFUeNrsG4t1ozDMzQSM4A2ODUonKBucN2hugtIJ6E1AboLcBiQTkJsANiAb9OCd/OpzMWBJBl5TvaeXPiiyJetry0J8wW3D3QpjRh3GjneXDq+fSQA9s2mH9x3KDhN4foJfCb8N/Jrv+2fnDn8vLRQOplWHVYdvHZYdZsBcZP1vBmh/n8DzEmhUQDPaOuP9pFuY+JwJHwHnCLQE2tnWBGEyXozY9xCUgHMhhjE2I4heVWtgIkZ83wL6Qgxj1obfWBxymPwe+b00BCCRNPbwfb60yleAkkBHGT5AEehIYz7eJrFDMF9CvH4wwhcGHiHMneFvLDQwlwvMLQq58trRcYBWfYn0A0OgHWQUSu25mE+BnoYKnnEJoeIWAifzOv7vLWd2ZKRfWAIme3tOiUaQ3UnLkb0xj1FxRIeEGKaGIHOs9nEgLaaA9i0JRYo1Ic67wJW86KSKE/ZAM8KuVMk8ITVhmxUxJ3Cl2xlm9Vtkeju1+mpCQNxaEGNCY8bs9X2YqwNoQeGjBWut/ma0QAWy/TqAsHx9wSya3I5IRxOfTC+leG+kA/4vSeEcGBtNUN6byhu3+keEZCQJUNh8MAO7HL6H8pQLnsW/Hd4T4lv93TPjfM7A46iEEqbB5EDOvwYNW6tGNZzT/o+CZ6sqZ6wUtR/wf7mi/VL8iNciT6rHih48Y55b4nKCHJCCzb4y0nwFmin3ZEMIoLfZF8F7nncFmvnWBaBj7CGAYA/WGJsUwHdYqVDwAmNsUgAx4CGgAA7GOOxADYOFWOaIKifuVYzmOpREqA21Mo7aPsgiY1PhOMAmxtR+AUbYH3Id2wc0SAFIQTsn9IUGWR8k9jx3vtXSiAacFxTAGakBk9UudkNECd6jLe+6HrshshvIuC6IlLMRy7er+JpcKma24SlE4cFZSZJDGVVrsNvitQhQrDhW0jfiOLfFd47C42eHT56D/BK0To+58Ahj+cAT8HT1UWlfLZCCd/uKawzU0Rh2EyIX/Icqth3niG8ybNroezwe6khdCNxRN+l4XGdOLVLlOOt2hTRJlr1ETIuMAltVTMz70mJrkdGAaZLSmnBEqmAE32JCMmuTlCnRgsBENtOUpHhvvsYIL0ibnBkaC6QvKcR7738GKp0AKnim7xgUSNv1bpS8QwhBt8r+EP47v/oyRK/S34yJ9nT+AN0Tkm4OdB9E4BsmXM3SnMlRFUrtp6IDpV2eKzdYvF3etm3KhQksbOLChGkSmcBdmcEwvqkrMy5BzL00NZeu3qPYJOOuCc+5NjcWKXQxFvTa3NoXJ4d8in7fiAUuTt781dkvuHX4K8AA2Usy7yNKLy0AAAAASUVORK5CYII=
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="64px" height="64px" viewBox="-1214 838 64 64" style="enable-background:new -1214 838 64 64;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:none;stroke:#000000;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M-1182,841.2c-15.9,0-28.8,12.9-28.8,28.8s12.9,28.8,28.8,28.8s28.8-12.9,28.8-28.8S-1166.1,841.2-1182,841.2
|
||||
z M-1182,891.2c-7.7,0-13.9-6.1-13.9-13.8s13.9-22.2,13.9-36.3c0,14.2,13.9,28.7,13.9,36.3S-1174.3,891.2-1182,891.2z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 740 B |
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="-607 419 64 64">
|
||||
<path d="M-573.4,478.9c-8,0-14.6-6.4-14.6-14.5s14.6-25.9,14.6-40.8c0,14.9,14.6,32.8,14.6,40.8S-565.4,478.9-573.4,478.9z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 163 B |
@@ -0,0 +1,52 @@
|
||||
import logo from "./distill-logo.svg";
|
||||
|
||||
let html = `
|
||||
<style>
|
||||
dt-footer {
|
||||
display: block;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-weight: 300;
|
||||
padding: 40px 0;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
background-color: hsl(200, 60%, 15%);
|
||||
text-align: center;
|
||||
}
|
||||
dt-footer .logo svg {
|
||||
width: 24px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
dt-footer .logo svg path {
|
||||
fill: none;
|
||||
stroke: rgba(255, 255, 255, 0.8);
|
||||
stroke-width: 3px;
|
||||
}
|
||||
dt-footer .logo {
|
||||
font-size: 17px;
|
||||
font-weight: 200;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-decoration: none;
|
||||
margin-right: 6px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="l-screen-inset">
|
||||
<a href="/" class="logo">
|
||||
${logo}
|
||||
Distill
|
||||
</a> is dedicated to clear explanations of machine learning
|
||||
</div>
|
||||
`;
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector("dt-footer");
|
||||
if(el) {
|
||||
el.innerHTML = html;
|
||||
} else {
|
||||
let footer = dom.createElement("dt-footer");
|
||||
footer.innerHTML = html;
|
||||
let b = dom.querySelector("body");
|
||||
b.appendChild(footer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
export default function(dom, data) {
|
||||
|
||||
var fnTags = [].slice.apply(dom.querySelectorAll("dt-fn"));
|
||||
var fnContent = [];
|
||||
fnTags.forEach((el,n) => {
|
||||
var content = el.innerHTML;
|
||||
fnContent.push(content);
|
||||
n = (n+1)+"";
|
||||
var key = "fn-"+n;
|
||||
var escaped_content = content.replace(/"/g, "'");
|
||||
el.innerHTML = `<sup><span id="${key}" data-hover="${escaped_content}" style="cursor:pointer">${n}</span></sup>`;
|
||||
});
|
||||
|
||||
let fnList = dom.querySelector("dt-fn-list");
|
||||
if (fnList) {
|
||||
let ol = dom.createElement("ol");
|
||||
fnContent.forEach(content => {
|
||||
let el = dom.createElement("li");
|
||||
el.innerHTML = content;
|
||||
ol.appendChild(el);
|
||||
})
|
||||
fnList.appendChild(ol);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import ymlParse from "js-yaml";
|
||||
|
||||
export default function(dom, data) {
|
||||
let localData = {};
|
||||
let el = dom.querySelector('script[type="text/front-matter"]');
|
||||
if (el) {
|
||||
let text = el.textContent;
|
||||
localData = ymlParse.safeLoad(text);
|
||||
}
|
||||
|
||||
data.title = localData.title ? localData.title : "Untitled";
|
||||
data.description = localData.description ? localData.description : "No description.";
|
||||
|
||||
data.authors = localData.authors ? localData.authors : [];
|
||||
|
||||
data.authors = data.authors.map((author, i) =>{
|
||||
let a = {};
|
||||
let name = Object.keys(author)[0];
|
||||
if ((typeof author) === "string") {
|
||||
name = author;
|
||||
} else {
|
||||
a.personalURL = author[name];
|
||||
}
|
||||
let names = name.split(" ");
|
||||
a.name = name;
|
||||
a.firstName = names.slice(0, names.length - 1).join(" ");
|
||||
a.lastName = names[names.length -1];
|
||||
if(localData.affiliations[i]) {
|
||||
let affiliation = Object.keys(localData.affiliations[i])[0];
|
||||
if ((typeof localData.affiliations[i]) === "string") {
|
||||
affiliation = localData.affiliations[i]
|
||||
} else {
|
||||
a.affiliationURL = localData.affiliations[i][affiliation];
|
||||
}
|
||||
a.affiliation = affiliation;
|
||||
}
|
||||
return a;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
//import xml from "xml";
|
||||
|
||||
export default function(data) {
|
||||
|
||||
|
||||
var date = data.publishedDate;
|
||||
|
||||
var batch_timestamp = Math.floor(Date.now() / 1000);
|
||||
var batch_id = data.authors.length ? data.authors[0].lastName.toLowerCase().slice(0,20) : "Anonymous";
|
||||
batch_id += "_" + date.getFullYear();
|
||||
batch_id += "_" + data.title.split(" ")[0].toLowerCase().slice(0,20) + "_" + batch_timestamp;
|
||||
// generate XML
|
||||
var crf_data =
|
||||
{doi_batch : [
|
||||
|
||||
{ _attr: {
|
||||
version: "4.3.7",
|
||||
xmlns: "http://www.crossref.org/schema/4.3.7",
|
||||
"xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
|
||||
"xsi:schemaLocation": "http://www.crossref.org/schema/4.3.7 http://www.crossref.org/schemas/crossref4.3.7.xsd",
|
||||
}},
|
||||
|
||||
{ head: [
|
||||
{doi_batch_id: batch_id},
|
||||
{timestamp: batch_timestamp},
|
||||
{depositor: [
|
||||
{depositor_name: data.journal.publisherName},
|
||||
{email_address: data.journal.publisherEmail},
|
||||
]},
|
||||
{registrant: data.journal.publisherName},
|
||||
]},
|
||||
|
||||
{body: [
|
||||
{journal: [
|
||||
|
||||
{journal_metadata: [
|
||||
{full_title: data.journal.full_title || data.journal.title},
|
||||
{abbrev_title: data.journal.abbrev_title || data.journal.title || data.journal.full_title},
|
||||
{issn: data.journal.issn},
|
||||
{doi_data: [
|
||||
{doi: data.journal.doi},
|
||||
{resource: data.journal.url},
|
||||
]},
|
||||
]},
|
||||
|
||||
{journal_issue: [
|
||||
{publication_date: [
|
||||
{month: date.getMonth()+1},
|
||||
{year: date.getFullYear()},
|
||||
]},
|
||||
{journal_volume: [
|
||||
{volume: data.volume},
|
||||
]},
|
||||
{issue: data.issue},
|
||||
]},
|
||||
|
||||
{journal_article: [
|
||||
{titles: [
|
||||
{title: data.title},
|
||||
]},
|
||||
{ contributors:
|
||||
data.authors.map((author, ind) => (
|
||||
{person_name: [
|
||||
{ _attr: {
|
||||
contributor_role: "author",
|
||||
sequence: (ind == 0)? "first" : "additional"
|
||||
}},
|
||||
{given_name: author.firstName},
|
||||
{surname: author.lastName},
|
||||
{affiliation: author.affiliation}
|
||||
// TODO: ORCID?
|
||||
]}
|
||||
))
|
||||
},
|
||||
{publication_date: [
|
||||
{month: date.getMonth()+1},
|
||||
{day: date.getDate()},
|
||||
{year: date.getFullYear()}
|
||||
]},
|
||||
{ publisher_item: [
|
||||
{item_number: data.doi}
|
||||
]},
|
||||
{doi_data: [
|
||||
{doi: data.doi},
|
||||
//{timestamp: ""},
|
||||
{resource: data.url},
|
||||
]},
|
||||
{citation_list:
|
||||
data.citations.map(key =>
|
||||
citation_xml(key, data.bibliography[key]))
|
||||
}
|
||||
|
||||
]},
|
||||
|
||||
]},
|
||||
]},
|
||||
]};
|
||||
|
||||
return xml(crf_data);
|
||||
}
|
||||
|
||||
function citation_xml(key, ent){
|
||||
if (ent == undefined) return {};
|
||||
var info = [];
|
||||
info.push({_attr: {key: key}});
|
||||
if ("title" in ent)
|
||||
info.push({article_title: ent.title});
|
||||
if ("author" in ent)
|
||||
info.push({author: ent.author.split(" and ")[0].split(",")[0].trim()});
|
||||
if ("journal" in ent)
|
||||
info.push({journal_title: ent.journal});
|
||||
if ("booktitle" in ent)
|
||||
info.push({volume_title: ent.booktitle});
|
||||
if ("volume" in ent)
|
||||
info.push({volume: ent.volume});
|
||||
if ("issue" in ent)
|
||||
info.push({issue: ent.issue});
|
||||
if ("doi" in ent)
|
||||
info.push({doi: ent.doi});
|
||||
return {citation: info}
|
||||
}
|
||||
|
||||
function xml(obj) {
|
||||
//console.log(typeof(obj), obj)
|
||||
if (typeof obj === 'string') return obj;
|
||||
if (typeof obj === 'number') return ""+obj;
|
||||
let keys = Object.keys(obj);
|
||||
if (keys.length != 1) console.error("can't interpret ", obj, "as xml");
|
||||
let name = keys[0];
|
||||
var full_content = obj[name];
|
||||
var attr = {};
|
||||
if (Array.isArray(full_content)){
|
||||
var content = [];
|
||||
for (var i in full_content) {
|
||||
var obj = full_content[i];
|
||||
var obj_name = Object.keys(obj)[0];
|
||||
if ("_attr" == obj_name) {
|
||||
attr = obj["_attr"];
|
||||
} else {
|
||||
//console.log(Object.keys(obj)[0])
|
||||
content.push(obj);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
content = full_content;
|
||||
}
|
||||
if (content == undefined){
|
||||
content = "undefined"
|
||||
}
|
||||
|
||||
let attr_string = "";
|
||||
for (var k in attr) {
|
||||
attr_string += ` ${k}=\"${attr[k]}\"`
|
||||
}
|
||||
|
||||
//console.log(typeof content, Array.isArray(content), content instanceof String, content)
|
||||
if (Array.isArray(content)){
|
||||
content = content.map(xml);
|
||||
content = content.join("\n").split("\n");
|
||||
content = content.map(s => " " + s).join("\n")
|
||||
var result = `<${name}${attr_string}>\n${content}\n</${name}>`;
|
||||
} else {
|
||||
content = xml(content);
|
||||
var result = `<${name}${attr_string}>${content}</${name}>`;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import logo from "./distill-logo.svg";
|
||||
|
||||
const html = `
|
||||
<style>
|
||||
dt-header {
|
||||
display: block;
|
||||
position: relative;
|
||||
height: 60px;
|
||||
background-color: hsl(200, 60%, 15%);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
z-index: 2;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
dt-header .content {
|
||||
height: 70px;
|
||||
}
|
||||
dt-header a {
|
||||
font-size: 16px;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
text-decoration: none;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
padding: 22px 0;
|
||||
}
|
||||
dt-header a:hover {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
dt-header svg {
|
||||
width: 24px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
@media(min-width: 1080px) {
|
||||
dt-header {
|
||||
height: 70px;
|
||||
}
|
||||
dt-header a {
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
padding: 28px 0;
|
||||
}
|
||||
dt-header .logo {
|
||||
}
|
||||
}
|
||||
dt-header svg path {
|
||||
fill: none;
|
||||
stroke: rgba(255, 255, 255, 0.8);
|
||||
stroke-width: 3px;
|
||||
}
|
||||
dt-header .logo {
|
||||
font-size: 17px;
|
||||
font-weight: 200;
|
||||
}
|
||||
dt-header .nav {
|
||||
float: right;
|
||||
font-weight: 300;
|
||||
}
|
||||
dt-header .nav a {
|
||||
font-size: 12px;
|
||||
margin-left: 24px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="content l-page">
|
||||
<a href="/" class="logo">
|
||||
${logo}
|
||||
Distill
|
||||
</a>
|
||||
<div class="nav">
|
||||
<a href="/faq">About</a>
|
||||
<a href="https://github.com/distillpub">GitHub</a>
|
||||
<!-- https://twitter.com/distillpub -->
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector("dt-header");
|
||||
if(el) {
|
||||
el.innerHTML = html;
|
||||
} else {
|
||||
let header = dom.createElement("dt-header");
|
||||
header.innerHTML = html;
|
||||
let b = dom.querySelector("body");
|
||||
b.insertBefore(header, b.firstChild);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import code from './hover-box.txt';
|
||||
|
||||
export default function(dom) {
|
||||
let s = dom.createElement("script");
|
||||
s.textContent = code;
|
||||
dom.querySelector("body").appendChild(s);
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
// DistillHoverBox
|
||||
//=====================================
|
||||
|
||||
function DistillHoverBox(key, pos){
|
||||
|
||||
if (!(key in DistillHoverBox.contentMap)){
|
||||
console.error("No DistillHoverBox content registered for key", key);
|
||||
}
|
||||
if (key in DistillHoverBox.liveBoxes) {
|
||||
console.error("There already exists a DistillHoverBox for key", key);
|
||||
} else {
|
||||
for (var k in DistillHoverBox.liveBoxes)
|
||||
DistillHoverBox.liveBoxes[k].remove();
|
||||
DistillHoverBox.liveBoxes[key] = this;
|
||||
}
|
||||
this.key = key;
|
||||
|
||||
var pretty = window.innerWidth > 600;
|
||||
|
||||
var padding = pretty? 18 : 12;
|
||||
var outer_padding = pretty ? 18 : 0;
|
||||
var bbox = document.querySelector("body").getBoundingClientRect();
|
||||
var left = pos[0] - bbox.left, top = pos[1] - bbox.top;
|
||||
var width = Math.min(window.innerWidth-2*outer_padding, 648);
|
||||
left = Math.min(left, window.innerWidth-width-outer_padding);
|
||||
width = width - 2*padding;
|
||||
|
||||
var str = `<div style="position: absolute;
|
||||
background-color: #FFF;
|
||||
white-s
|
||||
opacity: 0.95;
|
||||
max-width: ${width}px;
|
||||
top: ${top}px;
|
||||
left: ${left}px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||
padding: ${padding}px;
|
||||
border-radius: ${pretty? 3 : 0}px;
|
||||
box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2);
|
||||
z-index: ${1e6}" >
|
||||
${DistillHoverBox.contentMap[key]}
|
||||
</div>`;
|
||||
|
||||
this.div = appendBody(str);
|
||||
|
||||
DistillHoverBox.bind (this.div, key);
|
||||
}
|
||||
|
||||
DistillHoverBox.prototype.remove = function remove(){
|
||||
if (this.div) this.div.remove();
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
delete DistillHoverBox.liveBoxes[this.key];
|
||||
}
|
||||
|
||||
DistillHoverBox.prototype.stopTimeout = function stopTimeout() {
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
DistillHoverBox.prototype.extendTimeout = function extendTimeout(T) {
|
||||
//console.log("extend", T)
|
||||
var this_ = this;
|
||||
this.stopTimeout();
|
||||
this.timeout = setTimeout(() => this_.remove(), T);
|
||||
}
|
||||
|
||||
DistillHoverBox.liveBoxes = {};
|
||||
DistillHoverBox.contentMap = {};
|
||||
|
||||
DistillHoverBox.bind = function bind(node, key) {
|
||||
if (typeof node == "string"){
|
||||
node = document.querySelector(node);
|
||||
}
|
||||
node.addEventListener("mouseover", () => {
|
||||
var bbox = node.getBoundingClientRect();
|
||||
if (!(key in DistillHoverBox.liveBoxes)){
|
||||
new DistillHoverBox(key, [bbox.right, bbox.bottom]);
|
||||
}
|
||||
DistillHoverBox.liveBoxes[key].stopTimeout();
|
||||
});
|
||||
node.addEventListener("mouseout", () => {
|
||||
if (key in DistillHoverBox.liveBoxes){
|
||||
DistillHoverBox.liveBoxes[key].extendTimeout(250);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function appendBody(str){
|
||||
var node = nodeFromString(str);
|
||||
var body = document.querySelector("body");
|
||||
body.appendChild(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
function nodeFromString(str) {
|
||||
var div = document.createElement("div");
|
||||
div.innerHTML = str;
|
||||
return div.firstChild;
|
||||
}
|
||||
|
||||
var hover_es = document.querySelectorAll("span[data-hover]");
|
||||
hover_es = [].slice.apply(hover_es);
|
||||
hover_es.forEach((e,n) => {
|
||||
var key = "hover-"+n;
|
||||
var content = e.getAttribute("data-hover");
|
||||
DistillHoverBox.contentMap[key] = content;
|
||||
DistillHoverBox.bind(e, key);
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
export default function(dom) {
|
||||
if (!dom.querySelector("html").getAttribute("lang")) {
|
||||
dom.querySelector("html").setAttribute("lang", "en")
|
||||
}
|
||||
|
||||
let head = dom.querySelector("head");
|
||||
|
||||
if (!dom.querySelector("meta[charset]")) {
|
||||
let meta = dom.createElement("meta");
|
||||
meta.setAttribute("charset", "utf-8");
|
||||
head.appendChild(meta);
|
||||
}
|
||||
if (!dom.querySelector("meta[name=viewport]")) {
|
||||
let meta = dom.createElement("meta");
|
||||
meta.setAttribute("name", "viewport");
|
||||
meta.setAttribute("content", "width=device-width, initial-scale=1");
|
||||
head.appendChild(meta);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import fetch from "fetch";
|
||||
let fetchUrl = fetch.fetchUrl
|
||||
|
||||
export default function(dom, data) {
|
||||
|
||||
var includeTags = [].slice.apply(dom.querySelectorAll("dt-include"));
|
||||
|
||||
includeTags.forEach(el => {
|
||||
let src = el.getAttribute("src");
|
||||
fetchUrl(src, (err, meta, body) => {
|
||||
console.log(err, meta, body);
|
||||
el.innerHTML = body.toString();
|
||||
})
|
||||
});
|
||||
data.bibliography = bibliography;
|
||||
data.citations = citations;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import marked from 'marked';
|
||||
|
||||
marked.setOptions({
|
||||
gfm: true,
|
||||
smartypants: true
|
||||
});
|
||||
|
||||
export default function(dom, data) {
|
||||
let markdownElements = [].slice.call(dom.querySelectorAll('[markdown]'));
|
||||
markdownElements.forEach(el => {
|
||||
let content = el.innerHTML;
|
||||
// Set default indents
|
||||
content = content.replace(/\n/, "");
|
||||
let tabs = content.match(/\s*/);
|
||||
content = content.replace(new RegExp("\n" + tabs, "g"), "\n");
|
||||
content = content.trim();
|
||||
|
||||
el.innerHTML = marked(content);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
import favicon from './distill-favicon.base64';
|
||||
|
||||
export default function(dom, data) {
|
||||
let head = dom.querySelector("head");
|
||||
let appendHead = html => appendHtml(head, html);
|
||||
|
||||
function meta(name, content) {
|
||||
if (content)
|
||||
appendHead(` <meta name="${name}" content="${content}" >\n`);
|
||||
}
|
||||
|
||||
appendHead(`
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,${favicon}">
|
||||
<link href="/rss.xml" rel="alternate" type="application/rss+xml" title="Articles from Distill">
|
||||
<link rel="canonical" href="${data.url}">
|
||||
<title>${data.title}</title>
|
||||
`);
|
||||
|
||||
appendHead(`
|
||||
<!-- https://schema.org/Article -->
|
||||
<meta property="article:published" itemprop="datePublished" content="${data.publishedYear}-${data.publishedMonthPadded}-${data.publishedDayPadded}" />
|
||||
<meta property="article:modified" itemprop="dateModified" content="${data.updatedDate}" />
|
||||
`);
|
||||
data.authors.forEach((a) => {
|
||||
appendHtml(head, `
|
||||
<meta property="article:author" content="${a.firstName} ${a.lastName}" />`)
|
||||
});
|
||||
|
||||
appendHead(`
|
||||
<!-- https://developers.facebook.com/docs/sharing/webmasters#markup -->
|
||||
<meta property="og:type" content="article"/>
|
||||
<meta property="og:title" content="${data.title}"/>
|
||||
<meta property="og:description" content="${data.description}">
|
||||
<meta property="og:url" content="${data.url}"/>
|
||||
<meta property="og:image" content="${data.url}/thumbnail.jpg"/>
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta property="og:site_name" content="Distill" />
|
||||
`);
|
||||
|
||||
appendHead(`
|
||||
<!-- https://dev.twitter.com/cards/types/summary -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="${data.title}">
|
||||
<meta name="twitter:description" content="${data.description}">
|
||||
<meta name="twitter:url" content="${data.url}">
|
||||
<meta name="twitter:image" content="${data.url}/thumbnail.jpg">
|
||||
<meta name="twitter:image:width" content="560">
|
||||
<meta name="twitter:image:height" content="295">
|
||||
`);
|
||||
|
||||
// if this is a proprer article, generate Google Scholar meta data
|
||||
if (data.doiSuffix){
|
||||
appendHead(`
|
||||
<!-- https://scholar.google.com/intl/en/scholar/inclusion.html#indexing -->\n`);
|
||||
|
||||
meta("citation_title", data.title);
|
||||
meta("citation_fulltext_html_url", data.url);
|
||||
meta("citation_volume", data.volume);
|
||||
meta("citation_issue", data.issue);
|
||||
meta("citation_firstpage", data.doiSuffix? `e${data.doiSuffix}` : undefined);
|
||||
meta("citation_doi", data.doi);
|
||||
|
||||
let journal = data.journal || {};
|
||||
meta("citation_journal_title", journal.name);
|
||||
meta("citation_journal_abbrev", journal.nameAbbrev);
|
||||
meta("citation_issn", journal.issn);
|
||||
meta("citation_publisher", journal.publisher);
|
||||
|
||||
if (data.publishedDate){
|
||||
let zeroPad = (n) => { return n < 10 ? "0" + n : n; };
|
||||
meta("citation_publication_date", `${data.publishedYear}/${data.publishedMonthPadded}/${data.publishedDayPadded}`);
|
||||
}
|
||||
|
||||
(data.authors || []).forEach((a) => {
|
||||
meta("citation_author", `${a.lastName}, ${a.firstName}`);
|
||||
meta("citation_author_institution", a.affiliation);
|
||||
});
|
||||
|
||||
if (data.citations) {
|
||||
data.citations.forEach(key => {
|
||||
let d = data.bibliography[key];
|
||||
if(!d) {
|
||||
console.warn("No bibliography data fround for " + key)
|
||||
} else {
|
||||
meta("citation_reference", citation_meta_content(data.bibliography[key]) )
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function appendHtml(el, html) {
|
||||
el.innerHTML += html;
|
||||
}
|
||||
|
||||
function citation_meta_content(ref){
|
||||
var content = `citation_title=${ref.title};`;
|
||||
ref.author.split(" and ").forEach(author => {
|
||||
content += `citation_author=${author.trim()};`;
|
||||
});
|
||||
if ("journal" in ref){
|
||||
content += `citation_journal_title=${ref.journal};`;
|
||||
}
|
||||
if ("volume" in ref) {
|
||||
content += `citation_volume=${ref.volume};`;
|
||||
}
|
||||
if ("issue" in ref || "number" in ref){
|
||||
content += `citation_number=${ref.issue || ref.number};`;
|
||||
}
|
||||
/*content += `citation_first_page=${};`;
|
||||
content += `citation_publication_date=${};`;*/
|
||||
return content;
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
dt-article {
|
||||
display: block;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
font: 17px/1.55em -apple-system, BlinkMacSystemFont, "Roboto", sans-serif;
|
||||
padding-bottom: 72px;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
min-height: calc(100vh - 70px - 182px);
|
||||
}
|
||||
|
||||
@media(min-width: 1024px) {
|
||||
dt-article {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H1 */
|
||||
|
||||
dt-article h1 {
|
||||
margin-top: 18px;
|
||||
font-weight: 400;
|
||||
font-size: 40px;
|
||||
line-height: 1em;
|
||||
font-family: HoeflerText-Regular, Cochin, Georgia, serif;
|
||||
}
|
||||
@media(min-width: 768px) {
|
||||
dt-article h1 {
|
||||
font-size: 46px;
|
||||
margin-top: 48px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media(min-width: 1080px) {
|
||||
.centered h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
dt-article h1 {
|
||||
font-size: 50px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
dt-article > h1:first-of-type,
|
||||
dt-article section > h1:first-of-type {
|
||||
margin-top: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media(min-width: 1200px) {
|
||||
dt-article h1 {
|
||||
font-size: 56px;
|
||||
}
|
||||
|
||||
dt-article > h1:first-of-type {
|
||||
margin-top: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H2 */
|
||||
|
||||
dt-article h2 {
|
||||
font-family: HoeflerText-Regular, Cochin, Georgia, serif;
|
||||
font-weight: 400;
|
||||
font-size: 26px;
|
||||
line-height: 1.25em;
|
||||
margin-top: 36px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
@media(min-width: 1024px) {
|
||||
dt-article h2 {
|
||||
margin-top: 48px;
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
dt-article h1 + h2 {
|
||||
font-weight: 300;
|
||||
font-size: 20px;
|
||||
line-height: 1.4em;
|
||||
margin-top: 8px;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
|
||||
@media(min-width: 1080px) {
|
||||
.centered h1 + h2 {
|
||||
text-align: center;
|
||||
}
|
||||
dt-article h1 + h2 {
|
||||
margin-top: 12px;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H3 */
|
||||
|
||||
dt-article h3 {
|
||||
font-family: HoeflerText-Regular, Georgia, serif;
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
line-height: 1.4em;
|
||||
margin-top: 36px;
|
||||
margin-bottom: 18px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
dt-article h1 + h3 {
|
||||
margin-top: 48px;
|
||||
}
|
||||
|
||||
@media(min-width: 1024px) {
|
||||
dt-article h3 {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H4 */
|
||||
|
||||
dt-article h4 {
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
dt-article a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
dt-article p,
|
||||
dt-article ul,
|
||||
dt-article ol {
|
||||
margin-bottom: 24px;
|
||||
font-family: Georgia, serif;
|
||||
}
|
||||
|
||||
dt-article p b,
|
||||
dt-article ul b,
|
||||
dt-article ol b {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
dt-article a {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.4);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
dt-article a:hover {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
dt-article .link {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
dt-article ul,
|
||||
dt-article ol {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
dt-article li {
|
||||
margin-bottom: 24px;
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
dt-article pre {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
dt-article hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
|
||||
margin-top: 60px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
dt-article section {
|
||||
margin-top: 60px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
|
||||
/* Figure */
|
||||
|
||||
dt-article figure {
|
||||
position: relative;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
@media(min-width: 1024px) {
|
||||
dt-article figure {
|
||||
margin-top: 48px;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
dt-article figure img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
dt-article figure svg text,
|
||||
dt-article figure svg tspan {
|
||||
}
|
||||
|
||||
dt-article figure figcaption {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
font-size: 12px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
dt-article figure figcaption {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
dt-article figure.external img {
|
||||
background: white;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.1);
|
||||
padding: 18px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
dt-article figure figcaption a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
/*dt-article figure figcaption::before {
|
||||
position: relative;
|
||||
display: block;
|
||||
top: -20px;
|
||||
content: "";
|
||||
width: 25px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.3);
|
||||
}*/
|
||||
|
||||
dt-article span.equation-mimic {
|
||||
font-family: georgia;
|
||||
font-size: 115%;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
dt-article figure figcaption b {
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 1.0);
|
||||
}
|
||||
|
||||
dt-article > dt-code,
|
||||
dt-article section > dt-code {
|
||||
display: block;
|
||||
}
|
||||
|
||||
dt-article .citation {
|
||||
color: #668;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
dt-include {
|
||||
width: auto;
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
html {
|
||||
font: 400 16px/1.55em -apple-system, BlinkMacSystemFont, "Roboto", Helvetica, sans-serif;
|
||||
/*background-color: hsl(223, 9%, 25%);*/
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
text-size-adjust: 100%;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
/*background-color: hsl(223, 9%, 25%);*/
|
||||
}
|
||||
|
||||
a {
|
||||
color: #004276;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: Cochin, Georgia, serif;
|
||||
}
|
||||
|
||||
/*
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}*/
|
||||
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
|
||||
code {
|
||||
white-space: nowrap;
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
border-radius: 2px;
|
||||
padding: 4px 7px;
|
||||
font-size: 15px;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
background: white;
|
||||
border-left: 3px solid rgba(0, 0, 0, 0.05);
|
||||
padding: 0 0 0 24px;
|
||||
}
|
||||
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #a67f59;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
Column: 60px
|
||||
Gutter: 24px
|
||||
|
||||
Body: 648px
|
||||
- 8 columns
|
||||
- 7 gutters
|
||||
Middle: 816px
|
||||
Page: 984px
|
||||
- 12 columns
|
||||
- 11 gutters
|
||||
*/
|
||||
|
||||
.l-body,
|
||||
.l-body-outset,
|
||||
.l-page,
|
||||
.l-page-outset,
|
||||
.l-middle,
|
||||
.l-middle-outset,
|
||||
dt-article > div,
|
||||
dt-article > p,
|
||||
dt-article > h1,
|
||||
dt-article > h2,
|
||||
dt-article > h3,
|
||||
dt-article > h4,
|
||||
dt-article > figure,
|
||||
dt-article > ul,
|
||||
dt-article > dt-byline,
|
||||
dt-article > dt-code,
|
||||
dt-article section > div,
|
||||
dt-article section > p,
|
||||
dt-article section > h1,
|
||||
dt-article section > h2,
|
||||
dt-article section > h3,
|
||||
dt-article section > h4,
|
||||
dt-article section > figure,
|
||||
dt-article section > ul,
|
||||
dt-article section > dt-byline,
|
||||
dt-article section > dt-code {
|
||||
width: auto;
|
||||
margin-left: 24px;
|
||||
margin-right: 24px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media(min-width: 768px) {
|
||||
.l-body,
|
||||
.l-body-outset,
|
||||
.l-page,
|
||||
.l-page-outset,
|
||||
.l-middle,
|
||||
.l-middle-outset,
|
||||
dt-article > div,
|
||||
dt-article > p,
|
||||
dt-article > h1,
|
||||
dt-article > h2,
|
||||
dt-article > h3,
|
||||
dt-article > h4,
|
||||
dt-article > figure,
|
||||
dt-article > ul,
|
||||
dt-article > dt-byline,
|
||||
dt-article > dt-code,
|
||||
dt-article section > div,
|
||||
dt-article section > p,
|
||||
dt-article section > h1,
|
||||
dt-article section > h2,
|
||||
dt-article section > h3,
|
||||
dt-article section > h4,
|
||||
dt-article section > figure,
|
||||
dt-article section > ul,
|
||||
dt-article section > dt-byline,
|
||||
dt-article section > dt-code {
|
||||
margin-left: 72px;
|
||||
margin-right: 72px;
|
||||
}
|
||||
}
|
||||
|
||||
@media(min-width: 1080px) {
|
||||
.l-body,
|
||||
dt-article > div,
|
||||
dt-article > p,
|
||||
dt-article > h2,
|
||||
dt-article > h3,
|
||||
dt-article > h4,
|
||||
dt-article > figure,
|
||||
dt-article > ul,
|
||||
dt-article > dt-byline,
|
||||
dt-article > dt-code,
|
||||
dt-article section > div,
|
||||
dt-article section > p,
|
||||
dt-article section > h2,
|
||||
dt-article section > h3,
|
||||
dt-article section > h4,
|
||||
dt-article section > figure,
|
||||
dt-article section > ul,
|
||||
dt-article section > dt-byline,
|
||||
dt-article section > dt-code {
|
||||
margin-left: calc(50% - 984px / 2);
|
||||
width: 648px;
|
||||
}
|
||||
.l-body-outset,
|
||||
dt-article .l-body-outset {
|
||||
margin-left: calc(50% - 984px / 2 - 96px/2);
|
||||
width: calc(648px + 96px);
|
||||
}
|
||||
.l-middle,
|
||||
dt-article .l-middle {
|
||||
width: 816px;
|
||||
margin-left: calc(50% - 984px / 2);
|
||||
margin-right: auto;
|
||||
}
|
||||
.l-middle-outset,
|
||||
dt-article .l-middle-outset {
|
||||
width: calc(816px + 96px);
|
||||
margin-left: calc(50% - 984px / 2 - 48px);
|
||||
margin-right: auto;
|
||||
}
|
||||
dt-article > h1,
|
||||
dt-article section > h1,
|
||||
.l-page,
|
||||
dt-article .l-page,
|
||||
dt-article.centered .l-page {
|
||||
width: 984px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.l-page-outset,
|
||||
dt-article .l-page-outset,
|
||||
dt-article.centered .l-page-outset {
|
||||
width: 1080px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.l-screen,
|
||||
dt-article .l-screen,
|
||||
dt-article.centered .l-screen {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: auto;
|
||||
}
|
||||
.l-screen-inset,
|
||||
dt-article .l-screen-inset,
|
||||
dt-article.centered .l-screen-inset {
|
||||
margin-left: 24px;
|
||||
margin-right: 24px;
|
||||
width: auto;
|
||||
}
|
||||
.l-gutter,
|
||||
dt-article .l-gutter {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 24px;
|
||||
margin-right: calc((100vw - 984px) / 2 + 168px);
|
||||
width: calc((984px - 648px) / 2 - 24px);
|
||||
}
|
||||
|
||||
/* Side */
|
||||
.side.l-body,
|
||||
dt-article .side.l-body {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px + 648px) / 2);
|
||||
width: calc(648px / 2 - 24px - 84px);
|
||||
}
|
||||
.side.l-body-outset,
|
||||
dt-article .side.l-body-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px + 648px - 48px) / 2);
|
||||
width: calc(648px / 2 - 48px + 24px);
|
||||
}
|
||||
.side.l-middle,
|
||||
dt-article .side.l-middle {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: calc(456px - 84px);
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px) / 2 + 168px);
|
||||
}
|
||||
.side.l-middle-outset,
|
||||
dt-article .side.l-middle-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: 456px;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px) / 2 + 168px);
|
||||
}
|
||||
.side.l-page,
|
||||
dt-article .side.l-page {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-left: 48px;
|
||||
width: calc(624px - 84px);
|
||||
margin-right: calc((100vw - 984px) / 2);
|
||||
}
|
||||
.side.l-page-outset,
|
||||
dt-article .side.l-page-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: 624px;
|
||||
margin-right: calc((100vw - 984px) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Centered */
|
||||
|
||||
@media(min-width: 1080px) {
|
||||
.centered .l-body,
|
||||
.centered.l-body,
|
||||
dt-article.centered > div,
|
||||
dt-article.centered > p,
|
||||
dt-article.centered > h2,
|
||||
dt-article.centered > h3,
|
||||
dt-article.centered > h4,
|
||||
dt-article.centered > figure,
|
||||
dt-article.centered > ul,
|
||||
dt-article.centered > dt-byline,
|
||||
dt-article.centered > dt-code,
|
||||
dt-article.centered section > div,
|
||||
dt-article.centered section > p,
|
||||
dt-article.centered section > h2,
|
||||
dt-article.centered section > h3,
|
||||
dt-article.centered section > h4,
|
||||
dt-article.centered section > figure,
|
||||
dt-article.centered section > ul,
|
||||
dt-article.centered section > dt-byline,
|
||||
dt-article.centered section > dt-code,
|
||||
dt-article section.centered > div,
|
||||
dt-article section.centered > p,
|
||||
dt-article section.centered > h2,
|
||||
dt-article section.centered > h3,
|
||||
dt-article section.centered > h4,
|
||||
dt-article section.centered > figure,
|
||||
dt-article section.centered > ul,
|
||||
dt-article section.centered > dt-byline,
|
||||
dt-article section.centered > dt-code {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 648px;
|
||||
}
|
||||
.centered .l-body-outset,
|
||||
.centered.l-body-outset,
|
||||
dt-article.centered .l-body-outset {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: calc(648px + 96px);
|
||||
}
|
||||
dt-article.centered > h1,
|
||||
dt-article.centered section > h1,
|
||||
dt-article section.centered > h1,
|
||||
.centered .l-middle,
|
||||
.centered.l-middle,
|
||||
dt-article.centered .l-middle {
|
||||
width: 816px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.centered .l-middle-outset,
|
||||
.centered.l-middle-outset,
|
||||
dt-article.centered .l-middle-outset {
|
||||
width: calc(816px + 96px);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* page and screen are already centered */
|
||||
|
||||
/* Side */
|
||||
|
||||
.centered .side.l-body,
|
||||
.centered dt-article .side.l-body {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 648px) / 2);
|
||||
width: calc(4 * 60px + 3 * 24px);
|
||||
}
|
||||
.centered .side.l-body-outset,
|
||||
.centered dt-article .side.l-body-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 648px) / 2);
|
||||
width: calc(4 * 60px + 3 * 24px);
|
||||
}
|
||||
.centered .side.l-middle,
|
||||
.centered dt-article .side.l-middle {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: 396px;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px) / 2 + 168px / 2);
|
||||
}
|
||||
.centered .side.l-middle-outset,
|
||||
.centered dt-article .side.l-middle-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: 456px;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px) / 2 + 168px);
|
||||
}
|
||||
.centered .side.l-page,
|
||||
.centered dt-article .side.l-page {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: 480px;
|
||||
margin-right: calc((100vw - 984px) / 2);
|
||||
}
|
||||
.centered .side.l-page-outset,
|
||||
.centered dt-article .side.l-page-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: 480px;
|
||||
margin-right: calc((100vw - 984px) / 2);
|
||||
}
|
||||
.centered .l-gutter,
|
||||
.centered.l-gutter,
|
||||
dt-article.centered .l-gutter {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 24px;
|
||||
margin-right: calc((100vw - 984px) / 2);
|
||||
width: calc((984px - 648px) / 2 - 24px);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Rows and Columns */
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
}
|
||||
.column {
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
margin-right: 24px;
|
||||
margin-left: 24px;
|
||||
}
|
||||
.row > .column:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
.row > .column:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
@media print {
|
||||
@page {
|
||||
size: 8in 11in;
|
||||
}
|
||||
html {
|
||||
}
|
||||
p, code {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
h2, h3 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
dt-header {
|
||||
visibility: hidden;
|
||||
}
|
||||
dt-footer {
|
||||
display: none!important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import base from './styles-base.css';
|
||||
import layout from './styles-layout.css';
|
||||
import article from './styles-article.css';
|
||||
import code from './styles-code.css';
|
||||
import print from './styles-print.css';
|
||||
|
||||
export default function(dom) {
|
||||
let s = dom.createElement("style");
|
||||
s.textContent = base + layout + article + code + print;
|
||||
dom.querySelector("head").appendChild(s);
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
export default function(dom, data) {
|
||||
|
||||
var textNodes = dom.createTreeWalker(
|
||||
dom.body,
|
||||
dom.defaultView.NodeFilter.SHOW_TEXT
|
||||
);
|
||||
while (textNodes.nextNode()) {
|
||||
var n = textNodes.currentNode,
|
||||
text = n.nodeValue;
|
||||
if (text && acceptNode(n)) {
|
||||
text = quotes(text);
|
||||
text = punctuation(text);
|
||||
n.nodeValue = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function acceptNode(node) {
|
||||
var parent = node.parentElement;
|
||||
var isMath = (parent && parent.getAttribute && parent.getAttribute("class")) ? parent.getAttribute("class").includes("katex") || parent.getAttribute("class").includes("MathJax") : false;
|
||||
return parent &&
|
||||
parent.nodeName !== "SCRIPT" &&
|
||||
parent.nodeName !== "STYLE" &&
|
||||
parent.nodeName !== "CODE" &&
|
||||
parent.nodeName !== "PRE" &&
|
||||
parent.nodeName !== "SPAN" &&
|
||||
parent.nodeName !== "D-HEADER" &&
|
||||
parent.nodeName !== "D-BYLINE" &&
|
||||
parent.nodeName !== "D-MATH" &&
|
||||
parent.nodeName !== "D-CODE" &&
|
||||
parent.nodeName !== "D-BIBLIOGRAPHY" &&
|
||||
parent.nodeName !== "D-FOOTER" &&
|
||||
parent.nodeType !== 8 && //comment nodes
|
||||
!isMath;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* typeset - Typesetting for the web
|
||||
* @version v0.1.6
|
||||
* @link https://github.com/davidmerfield/Typeset.js
|
||||
* @author David Merfield
|
||||
*/
|
||||
// which has a CC0 license
|
||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
|
||||
function punctuation(text){
|
||||
|
||||
// Dashes
|
||||
text = text.replace(/--/g, '\u2014');
|
||||
text = text.replace(/ \u2014 /g,"\u2009\u2014\u2009"); //this has thin spaces
|
||||
|
||||
// Elipses
|
||||
text = text.replace(/\.\.\./g,'…');
|
||||
|
||||
// Nbsp for punc with spaces
|
||||
var NBSP = "\u00a0";
|
||||
var NBSP_PUNCTUATION_START = /([«¿¡]) /g;
|
||||
var NBSP_PUNCTUATION_END = / ([\!\?:;\.,‽»])/g;
|
||||
|
||||
text = text.replace(NBSP_PUNCTUATION_START, '$1' + NBSP);
|
||||
text = text.replace(NBSP_PUNCTUATION_END, NBSP + '$1');
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
function quotes(text) {
|
||||
|
||||
text = text
|
||||
.replace(/(\W|^)"([^\s\!\?:;\.,‽»])/g, '$1\u201c$2') // beginning "
|
||||
.replace(/(\u201c[^"]*)"([^"]*$|[^\u201c"]*\u201c)/g, '$1\u201d$2') // ending "
|
||||
.replace(/([^0-9])"/g,'$1\u201d') // remaining " at end of word
|
||||
.replace(/(\W|^)'(\S)/g, '$1\u2018$2') // beginning '
|
||||
.replace(/([a-z])'([a-z])/ig, '$1\u2019$2') // conjunction's possession
|
||||
.replace(/((\u2018[^']*)|[a-z])'([^0-9]|$)/ig, '$1\u2019$3') // ending '
|
||||
.replace(/(\u2018)([0-9]{2}[^\u2019]*)(\u2018([^0-9]|$)|$|\u2019[a-z])/ig, '\u2019$2$3') // abbrev. years like '93
|
||||
.replace(/(\B|^)\u2018(?=([^\u2019]*\u2019\b)*([^\u2019\u2018]*\W[\u2019\u2018]\b|[^\u2019\u2018]*$))/ig, '$1\u2019') // backwards apostrophe
|
||||
.replace(/'''/g, '\u2034') // triple prime
|
||||
.replace(/("|'')/g, '\u2033') // double prime
|
||||
.replace(/'/g, '\u2032');
|
||||
|
||||
// Allow escaped quotes
|
||||
text = text.replace(/\\“/, '\"');
|
||||
text = text.replace(/\\”/, '\"');
|
||||
text = text.replace(/\\’/, '\'');
|
||||
text = text.replace(/\\‘/, '\'');
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
function ligatures(text){
|
||||
|
||||
text = text.replace(/fi/g, 'fi');
|
||||
text = text.replace(/fl/g, 'fl');
|
||||
|
||||
return text;
|
||||
};
|
||||
Reference in New Issue
Block a user