mirror of
https://github.com/wassname/template.git
synced 2026-06-27 17:50:45 +08:00
Switch to central controller for distributed control flow
This commit is contained in:
@@ -34,3 +34,8 @@ jspm_packages
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# Copied fonts
|
||||
examples/fonts
|
||||
dist/examples/fonts
|
||||
dist/fonts
|
||||
|
||||
+37
-27
@@ -1,32 +1,42 @@
|
||||
// load `webcomponent` polyfills asynchronously
|
||||
// import "webcomponents.js/webcomponents-loader.js";
|
||||
/* Static styles and other modules */
|
||||
import * as Styles from './components/styles';
|
||||
|
||||
import * as frontMatter from "./components/d-front-matter";
|
||||
import * as title from "./components/d-title";
|
||||
import * as byline from "./components/d-byline";
|
||||
import * as article from "./components/d-article";
|
||||
import * as abstract from "./components/d-abstract";
|
||||
import * as toc from "./components/d-toc";
|
||||
import * as styles from "./components/styles";
|
||||
import * as appendix from "./components/d-appendix";
|
||||
import * as distillAppendix from "./components/distill-appendix";
|
||||
import * as bibliography from "./components/d-bibliography";
|
||||
import * as references from "./components/d-references";
|
||||
import * as code from "./components/d-code";
|
||||
import * as math from "./components/d-math";
|
||||
import * as footnote from "./components/d-footnote";
|
||||
import * as footnoteList from "./components/d-footnote-list";
|
||||
import * as acknowledgements from "./components/d-acknowledgements";
|
||||
import * as cite from "./components/d-cite";
|
||||
/* Components */
|
||||
import { Abstract } from './components/d-abstract';
|
||||
import { Acknowledgements } from './components/d-acknowledgements';
|
||||
import { Appendix } from './components/d-appendix';
|
||||
import { Article } from './components/d-article';
|
||||
import { Bibliography } from './components/d-bibliography';
|
||||
import { Byline } from './components/d-byline';
|
||||
import { Cite } from './components/d-cite';
|
||||
import { Code } from './components/d-code';
|
||||
import { Footnote } from './components/d-footnote';
|
||||
import { FootnoteList } from './components/d-footnote-list';
|
||||
import { FrontMatter } from './components/d-front-matter';
|
||||
import { DMath } from './components/d-math';
|
||||
import { References } from './components/d-references';
|
||||
import { Title } from './components/d-title';
|
||||
import { TOC } from './components/d-toc';
|
||||
|
||||
// let codeStyle = document.createElement("style");
|
||||
// codeStyle.textContent = codeCss;
|
||||
// document.querySelector("head").appendChild(codeStyle);
|
||||
const components = [
|
||||
Abstract, Acknowledgements, Appendix, Article, Bibliography,
|
||||
Byline, Cite, Code, Footnote, FootnoteList, FrontMatter, DMath,
|
||||
References, Title, TOC,
|
||||
];
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Render byline with authors list.
|
||||
/* Distill website specific components */
|
||||
import { DistillHeader } from "./distill-components/distill-header";
|
||||
import { DistillAppendix } from "./distill-components/distill-appendix";
|
||||
|
||||
// Render distill appendix with distill journal data.
|
||||
// document.querySelector("distill-appendix").render([]);
|
||||
const distillComponents = [
|
||||
DistillHeader, DistillAppendix,
|
||||
];
|
||||
|
||||
})
|
||||
function defineComponents() {
|
||||
const allComponents = components.concat(distillComponents);
|
||||
for (const component of allComponents) {
|
||||
customElements.define(component.is, component);
|
||||
}
|
||||
}
|
||||
|
||||
defineComponents();
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
import { FrontMatter } from '../transforms/data';
|
||||
import { collectCitations } from './d-cite';
|
||||
|
||||
const frontMatter = new FrontMatter();
|
||||
|
||||
// set up global controller object
|
||||
/* functions whose names start with 'on' will be registered as listeners on d-article */
|
||||
export const Controller = {
|
||||
|
||||
frontMatter: frontMatter,
|
||||
waitingOn: {
|
||||
bibliography: [],
|
||||
citations: [],
|
||||
},
|
||||
listeners: {
|
||||
|
||||
onCiteKeyCreated(event) {
|
||||
const [citeTag, keys] = event.detail;
|
||||
|
||||
// ensure we have citations
|
||||
if (frontMatter.citations.length === 0) {
|
||||
console.debug('onCiteKeyCreated, but unresolved dependency ("citations"). Enqueing.');
|
||||
Controller.waitingOn.citations.push(() => Controller.listeners.onCiteKeyCreated(event));
|
||||
return;
|
||||
}
|
||||
|
||||
// ensure we have a loaded bibliography
|
||||
if (frontMatter.bibliography.size === 0) {
|
||||
console.debug('onCiteKeyCreated, but unresolved dependency ("bibliography"). Enqueing.');
|
||||
Controller.waitingOn.bibliography.push(() => Controller.listeners.onCiteKeyCreated(event));
|
||||
return;
|
||||
}
|
||||
|
||||
const numbers = keys.map( key => frontMatter.citations.indexOf(key) );
|
||||
citeTag.numbers = numbers;
|
||||
const entries = keys.map( key => frontMatter.bibliography.get(key) );
|
||||
citeTag.entries = entries;
|
||||
},
|
||||
|
||||
onCiteKeyChanged(event) {
|
||||
const [citeTag, keys] = event.detail;
|
||||
|
||||
// update citations
|
||||
frontMatter.citations = collectCitations();
|
||||
for (const waitingCallback of Controller.waitingOn.citations) {
|
||||
waitingCallback();
|
||||
}
|
||||
|
||||
// update bibliography
|
||||
const bibliographyTag = document.querySelector('d-bibliography');
|
||||
const bibliographyEntries = new Map(frontMatter.citations.map( citationKey => {
|
||||
return [citationKey, frontMatter.bibliography.get(citationKey)];
|
||||
}));
|
||||
bibliographyTag.entries = bibliographyEntries;
|
||||
|
||||
const citeTags = document.querySelectorAll('d-cite');
|
||||
for (const citeTag of citeTags) {
|
||||
const keys = citeTag.keys;
|
||||
const numbers = keys.map( key => frontMatter.citations.indexOf(key) );
|
||||
citeTag.numbers = numbers;
|
||||
const entries = keys.map( key => frontMatter.bibliography.get(key) );
|
||||
citeTag.entries = entries;
|
||||
}
|
||||
|
||||
const numbers = keys.map( key => frontMatter.citations.indexOf(key) );
|
||||
citeTag.numbers = numbers;
|
||||
const entries = keys.map( key => frontMatter.bibliography.get(key) );
|
||||
citeTag.entries = entries;
|
||||
},
|
||||
|
||||
onBibliographyChanged(event) {
|
||||
const bibliographyTag = event.target;
|
||||
const bibliography = event.detail;
|
||||
|
||||
frontMatter.bibliography = bibliography;
|
||||
for (const waitingCallback of Controller.waitingOn.bibliography) {
|
||||
waitingCallback();
|
||||
}
|
||||
|
||||
// ensure we have citations
|
||||
if (frontMatter.citations.length === 0) {
|
||||
console.debug('onBibliographyChanged, but unresolved dependency ("citations"). Enqueing.');
|
||||
Controller.waitingOn.citations.push(() => Controller.listeners.onBibliographyChanged(event));
|
||||
return;
|
||||
}
|
||||
|
||||
const entries = new Map(frontMatter.citations.map( citationKey => {
|
||||
return [citationKey, frontMatter.bibliography.get(citationKey)];
|
||||
}));
|
||||
bibliographyTag.entries = entries;
|
||||
},
|
||||
|
||||
onFootnoteChanged(event) {
|
||||
const footnote = event.detail;
|
||||
//TODO: optimize to only update current footnote
|
||||
const footnotesList = document.querySelector('d-footnote-list');
|
||||
if (footnotesList) {
|
||||
const footnotes = document.querySelectorAll('d-footnote');
|
||||
footnotesList.footnotes = footnotes;
|
||||
}
|
||||
},
|
||||
|
||||
onFrontMatterChanged(event) {
|
||||
const data = event.detail;
|
||||
frontMatter.mergeFromYMLFrontmatter(data);
|
||||
|
||||
const appendix = document.querySelector('distill-appendix');
|
||||
appendix.frontMatter = frontMatter;
|
||||
},
|
||||
|
||||
DOMContentLoaded(event) {
|
||||
console.debug('DOMContentLoaded.');
|
||||
|
||||
const frontMatterTag = document.querySelector('d-front-matter');
|
||||
const data = frontMatterTag.parse();
|
||||
frontMatter.mergeFromYMLFrontmatter(data);
|
||||
const appendix = document.querySelector('distill-appendix');
|
||||
appendix.frontMatter = frontMatter;
|
||||
|
||||
console.debug('Resolving "citations" dependency due to initial DOM load.');
|
||||
frontMatter.citations = collectCitations();
|
||||
for (const waitingCallback of Controller.waitingOn.citations) {
|
||||
waitingCallback();
|
||||
}
|
||||
|
||||
const footnotesList = document.querySelector('d-footnote-list');
|
||||
if (footnotesList) {
|
||||
const footnotes = document.querySelectorAll('d-footnote');
|
||||
footnotesList.footnotes = footnotes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}, // listeners
|
||||
|
||||
update: {
|
||||
cite(element) {
|
||||
|
||||
},
|
||||
footnoteList(element) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // Controller
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Template} from "../mixins/template";
|
||||
import {body} from "./layout";
|
||||
import { Template } from "../mixins/template";
|
||||
import { body } from "./layout";
|
||||
|
||||
const T = Template("d-abstract", `
|
||||
<style>
|
||||
@@ -13,8 +13,6 @@ const T = Template("d-abstract", `
|
||||
</style>
|
||||
`, false);
|
||||
|
||||
export default class Abstract extends T(HTMLElement) {
|
||||
static get is() { return "d-abstract"; }
|
||||
}
|
||||
export class Abstract extends T(HTMLElement) {
|
||||
|
||||
customElements.define(Abstract.is, Abstract);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { Template } from "../mixins/template";
|
||||
|
||||
const name = 'd-acknowledgements';
|
||||
|
||||
const T = Template(name, `
|
||||
const T = Template('d-acknowledgements', `
|
||||
<style>
|
||||
::slotted(h3) {
|
||||
font-size: 15px;
|
||||
@@ -20,10 +18,6 @@ const T = Template(name, `
|
||||
<slot></slot>
|
||||
`);
|
||||
|
||||
export default class Acknowledgements extends T(HTMLElement) {
|
||||
|
||||
static get is() { return name; }
|
||||
export class Acknowledgements extends T(HTMLElement) {
|
||||
|
||||
}
|
||||
|
||||
customElements.define(name, Acknowledgements);
|
||||
|
||||
@@ -25,10 +25,6 @@ ${page(".l-body")}
|
||||
</div>
|
||||
`);
|
||||
|
||||
export default class Appendix extends T(HTMLElement) {
|
||||
|
||||
static get is() { return "d-appendix"; }
|
||||
export class Appendix extends T(HTMLElement) {
|
||||
|
||||
}
|
||||
|
||||
customElements.define(Appendix.is, Appendix);
|
||||
|
||||
+22
-205
@@ -1,209 +1,26 @@
|
||||
import {Template} from "../mixins/template";
|
||||
import { Template } from '../mixins/template';
|
||||
import { Controller } from './controller';
|
||||
|
||||
const T = Template("d-article", `
|
||||
<style>
|
||||
d-article {
|
||||
display: block;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
padding-top: 36px;
|
||||
padding-bottom: 72px;
|
||||
overflow: hidden;
|
||||
font-size: 16px;
|
||||
line-height: 1.6em;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H2 */
|
||||
|
||||
d-article h2 {
|
||||
font-weight: 400;
|
||||
font-size: 26px;
|
||||
line-height: 1.25em;
|
||||
margin-top: 36px;
|
||||
margin-bottom: 24px;
|
||||
padding-bottom: 24px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article h2 {
|
||||
margin-top: 2em;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
d-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;
|
||||
}
|
||||
d-article h1 + h2 {
|
||||
margin-top: 12px;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H3 */
|
||||
|
||||
d-article h3 {
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
line-height: 1.4em;
|
||||
margin-top: 36px;
|
||||
margin-bottom: 18px;
|
||||
font-style: italic;
|
||||
}
|
||||
d-article h1 + h3 {
|
||||
margin-top: 48px;
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article h3 {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H4 */
|
||||
|
||||
d-article h4 {
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
d-article a {
|
||||
color: inherit;
|
||||
}
|
||||
d-article p,
|
||||
d-article ul,
|
||||
d-article ol {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
d-article p b,
|
||||
d-article ul b,
|
||||
d-article ol b {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
d-article a {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.4);
|
||||
text-decoration: none;
|
||||
}
|
||||
d-article a:hover {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
d-article .link {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
d-article ul,
|
||||
d-article ol {
|
||||
padding-left: 24px;
|
||||
}
|
||||
d-article li {
|
||||
margin-bottom: 24px;
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
d-article pre {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
d-article hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
|
||||
margin-top: 60px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
d-article section {
|
||||
margin-top: 60px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
/* Figure */
|
||||
|
||||
d-article figure {
|
||||
position: relative;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article figure {
|
||||
margin-top: 48px;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
}
|
||||
d-article figure img {
|
||||
width: 100%;
|
||||
}
|
||||
d-article figure svg text,
|
||||
d-article figure svg tspan {
|
||||
}
|
||||
d-article figure figcaption {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
font-size: 12px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article figure figcaption {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
d-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;
|
||||
}
|
||||
d-article figure figcaption a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
/*d-article figure figcaption::before {
|
||||
position: relative;
|
||||
display: block;
|
||||
top: -20px;
|
||||
content: "";
|
||||
width: 25px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.3);
|
||||
}*/
|
||||
d-article span.equation-mimic {
|
||||
font-family: georgia;
|
||||
font-size: 115%;
|
||||
font-style: italic;
|
||||
}
|
||||
d-article figure figcaption b {
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 1.0);
|
||||
}
|
||||
d-article > d-code,
|
||||
d-article section > d-code {
|
||||
display: block;
|
||||
}
|
||||
d-article > d-math[block],
|
||||
d-article section > d-math[block] {
|
||||
display: block;
|
||||
}
|
||||
d-article .citation {
|
||||
color: #668;
|
||||
cursor: pointer;
|
||||
}
|
||||
d-include {
|
||||
width: auto;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
const T = Template('d-article', `
|
||||
<style></style>
|
||||
`, false);
|
||||
|
||||
export default class Article extends T(HTMLElement) {
|
||||
static get is() { return "d-article"; }
|
||||
}
|
||||
|
||||
customElements.define(Article.is, Article);
|
||||
|
||||
export class Article extends T(HTMLElement) {
|
||||
|
||||
// constructor() {
|
||||
// super();
|
||||
// }
|
||||
|
||||
connectedCallback() {
|
||||
for (const [functionName, callback] of Object.entries(Controller.listeners)) {
|
||||
if (typeof callback === 'function') {
|
||||
document.addEventListener(functionName, callback);
|
||||
} else {
|
||||
console.error('Controller listeners need to be functions!')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import bibtexParse from "bibtex-parse-js";
|
||||
import { Template } from "../mixins/template";
|
||||
import { Mutating } from "../mixins/mutating";
|
||||
import { collectCitations } from './d-cite'
|
||||
import bibtexParse from "bibtex-parse-js";
|
||||
import { bibliography_cite } from "./citation";
|
||||
|
||||
const name = 'd-bibliography';
|
||||
const T = Template(name, `
|
||||
const T = Template('d-bibliography', `
|
||||
<style>
|
||||
.references {
|
||||
font-size: 12px;
|
||||
@@ -35,7 +36,7 @@ const T = Template(name, `
|
||||
<ol></ol>
|
||||
`);
|
||||
|
||||
function parseBibtex(bibtex) {
|
||||
export function parseBibtex(bibtex) {
|
||||
const bibliography = new Map();
|
||||
const parsedEntries = bibtexParse.toJSON(bibtex);
|
||||
for (const entry of parsedEntries) {
|
||||
@@ -56,66 +57,80 @@ function parseBibtex(bibtex) {
|
||||
return bibliography;
|
||||
}
|
||||
|
||||
export default class Bibliography extends T(HTMLElement) {
|
||||
export class Bibliography extends T(HTMLElement) {
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
this.citations = new Array();
|
||||
this.finishedLoading = false;
|
||||
// set up mutation observer
|
||||
const options = {childList: true, subtree: true};
|
||||
const observer = new MutationObserver( (mutations) => {
|
||||
observer.disconnect();
|
||||
this.parseIfPossible();
|
||||
observer.observe(this, options);
|
||||
});
|
||||
// ...and listen for changes
|
||||
observer.observe(this, options);
|
||||
}
|
||||
|
||||
parseIfPossible() {
|
||||
if (this.firstElementChild && this.firstElementChild.tagName === 'SCRIPT') {
|
||||
const newBibtex = this.firstElementChild.textContent;
|
||||
if (this.bibtex !== newBibtex) {
|
||||
this.bibtex = newBibtex;
|
||||
const bibliography = parseBibtex(this.bibtex);
|
||||
this.notify(bibliography);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
connectedCallback() {
|
||||
this.list = this.root.querySelector('ol');
|
||||
// bibliography is initially hidden
|
||||
this.root.host.style.display = 'none';
|
||||
// parse bibliography
|
||||
const scriptTag = this.querySelector("script");
|
||||
if (scriptTag) {
|
||||
this.bibliography = parseBibtex(scriptTag.textContent);
|
||||
this.finishedLoading = true;
|
||||
// look through document and register existing citations
|
||||
document.querySelectorAll('d-cite')
|
||||
.forEach(citation => this.registerCitation(citation));
|
||||
} else {
|
||||
console.error("No script tag with bibtex found in d-bibliography tag!")
|
||||
// this.parseIfPossible();
|
||||
// Store.subscribeTo('citations', (citations) => {
|
||||
// // ensure citations list is visible
|
||||
// this.root.host.style.display = 'initial';
|
||||
// this.list.innerHTML = '';
|
||||
// for (const key of citations) {
|
||||
// const bibliography = Store.get('bibliography');
|
||||
// const entry = bibliography.get(key);
|
||||
// // construct and append list item to show citation
|
||||
// const listItem = document.createElement('li');
|
||||
// listItem.id = key;
|
||||
// listItem.innerHTML = bibliography_cite(entry);
|
||||
// this.list.appendChild(listItem);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
notify(bibliography) {
|
||||
const options = { detail: bibliography, bubbles: true };
|
||||
const event = new CustomEvent('onBibliographyChanged', options);
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
set entries(newEntries) {
|
||||
this.root.host.style.display = 'initial';
|
||||
this.list.innerHTML = '';
|
||||
|
||||
for (const [key, entry] of newEntries) {
|
||||
const listItem = document.createElement('li');
|
||||
listItem.id = key;
|
||||
listItem.innerHTML = bibliography_cite(entry);
|
||||
this.list.appendChild(listItem);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getEntry(key) {
|
||||
return this.bibliography.get(key);
|
||||
}
|
||||
|
||||
hasEntry(key) {
|
||||
return this.bibliography.has(key);
|
||||
}
|
||||
|
||||
getIndex(key) {
|
||||
return this.citations.indexOf(key);
|
||||
}
|
||||
|
||||
registerCitation(citation) {
|
||||
// a d-cite element may cite multiple sources
|
||||
const keyString = citation.getAttribute("key");
|
||||
const keys = keyString ? keyString.split(",") : [];
|
||||
for (const key of keys) {
|
||||
if (!this.bibliography.has(key)) {
|
||||
console.error("Citation key '" + key + "' is not present in bibliography!")
|
||||
} else if (this.citations.indexOf(key) === -1) {
|
||||
this.citations.push(key);
|
||||
const entry = this.getEntry(key);
|
||||
// ensure citations list is visible
|
||||
this.root.host.style.display = 'initial';
|
||||
// construct and append list item to show citation
|
||||
const listItem = document.createElement('li');
|
||||
listItem.id = key;
|
||||
listItem.innerHTML = bibliography_cite(entry);
|
||||
this.list.appendChild(listItem);
|
||||
}
|
||||
}
|
||||
renderContent() {
|
||||
// compute and store bibliography
|
||||
// FrontMatter.bibliography = parseBibtex(this.bibtex);
|
||||
// this.notify();
|
||||
// Store.set('bibliography', bibliography);
|
||||
// compute and store citations
|
||||
// const citations = collectCitations();
|
||||
// Store.set('citations', citations);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
customElements.define(Bibliography.is, Bibliography);
|
||||
|
||||
+6
-15
@@ -55,13 +55,8 @@ const T = Template("d-byline", `
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@media(min-width: 768px) {
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@media(min-width: 1080px) {
|
||||
{
|
||||
:host {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
@@ -152,17 +147,13 @@ const mustacheTemplate = `
|
||||
{{/citation}}
|
||||
`;
|
||||
|
||||
export default class Byline extends T(HTMLElement) {
|
||||
|
||||
static get is() { return "d-byline"; }
|
||||
export class Byline extends T(HTMLElement) {
|
||||
|
||||
connectedCallback() {
|
||||
const frontmatter = document.querySelector('d-front-matter');
|
||||
const container = this.root.querySelector('.byline');
|
||||
container.innerHTML = mustache.render(mustacheTemplate, frontmatter.data);
|
||||
console.log(frontmatter.data)
|
||||
// const frontmatter = document.querySelector('d-front-matter');
|
||||
// const container = this.root.querySelector('.byline');
|
||||
// container.innerHTML = mustache.render(mustacheTemplate, frontmatter.data);
|
||||
// // console.log(frontmatter.data)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
customElements.define(Byline.is, Byline);
|
||||
|
||||
+94
-50
@@ -28,7 +28,7 @@ const T = Template('d-cite', `
|
||||
}
|
||||
</style>
|
||||
|
||||
<div style="display: none;" class="dt-hover-box">
|
||||
<div style="display: none;" id="hover-box" class="dt-hover-box">
|
||||
</div>
|
||||
|
||||
<span id="citation-" class="citation">
|
||||
@@ -37,76 +37,120 @@ const T = Template('d-cite', `
|
||||
</span>
|
||||
`);
|
||||
|
||||
|
||||
function inline_cite_short(keys, bibliography) {
|
||||
function cite_string(key) {
|
||||
if (bibliography.hasEntry(key)){
|
||||
return (bibliography.getIndex(key)+1).toString();
|
||||
} else {
|
||||
return "?";
|
||||
export function collectCitations() {
|
||||
const citations = new Set();
|
||||
const citeTags = document.querySelectorAll('d-cite');
|
||||
for (const tag of citeTags) {
|
||||
const keys = tag.getAttribute('key').split(',');
|
||||
for (const key of keys) {
|
||||
citations.add(key);
|
||||
}
|
||||
}
|
||||
return "[" + keys.map(cite_string).join(", ") + "]";
|
||||
return [...citations];
|
||||
}
|
||||
|
||||
export class Cite extends T(HTMLElement) {
|
||||
|
||||
export default class Cite extends T(HTMLElement) {
|
||||
/* Lifecycle */
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this._key = null;
|
||||
|
||||
Cite.currentId += 1;
|
||||
this.citeId = Cite.currentId;
|
||||
// Cite.currentId += 1;
|
||||
// this.citeId = Cite.currentId;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
// this.notify();
|
||||
|
||||
this.hoverDiv = this.root.querySelector('.dt-hover-box');
|
||||
this.outerSpan = this.root.querySelector('#citation-');
|
||||
this.innerSpan = this.root.querySelector('.citation-number');
|
||||
// this.outerSpan.id = `citation-${this.citeId}`;
|
||||
// this.hoverDiv.id = `dt-cite-hover-box-${this.citeId}`;
|
||||
HoverBox.get_box(this.hoverDiv).bind(this.outerSpan);
|
||||
|
||||
}
|
||||
|
||||
/* Observed Attributes */
|
||||
|
||||
// renderCitationNumbers(citations) {
|
||||
// const numbers = this._keys.map( (key) => {
|
||||
// const index = citations.indexOf(key);
|
||||
// return index == -1 ? '?' : index + 1 + '';
|
||||
// });
|
||||
// const text = "[" + numbers.join(", ") + "]";
|
||||
// this.innerSpan.textContent = text;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
/* observe 'key' attribute */
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['key'];
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
// name will always be "key" due to observedAttributes
|
||||
this._key = newValue;
|
||||
this.renderContent();
|
||||
}
|
||||
|
||||
get key() {
|
||||
return this._key;
|
||||
const eventName = oldValue ? 'onCiteKeyChanged' : 'onCiteKeyCreated';
|
||||
const keys = newValue.split(',');
|
||||
const options = { detail: [this, keys], bubbles: true };
|
||||
const event = new CustomEvent(eventName, options);
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
set key(value) {
|
||||
this.setAttribute('key', value);
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
const bibliography = document.querySelector('d-bibliography');
|
||||
if (bibliography && bibliography.finishedLoading) {
|
||||
customElements.whenDefined('d-bibliography').then( () => {
|
||||
const keys = this.key.split(",");
|
||||
|
||||
// set up hidden hover box
|
||||
const div = this.root.querySelector('.dt-hover-box');
|
||||
div.innerHTML = keys.map( (key) => {
|
||||
return bibliography.getEntry(key);
|
||||
}).map(hover_cite).join('<br><br>');
|
||||
div.id ='dt-cite-hover-box-' + this.citeId;
|
||||
|
||||
// set up visible citation marker
|
||||
const outerSpan = this.root.querySelector('#citation-');
|
||||
outerSpan.id = `citation-${this.citeId}`;
|
||||
// outerSpan.setAttribute('data-hover', dataHoverString); // directly tell HoverBox instead?
|
||||
const innerSpan = this.root.querySelector('.citation-number');
|
||||
innerSpan.textContent = inline_cite_short(keys, bibliography);
|
||||
|
||||
HoverBox.get_box(div).bind(outerSpan);
|
||||
});
|
||||
} else {
|
||||
console.error(`You used a d-cite tag (${key}) without including a d-bibliography tag in your article. We can't lookup your citation this way.`)
|
||||
}
|
||||
get key() {
|
||||
return this.getAttribute('key');
|
||||
}
|
||||
|
||||
get keys() {
|
||||
return this.getAttribute('key').split(',');
|
||||
}
|
||||
|
||||
/* Setters & Rendering */
|
||||
|
||||
set numbers(numbers) {
|
||||
const numberStrings = numbers.map( index => {
|
||||
return index == -1 ? '?' : index + 1 + '';
|
||||
});
|
||||
const textContent = "[" + numberStrings.join(", ") + "]";
|
||||
const innerSpan = this.root.querySelector('.citation-number');
|
||||
innerSpan.textContent = textContent;
|
||||
}
|
||||
|
||||
set entries(entries) {
|
||||
const div = this.root.querySelector('#hover-box');
|
||||
div.innerHTML = entries.map(hover_cite).join('<br><br>');
|
||||
}
|
||||
|
||||
// renderContent() {
|
||||
// const bibliography = document.querySelector('d-bibliography');
|
||||
// if (bibliography && bibliography.finishedLoading) {
|
||||
// customElements.whenDefined('d-bibliography').then( () => {
|
||||
// const keys = this.key.split(",");
|
||||
//
|
||||
// // set up hidden hover box
|
||||
// const div = this.root.querySelector('.dt-hover-box');
|
||||
// div.innerHTML = keys.map( (key) => {
|
||||
// return bibliography.getEntry(key);
|
||||
// }).map(hover_cite).join('<br><br>');
|
||||
// div.id ='dt-cite-hover-box-' + this.citeId;
|
||||
//
|
||||
// // set up visible citation marker
|
||||
// const outerSpan = this.root.querySelector('#citation-');
|
||||
// outerSpan.id = `citation-${this.citeId}`;
|
||||
// // outerSpan.setAttribute('data-hover', dataHoverString); // directly tell HoverBox instead?
|
||||
// const innerSpan = this.root.querySelector('.citation-number');
|
||||
// innerSpan.textContent = inline_cite_short(keys, bibliography);
|
||||
//
|
||||
// HoverBox.get_box(div).bind(outerSpan);
|
||||
// });
|
||||
// } else {
|
||||
// console.error(`You used a d-cite tag (${key}) without including a d-bibliography tag in your article. We can't lookup your citation this way.`)
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
Cite.currentId = 0;
|
||||
|
||||
customElements.define(Cite.is, Cite);
|
||||
|
||||
@@ -6,9 +6,7 @@ import css from "prismjs/themes/prism.css";
|
||||
import { Template } from "../mixins/template.js"
|
||||
import { Mutating } from "../mixins/mutating.js"
|
||||
|
||||
|
||||
|
||||
const templateString = `
|
||||
const T = Template("d-code", `
|
||||
<style>
|
||||
|
||||
code {
|
||||
@@ -32,11 +30,9 @@ ${css}
|
||||
|
||||
<code id="code-container"></code>
|
||||
|
||||
`
|
||||
`);
|
||||
|
||||
const Templated = Template("d-code", templateString);
|
||||
|
||||
export class Code extends Mutating(Templated(HTMLElement)) {
|
||||
export class Code extends Mutating(T(HTMLElement)) {
|
||||
|
||||
renderContent() {
|
||||
|
||||
@@ -76,5 +72,3 @@ export class Code extends Mutating(Templated(HTMLElement)) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
customElements.define("d-code", Code);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Template } from "../mixins/template";
|
||||
// import { Store } from './store';
|
||||
|
||||
const name = 'd-footnote-list';
|
||||
const T = Template(name, `
|
||||
const T = Template('d-footnote-list', `
|
||||
<style>
|
||||
ol {
|
||||
padding: 0 0 0 18px;
|
||||
@@ -33,40 +33,47 @@ a.footnote-backlink {
|
||||
<ol></ol>
|
||||
`);
|
||||
|
||||
export default class FootnoteList extends T(HTMLElement) {
|
||||
|
||||
static get is() { return name; }
|
||||
export class FootnoteList extends T(HTMLElement) {
|
||||
|
||||
connectedCallback() {
|
||||
this.list = this.root.querySelector('ol');
|
||||
this.footnotes = new Map();
|
||||
// footnotes list is initially hidden
|
||||
this.root.host.style.display = 'none';
|
||||
// look through document and register existing footnotes
|
||||
document.querySelectorAll('d-footnote')
|
||||
.forEach(footnote => this.registerFootnote(footnote));
|
||||
// Store.subscribeTo('footnotes', (footnote) => {
|
||||
// this.renderFootnote(footnote);
|
||||
// });
|
||||
}
|
||||
|
||||
registerFootnote(element) {
|
||||
// check if we already know about this footnote
|
||||
if (!this.footnotes.has(element.id)) {
|
||||
this.footnotes.set(element.id, element);
|
||||
// TODO: could optimize this to accept individual footnotes?
|
||||
set footnotes(footnotes) {
|
||||
this.list.innerHTML = '';
|
||||
if (footnotes.length) {
|
||||
// ensure footnote list is visible
|
||||
this.root.host.style.display = 'initial'
|
||||
// construct and append list item to show footnote
|
||||
const listItem = document.createElement('li');
|
||||
listItem.innerHTML = element.innerHTML;
|
||||
const backlink = document.createElement('a');
|
||||
backlink.setAttribute('class', 'footnote-backlink');
|
||||
backlink.textContent = '[↩]';
|
||||
backlink.href = `#${element.id}`;
|
||||
listItem.appendChild(backlink);
|
||||
this.list.appendChild(listItem);
|
||||
} /*else {
|
||||
console.debug('Had already registered footnote ' + element.id + '!')
|
||||
}*/
|
||||
|
||||
for (const footnote of footnotes) {
|
||||
// construct and append list item to show footnote
|
||||
const listItem = document.createElement('li');
|
||||
listItem.id = footnote.id + '-listing';
|
||||
listItem.innerHTML = footnote.innerHTML;
|
||||
|
||||
const backlink = document.createElement('a');
|
||||
backlink.setAttribute('class', 'footnote-backlink');
|
||||
backlink.textContent = '[↩]';
|
||||
backlink.href = `#${footnote.id}`;
|
||||
|
||||
listItem.appendChild(backlink);
|
||||
this.list.appendChild(listItem);
|
||||
}
|
||||
} else {
|
||||
// ensure footnote list is invisible
|
||||
this.shadowRoot.host.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
renderFootnote(element) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
customElements.define(name, FootnoteList);
|
||||
|
||||
+23
-16
@@ -1,7 +1,8 @@
|
||||
import { Template } from "../mixins/template.js"
|
||||
import { HoverBox } from "./hover-box.js"
|
||||
// import { Store } from './store';
|
||||
|
||||
const templateString = `
|
||||
const T = Template("d-footnote", `
|
||||
<style>
|
||||
|
||||
d-math[block] {
|
||||
@@ -11,18 +12,34 @@ d-math[block] {
|
||||
</style>
|
||||
|
||||
<div style="display: none;" class="dt-hover-box">
|
||||
<slot></slot>
|
||||
<slot id='slot'></slot>
|
||||
</div>
|
||||
|
||||
<sup><span id="fn-" data-hover-ref="" style="cursor:pointer"></span></sup>
|
||||
|
||||
`;
|
||||
`);
|
||||
|
||||
const TemplatedFootnote = Template("d-footnote", templateString);
|
||||
export class Footnote extends T(HTMLElement) {
|
||||
|
||||
export class Footnote extends TemplatedFootnote(HTMLElement) {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const options = {childList: true, characterData: true, subtree: true};
|
||||
const observer = new MutationObserver(this.notify);
|
||||
observer.observe(this, options);
|
||||
}
|
||||
|
||||
notify() {
|
||||
const options = { detail: this, bubbles: true };
|
||||
const event = new CustomEvent('onFootnoteChanged', options);
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
// listen and notify about changes to slotted content
|
||||
// const slot = this.shadowRoot.querySelector('#slot');
|
||||
// slot.addEventListener('slotchange', this.notify);
|
||||
|
||||
// create numeric ID
|
||||
Footnote.currentFootnoteId += 1;
|
||||
const IdString = Footnote.currentFootnoteId.toString();
|
||||
@@ -37,20 +54,10 @@ export class Footnote extends TemplatedFootnote(HTMLElement) {
|
||||
span.setAttribute('id', 'fn-' + IdString);
|
||||
span.setAttribute('data-hover-ref', div.id);
|
||||
span.textContent = IdString;
|
||||
|
||||
HoverBox.get_box(div).bind(span);
|
||||
|
||||
// register with footnote list should there be one
|
||||
const footnoteList = document.querySelector('d-footnote-list');
|
||||
if (footnoteList) {
|
||||
customElements.whenDefined('d-footnote-list').then(() => {
|
||||
footnoteList.registerFootnote(this);
|
||||
});
|
||||
}
|
||||
HoverBox.get_box(div).bind(span);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Footnote.currentFootnoteId = 0;
|
||||
|
||||
customElements.define("d-footnote", Footnote);
|
||||
|
||||
@@ -1,52 +1,36 @@
|
||||
import ymlParse from "js-yaml";
|
||||
import expandData from "../transforms/expand-data"
|
||||
|
||||
export default class FrontMatter extends HTMLElement {
|
||||
export class FrontMatter extends HTMLElement {
|
||||
|
||||
static get is() { return "d-front-matter"; }
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.data = {};
|
||||
|
||||
const options = {childList: true, characterData: true, subtree: true};
|
||||
const observer = new MutationObserver( (mutation) => {
|
||||
const data = this.parse();
|
||||
this.notify(data);
|
||||
});
|
||||
observer.observe(this, options);
|
||||
}
|
||||
connectedCallback() {
|
||||
const el = this.querySelector("script");
|
||||
if (el) {
|
||||
const text = el.textContent;
|
||||
this.parse(ymlParse.safeLoad(text));
|
||||
|
||||
parse(){
|
||||
const scriptTag = this.querySelector("script");
|
||||
if (scriptTag) {
|
||||
const yml = scriptTag.textContent;
|
||||
const data = ymlParse.safeLoad(yml);
|
||||
return data;
|
||||
} else {
|
||||
console.error('You added a frontmatter tag but did not provide a script tag with front matter data in it. Please take a look at our templates.')
|
||||
return {};
|
||||
}
|
||||
}
|
||||
parse(localData) {
|
||||
this.data.title = localData.title ? localData.title : "Untitled";
|
||||
this.data.description = localData.description ? localData.description : "No description.";
|
||||
this.data.publishedDate = localData.published ? new Date(localData.published) : false;
|
||||
|
||||
this.data.authors = localData.authors ? localData.authors : [];
|
||||
|
||||
this.data.authors = this.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;
|
||||
});
|
||||
|
||||
expandData(null, this.data);
|
||||
notify(data) {
|
||||
const options = { detail: data, bubbles: true };
|
||||
const event = new CustomEvent('onFrontMatterChanged', options);
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(FrontMatter.is, FrontMatter);
|
||||
}
|
||||
|
||||
+8
-10
@@ -1,30 +1,28 @@
|
||||
import katex from "katex";
|
||||
import { Mutating } from "../mixins/mutating.js"
|
||||
import { Template } from "../mixins/template.js"
|
||||
import katexCSS from "../node_modules/katex/dist/katex.min.css"
|
||||
|
||||
const templateString = `
|
||||
const T = Template("d-math", `
|
||||
<style>
|
||||
|
||||
d-math[block] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
${katexCSS}
|
||||
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css">
|
||||
|
||||
<span id="katex-container"></span>
|
||||
`;
|
||||
`);
|
||||
|
||||
const TemplatedMath = Template("d-math", templateString);
|
||||
|
||||
export class Math extends Mutating(TemplatedMath(HTMLElement)) {
|
||||
export class DMath extends Mutating(T(HTMLElement)) {
|
||||
|
||||
renderContent() {
|
||||
const options = { displayMode: this.hasAttribute("block") };
|
||||
const container = this.shadowRoot.querySelector("#katex-container")
|
||||
const container = this.root.querySelector("#katex-container");
|
||||
katex.render(this.textContent, container, options);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("d-math", Math);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Template} from "../mixins/template";
|
||||
import {body} from "./layout";
|
||||
import { Template } from "../mixins/template";
|
||||
import { body } from "./layout";
|
||||
|
||||
const T = Template("d-references", `
|
||||
<style>
|
||||
@@ -9,11 +9,10 @@ d-references {
|
||||
</style>
|
||||
`, false);
|
||||
|
||||
export default class References extends T(HTMLElement) {
|
||||
static get is() { return "d-references"; }
|
||||
export class References extends T(HTMLElement) {
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(References.is, References);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Template} from "../mixins/template";
|
||||
import {page} from "./layout";
|
||||
import { Template } from "../mixins/template";
|
||||
import { page } from "./layout";
|
||||
|
||||
const T = Template("d-title", `
|
||||
<style>
|
||||
@@ -32,9 +32,7 @@ ${page("::slotted(h1), ::slotted(h2)")}
|
||||
<d-byline></d-byline>
|
||||
`);
|
||||
|
||||
export default class Title extends T(HTMLElement) {
|
||||
|
||||
static get is() { return "d-title"; }
|
||||
export class Title extends T(HTMLElement) {
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
@@ -44,5 +42,3 @@ export default class Title extends T(HTMLElement) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
customElements.define(Title.is, Title);
|
||||
|
||||
+2
-6
@@ -8,10 +8,6 @@ d-toc {
|
||||
</style>
|
||||
`, false);
|
||||
|
||||
export default class Toc extends T(HTMLElement) {
|
||||
static get is() {
|
||||
return "d-toc";
|
||||
}
|
||||
}
|
||||
export class TOC extends T(HTMLElement) {
|
||||
|
||||
customElements.define(Toc.is, Toc);
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import {page} from "./layout";
|
||||
import mustache from "mustache";
|
||||
|
||||
let mustacheTemplate = `
|
||||
<style>
|
||||
distill-appendix h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0;
|
||||
color: rgba(0,0,0,0.65);
|
||||
line-height: 1em;
|
||||
}
|
||||
distill-appendix a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
distill-appendix ol,
|
||||
distill-appendix ul {
|
||||
padding-left: 24px;
|
||||
}
|
||||
distill-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;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h3>Updates and Corrections</h3>
|
||||
<p><a href="">View all changes</a> to this article since it was first published. If you see mistakes or want to suggest changes, please <a href="">create an issue on GitHub</a>. </p>
|
||||
|
||||
<h3>Reuse</h3>
|
||||
<p>Diagrams and text are licensed under Creative Commons Attribution <a href="https://creativecommons.org/licenses/by/2.0/">CC-BY 2.0</a> with the <a class="github" href="https://github.com/distillpub/post--augmented-rnns">source available on GitHub</a>, unless noted otherwise. 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>
|
||||
|
||||
<h3>Citation</h3>
|
||||
<p>For attribution in academic contexts, please cite this work as</p>
|
||||
<pre class="citation short">Olah & Carter, "Attention and Augmented Recurrent Neural Networks", Distill, 2016.</pre>
|
||||
<p>BibTeX citation</p>
|
||||
<pre class="citation long">@article{olah2016attention,
|
||||
author = {Olah, Chris and Carter, Shan},
|
||||
title = {Attention and Augmented Recurrent Neural Networks},
|
||||
journal = {Distill},
|
||||
year = {2016},
|
||||
note = {http://distill.pub/2016/augmented-rnns}
|
||||
}</pre>
|
||||
`;
|
||||
|
||||
export default class DistillAppendix extends HTMLElement {
|
||||
static get is() { return "distill-appendix"; }
|
||||
connectedCallback(data) {
|
||||
this.innerHTML = mustache.render(mustacheTemplate, data);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(DistillAppendix.is, DistillAppendix);
|
||||
@@ -94,7 +94,7 @@ HoverBox.prototype.bind = function bind(node) {
|
||||
}
|
||||
// Don't trigger body touchstart event when touching link
|
||||
e.stopPropagation();
|
||||
}.bind(this));
|
||||
}.bind(this), {passive: true});
|
||||
}
|
||||
|
||||
HoverBox.prototype.bindDivEvents = function bindDivEvents(node){
|
||||
@@ -106,7 +106,7 @@ HoverBox.prototype.bindDivEvents = function bindDivEvents(node){
|
||||
this.div.addEventListener("mouseout", function(){this.extendTimeout(250);}.bind(this));
|
||||
|
||||
// Don't trigger body touchstart event when touching within box
|
||||
this.div.addEventListener("touchstart", function(e){e.stopPropagation();});
|
||||
this.div.addEventListener("touchstart", function(e){e.stopPropagation();}, {passive: true});
|
||||
// Close box when touching outside box
|
||||
document.body.addEventListener("touchstart", function(){this.hide();}.bind(this));
|
||||
document.body.addEventListener("touchstart", function(){this.hide();}.bind(this), {passive: true});
|
||||
}
|
||||
|
||||
@@ -44,29 +44,6 @@ export function page(selector) {
|
||||
`;
|
||||
}
|
||||
|
||||
export function pagePadding(selector) {
|
||||
return `${selector} {
|
||||
width: auto;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@media(min-width: 768px) {
|
||||
${selector} {
|
||||
padding-left: 72px;
|
||||
padding-right: 72px;
|
||||
}
|
||||
}
|
||||
@media(min-width: 1080px) {
|
||||
${selector} {
|
||||
width: 984px;
|
||||
padding-left: auto;
|
||||
padding-right: auto;
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
export function screen(selector) {
|
||||
return `${selector} {
|
||||
width: auto;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
class DataStore {
|
||||
|
||||
constructor() {
|
||||
this.collections = new Map();
|
||||
this.subscribers = new Map();
|
||||
}
|
||||
|
||||
get(collectionName) {
|
||||
return this.collections.get(collectionName);
|
||||
}
|
||||
|
||||
set(collectionName, collection) {
|
||||
this.collections.set(collectionName, collection);
|
||||
// notify subscribers
|
||||
if (this.subscribers.has(collectionName)) {
|
||||
const subscribers = this.subscribers.get(collectionName);
|
||||
for (const subscriber of subscribers) {
|
||||
subscriber(collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
register(collectionName, element) {
|
||||
// create collection if it doesn't yet exist
|
||||
if (!this.collections.has(collectionName)) {
|
||||
this.collections.set(collectionName, []);
|
||||
}
|
||||
// add new element to collection
|
||||
const collection = this.collections.get(collectionName);
|
||||
collection.push(element);
|
||||
// notify subscribers
|
||||
if (this.subscribers.has(collectionName)) {
|
||||
const subscribers = this.subscribers.get(collectionName);
|
||||
for (const subscriber of subscribers) {
|
||||
subscriber(element, collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subscribeTo(collectionName, callback) {
|
||||
// create subscriber collection if it doesn't yet exist
|
||||
if (!this.subscribers.has(collectionName)) {
|
||||
this.subscribers.set(collectionName, []);
|
||||
}
|
||||
// add new callback to list of subscribers
|
||||
const subscribers = this.subscribers.get(collectionName);
|
||||
subscribers.push(callback);
|
||||
// notify subscriber about existing collection entries
|
||||
if (this.collections.has(collectionName)) {
|
||||
const collection = this.collections.get(collectionName);
|
||||
for (const entry of collection) {
|
||||
callback(entry, collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// set up store
|
||||
// export const Store = new DataStore();
|
||||
@@ -0,0 +1,197 @@
|
||||
d-article {
|
||||
display: block;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
padding-top: 36px;
|
||||
padding-bottom: 72px;
|
||||
overflow: hidden;
|
||||
font-size: 16px;
|
||||
line-height: 1.6em;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H2 */
|
||||
|
||||
d-article h2 {
|
||||
font-weight: 400;
|
||||
font-size: 26px;
|
||||
line-height: 1.25em;
|
||||
margin-top: 36px;
|
||||
margin-bottom: 24px;
|
||||
padding-bottom: 24px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article h2 {
|
||||
margin-top: 2em;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
d-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;
|
||||
}
|
||||
d-article h1 + h2 {
|
||||
margin-top: 12px;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H3 */
|
||||
|
||||
d-article h3 {
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
line-height: 1.4em;
|
||||
margin-top: 36px;
|
||||
margin-bottom: 18px;
|
||||
font-style: italic;
|
||||
}
|
||||
d-article h1 + h3 {
|
||||
margin-top: 48px;
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article h3 {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H4 */
|
||||
|
||||
d-article h4 {
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
d-article a {
|
||||
color: inherit;
|
||||
}
|
||||
d-article p,
|
||||
d-article ul,
|
||||
d-article ol {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
d-article p b,
|
||||
d-article ul b,
|
||||
d-article ol b {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
d-article a {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.4);
|
||||
text-decoration: none;
|
||||
}
|
||||
d-article a:hover {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
d-article .link {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
d-article ul,
|
||||
d-article ol {
|
||||
padding-left: 24px;
|
||||
}
|
||||
d-article li {
|
||||
margin-bottom: 24px;
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
d-article pre {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
d-article hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
|
||||
margin-top: 60px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
d-article section {
|
||||
margin-top: 60px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
/* Figure */
|
||||
|
||||
d-article figure {
|
||||
position: relative;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article figure {
|
||||
margin-top: 48px;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
}
|
||||
d-article figure img {
|
||||
width: 100%;
|
||||
}
|
||||
d-article figure svg text,
|
||||
d-article figure svg tspan {
|
||||
}
|
||||
d-article figure figcaption {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
font-size: 12px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article figure figcaption {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
d-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;
|
||||
}
|
||||
d-article figure figcaption a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
/*d-article figure figcaption::before {
|
||||
position: relative;
|
||||
display: block;
|
||||
top: -20px;
|
||||
content: "";
|
||||
width: 25px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.3);
|
||||
}*/
|
||||
d-article span.equation-mimic {
|
||||
font-family: georgia;
|
||||
font-size: 115%;
|
||||
font-style: italic;
|
||||
}
|
||||
d-article figure figcaption b {
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 1.0);
|
||||
}
|
||||
d-article > d-code,
|
||||
d-article section > d-code {
|
||||
display: block;
|
||||
}
|
||||
d-article > d-math[block],
|
||||
d-article section > d-math[block] {
|
||||
display: block;
|
||||
}
|
||||
d-article .citation {
|
||||
color: #668;
|
||||
cursor: pointer;
|
||||
}
|
||||
d-include {
|
||||
width: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@ 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 katex from '../node_modules/katex/dist/katex.min.css'
|
||||
|
||||
let s = document.createElement("style");
|
||||
s.textContent = base + layout + print + article;
|
||||
s.textContent = base + layout + print + article + katex;
|
||||
document.querySelector("head").appendChild(s);
|
||||
export default s;
|
||||
|
||||
Vendored
+4344
-4129
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,66 @@
|
||||
const styles = `
|
||||
<style>
|
||||
distill-appendix h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0;
|
||||
color: rgba(0,0,0,0.65);
|
||||
line-height: 1em;
|
||||
}
|
||||
distill-appendix a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
distill-appendix ol,
|
||||
distill-appendix ul {
|
||||
padding-left: 24px;
|
||||
}
|
||||
distill-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;
|
||||
}
|
||||
</style>
|
||||
`
|
||||
|
||||
export function appendixTemplate(frontMatter) {
|
||||
return `
|
||||
${styles}
|
||||
|
||||
<h3>Updates and Corrections</h3>
|
||||
<p><a href="">View all changes</a> to this article since it was first published. If you see mistakes or want to suggest changes, please <a href="${frontMatter.githubUrl + '/issues/new'}">create an issue on GitHub</a>. </p>
|
||||
|
||||
<h3>Reuse</h3>
|
||||
<p>Diagrams and text are licensed under Creative Commons Attribution <a href="https://creativecommons.org/licenses/by/2.0/">CC-BY 2.0</a> with the <a class="github" href="${frontMatter.githubUrl}">source available on GitHub</a>, unless noted otherwise. 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>
|
||||
|
||||
<h3>Citation</h3>
|
||||
<p>For attribution in academic contexts, please cite this work as</p>
|
||||
<pre class="citation short">${frontMatter.concatenatedAuthors}, "${frontMatter.title}", Distill, ${frontMatter.publishedYear}.</pre>
|
||||
<p>BibTeX citation</p>
|
||||
<pre class="citation long">@article{${frontMatter.slug},
|
||||
author = {${frontMatter.bibtexAuthors}},
|
||||
title = {${frontMatter.title}},
|
||||
journal = {Distill},
|
||||
year = {${frontMatter.publishedYear}},
|
||||
note = {${frontMatter.url}}
|
||||
}</pre>
|
||||
`;
|
||||
}
|
||||
|
||||
export class DistillAppendix extends HTMLElement {
|
||||
|
||||
static get is() { return "distill-appendix"; }
|
||||
|
||||
set frontMatter(frontMatter) {
|
||||
this.innerHTML = appendixTemplate(frontMatter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Template} from "./mixins/template";
|
||||
import {Template} from "../mixins/template";
|
||||
|
||||
// import logo from "./distill-logo.svg";
|
||||
var logo = "";
|
||||
@@ -84,10 +84,8 @@ svg path {
|
||||
</div>
|
||||
`);
|
||||
|
||||
export default class DistillHeader extends T(HTMLElement) {
|
||||
export class DistillHeader extends T(HTMLElement) {
|
||||
static get is() {
|
||||
return "distill-header";
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(DistillHeader.is, DistillHeader);
|
||||
|
||||
+35
-17
@@ -1,23 +1,40 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf8">
|
||||
<script src="../dist/components.js" async></script>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css">
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
|
||||
|
||||
<d-front-matter>
|
||||
<script type="text/yml">
|
||||
title: Demo Title Attention and Augmented Recurrent Neural Networks
|
||||
published: Jan 10, 2017
|
||||
authors:
|
||||
- Chris Olah:
|
||||
- Shan Carter: http://shancarter.com
|
||||
affiliations:
|
||||
- Google Brain:
|
||||
- Google Brain: http://g.co/brain
|
||||
<script>
|
||||
// checks for webcomponents compatibility
|
||||
if ('registerElement' in document &&
|
||||
'import' in document.createElement('link') &&
|
||||
'content' in document.createElement('template')) {
|
||||
// Platform supports webcomponents natively! :-)
|
||||
} else {
|
||||
// Platform does not support webcomponents--loading polyfills.
|
||||
const scriptTag = document.createElement('script');
|
||||
scriptTag.src = '../node_modules/webcomponents.js/webcomponents-lite.js';
|
||||
scriptTag.src = '../node_modules/webcomponents.js/webcomponents-lite.js';
|
||||
scriptTag.async = false;
|
||||
document.currentScript.parentNode.insertBefore(scriptTag, document.currentScript.nextSibling);
|
||||
}
|
||||
</script>
|
||||
</d-front-matter>
|
||||
<script src="../dist/components.js"></script>
|
||||
|
||||
<d-front-matter>
|
||||
<script type="text/yml">
|
||||
title: Demo Title Attention and Augmented Recurrent Neural Networks
|
||||
published: Jan 10, 2017
|
||||
authors:
|
||||
- Chris Olah:
|
||||
- Shan Carter: http://shancarter.com
|
||||
affiliations:
|
||||
- Google Brain:
|
||||
- Google Brain: http://g.co/brain
|
||||
</script>
|
||||
</d-front-matter>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<d-article>
|
||||
<d-title>
|
||||
<h1>Attention and Augmented Recurrent Neural Networks</h1>
|
||||
@@ -31,8 +48,8 @@
|
||||
<d-math block>
|
||||
c = \pm \sqrt{ \sum_{i=0}^{n}{a^{222} + b^2}}
|
||||
</d-math>
|
||||
<p>We can also cite <d-cite key="gregor2015draw,mercier2011humans"></d-cite> external publications. <d-cite key="dong2014image,dumoulin2016guide,mordvintsev2015inceptionism"></d-cite></p>
|
||||
<p>We should also be testing footnotes<d-footnote>This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote.</d-footnote>. There are multiple footnotes, and they appear in the appendix<d-footnote>Given I have coded them right. Also, here's math in a footnote: <d-math>c = \sum_0^i{x}<d-math>.</d-footnote> as well.</p>
|
||||
<p>We can<d-cite key="mercier2011humans"></d-cite> also cite <d-cite key="gregor2015draw,mercier2011humans"></d-cite> external publications. <d-cite key="dong2014image,dumoulin2016guide,mordvintsev2015inceptionism"></d-cite></p>
|
||||
<p>We should also be testing footnotes<d-footnote>This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote.</d-footnote>. There are multiple footnotes, and they appear in the appendix<d-footnote>Given I have coded them right. Also, here's math in a footnote: <d-math>c = \sum_0^i{x}</d-math>. Also, a citation. Box-ception<d-cite key='gregor2015draw'></d-cite>!</d-footnote> as well.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>First</th><th>Second</th><th>Third</th></tr>
|
||||
@@ -182,3 +199,4 @@
|
||||
|
||||
<distill-appendix> </distill-appendix>
|
||||
</d-appendix>
|
||||
</body>
|
||||
|
||||
+6
-13
@@ -1,16 +1,7 @@
|
||||
|
||||
|
||||
export const Mutating = (superclass) => {
|
||||
return class extends superclass {
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['textContent'];
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
console.warn(name, oldValue, newValue);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -22,20 +13,22 @@ export const Mutating = (superclass) => {
|
||||
observer.observe(this, options);
|
||||
});
|
||||
|
||||
this.renderIfPossible();
|
||||
|
||||
// ...and listen for changes afterwards
|
||||
// ...and listen for changes
|
||||
observer.observe(this, options);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
this.renderIfPossible();
|
||||
}
|
||||
|
||||
// potential TODO: check if this is enough for all our usecases
|
||||
// maybe provide a custom function to tell if we have enough information to render
|
||||
renderIfPossible() {
|
||||
if (this.textContent && this.shadowRoot) { this.renderContent(); }
|
||||
if (this.textContent && this.root) {
|
||||
this.renderContent();
|
||||
}
|
||||
};
|
||||
|
||||
renderContent() {
|
||||
|
||||
+9
-6
@@ -1,11 +1,11 @@
|
||||
// import '@webcomponents/shadycss/scoping-shim';
|
||||
|
||||
export const Template = (name, templateString, useShadow = true) => {
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = templateString;
|
||||
|
||||
// ShadyCSS.prepareTemplate(template, name);
|
||||
if (useShadow && 'ShadyCSS' in window) {
|
||||
ShadyCSS.prepareTemplate(template, name);
|
||||
}
|
||||
|
||||
return (superclass) => {
|
||||
return class extends superclass {
|
||||
@@ -17,19 +17,21 @@ export const Template = (name, templateString, useShadow = true) => {
|
||||
|
||||
this.clone = document.importNode(template.content, true);
|
||||
if (useShadow) {
|
||||
// ShadyCSS.applyStyle(this);
|
||||
this.attachShadow({mode: 'open'});
|
||||
this.shadowRoot.appendChild(this.clone);
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (!useShadow) {
|
||||
if (useShadow) {
|
||||
if ('ShadyCSS' in window) {
|
||||
ShadyCSS.styleElement(this);
|
||||
}
|
||||
} else {
|
||||
this.insertBefore(this.clone, this.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Are we using these? Should we even? */
|
||||
get root() {
|
||||
if (useShadow) {
|
||||
return this.shadowRoot;
|
||||
@@ -38,6 +40,7 @@ export const Template = (name, templateString, useShadow = true) => {
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Are we using these? Should we even? */
|
||||
$(query) {
|
||||
return this.root.querySelector(query);
|
||||
}
|
||||
|
||||
+9
-7
@@ -3,21 +3,21 @@
|
||||
"version": "0.0.21",
|
||||
"description": "Template for creating Distill articles.",
|
||||
"main": "dist/template.js",
|
||||
"author": "Shan Carter",
|
||||
"homepage": "https://github.com/distillpub/distill-template#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/distillpub/distill-template/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "rollup -c rollup.config.components.js -w",
|
||||
"serve": "python3 -m http.server",
|
||||
"serve": "python3 -m http.server --bind 127.0.0.1",
|
||||
"test": "mocha",
|
||||
"build": "rollup -c rollup.config.components.js && rollup -c rollup.config.transforms.js"
|
||||
"build": "rollup -c rollup.config.components.js"
|
||||
},
|
||||
"author": "Shan Carter",
|
||||
"repository": {
|
||||
"url": "git+https://github.com/distillpub/distill-template.git",
|
||||
"type": "git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/distillpub/distill-template/issues"
|
||||
},
|
||||
"homepage": "https://github.com/distillpub/distill-template#readme",
|
||||
"devDependencies": {
|
||||
"bibtex-parse-js": "^0.0.23",
|
||||
"chai": "^3.5.0",
|
||||
@@ -36,12 +36,14 @@
|
||||
"rollup-watch": "^2.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@webcomponents/webcomponentsjs": "webcomponents/webcomponentsjs",
|
||||
"commander": "^2.9.0",
|
||||
"d3-time-format": "^2.0.3",
|
||||
"handlebars": "^4.0.6",
|
||||
"katex": "^0.7.1",
|
||||
"mustache": "^2.3.0",
|
||||
"rollup-plugin-babili": "^3.1.0",
|
||||
"rollup-plugin-copy": "^0.2.3",
|
||||
"rollup-plugin-gzip": "^1.2.0",
|
||||
"webcomponents.js": "webcomponents/webcomponentsjs",
|
||||
"webpack": "^2.2.1"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import copy from 'rollup-plugin-copy';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import string from 'rollup-plugin-string';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import babili from 'rollup-plugin-babili';
|
||||
import gzip from 'rollup-plugin-gzip';
|
||||
// import babili from 'rollup-plugin-babili';
|
||||
// import gzip from 'rollup-plugin-gzip';
|
||||
import serve from 'rollup-plugin-serve';
|
||||
|
||||
const PORT = 8080;
|
||||
@@ -13,7 +14,7 @@ export default {
|
||||
sourceMap: true,
|
||||
targets: [
|
||||
{
|
||||
format: 'umd',
|
||||
format: 'iife',
|
||||
moduleName: 'dl',
|
||||
dest: `dist/components.js`,
|
||||
}
|
||||
@@ -28,13 +29,16 @@ export default {
|
||||
}),
|
||||
commonjs(),
|
||||
// babili({
|
||||
// comments: false, // means: *don't* preserve comments
|
||||
// comments: false, // means: *remove comments
|
||||
// sourceMap: true,
|
||||
// }),
|
||||
// gzip(), // just for testing -- firebase CDN gzips automatically
|
||||
serve({
|
||||
port: PORT,
|
||||
open: true,
|
||||
})
|
||||
// serve({
|
||||
// port: PORT,
|
||||
// open: true,
|
||||
// })
|
||||
copy({
|
||||
'node_modules/katex/dist/fonts': 'examples/fonts',
|
||||
}),
|
||||
]
|
||||
};
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import string from 'rollup-plugin-string';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import babili from 'rollup-plugin-babili';
|
||||
import gzip from 'rollup-plugin-gzip';
|
||||
import serve from 'rollup-plugin-serve';
|
||||
|
||||
const PORT = 8080;
|
||||
console.log(`opening http://localhost:${PORT} .../`);
|
||||
|
||||
export default {
|
||||
entry: 'template.v2.js',
|
||||
sourceMap: true,
|
||||
targets: [
|
||||
{
|
||||
format: 'umd',
|
||||
moduleName: 'dl',
|
||||
dest: `dist/template.v2.js`,
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
resolve({
|
||||
jsnext: true,
|
||||
browser: true,
|
||||
}),
|
||||
string({
|
||||
include: ["**/*.txt", "**/*.svg", "**/*.html", "**/*.css", "**/*.base64"]
|
||||
}),
|
||||
commonjs(),
|
||||
// babili({
|
||||
// comments: false, // means: *remove* comments
|
||||
// sourceMap: true,
|
||||
// }),
|
||||
// gzip(), // just for testing -- firebase CDN gzips automatically
|
||||
serve({
|
||||
port: PORT,
|
||||
open: true,
|
||||
})
|
||||
]
|
||||
};
|
||||
@@ -16,7 +16,7 @@ export default {
|
||||
{
|
||||
format: 'umd',
|
||||
moduleName: 'dl',
|
||||
dest: `dist/template.js`,
|
||||
dest: `dist/transforms.js`,
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
|
||||
+53
-14
@@ -1,26 +1,27 @@
|
||||
import {timeFormat} from "d3-time-format";
|
||||
|
||||
const zeroPad = n => n < 10 ? "0" + n : n;
|
||||
const zeroPad = n => n < 10 ? "0" + n : n;
|
||||
const RFC = timeFormat("%a, %d %b %Y %H:%M:%S %Z");
|
||||
const months = ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"];
|
||||
|
||||
class Author {
|
||||
constructor() {
|
||||
this.personalURL = ""; // "https://colah.github.io"
|
||||
this.name = ""; // "Chris Olah"
|
||||
this.affiliationURL = ""; // "https://g.co/brain"
|
||||
this.affiliation = ""; // "Google Brain"
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
// "Chris"
|
||||
get firstName() {
|
||||
let names = this.name.split(" ");
|
||||
const names = this.name.split(" ");
|
||||
return names.slice(0, names.length - 1).join(" ");
|
||||
}
|
||||
|
||||
// "Olah"
|
||||
get lastName() {
|
||||
let names = this.name.split(" ");
|
||||
const names = this.name.split(" ");
|
||||
return names[names.length -1];
|
||||
}
|
||||
}
|
||||
@@ -31,7 +32,7 @@ export class FrontMatter {
|
||||
this.description = ""; // "A visual overview of neural attention..."
|
||||
this.authors = []; // Array of Author(s)
|
||||
|
||||
this.bibliography = {};
|
||||
this.bibliography = new Map();
|
||||
// {
|
||||
// "gregor2015draw": {
|
||||
// "title": "DRAW: A recurrent neural network for image generation",
|
||||
@@ -61,7 +62,7 @@ export class FrontMatter {
|
||||
//
|
||||
// Assigned from journal
|
||||
//
|
||||
|
||||
this.journal = {};
|
||||
// journal: {
|
||||
// "title": "Distill",
|
||||
// "full_title": "Distill",
|
||||
@@ -87,6 +88,34 @@ export class FrontMatter {
|
||||
|
||||
}
|
||||
|
||||
// Example:
|
||||
// title: Demo Title Attention and Augmented Recurrent Neural Networks
|
||||
// published: Jan 10, 2017
|
||||
// authors:
|
||||
// - Chris Olah:
|
||||
// - Shan Carter: http://shancarter.com
|
||||
// affiliations:
|
||||
// - Google Brain:
|
||||
// - Google Brain: http://g.co/brain
|
||||
mergeFromYMLFrontmatter(data) {
|
||||
this.title = data.title;
|
||||
this.publishedDate = new Date(data.published);
|
||||
this.description = data.description;
|
||||
const zipped = data.authors.map( (author, index) => [author, data.affiliations[index]]);
|
||||
this.authors = zipped.map( ([authorEntry, affiliationEntry]) => {
|
||||
const name = Object.keys(authorEntry)[0];
|
||||
const author = new Author(name);
|
||||
if (typeof authorEntry === 'object') {
|
||||
author.personalURL = authorEntry[name];
|
||||
}
|
||||
author.affiliation = Object.keys(affiliationEntry)[0];
|
||||
if (typeof affiliationEntry === 'object') {
|
||||
author.affiliationURL = affiliationEntry[author.affiliation]
|
||||
}
|
||||
return author;
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Computed Properties
|
||||
//
|
||||
@@ -102,6 +131,8 @@ export class FrontMatter {
|
||||
return this.journal.url + "/" + this.distillPath;
|
||||
} else if (this.journal.url) {
|
||||
return this.journal.url;
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,23 +191,31 @@ export class FrontMatter {
|
||||
|
||||
// 'Olah & Carter',
|
||||
get concatenatedAuthors() {
|
||||
if (this.authors.length > 2) {
|
||||
if (this.authors.length > 2) {
|
||||
return this.authors[0].lastName + ", et al.";
|
||||
} else if (this.authors.length === 2) {
|
||||
return this.authors[0].lastName + " & " + this.authors[1].lastName;
|
||||
} else if (this.authors.length === 1) {
|
||||
return this.authors[0].lastName
|
||||
return this.authors[0].lastName;
|
||||
}
|
||||
}
|
||||
|
||||
// 'Olah, Chris and Carter, Shan',
|
||||
get bibtexAuthors() {
|
||||
return this.authors.map(author => author.lastName + ", " + author.firstName }).join(" and ");
|
||||
return this.authors.map(author => {
|
||||
return author.lastName + ", " + author.firstName
|
||||
}).join(" and ");
|
||||
}
|
||||
|
||||
// 'olah2016attention'
|
||||
get slug() {
|
||||
return this.authors.length ? this.authors[0].lastName.toLowerCase() + this.publishedYear + this.title.split(" ")[0].toLowerCase() : "Untitled";
|
||||
let slug = '';
|
||||
if (this.authors.length) {
|
||||
slug += this.authors[0].lastName.toLowerCase();
|
||||
slug += this.publishedYear;
|
||||
slug += this.title.split(' ')[0].toLowerCase();
|
||||
}
|
||||
return slug || 'Untitled';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@comandeer/babel-plugin-banner/-/babel-plugin-banner-1.0.0.tgz#40bcce0bbee084b5b02545a33635d053c248356f"
|
||||
|
||||
"@webcomponents/webcomponentsjs@webcomponents/webcomponentsjs":
|
||||
version "1.0.3"
|
||||
resolved "https://codeload.github.com/webcomponents/webcomponentsjs/tar.gz/f01672c05cca9ec5839b064d2f5e1da73f01ea10"
|
||||
|
||||
abab@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d"
|
||||
@@ -728,6 +732,10 @@ code-point-at@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
|
||||
colors@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
|
||||
|
||||
combined-stream@^1.0.5, combined-stream@~1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
|
||||
@@ -1084,6 +1092,14 @@ form-data@~2.1.1:
|
||||
combined-stream "^1.0.5"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fs-extra@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291"
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^3.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
@@ -1202,7 +1218,7 @@ good-listener@^1.2.0:
|
||||
dependencies:
|
||||
delegate "^3.1.1"
|
||||
|
||||
graceful-fs@^4.1.2:
|
||||
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
|
||||
version "4.1.11"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
|
||||
|
||||
@@ -1539,6 +1555,12 @@ json5@^0.5.0:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
||||
|
||||
jsonfile@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66"
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonify@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
||||
@@ -2365,6 +2387,13 @@ rollup-plugin-commonjs@^7.0.0:
|
||||
resolve "^1.1.7"
|
||||
rollup-pluginutils "^1.5.1"
|
||||
|
||||
rollup-plugin-copy@^0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-copy/-/rollup-plugin-copy-0.2.3.tgz#dac1ab81d1f220baeb98e5c4c0108252e1edbb98"
|
||||
dependencies:
|
||||
colors "^1.1.2"
|
||||
fs-extra "^3.0.0"
|
||||
|
||||
rollup-plugin-gzip@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-gzip/-/rollup-plugin-gzip-1.2.0.tgz#4b63c2fcfb7b5eefaf5ea187ef2b4496b2d418d0"
|
||||
@@ -2724,6 +2753,10 @@ uid-number@^0.0.6, uid-number@~0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
|
||||
|
||||
universalify@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"
|
||||
|
||||
url@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
|
||||
|
||||
Reference in New Issue
Block a user