mirror of
https://github.com/wassname/template.git
synced 2026-06-27 19:33:10 +08:00
Merging
This commit is contained in:
+2
-2
@@ -4,7 +4,7 @@ const fs = require('fs');
|
||||
const jsdom = require('jsdom').jsdom;
|
||||
const serialize = require('jsdom').serializeDocument;
|
||||
const program = require('commander');
|
||||
const transforms = require('../dist/transforms.js');
|
||||
const transforms = require('../dist/transforms.v2.js');
|
||||
|
||||
program
|
||||
.version('0.0.1')
|
||||
@@ -12,7 +12,7 @@ program
|
||||
.parse(process.argv);
|
||||
|
||||
const htmlString = fs.readFileSync(program.input, 'utf8');
|
||||
const data = {};
|
||||
const data = new transforms.FrontMatter;
|
||||
const dom = jsdom(htmlString, {features: {ProcessExternalResources: false, FetchExternalResources: false, runScripts: 'dangerously'}});
|
||||
transforms.render(dom, data);
|
||||
transforms.distillify(dom, data);
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
<d-title>
|
||||
<h1>How to Use t-SNE Effectively</h1>
|
||||
<h2>Although extremely useful for visualizing high-dimensional data, t-SNE plots can sometimes be mysterious or misleading.</h2>
|
||||
<d-byline></d-byline>
|
||||
</d-title>
|
||||
<d-byline></d-byline>
|
||||
<!-- <d-abstract>
|
||||
<p>This is the first paragraph of the article. Test a long — dash -- here it is.</p>
|
||||
</d-abstract> -->
|
||||
|
||||
Generated
+93
-8
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "distill-template",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.0-alpha",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -71,6 +71,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"acorn-object-spread": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-object-spread/-/acorn-object-spread-1.0.0.tgz",
|
||||
"integrity": "sha1-SOrQ9KjrFplaF6Dbn/xqyq2kumg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "3.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
|
||||
"integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "4.11.8",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
|
||||
@@ -852,6 +869,44 @@
|
||||
"pako": "0.2.9"
|
||||
}
|
||||
},
|
||||
"buble": {
|
||||
"version": "0.15.2",
|
||||
"resolved": "https://registry.npmjs.org/buble/-/buble-0.15.2.tgz",
|
||||
"integrity": "sha1-VH/EdIP45egXbYKqXrzLGDsC1hM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "3.3.0",
|
||||
"acorn-jsx": "3.0.1",
|
||||
"acorn-object-spread": "1.0.0",
|
||||
"chalk": "1.1.3",
|
||||
"magic-string": "0.14.0",
|
||||
"minimist": "1.2.0",
|
||||
"os-homedir": "1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
|
||||
"integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
|
||||
"dev": true
|
||||
},
|
||||
"magic-string": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.14.0.tgz",
|
||||
"integrity": "sha1-VyJK7xcByu7Sc7F6OalW5ysXJGI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"vlq": "0.2.2"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "4.9.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
|
||||
@@ -3181,6 +3236,11 @@
|
||||
"integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=",
|
||||
"dev": true
|
||||
},
|
||||
"intersection-observer": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.4.0.tgz",
|
||||
"integrity": "sha512-hBECeRcNPMrQP02IlicMCDiL19KQweoWukv35juIVehB2lE+spel5UyfTux/YCkXaR8Zz0jq3xMZeWYZBAU2SA=="
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
|
||||
@@ -4699,13 +4759,10 @@
|
||||
}
|
||||
},
|
||||
"rollup": {
|
||||
"version": "0.45.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-0.45.2.tgz",
|
||||
"integrity": "sha512-2+bq5GQSrocdhr+M92mOQRmF1evtLRzv9NdmEC2wo7BILvTG8irHCtD0q+zg8ikNu63iJicdN5IzyxAXRTFKOQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"source-map-support": "0.4.15"
|
||||
}
|
||||
"version": "0.49.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-0.49.2.tgz",
|
||||
"integrity": "sha512-9mySqItSwq5/dXYQyFGrrzqV282EZfz4kSCU2m4e6OjgqLmIsp9zK6qNQ6wbBWR4EhASEqQMBQ/IF45jaNPAtw==",
|
||||
"dev": true
|
||||
},
|
||||
"rollup-plugin-babili": {
|
||||
"version": "3.1.0",
|
||||
@@ -4718,6 +4775,34 @@
|
||||
"babel-preset-babili": "0.1.4"
|
||||
}
|
||||
},
|
||||
"rollup-plugin-buble": {
|
||||
"version": "0.15.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-buble/-/rollup-plugin-buble-0.15.0.tgz",
|
||||
"integrity": "sha1-g8PonH/SJmx5GPQbo5gDE1Gcf9A=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buble": "0.15.2",
|
||||
"rollup-pluginutils": "1.5.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"estree-walker": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz",
|
||||
"integrity": "sha1-va/oCVOD2EFNXcLs9MkXO225QS4=",
|
||||
"dev": true
|
||||
},
|
||||
"rollup-pluginutils": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz",
|
||||
"integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"estree-walker": "0.2.1",
|
||||
"minimatch": "3.0.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rollup-plugin-commonjs": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-7.1.0.tgz",
|
||||
|
||||
+2
-1
@@ -10,7 +10,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "rollup -c rollup.config.dev.js -w",
|
||||
"serve": "python3 -m http.server --bind 127.0.0.1",
|
||||
"serve": "python3 -m http.server --bind 127.0.0.1 8888",
|
||||
"test": "mocha",
|
||||
"lint": "eslint",
|
||||
"build": "rollup -c rollup.config.js"
|
||||
@@ -32,6 +32,7 @@
|
||||
"prismjs": "^1.6.0",
|
||||
"rollup": "latest",
|
||||
"rollup-plugin-babili": "^3.1.0",
|
||||
"rollup-plugin-buble": "^0.15.0",
|
||||
"rollup-plugin-commonjs": "^7.0.0",
|
||||
"rollup-plugin-copy": "^0.2.3",
|
||||
"rollup-plugin-gzip": "^1.2.0",
|
||||
|
||||
+12
-5
@@ -1,19 +1,20 @@
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import string from 'rollup-plugin-string';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import buble from 'rollup-plugin-buble';
|
||||
|
||||
const componentsConfig = {
|
||||
entry: 'src/components.js',
|
||||
targets: [{format: 'umd', moduleName: 'dl', dest: 'dist/template.v2.js'}],
|
||||
input: 'src/components.js',
|
||||
output: [{format: 'umd', name: 'dl', file: 'dist/template.v2.js'}],
|
||||
};
|
||||
|
||||
const transformsConfig = {
|
||||
entry: 'src/transforms.js',
|
||||
targets: [{format: 'umd', moduleName: 'dl', dest: 'dist/transforms.v2.js'}],
|
||||
input: 'src/transforms.js',
|
||||
output: [{format: 'umd', name: 'dl', file: 'dist/transforms.v2.js'}],
|
||||
};
|
||||
|
||||
const defaultConfig = {
|
||||
sourceMap: true,
|
||||
sourcemap: true,
|
||||
plugins: [
|
||||
resolve({
|
||||
jsnext: true,
|
||||
@@ -29,6 +30,12 @@ const defaultConfig = {
|
||||
Object.assign(componentsConfig, defaultConfig);
|
||||
Object.assign(transformsConfig, defaultConfig);
|
||||
|
||||
// transpile transforms so the node render script works…
|
||||
transformsConfig.plugins.push(
|
||||
buble({
|
||||
target: { 'node': 6 }
|
||||
}));
|
||||
|
||||
export default [
|
||||
componentsConfig,
|
||||
transformsConfig,
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
/* Static styles and other modules */
|
||||
import './styles/styles';
|
||||
import { makeStyleTag } from './styles/styles';
|
||||
makeStyleTag(document);
|
||||
|
||||
/* Components */
|
||||
import { Abstract } from './components/d-abstract';
|
||||
|
||||
@@ -7,7 +7,8 @@ const T = Template('d-abstract', `
|
||||
display: block;
|
||||
font-size: 23px;
|
||||
line-height: 1.7em;
|
||||
margin-bottom: 140px;
|
||||
margin-top: 64px;
|
||||
margin-bottom: 64px;
|
||||
}
|
||||
${body('d-abstract')}
|
||||
</style>
|
||||
|
||||
@@ -2,6 +2,11 @@ import { Template } from '../mixins/template';
|
||||
|
||||
const T = Template('d-acknowledgements', `
|
||||
<style>
|
||||
|
||||
:host {
|
||||
contain: content;
|
||||
}
|
||||
|
||||
::slotted(h3) {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
@@ -10,9 +15,11 @@ const T = Template('d-acknowledgements', `
|
||||
color: rgba(0,0,0,0.65);
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
::slotted(*) a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<slot></slot>
|
||||
|
||||
@@ -14,9 +14,10 @@ const T = Template('d-appendix', `
|
||||
margin-bottom: 0;
|
||||
border-top: 1px solid rgba(0,0,0,0.1);
|
||||
color: rgba(0,0,0,0.5);
|
||||
background: hsl(180, 5%, 98%);
|
||||
padding-top: 36px;
|
||||
padding-bottom: 48px;
|
||||
|
||||
contain: content;
|
||||
}
|
||||
|
||||
${body('.content')}
|
||||
|
||||
@@ -2,7 +2,11 @@ import { Template } from '../mixins/template';
|
||||
import { Controller } from '../controller';
|
||||
|
||||
const T = Template('d-article', `
|
||||
<style></style>
|
||||
<style>
|
||||
d-article {
|
||||
contain: content;
|
||||
}
|
||||
</style>
|
||||
`, false);
|
||||
|
||||
// export function addInferableTags(dom, frontMatter) {
|
||||
|
||||
@@ -4,6 +4,9 @@ import { bibliography_cite } from '../helpers/citation';
|
||||
|
||||
export const templateString = `
|
||||
<style>
|
||||
:host {
|
||||
contain: content;
|
||||
}
|
||||
.references {
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
|
||||
+78
-105
@@ -1,110 +1,81 @@
|
||||
import { Template } from '../mixins/template';
|
||||
import { page } from '../helpers/layout';
|
||||
export const style = `
|
||||
d-byline {
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
padding-bottom: 20px;
|
||||
contain: content;
|
||||
}
|
||||
|
||||
const T = Template('d-byline', `
|
||||
<style>
|
||||
:host {
|
||||
box-sizing: border-box;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
display: block;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
${page('.byline')}
|
||||
d-article.centered {
|
||||
text-align: center;
|
||||
}
|
||||
a,
|
||||
d-article a {
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
d-article a:hover {
|
||||
text-decoration: underline;
|
||||
border-bottom: none;
|
||||
}
|
||||
.authors {
|
||||
text-align: left;
|
||||
}
|
||||
.name {
|
||||
font-weight: 600;
|
||||
display: inline;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.affiliation {
|
||||
display: inline;
|
||||
}
|
||||
.date {
|
||||
display: block;
|
||||
text-align: left;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.year, .month {
|
||||
display: inline;
|
||||
}
|
||||
.citation {
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
.citation div {
|
||||
display: inline;
|
||||
}
|
||||
.byline {
|
||||
line-height: 1.8em;
|
||||
border-top: solid 1px rgba(0, 0, 0, 0.1);
|
||||
margin-top: 20px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
/*.byline::after {
|
||||
content: "";
|
||||
display: block;
|
||||
border-bottom: solid 1px #999;
|
||||
width: 40px;
|
||||
margin-top: 60px;
|
||||
}*/
|
||||
d-byline .byline {
|
||||
grid-column: margin-left / page;
|
||||
line-height: 1.8em;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px), print {
|
||||
d-byline {
|
||||
border-bottom: none;
|
||||
}
|
||||
a:hover {
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
.authors {
|
||||
}
|
||||
.author {
|
||||
margin-right: 12px;
|
||||
}
|
||||
.affiliation {
|
||||
display: inline;
|
||||
}
|
||||
.author:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
.name {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.date {
|
||||
display: none;
|
||||
margin-top: 0;
|
||||
}
|
||||
.year, .month {
|
||||
}
|
||||
.citation {
|
||||
}
|
||||
.citation div {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
d-byline .byline::after {
|
||||
content: "";
|
||||
display: block;
|
||||
border-bottom: solid 1px #999;
|
||||
width: 40px;
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
d-byline a,
|
||||
d-article d-byline a {
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
d-article d-byline a:hover {
|
||||
text-decoration: underline;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
d-byline .authors {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
d-byline .author {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
d-byline .author .name {
|
||||
font-weight: 600;
|
||||
display: inline;
|
||||
text-transform: uppercase;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
d-byline .author .affiliation {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
d-byline .date {
|
||||
display: inline;
|
||||
text-align: left;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
d-byline .date .year,
|
||||
d-byline .date .month {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
d-byline .citation {
|
||||
display: inline;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
d-byline .citation div {
|
||||
display: inline;
|
||||
}
|
||||
`;
|
||||
|
||||
<div class='byline'>
|
||||
</div>
|
||||
`, true);
|
||||
|
||||
export function bylineTemplate(frontMatter) {
|
||||
return `
|
||||
<div class='byline'>
|
||||
<div class="authors">
|
||||
${frontMatter.authors.map( author => `<div class="author">
|
||||
${author.personalURL ?
|
||||
@@ -126,14 +97,16 @@ export function bylineTemplate(frontMatter) {
|
||||
<a class="citation" href="#citation">
|
||||
<div>${frontMatter.concatenatedAuthors}, ${frontMatter.publishedYear}</div>
|
||||
</a>
|
||||
`;
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
export class Byline extends T(HTMLElement) {
|
||||
export class Byline extends HTMLElement {
|
||||
|
||||
static get is() { return 'd-byline'; }
|
||||
|
||||
set frontMatter(frontMatter) {
|
||||
const container = this.root.querySelector('.byline');
|
||||
container.innerHTML = bylineTemplate(frontMatter);
|
||||
this.innerHTML = bylineTemplate(frontMatter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,8 +17,39 @@ export class Figure extends HTMLElement {
|
||||
|
||||
static get is() { return 'd-figure'; }
|
||||
|
||||
static get readyQueue() {
|
||||
if (!Figure._readyQueue) {
|
||||
Figure._readyQueue = [];
|
||||
}
|
||||
return Figure._readyQueue;
|
||||
}
|
||||
|
||||
static addToReadyQueue(figure) {
|
||||
if (Figure.readyQueue.indexOf(figure) === -1) {
|
||||
Figure.readyQueue.push(figure);
|
||||
Figure.runReadyQueue();
|
||||
}
|
||||
}
|
||||
|
||||
static runReadyQueue() {
|
||||
// console.log("Checking to run readyQueue, length: " + Figure.readyQueue.length + ", scrolling: " + Figure.isScrolling);
|
||||
if (Figure.isScrolling) return;
|
||||
|
||||
// console.log("Running ready Queue");
|
||||
const figure = Figure.readyQueue
|
||||
.sort((a,b) => a._seenOnScreen - b._seenOnScreen )
|
||||
.filter((figure) => !figure._ready)
|
||||
.pop();
|
||||
if (figure) {
|
||||
figure.ready();
|
||||
requestAnimationFrame(Figure.runReadyQueue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
// debugger
|
||||
this._ready = false;
|
||||
this._onscreen = false;
|
||||
this._offscreen = true;
|
||||
@@ -54,7 +85,7 @@ export class Figure extends HTMLElement {
|
||||
for (const entry of entries) {
|
||||
const figure = entry.target;
|
||||
if (entry.isIntersecting && !figure._ready) {
|
||||
figure.ready();
|
||||
Figure.addToReadyQueue(figure);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,7 +105,8 @@ export class Figure extends HTMLElement {
|
||||
for (const entry of entries) {
|
||||
const figure = entry.target;
|
||||
if (entry.isIntersecting) {
|
||||
if (!figure._ready) { figure.ready(); }
|
||||
figure._seenOnScreen = new Date();
|
||||
// if (!figure._ready) { figure.ready(); }
|
||||
if (figure._offscreen) { figure.onscreen(); }
|
||||
} else {
|
||||
if (figure._onscreen) { figure.offscreen(); }
|
||||
@@ -87,19 +119,22 @@ export class Figure extends HTMLElement {
|
||||
addEventListener(eventName, callback) {
|
||||
super.addEventListener(eventName, callback);
|
||||
// if we had already dispatched something while presumingly no one was listening, we do so again
|
||||
setTimeout(() => {
|
||||
if (this._ready && eventName === 'ready') {
|
||||
this.ready();
|
||||
// debugger
|
||||
if (eventName === 'ready') {
|
||||
if (Figure.readyQueue.indexOf(this) !== -1) {
|
||||
this._ready = false;
|
||||
Figure.runReadyQueue();
|
||||
}
|
||||
if (this._onscreen && eventName === 'onscreen') {
|
||||
this.onscreen();
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
if (eventName === 'onscreen') {
|
||||
this.onscreen();
|
||||
}
|
||||
}
|
||||
|
||||
// Custom Events
|
||||
|
||||
ready() {
|
||||
// debugger
|
||||
this._ready = true;
|
||||
Figure.marginObserver.unobserve(this);
|
||||
const event = new CustomEvent('ready');
|
||||
@@ -121,3 +156,20 @@ export class Figure extends HTMLElement {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
|
||||
Figure.isScrolling = false;
|
||||
let timeout;
|
||||
const resetTimer = () => {
|
||||
Figure.isScrolling = true;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => {
|
||||
Figure.isScrolling = false;
|
||||
console.log('Stopped Scrolling')
|
||||
Figure.runReadyQueue();
|
||||
}, 500);
|
||||
};
|
||||
window.addEventListener('scroll', resetTimer, true);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ import { Template } from '../mixins/template';
|
||||
|
||||
const T = Template('d-footnote-list', `
|
||||
<style>
|
||||
:host {
|
||||
contain: content;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding: 0 0 0 18px;
|
||||
}
|
||||
|
||||
@@ -19,10 +19,10 @@ export class FrontMatter extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const options = {childList: true};
|
||||
const options = {childList: true, characterData: true, subtree: true};
|
||||
const observer = new MutationObserver( (entries) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.target.nodeName === 'SCRIPT') {
|
||||
if (entry.target.nodeName === 'SCRIPT' || entry.type === 'characterData') {
|
||||
const data = parseFrontmatter(this);
|
||||
this.notify(data);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ const katexCSSTag = '<link rel="stylesheet" href="https://distill.pub/third-part
|
||||
const T = Template('d-math', `
|
||||
<style>
|
||||
|
||||
:host {
|
||||
contain: content;
|
||||
}
|
||||
|
||||
d-math[block] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
+62
-9
@@ -1,13 +1,66 @@
|
||||
import {Template} from '../mixins/template';
|
||||
export class TOC extends HTMLElement {
|
||||
|
||||
const T = Template('d-toc', `
|
||||
<style>
|
||||
d-toc {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
`, false);
|
||||
static get is() { return 'd-toc'; }
|
||||
|
||||
export class TOC extends T(HTMLElement) {
|
||||
connectedCallback() {
|
||||
if (!this.getAttribute('prerendered')) {
|
||||
window.onload = () => {
|
||||
const article = document.querySelector('d-article');
|
||||
const headings = article.querySelectorAll('h2, h3');
|
||||
renderTOC(this, headings);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function renderTOC(element, headings) {
|
||||
|
||||
let ToC =`
|
||||
<style>
|
||||
|
||||
d-toc {
|
||||
contain: content;
|
||||
display: block;
|
||||
}
|
||||
|
||||
d-toc ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
d-toc ul > ul {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
d-toc a {
|
||||
border-bottom: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
<nav role="navigation" class="table-of-contents"></nav>
|
||||
<h2>Table of contents</h2>
|
||||
<ul>`;
|
||||
|
||||
for (const el of headings) {
|
||||
// should element be included in TOC?
|
||||
const isInTitle = el.parentElement.tagName == 'D-TITLE';
|
||||
const isException = el.getAttribute('no-toc');
|
||||
if (isInTitle || isException) continue;
|
||||
// create TOC entry
|
||||
const title = el.textContent;
|
||||
const link = '#' + el.getAttribute('id');
|
||||
|
||||
let newLine = '<li>' + '<a href="' + link + '">' + title + '</a>' + '</li>';
|
||||
if (el.tagName == 'H3') {
|
||||
newLine = '<ul>' + newLine + '</ul>';
|
||||
} else {
|
||||
newLine += '<br>';
|
||||
}
|
||||
ToC += newLine;
|
||||
|
||||
}
|
||||
|
||||
ToC += '</ul></nav>';
|
||||
element.innerHTML = ToC;
|
||||
}
|
||||
|
||||
+2
-2
@@ -108,12 +108,12 @@ export const Controller = {
|
||||
frontMatter.mergeFromYMLFrontmatter(data);
|
||||
|
||||
const appendix = document.querySelector('distill-appendix');
|
||||
if (appendix) {
|
||||
if (appendix && !appendix.getAttribute('prerendered')) {
|
||||
appendix.frontMatter = frontMatter;
|
||||
}
|
||||
|
||||
const byline = document.querySelector('d-byline');
|
||||
if (byline) {
|
||||
if (byline && !byline.getAttribute('prerendered')) {
|
||||
byline.frontMatter = frontMatter;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2,6 +2,9 @@ import { serializeFrontmatterToBibtex } from '../helpers/bibtex';
|
||||
|
||||
const styles = `
|
||||
<style>
|
||||
distill-appendix {
|
||||
contain: content;
|
||||
}
|
||||
distill-appendix h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
|
||||
@@ -12,6 +12,8 @@ const T = Template('distill-footer', `
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
background-color: hsl(180, 5%, 15%); /*hsl(200, 60%, 15%);*/
|
||||
text-align: left;
|
||||
|
||||
contain: content;
|
||||
}
|
||||
|
||||
.logo svg {
|
||||
|
||||
@@ -16,6 +16,7 @@ const T = Template('distill-header', `
|
||||
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);*/
|
||||
contain: content;
|
||||
}
|
||||
.content {
|
||||
height: 70px;
|
||||
@@ -42,6 +43,9 @@ svg {
|
||||
margin-right: 2px;
|
||||
}
|
||||
@media(min-width: 768px) {
|
||||
:host {
|
||||
height: 120px;
|
||||
}
|
||||
svg {
|
||||
top: 40px;
|
||||
left: 40px;
|
||||
@@ -50,7 +54,7 @@ svg {
|
||||
|
||||
@media(min-width: 1080px) {
|
||||
:host {
|
||||
height: 70px;
|
||||
height: 120px;
|
||||
}
|
||||
a {
|
||||
height: 70px;
|
||||
|
||||
@@ -7,5 +7,5 @@ export default function(dom, data) {
|
||||
return;
|
||||
}
|
||||
const extractedData = parseFrontmatter(frontMatterTag);
|
||||
Object.assign(data, extractedData);
|
||||
data.mergeFromYMLFrontmatter(extractedData);
|
||||
}
|
||||
|
||||
+39
-30
@@ -1,25 +1,34 @@
|
||||
import {timeFormat} from 'd3-time-format';
|
||||
|
||||
const zeroPad = n => n < 10 ? '0' + n : n;
|
||||
const RFC = timeFormat('%a, %d %b %Y %H:%M:%S %Z');
|
||||
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`;
|
||||
};
|
||||
|
||||
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"
|
||||
this.name = name; // 'Chris Olah'
|
||||
this.personalURL = personalURL; // 'https://colah.github.io'
|
||||
this.affiliation = affiliation; // 'Google Brain'
|
||||
this.affiliationURL = affiliationURL; // 'https://g.co/brain'
|
||||
}
|
||||
|
||||
// "Chris"
|
||||
// 'Chris'
|
||||
get firstName() {
|
||||
const names = this.name.split(' ');
|
||||
return names.slice(0, names.length - 1).join(' ');
|
||||
}
|
||||
|
||||
// "Olah"
|
||||
// 'Olah'
|
||||
get lastName() {
|
||||
const names = this.name.split(' ');
|
||||
return names[names.length -1];
|
||||
@@ -28,26 +37,26 @@ class Author {
|
||||
|
||||
export class FrontMatter {
|
||||
constructor() {
|
||||
this.title = ''; // "Attention and Augmented Recurrent Neural Networks"
|
||||
this.description = ''; // "A visual overview of neural attention..."
|
||||
this.title = ''; // '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"
|
||||
// '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.citations = []; // [ 'gregor2015draw', 'mercier2011humans' ]
|
||||
this.citationsCollected = false;
|
||||
|
||||
//
|
||||
@@ -65,16 +74,16 @@ export class FrontMatter {
|
||||
//
|
||||
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": [...]
|
||||
// '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,
|
||||
|
||||
@@ -183,3 +183,9 @@ d-include {
|
||||
width: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
d-figure {
|
||||
contain: content;
|
||||
overflow: hidden;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ distill-footer {
|
||||
|
||||
d-appendix,
|
||||
d-article > d-title,
|
||||
d-article > d-title > d-byline,
|
||||
d-article > d-byline,
|
||||
d-article > distill-footer {
|
||||
grid-column: start / end;
|
||||
}
|
||||
@@ -89,228 +89,6 @@ aside {
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
/*
|
||||
.l-body,
|
||||
.l-page,
|
||||
.l-middle,
|
||||
d-article > div,
|
||||
d-article > p,
|
||||
d-article > h1,
|
||||
d-article > h2,
|
||||
d-article > h3,
|
||||
d-article > h4,
|
||||
d-article > figure,
|
||||
d-article > ul,
|
||||
d-article > d-abstract,
|
||||
d-article > d-code,
|
||||
d-article > d-math,
|
||||
d-article > table,
|
||||
d-article section > div,
|
||||
d-article section > p,
|
||||
d-article section > h1,
|
||||
d-article section > h2,
|
||||
d-article section > h3,
|
||||
d-article section > h4,
|
||||
d-article section > figure,
|
||||
d-article section > ul,
|
||||
d-article section > d-abstract,
|
||||
d-article section > d-code,
|
||||
d-article section > d-math,
|
||||
d-article section > table {
|
||||
width: calc(100% - 32px);
|
||||
margin-left: 16px;
|
||||
margin-right: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.l-body-outset,
|
||||
.l-page-outset,
|
||||
.l-middle-outset {
|
||||
width: calc(100% - 16px);
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.l-screen {
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
width: 100%;
|
||||
background-color: #F8F8FC;
|
||||
border-top: 1px solid #E8E8EC;
|
||||
border-bottom: 1px solid #E8E8EC;
|
||||
}
|
||||
|
||||
@media(min-width: 768px) {
|
||||
.l-body,
|
||||
d-article > div,
|
||||
d-article > p,
|
||||
d-article > h1,
|
||||
d-article > h2,
|
||||
d-article > h3,
|
||||
d-article > h4,
|
||||
d-article > figure,
|
||||
d-article > ul,
|
||||
d-article > d-abstract,
|
||||
d-article > d-code,
|
||||
d-article > d-math,
|
||||
d-article > d-math,
|
||||
d-article section > div,
|
||||
d-article section > p,
|
||||
d-article section > h1,
|
||||
d-article section > h2,
|
||||
d-article section > h3,
|
||||
d-article section > h4,
|
||||
d-article section > figure,
|
||||
d-article section > ul,
|
||||
d-article section > d-abstract,
|
||||
d-article section > d-code,
|
||||
d-article section > d-math,
|
||||
d-article section > table {
|
||||
margin-left: 64px;
|
||||
width: calc((100% - 2 * 64px - 3 * 16px)/4*3 + 2*16px );
|
||||
}
|
||||
|
||||
.l-body-outset {
|
||||
margin-left: 32px;
|
||||
width: calc((100% - 2 * 64px - 3 * 16px)/4*3 + 2*16px + 64px );;
|
||||
}
|
||||
|
||||
.l-middle,
|
||||
.l-middle-outset,
|
||||
.l-page {
|
||||
margin-left: 64px;
|
||||
margin-right: 64px;
|
||||
width: calc(100% - 2*64px);
|
||||
}
|
||||
|
||||
.l-page-outset {
|
||||
margin-left: 32px;
|
||||
margin-right: 32px;
|
||||
width: calc(100% - 64px);
|
||||
}
|
||||
|
||||
.margin {
|
||||
font-size: 14px;
|
||||
line-height: normal;
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 0;
|
||||
margin-right: 64px;
|
||||
width: calc((100% - 2 * 64px - 3 * 16px)/4);
|
||||
}
|
||||
}
|
||||
|
||||
@media(min-width: 1024px) {
|
||||
.l-body,
|
||||
d-article > div,
|
||||
d-article > p,
|
||||
d-article > h2,
|
||||
d-article > h3,
|
||||
d-article > h4,
|
||||
d-article > figure,
|
||||
d-article > ul,
|
||||
d-article > d-abstract,
|
||||
d-article > d-code,
|
||||
d-article > d-math,
|
||||
d-article > table,
|
||||
d-article section > div,
|
||||
d-article section > p,
|
||||
d-article section > h2,
|
||||
d-article section > h3,
|
||||
d-article section > h4,
|
||||
d-article section > figure,
|
||||
d-article section > ul,
|
||||
d-article section > d-abstract,
|
||||
d-article section > d-code,
|
||||
d-article section > d-math,
|
||||
d-article section > table {
|
||||
margin-left: calc(50% - (1024px - 2*64px) / 2);
|
||||
width: 668px;
|
||||
}
|
||||
|
||||
.l-body-outset {
|
||||
margin-left: calc((50% - (1024px - 2*64px) / 2) - 32px);
|
||||
width: calc(668px + 64px)
|
||||
}
|
||||
|
||||
.l-middle,
|
||||
.l-middle-outset,
|
||||
.l-page {
|
||||
margin-left: calc(50% - (1024px - 2*64px) / 2);
|
||||
width: calc(100% - 2* (50% - (1024px - 2*64px) / 2));
|
||||
}
|
||||
|
||||
.l-page-outset {
|
||||
margin-left: calc((50% - (1024px - 2*64px) / 2) - 32px);
|
||||
width: calc(100% - 2* (50% - (1024px - 2*64px) / 2) + 64px);
|
||||
}
|
||||
|
||||
.margin {
|
||||
font-size: 14px;
|
||||
line-height: normal;
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 0;
|
||||
margin-right: calc(50% - (1024px - 2*64px) / 2);
|
||||
width: 206px;
|
||||
}
|
||||
|
||||
|
||||
/* Side */
|
||||
|
||||
/*
|
||||
.side.l-body,
|
||||
d-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,
|
||||
d-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,
|
||||
d-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,
|
||||
d-article .side.l-middle-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: 456px;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px) / 2 + 168px);
|
||||
}
|
||||
.side.l-page,
|
||||
d-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,
|
||||
d-article .side.l-page-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: 624px;
|
||||
margin-right: calc((100vw - 984px) / 2);
|
||||
}
|
||||
}*/
|
||||
|
||||
/* Rows and Columns */
|
||||
|
||||
|
||||
+13
-4
@@ -2,8 +2,17 @@ import base from './styles-base.css';
|
||||
import layout from './styles-layout.css';
|
||||
import article from './styles-article.css';
|
||||
import print from './styles-print.css';
|
||||
import { style as byline } from '../components/d-byline.js';
|
||||
|
||||
let s = document.createElement('style');
|
||||
s.textContent = base + layout + print + article;
|
||||
document.querySelector('head').appendChild(s);
|
||||
export default s;
|
||||
export const styles = base + layout + byline + article + print;
|
||||
const styleTagId = 'distill-prerendered-styles';
|
||||
|
||||
export function makeStyleTag(dom) {
|
||||
const prerenderedTag = dom.getElementById(styleTagId);
|
||||
if (!prerenderedTag) {
|
||||
let styleTag = dom.createElement('style');
|
||||
styleTag.id = styleTagId;
|
||||
styleTag.textContent = styles;
|
||||
dom.head.insertBefore(styleTag, dom.head.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-2
@@ -1,5 +1,7 @@
|
||||
/* eslint-env node, mocha */
|
||||
|
||||
import { FrontMatter } from './front-matter';
|
||||
|
||||
/* Extractors */
|
||||
import ExtractFrontmatter from './extractors/front-matter';
|
||||
import ExtractBibliography from './extractors/bibliography';
|
||||
@@ -13,13 +15,16 @@ const extractors = [
|
||||
|
||||
/* Transforms */
|
||||
import HTML from './transforms/html';
|
||||
import Byline from './transforms/byline';
|
||||
import Polyfills from './transforms/polyfills';
|
||||
import Meta from './transforms/meta';
|
||||
import Typeset from './transforms/typeset';
|
||||
import { makeStyleTag } from './styles/styles';
|
||||
import TOC from './transforms/toc';
|
||||
// import Typeset from './transforms/typeset';
|
||||
// import Bibliography from './transforms/bibliography';
|
||||
|
||||
const transforms = [
|
||||
HTML, Polyfills, Meta, Typeset//, Bibliography
|
||||
HTML, makeStyleTag, TOC, Byline, Polyfills, Meta//, Typeset//, Bibliography
|
||||
];
|
||||
|
||||
/* Distill Transforms */
|
||||
@@ -51,3 +56,5 @@ export function distillify(dom, data) {
|
||||
transform(dom, data);
|
||||
}
|
||||
}
|
||||
|
||||
export { FrontMatter };
|
||||
|
||||
+5
-151
@@ -1,155 +1,9 @@
|
||||
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>
|
||||
`;
|
||||
import { bylineTemplate } from '../components/d-byline.js';
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector('dt-byline');
|
||||
if (el) {
|
||||
el.innerHTML = html + mustache.render(template, data);
|
||||
const byline = dom.querySelector('d-byline');
|
||||
if (byline) {
|
||||
byline.innerHTML = bylineTemplate(data);
|
||||
byline.setAttribute('prerendered', true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import bibtexParse from 'bibtex-parse-js';
|
||||
|
||||
function normalizeTag(string) {
|
||||
return string
|
||||
.replace(/[\t\n ]+/g, ' ')
|
||||
.replace(/{\\["^`.'acu~Hvs]( )?([a-zA-Z])}/g, (full, x, char) => char)
|
||||
.replace(/{\\([a-zA-Z])}/g, (full, char) => char);
|
||||
}
|
||||
|
||||
export function parseBibtex(bibtex) {
|
||||
const bibliography = new Map();
|
||||
const parsedEntries = bibtexParse.toJSON(bibtex);
|
||||
for (const entry of parsedEntries) {
|
||||
// normalize tags; note entryTags is an object, not Map
|
||||
for (const [key, value] of Object.entries(entry.entryTags)) {
|
||||
entry.entryTags[key] = normalizeTag(value);
|
||||
}
|
||||
entry.entryTags.type = entry.entryType;
|
||||
// add to bibliography
|
||||
bibliography.set(entry.citationKey, entry.entryTags);
|
||||
}
|
||||
return bibliography;
|
||||
}
|
||||
|
||||
export function serializeFrontmatterToBibtex(frontMatter) {
|
||||
return `@article{${frontMatter.slug},
|
||||
author = {${frontMatter.bibtexAuthors}},
|
||||
title = {${frontMatter.title}},
|
||||
journal = {${frontMatter.journal.title}},
|
||||
year = {${frontMatter.publishedYear}},
|
||||
note = {${frontMatter.url}}
|
||||
}`;
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
export 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(', ')+']';
|
||||
}
|
||||
|
||||
export 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 '';
|
||||
}
|
||||
}
|
||||
|
||||
export 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 '?';
|
||||
}
|
||||
}
|
||||
|
||||
export 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(' ')});
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
function make_hover_css(pos) {
|
||||
const pretty = window.innerWidth > 600;
|
||||
const padding = pretty? 18 : 12;
|
||||
const outer_padding = pretty ? 18 : 0;
|
||||
const bbox = document.querySelector('body').getBoundingClientRect();
|
||||
let left = pos[0] - bbox.left, top = pos[1] - bbox.top;
|
||||
let width = Math.min(window.innerWidth-2*outer_padding, 648);
|
||||
left = Math.min(left, window.innerWidth-width-outer_padding);
|
||||
width = width - 2 * padding;
|
||||
return (`position: absolute;
|
||||
background-color: #FFF;
|
||||
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};`);
|
||||
}
|
||||
|
||||
export class HoverBox {
|
||||
|
||||
constructor(contentHTML, triggerElement) {
|
||||
this.visible = false;
|
||||
// div hold teh contents of the box that will become visible
|
||||
this.div = contentHTML;
|
||||
this.bindDivEvents(this.div);
|
||||
// triggerElement holds the element that needs to be hovered etc to show contents
|
||||
this.triggerElement = triggerElement;
|
||||
this.bindTriggerEvents(this.triggerElement);
|
||||
this.hide();
|
||||
}
|
||||
|
||||
bindDivEvents(node) {
|
||||
// For mice, same behavior as hovering on links
|
||||
this.div.addEventListener('mouseover', () => {
|
||||
if (!this.visible) this.showAtNode(node);
|
||||
this.stopTimeout();
|
||||
});
|
||||
this.div.addEventListener('mouseout', () => {
|
||||
this.extendTimeout(250);
|
||||
});
|
||||
// Don't trigger body touchstart event when touching within box
|
||||
this.div.addEventListener('touchstart', (event) => {
|
||||
event.stopPropagation();
|
||||
}, {passive: true});
|
||||
// Close box when touching outside box
|
||||
document.body.addEventListener('touchstart', () => {
|
||||
this.hide();
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
bindTriggerEvents(node) {
|
||||
node.addEventListener('mouseover', () => {
|
||||
if (!this.visible) {
|
||||
this.showAtNode(node);
|
||||
}
|
||||
this.stopTimeout();
|
||||
});
|
||||
|
||||
node.addEventListener('mouseout', () => {
|
||||
this.extendTimeout(250);
|
||||
});
|
||||
|
||||
node.addEventListener('touchstart', (event) => {
|
||||
if (this.visible) {
|
||||
this.hide();
|
||||
} else {
|
||||
this.showAtNode(node);
|
||||
}
|
||||
// Don't trigger body touchstart event when touching link
|
||||
event.stopPropagation();
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
show(position) {
|
||||
this.visible = true;
|
||||
const css = make_hover_css(position);
|
||||
this.div.setAttribute('style', css );
|
||||
}
|
||||
|
||||
showAtNode(node) {
|
||||
const bbox = node.getBoundingClientRect();
|
||||
this.show([bbox.right, bbox.bottom]);
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.visible = false;
|
||||
this.div.setAttribute('style', 'display:none');
|
||||
this.stopTimeout();
|
||||
}
|
||||
|
||||
stopTimeout() {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
extendTimeout(time) {
|
||||
this.stopTimeout();
|
||||
this.timeout = setTimeout(() => {
|
||||
this.hide();
|
||||
}, time);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// const marginSmall = 16;
|
||||
// const marginLarge = 3 * marginSmall;
|
||||
// const margin = marginSmall + marginLarge;
|
||||
// const gutter = marginSmall;
|
||||
// const outsetAmount = margin / 2;
|
||||
// const numCols = 4;
|
||||
// const numGutters = numCols - 1;
|
||||
// const columnWidth = (768 - 2 * marginLarge - numGutters * gutter) / numCols;
|
||||
//
|
||||
// const screenwidth = 768;
|
||||
// const pageWidth = screenwidth - 2 * marginLarge;
|
||||
// const bodyWidth = pageWidth - columnWidth - gutter;
|
||||
|
||||
export function body(selector) {
|
||||
return `${selector} {
|
||||
grid-column: margin-left / body;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
export function page(selector) {
|
||||
return `${selector} {
|
||||
grid-column: margin-left / page;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
export function screen(selector) {
|
||||
return `${selector} {
|
||||
grid-column: start / end;
|
||||
}
|
||||
`;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import bibtexParse from 'bibtex-parse-js';
|
||||
|
||||
function normalizeTag(string) {
|
||||
return string
|
||||
.replace(/[\t\n ]+/g, ' ')
|
||||
.replace(/{\\["^`.'acu~Hvs]( )?([a-zA-Z])}/g, (full, x, char) => char)
|
||||
.replace(/{\\([a-zA-Z])}/g, (full, char) => char);
|
||||
}
|
||||
|
||||
export function parseBibtex(bibtex) {
|
||||
const bibliography = new Map();
|
||||
const parsedEntries = bibtexParse.toJSON(bibtex);
|
||||
for (const entry of parsedEntries) {
|
||||
// normalize tags; note entryTags is an object, not Map
|
||||
for (const [key, value] of Object.entries(entry.entryTags)) {
|
||||
entry.entryTags[key] = normalizeTag(value);
|
||||
}
|
||||
entry.entryTags.type = entry.entryType;
|
||||
// add to bibliography
|
||||
bibliography.set(entry.citationKey, entry.entryTags);
|
||||
}
|
||||
return bibliography;
|
||||
}
|
||||
|
||||
export function serializeFrontmatterToBibtex(frontMatter) {
|
||||
return `@article{${frontMatter.slug},
|
||||
author = {${frontMatter.bibtexAuthors}},
|
||||
title = {${frontMatter.title}},
|
||||
journal = {${frontMatter.journal.title}},
|
||||
year = {${frontMatter.publishedYear}},
|
||||
note = {${frontMatter.url}}
|
||||
}`;
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
export 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(', ')+']';
|
||||
}
|
||||
|
||||
export 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 '';
|
||||
}
|
||||
}
|
||||
|
||||
export 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 '?';
|
||||
}
|
||||
}
|
||||
|
||||
export 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(' ')});
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
function make_hover_css(pos) {
|
||||
const pretty = window.innerWidth > 600;
|
||||
const padding = pretty? 18 : 12;
|
||||
const outer_padding = pretty ? 18 : 0;
|
||||
const bbox = document.querySelector('body').getBoundingClientRect();
|
||||
let left = pos[0] - bbox.left, top = pos[1] - bbox.top;
|
||||
let width = Math.min(window.innerWidth-2*outer_padding, 648);
|
||||
left = Math.min(left, window.innerWidth-width-outer_padding);
|
||||
width = width - 2 * padding;
|
||||
return (`position: absolute;
|
||||
background-color: #FFF;
|
||||
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};`);
|
||||
}
|
||||
|
||||
export class HoverBox {
|
||||
|
||||
constructor(contentHTML, triggerElement) {
|
||||
this.visible = false;
|
||||
// div hold teh contents of the box that will become visible
|
||||
this.div = contentHTML;
|
||||
this.bindDivEvents(this.div);
|
||||
// triggerElement holds the element that needs to be hovered etc to show contents
|
||||
this.triggerElement = triggerElement;
|
||||
this.bindTriggerEvents(this.triggerElement);
|
||||
this.hide();
|
||||
}
|
||||
|
||||
bindDivEvents(node) {
|
||||
// For mice, same behavior as hovering on links
|
||||
this.div.addEventListener('mouseover', () => {
|
||||
if (!this.visible) this.showAtNode(node);
|
||||
this.stopTimeout();
|
||||
});
|
||||
this.div.addEventListener('mouseout', () => {
|
||||
this.extendTimeout(250);
|
||||
});
|
||||
// Don't trigger body touchstart event when touching within box
|
||||
this.div.addEventListener('touchstart', (event) => {
|
||||
event.stopPropagation();
|
||||
}, {passive: true});
|
||||
// Close box when touching outside box
|
||||
document.body.addEventListener('touchstart', () => {
|
||||
this.hide();
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
bindTriggerEvents(node) {
|
||||
node.addEventListener('mouseover', () => {
|
||||
if (!this.visible) {
|
||||
this.showAtNode(node);
|
||||
}
|
||||
this.stopTimeout();
|
||||
});
|
||||
|
||||
node.addEventListener('mouseout', () => {
|
||||
this.extendTimeout(250);
|
||||
});
|
||||
|
||||
node.addEventListener('touchstart', (event) => {
|
||||
if (this.visible) {
|
||||
this.hide();
|
||||
} else {
|
||||
this.showAtNode(node);
|
||||
}
|
||||
// Don't trigger body touchstart event when touching link
|
||||
event.stopPropagation();
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
show(position) {
|
||||
this.visible = true;
|
||||
const css = make_hover_css(position);
|
||||
this.div.setAttribute('style', css );
|
||||
}
|
||||
|
||||
showAtNode(node) {
|
||||
const bbox = node.getBoundingClientRect();
|
||||
this.show([bbox.right, bbox.bottom]);
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.visible = false;
|
||||
this.div.setAttribute('style', 'display:none');
|
||||
this.stopTimeout();
|
||||
}
|
||||
|
||||
stopTimeout() {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
extendTimeout(time) {
|
||||
this.stopTimeout();
|
||||
this.timeout = setTimeout(() => {
|
||||
this.hide();
|
||||
}, time);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// const marginSmall = 16;
|
||||
// const marginLarge = 3 * marginSmall;
|
||||
// const margin = marginSmall + marginLarge;
|
||||
// const gutter = marginSmall;
|
||||
// const outsetAmount = margin / 2;
|
||||
// const numCols = 4;
|
||||
// const numGutters = numCols - 1;
|
||||
// const columnWidth = (768 - 2 * marginLarge - numGutters * gutter) / numCols;
|
||||
//
|
||||
// const screenwidth = 768;
|
||||
// const pageWidth = screenwidth - 2 * marginLarge;
|
||||
// const bodyWidth = pageWidth - columnWidth - gutter;
|
||||
|
||||
export function body(selector) {
|
||||
return `${selector} {
|
||||
grid-column: margin-left / body;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
export function page(selector) {
|
||||
return `${selector} {
|
||||
grid-column: margin-left / page;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
export function screen(selector) {
|
||||
return `${selector} {
|
||||
grid-column: start / end;
|
||||
}
|
||||
`;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import bibtexParse from 'bibtex-parse-js';
|
||||
|
||||
function normalizeTag(string) {
|
||||
return string
|
||||
.replace(/[\t\n ]+/g, ' ')
|
||||
.replace(/{\\["^`.'acu~Hvs]( )?([a-zA-Z])}/g, (full, x, char) => char)
|
||||
.replace(/{\\([a-zA-Z])}/g, (full, char) => char);
|
||||
}
|
||||
|
||||
export function parseBibtex(bibtex) {
|
||||
const bibliography = new Map();
|
||||
const parsedEntries = bibtexParse.toJSON(bibtex);
|
||||
for (const entry of parsedEntries) {
|
||||
// normalize tags; note entryTags is an object, not Map
|
||||
for (const [key, value] of Object.entries(entry.entryTags)) {
|
||||
entry.entryTags[key] = normalizeTag(value);
|
||||
}
|
||||
entry.entryTags.type = entry.entryType;
|
||||
// add to bibliography
|
||||
bibliography.set(entry.citationKey, entry.entryTags);
|
||||
}
|
||||
return bibliography;
|
||||
}
|
||||
|
||||
export function serializeFrontmatterToBibtex(frontMatter) {
|
||||
return `@article{${frontMatter.slug},
|
||||
author = {${frontMatter.bibtexAuthors}},
|
||||
title = {${frontMatter.title}},
|
||||
journal = {${frontMatter.journal.title}},
|
||||
year = {${frontMatter.publishedYear}},
|
||||
note = {${frontMatter.url}}
|
||||
}`;
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
export 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(', ')+']';
|
||||
}
|
||||
|
||||
export 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 '';
|
||||
}
|
||||
}
|
||||
|
||||
export 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 '?';
|
||||
}
|
||||
}
|
||||
|
||||
export 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(' ')});
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
function make_hover_css(pos) {
|
||||
const pretty = window.innerWidth > 600;
|
||||
const padding = pretty? 18 : 12;
|
||||
const outer_padding = pretty ? 18 : 0;
|
||||
const bbox = document.querySelector('body').getBoundingClientRect();
|
||||
let left = pos[0] - bbox.left, top = pos[1] - bbox.top;
|
||||
let width = Math.min(window.innerWidth-2*outer_padding, 648);
|
||||
left = Math.min(left, window.innerWidth-width-outer_padding);
|
||||
width = width - 2 * padding;
|
||||
return (`position: absolute;
|
||||
background-color: #FFF;
|
||||
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};`);
|
||||
}
|
||||
|
||||
export class HoverBox {
|
||||
|
||||
constructor(contentHTML, triggerElement) {
|
||||
this.visible = false;
|
||||
// div hold teh contents of the box that will become visible
|
||||
this.div = contentHTML;
|
||||
this.bindDivEvents(this.div);
|
||||
// triggerElement holds the element that needs to be hovered etc to show contents
|
||||
this.triggerElement = triggerElement;
|
||||
this.bindTriggerEvents(this.triggerElement);
|
||||
this.hide();
|
||||
}
|
||||
|
||||
bindDivEvents(node) {
|
||||
// For mice, same behavior as hovering on links
|
||||
this.div.addEventListener('mouseover', () => {
|
||||
if (!this.visible) this.showAtNode(node);
|
||||
this.stopTimeout();
|
||||
});
|
||||
this.div.addEventListener('mouseout', () => {
|
||||
this.extendTimeout(250);
|
||||
});
|
||||
// Don't trigger body touchstart event when touching within box
|
||||
this.div.addEventListener('touchstart', (event) => {
|
||||
event.stopPropagation();
|
||||
}, {passive: true});
|
||||
// Close box when touching outside box
|
||||
document.body.addEventListener('touchstart', () => {
|
||||
this.hide();
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
bindTriggerEvents(node) {
|
||||
node.addEventListener('mouseover', () => {
|
||||
if (!this.visible) {
|
||||
this.showAtNode(node);
|
||||
}
|
||||
this.stopTimeout();
|
||||
});
|
||||
|
||||
node.addEventListener('mouseout', () => {
|
||||
this.extendTimeout(250);
|
||||
});
|
||||
|
||||
node.addEventListener('touchstart', (event) => {
|
||||
if (this.visible) {
|
||||
this.hide();
|
||||
} else {
|
||||
this.showAtNode(node);
|
||||
}
|
||||
// Don't trigger body touchstart event when touching link
|
||||
event.stopPropagation();
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
show(position) {
|
||||
this.visible = true;
|
||||
const css = make_hover_css(position);
|
||||
this.div.setAttribute('style', css );
|
||||
}
|
||||
|
||||
showAtNode(node) {
|
||||
const bbox = node.getBoundingClientRect();
|
||||
this.show([bbox.right, bbox.bottom]);
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.visible = false;
|
||||
this.div.setAttribute('style', 'display:none');
|
||||
this.stopTimeout();
|
||||
}
|
||||
|
||||
stopTimeout() {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
extendTimeout(time) {
|
||||
this.stopTimeout();
|
||||
this.timeout = setTimeout(() => {
|
||||
this.hide();
|
||||
}, time);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// const marginSmall = 16;
|
||||
// const marginLarge = 3 * marginSmall;
|
||||
// const margin = marginSmall + marginLarge;
|
||||
// const gutter = marginSmall;
|
||||
// const outsetAmount = margin / 2;
|
||||
// const numCols = 4;
|
||||
// const numGutters = numCols - 1;
|
||||
// const columnWidth = (768 - 2 * marginLarge - numGutters * gutter) / numCols;
|
||||
//
|
||||
// const screenwidth = 768;
|
||||
// const pageWidth = screenwidth - 2 * marginLarge;
|
||||
// const bodyWidth = pageWidth - columnWidth - gutter;
|
||||
|
||||
export function body(selector) {
|
||||
return `${selector} {
|
||||
grid-column: margin-left / body;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
export function page(selector) {
|
||||
return `${selector} {
|
||||
grid-column: margin-left / page;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
export function screen(selector) {
|
||||
return `${selector} {
|
||||
grid-column: start / end;
|
||||
}
|
||||
`;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { renderTOC } from '../components/d-toc';
|
||||
|
||||
export default function(dom) {
|
||||
const article = dom.querySelector('d-article');
|
||||
const toc = dom.querySelector('d-toc');
|
||||
const headings = article.querySelectorAll('h2, h3');
|
||||
renderTOC(toc, headings);
|
||||
toc.setAttribute('prerendered', 'true');
|
||||
}
|
||||
Reference in New Issue
Block a user