mirror of
https://github.com/wassname/template.git
synced 2026-06-27 21:09:08 +08:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bf862cc4fe | |||
| 6a34fbd2f4 | |||
| 081b686820 | |||
| fcc3cc3fc2 | |||
| bf80d37e4a | |||
| 16447ea737 | |||
| cef46a20ed | |||
| 6b018b9d3a | |||
| b9148736e7 | |||
| 9be3faee20 | |||
| f95deb292e | |||
| dccd48154b | |||
| 0d6de08c82 | |||
| 9d253fdd33 | |||
| 7fcd24a07b | |||
| f569b07151 | |||
| 4b21625c70 | |||
| 97a01fae73 | |||
| 042da68b9a | |||
| 4adbf9dcd2 | |||
| f933920421 | |||
| cdfa045a36 | |||
| 5d83dbfd61 | |||
| 94510ee10b | |||
| 7b3038bbd3 | |||
| e9df166db9 | |||
| e6dd2fbfd9 | |||
| 37cc1f3157 | |||
| 9ead1f6f01 | |||
| ebe56d2329 | |||
| c3ff605777 | |||
| 0300b98cb6 | |||
| ecfd28bdf9 | |||
| 86ca6f72f4 | |||
| d0f5824e0c | |||
| 8bd32bdf0b | |||
| f2ae6d7aa3 | |||
| 37c7483cb0 | |||
| a272efb89c | |||
| bb19b13467 | |||
| 7e240ddf4f | |||
| 84c400184d | |||
| d187130657 | |||
| cc6b6bf595 | |||
| 9463d6e58d | |||
| 3c2f782e74 | |||
| 6bd5d0bf03 | |||
| a5f663c249 | |||
| 975c3e8256 | |||
| b854bd0124 | |||
| a6df552537 |
+1
-43
@@ -1,44 +1,2 @@
|
|||||||
# Logs
|
.DS_Store
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
|
|
||||||
# node-waf configuration
|
|
||||||
.lock-wscript
|
|
||||||
|
|
||||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
|
||||||
build/Release
|
|
||||||
|
|
||||||
# Dependency directories
|
|
||||||
node_modules
|
node_modules
|
||||||
bower_components
|
|
||||||
jspm_packages
|
|
||||||
|
|
||||||
# Optional npm cache directory
|
|
||||||
.npm
|
|
||||||
|
|
||||||
# Optional eslint cache
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# Copied fonts
|
|
||||||
examples/fonts
|
|
||||||
dist
|
|
||||||
article-rendered.html
|
|
||||||
|
|
||||||
# dependency graph
|
|
||||||
rollup-grapher.html
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
# Distill Template
|
# Distill Template
|
||||||
|
|
||||||
_Disclaimer: This project is research code. It is not an official Google product._
|
This is the repository for the Distill web framework.
|
||||||
|
|
||||||
This is the repository for the distill web framework.
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -13,10 +11,12 @@ To contribute a change, [check out the contributing guide](CONTRIBUTING.md).
|
|||||||
|
|
||||||
### Local Development
|
### Local Development
|
||||||
|
|
||||||
Run `npm run start` to start a watching build rollup server. To view the sample pages in the repo, you can run `npm run serve` as a separate process which starts a static server. `npm run build` will run a one-time build.
|
First, run `npm install` to install all node modules required. Then, run `npm run dev` to start a watching build rollup server. To view the sample pages in the repo, you can run `npm run serve` as a separate process which starts a static server. `npm run build` will run a one-time build.
|
||||||
|
|
||||||
|
|
||||||
## License
|
## Disclaimer & License
|
||||||
|
|
||||||
|
_This project is research code. It is not an official product of Google or any other institution supporting Distill._
|
||||||
|
|
||||||
Copyright 2018, The Distill Template Authors.
|
Copyright 2018, The Distill Template Authors.
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ const options = { runScripts: 'outside-only', QuerySelector: true, virtualConsol
|
|||||||
JSDOM.fromFile(program.inputPath, options).then(dom => {
|
JSDOM.fromFile(program.inputPath, options).then(dom => {
|
||||||
const window = dom.window;
|
const window = dom.window;
|
||||||
const document = window.document;
|
const document = window.document;
|
||||||
|
const HTMLElement = window.HTMLElement;
|
||||||
|
|
||||||
const data = new transforms.FrontMatter;
|
const data = new transforms.FrontMatter;
|
||||||
data.inputHTMLPath = program.inputPath; // may be needed to resolve relative links!
|
data.inputHTMLPath = program.inputPath; // may be needed to resolve relative links!
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright 2018 The Distill Template Authors
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<!doctype html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<script src="../dist/template.v2.js"></script>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" >
|
|
||||||
<meta charset="utf8">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<distill-header></distill-header>
|
|
||||||
<d-front-matter>
|
|
||||||
<script id='distill-front-matter' type="text/json">{
|
|
||||||
"title": "Why Momentum Really Works",
|
|
||||||
"description": "Although \" extremely useful for visualizing high-dimensional data, t-SNE plots can sometimes be mysterious or misleading.",
|
|
||||||
"published": "Jan 10, 2017",
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"author":"Chris Olah",
|
|
||||||
"authorURL":"https://colah.github.io/",
|
|
||||||
"affiliations": [{"name": "Google Brain", "url": "https://g.co/brain"}]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"author":"Ludwig Schubert",
|
|
||||||
"authorURL":"https://shancarter.com/",
|
|
||||||
"affiliations": [{"name": "Google Brain", "url": "https://g.co/brain"}]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"author":"Shan Carter",
|
|
||||||
"authorURL":"https://shancarter.com/",
|
|
||||||
"affiliations": [
|
|
||||||
{"name": "Google Brain", "url": "https://g.co/brain"},
|
|
||||||
{"name": "NYT", "url": "https://nytimes.com"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"katex": {
|
|
||||||
"delimiters": [
|
|
||||||
{"left": "$$", "right": "$$", "display": false}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}</script>
|
|
||||||
</d-front-matter>
|
|
||||||
<d-title>
|
|
||||||
<figure style="grid-column: page; margin: 1rem 0;"><img src="momentum.png" style="width:100%; border: 1px solid rgba(0, 0, 0, 0.2);"/></figure>
|
|
||||||
<p>We often think of Momentum<d-cite key="mercier2011humans"></d-cite> as a means of dampening oscillations and speeding up the iterations, leading to faster convergence. But it has other interesting behavior. It allows a larger range of step-sizes to be used, and creates its own oscillations. What is going on?</p>
|
|
||||||
</d-title>
|
|
||||||
<d-byline></d-byline>
|
|
||||||
<d-article>
|
|
||||||
<a class="marker" href="#section-1" id="section-1"><span>1</span></a>
|
|
||||||
<h2>A Brief Survey of Techniques</h2>
|
|
||||||
<p>Before diving in: if you haven’t encountered t-SNE before, here’s what you need to know about the math behind it. The goal is to take a set of points in a high-dimensional space and find a faithful representation of those points in a lower-dimensional space, typically the 2D plane. The algorithm is non-linear and adapts to the underlying data, performing different transformations on different regions. Those differences can be a major source of confusion.</p>
|
|
||||||
<p>This is the first paragraph of the article. Test a long — dash -- here it is.</p>
|
|
||||||
<p>Test for owner's possessive. Test for "quoting a passage." And another sentence. Or two. Some flopping fins; for diving.</p>
|
|
||||||
<aside>Some text in an aside, margin notes, etc...</aside>
|
|
||||||
<p>Here's a test of an inline equation <d-math>c = a^2 + b^2</d-math>. Also with configurable katex standards just using inline '$' signs: $$x^2$$ And then there's a block equation:</p>
|
|
||||||
<d-math block>
|
|
||||||
c = \pm \sqrt{ \sum_{i=0}^{n}{a^{222} + b^2}}
|
|
||||||
</d-math>
|
|
||||||
<p>Math can also be quite involved:</p>
|
|
||||||
<d-math block>
|
|
||||||
\frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\cdots} } } }
|
|
||||||
</d-math>
|
|
||||||
<a class="marker" href="#section-1.1" id="section-1.1"><span>1.1</span></a>
|
|
||||||
<h3>Citations</h3>
|
|
||||||
<p><d-slider style="width: 200px;"></d-slider></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>. 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>
|
|
||||||
<a class="marker" href="#section-2" id="section-2"><span>2</span></a>
|
|
||||||
<h2>Displaying code snippets</h2>
|
|
||||||
<p>Some inline javascript:<d-code language="javascript">var x = 25;</d-code>. And here's a javascript code block.</p>
|
|
||||||
<d-code block language="javascript">
|
|
||||||
var x = 25;
|
|
||||||
function(x){
|
|
||||||
return x * x;
|
|
||||||
}
|
|
||||||
</d-code>
|
|
||||||
<p>We also support python.</p>
|
|
||||||
<d-code block language="python">
|
|
||||||
# Python 3: Fibonacci series up to n
|
|
||||||
def fib(n):
|
|
||||||
a, b = 0, 1
|
|
||||||
while a < n:
|
|
||||||
print(a, end=' ')
|
|
||||||
a, b = b, a+b
|
|
||||||
</d-code>
|
|
||||||
<p>And a table</p>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr><th>First</th><th>Second</th><th>Third</th></tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr><td>23</td><td>654</td><td>23</td></tr>
|
|
||||||
<tr><td>14</td><td>54</td><td>34</td></tr>
|
|
||||||
<tr><td>234</td><td>54</td><td>23</td></tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<d-figure id="last-figure"></d-figure>
|
|
||||||
<script>
|
|
||||||
const figure = document.querySelector("d-figure#last-figure");
|
|
||||||
const initTag = document.createElement("span");
|
|
||||||
initTag.textContent = "initialized!"
|
|
||||||
figure.appendChild(initTag);
|
|
||||||
figure.addEventListener("ready", function() {
|
|
||||||
const initTag = figure.querySelector("span");
|
|
||||||
initTag.textContent = "ready"
|
|
||||||
console.log('ready')
|
|
||||||
});
|
|
||||||
figure.addEventListener("onscreen", function() {
|
|
||||||
const initTag = figure.querySelector("span");
|
|
||||||
initTag.textContent = "onscreen"
|
|
||||||
console.log('onscreen')
|
|
||||||
});
|
|
||||||
figure.addEventListener("offscreen", function() {
|
|
||||||
const initTag = figure.querySelector("span");
|
|
||||||
initTag.textContent = "offscreen!"
|
|
||||||
console.log('offscreen')
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<p>That's it for the example article!</p>
|
|
||||||
|
|
||||||
</d-article>
|
|
||||||
|
|
||||||
<d-appendix>
|
|
||||||
|
|
||||||
<h3>Contributions</h3>
|
|
||||||
<p>Some text describing who did what.</p>
|
|
||||||
<h3>Reviewers</h3>
|
|
||||||
<p>Some text with links describing who reviewed the article.</p>
|
|
||||||
|
|
||||||
<d-bibliography src="bibliography.bib"></d-bibliography>
|
|
||||||
</d-appendix>
|
|
||||||
|
|
||||||
<distill-footer></distill-footer>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
@@ -97,3 +97,12 @@
|
|||||||
year={2016},
|
year={2016},
|
||||||
url={https://arxiv.org/pdf/1609.07009.pdf}
|
url={https://arxiv.org/pdf/1609.07009.pdf}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@misc{openai2018charter,
|
||||||
|
author={OpenAI},
|
||||||
|
title={OpenAI Charter},
|
||||||
|
type={Blog},
|
||||||
|
number={April 9},
|
||||||
|
year={2018},
|
||||||
|
url={https://blog.openai.com/charter},
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,183 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2018 The Distill Template Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script src="template.v2.js"></script>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta charset="utf8">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<distill-header></distill-header>
|
||||||
|
<d-front-matter>
|
||||||
|
<script id='distill-front-matter' type="text/json">{
|
||||||
|
"title": "Why Momentum Really Works",
|
||||||
|
"description": "Although \" extremely useful for visualizing high-dimensional data, t-SNE plots can sometimes be mysterious or misleading.",
|
||||||
|
"published": "Jan 10, 2017",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"author":"Chris Olah",
|
||||||
|
"authorURL":"https://colah.github.io/",
|
||||||
|
"affiliations": [{"name": "Google Brain"}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author":"Ludwig Schubert",
|
||||||
|
"authorURL":"https://shancarter.com/",
|
||||||
|
"affiliations": [{"name": "Google Brain", "url": "https://g.co/brain"}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author":"Shan Carter",
|
||||||
|
"authorURL":"https://shancarter.com/",
|
||||||
|
"affiliations": [
|
||||||
|
{"name": "Google Brain", "url": "https://g.co/brain"},
|
||||||
|
{"name": "NYT", "url": "https://nytimes.com"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"katex": {
|
||||||
|
"delimiters": [
|
||||||
|
{"left": "$$", "right": "$$", "display": false}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}</script>
|
||||||
|
</d-front-matter>
|
||||||
|
<d-title>
|
||||||
|
<figure style="grid-column: page; margin: 1rem 0;"><img src="momentum.png"
|
||||||
|
style="width:100%; border: 1px solid rgba(0, 0, 0, 0.2);" /></figure>
|
||||||
|
<p>We often think of Momentum<d-cite key="mercier2011humans"></d-cite> as a means of dampening oscillations and
|
||||||
|
speeding up the iterations, leading to faster convergence. But it has other interesting behavior. It allows a
|
||||||
|
larger range of step-sizes to be used, and creates its own oscillations. What is going on?</p>
|
||||||
|
</d-title>
|
||||||
|
<d-byline></d-byline>
|
||||||
|
<d-article>
|
||||||
|
<a class="marker" href="#section-1" id="section-1"><span>1</span></a>
|
||||||
|
<h2>A Brief Survey of Techniques</h2>
|
||||||
|
<p>Before diving in: if you haven’t encountered t-SNE before, here’s what you need to know about the math behind it.
|
||||||
|
The goal is to take a set of points in a high-dimensional space and find a faithful representation of those points
|
||||||
|
in a lower-dimensional space, typically the 2D plane. The algorithm is non-linear and adapts to the underlying
|
||||||
|
data, performing different transformations on different regions. Those differences can be a major source of
|
||||||
|
confusion.</p>
|
||||||
|
<p>This is the first paragraph of the article. Test a long — dash -- here it is.</p>
|
||||||
|
<p>Test for owner's possessive. Test for "quoting a passage." And another sentence. Or two. Some flopping fins; for
|
||||||
|
diving.</p>
|
||||||
|
<aside>Some text in an aside, margin notes, etc...</aside>
|
||||||
|
<p>Here's a test of an inline equation <d-math>c = a^2 + b^2</d-math>. Also with configurable katex standards just
|
||||||
|
using inline '$' signs: $$x^2$$ And then there's a block equation:</p>
|
||||||
|
<d-math block>
|
||||||
|
c = \pm \sqrt{ \sum_{i=0}^{n}{a^{222} + b^2}}
|
||||||
|
</d-math>
|
||||||
|
<p>Math can also be quite involved:</p>
|
||||||
|
<d-math block>
|
||||||
|
\frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}}
|
||||||
|
{1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\cdots} } } }
|
||||||
|
</d-math>
|
||||||
|
<a class="marker" href="#section-1.1" id="section-1.1"><span>1.1</span></a>
|
||||||
|
<h3>Citations</h3>
|
||||||
|
<p>
|
||||||
|
<d-slider style="width: 200px;"></d-slider>
|
||||||
|
</p>
|
||||||
|
<p>We can<d-cite bibtex-key="mercier2011humans"></d-cite> also cite <d-cite
|
||||||
|
key="gregor2015draw,mercier2011humans,openai2018charter"></d-cite> external publications. <d-cite
|
||||||
|
key="dong2014image,dumoulin2016guide,mordvintsev2015inceptionism"></d-cite>. 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>
|
||||||
|
<a class="marker" href="#section-2" id="section-2"><span>2</span></a>
|
||||||
|
<h2>Displaying code snippets</h2>
|
||||||
|
<p>Some inline javascript:<d-code language="javascript">var x = 25;</d-code>. And here's a javascript code block.
|
||||||
|
</p>
|
||||||
|
<d-code block language="javascript">
|
||||||
|
var x = 25;
|
||||||
|
function(x){
|
||||||
|
return x * x;
|
||||||
|
}
|
||||||
|
</d-code>
|
||||||
|
<p>We also support python.</p>
|
||||||
|
<d-code block language="python">
|
||||||
|
# Python 3: Fibonacci series up to n
|
||||||
|
def fib(n):
|
||||||
|
a, b = 0, 1
|
||||||
|
while a < n: print(a, end=' ' ) a, b=b, a+b </d-code>
|
||||||
|
<p>And a table</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>First</th>
|
||||||
|
<th>Second</th>
|
||||||
|
<th>Third</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>23</td>
|
||||||
|
<td>654</td>
|
||||||
|
<td>23</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>14</td>
|
||||||
|
<td>54</td>
|
||||||
|
<td>34</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>234</td>
|
||||||
|
<td>54</td>
|
||||||
|
<td>23</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<d-figure id="last-figure"></d-figure>
|
||||||
|
<script>
|
||||||
|
const figure = document.querySelector("d-figure#last-figure");
|
||||||
|
const initTag = document.createElement("span");
|
||||||
|
initTag.textContent = "initialized!"
|
||||||
|
figure.appendChild(initTag);
|
||||||
|
figure.addEventListener("ready", function () {
|
||||||
|
const initTag = figure.querySelector("span");
|
||||||
|
initTag.textContent = "ready"
|
||||||
|
console.log('ready')
|
||||||
|
});
|
||||||
|
figure.addEventListener("onscreen", function () {
|
||||||
|
const initTag = figure.querySelector("span");
|
||||||
|
initTag.textContent = "onscreen"
|
||||||
|
console.log('onscreen')
|
||||||
|
});
|
||||||
|
figure.addEventListener("offscreen", function () {
|
||||||
|
const initTag = figure.querySelector("span");
|
||||||
|
initTag.textContent = "offscreen!"
|
||||||
|
console.log('offscreen')
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<p>That's it for the example article!</p>
|
||||||
|
|
||||||
|
</d-article>
|
||||||
|
|
||||||
|
<d-appendix>
|
||||||
|
|
||||||
|
<h3>Contributions</h3>
|
||||||
|
<p>Some text describing who did what.</p>
|
||||||
|
<h3>Reviewers</h3>
|
||||||
|
<p>Some text with links describing who reviewed the article.</p>
|
||||||
|
|
||||||
|
<d-bibliography src="bibliography.bib"></d-bibliography>
|
||||||
|
</d-appendix>
|
||||||
|
|
||||||
|
<distill-footer></distill-footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
@@ -1,270 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright 2018 The Distill Template Authors
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<!doctype html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<script src="../dist/template.js"></script>
|
|
||||||
<style>
|
|
||||||
.fake-img {
|
|
||||||
background: #bbb;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
box-shadow: 0 0px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
.fake-img p {
|
|
||||||
font-family: monospace;
|
|
||||||
color: white;
|
|
||||||
text-align: left;
|
|
||||||
margin: 12px 0;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<dt-article>
|
|
||||||
<h1>How to Create a Distill Article</h1>
|
|
||||||
<h2>A collection of examples and best practices for creating interactive explanatory articles using the Distill web framework</h2>
|
|
||||||
<hr>
|
|
||||||
<h2>Getting Started</h2>
|
|
||||||
<p>Distill ships with a CSS framework and a collection of custom web components that make building interactive academic articles easier than with raw HTML, CSS and JavaScript. At its simplest, each distill post is just a single HTML file with one special script tag.</p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<!doctype html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<script src="http://distill.pub/template.js"></script>
|
|
||||||
|
|
||||||
<dt-article>
|
|
||||||
<h1>Hello World</h1>
|
|
||||||
</dt-article>
|
|
||||||
</dt-code>
|
|
||||||
<p>This script tag will modify your post in your browser, adding the distill styling and functionality. When we publish your article, we will bake in these transformations, but during development it’s handy to be able to preview it locally (It even works without a web server).</p>
|
|
||||||
<p>A typical distill post will be quite a bit longer than the one above. Below is a more complete example. Don’t worry if some of the tags don’t make sense, they’re all documented further in this post.</p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<!doctype html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<script src="http://distill.pub/template.js"></script>
|
|
||||||
|
|
||||||
<script type="text/front-matter">
|
|
||||||
title: Article Title
|
|
||||||
description: Description of the post
|
|
||||||
published: Jan 10, 2017
|
|
||||||
authors:
|
|
||||||
- Chris Olah: http://colah.github.io
|
|
||||||
- Shan Carter: http://shancarter.com
|
|
||||||
affiliations:
|
|
||||||
- Google Brain: http://g.co/brain
|
|
||||||
- Google Brain: http://g.co/brain
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<dt-article>
|
|
||||||
<h1>Hello World</h1>
|
|
||||||
<h2>A description of the article</h2>
|
|
||||||
<dt-byline></dt-byline>
|
|
||||||
<p>This is the first paragraph of the article.</p>
|
|
||||||
<p>We can also cite <dt-cite key="gregor2015draw"></dt-cite> external publications.</p>
|
|
||||||
</dt-article>
|
|
||||||
|
|
||||||
<dt-appendix>
|
|
||||||
</dt-appendix>
|
|
||||||
|
|
||||||
<script type="text/bibliography">
|
|
||||||
@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={arXivreprint arXiv:1502.04623},
|
|
||||||
year={2015},
|
|
||||||
url={https://arxiv.org/pdf/1502.04623.pdf}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</dt-code>
|
|
||||||
<!-- <hr>
|
|
||||||
<h2>Markdown</h2>
|
|
||||||
<p>Markdown is supported as an alternative to html for the <dt-code language="html"><dt-article></dt-code> element. </p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<!doctype html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<script src="../dist/template.min.js"></script>
|
|
||||||
<dt-article markdown>
|
|
||||||
# Hello World
|
|
||||||
|
|
||||||
## A description of the post
|
|
||||||
|
|
||||||
First paragraph of the article.
|
|
||||||
</dt-article>
|
|
||||||
<script type="text/bibliography"></script>
|
|
||||||
</dt-code>
|
|
||||||
<p>We use <a href="https://github.com/chjj/marked">marked</a> as the rendering engine, with <a href="https://help.github.com/articles/basic-writing-and-formatting-syntax/">github flavored markdown</a> and <a href="https://daringfireball.net/projects/smartypants/">smartypants</a> enabled. In development mode the markdown is translated in the client after the dom content has loaded, but when published, the translation is precompiled.</p> -->
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Project Structure</h2>
|
|
||||||
<p>Because all the templating is delivered via a script tag, you are generally free to develop however you are most comfortable. The only requirements are that each article must be its own Github repository. The simplest setup would be a repository that contained a single HTML file, along with any additional assets, like images or javascript files. Note, in this default setup, all files in the root of the repository will be published. Note, also, in this configuration you generally will not even need to run a static local webserver. You can just open the <dt-code>index.html</dt-code> file in your browser to preview.</p>
|
|
||||||
|
|
||||||
<dt-code block language="html">
|
|
||||||
image.jpg
|
|
||||||
index.html
|
|
||||||
script.js
|
|
||||||
</dt-code>
|
|
||||||
|
|
||||||
<p>If you have a more complicated build process, or have files you don’t want published, put your output in a <dt-code>public</dt-code> folder and we will only publish its contents.</p>
|
|
||||||
|
|
||||||
<dt-code block language="html">
|
|
||||||
build/
|
|
||||||
_index.html
|
|
||||||
package.json
|
|
||||||
public/
|
|
||||||
index.html
|
|
||||||
image.jpg
|
|
||||||
</dt-code>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Front Matter</h2>
|
|
||||||
<p>You’ll need to describe some data about you post — title, description, authors, etc. For this use the <dt-code language="html"><script type="text/front-matter"></dt-code> tag.</p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<script type="text/front-matter">
|
|
||||||
title: Article Title
|
|
||||||
description: Description of the post
|
|
||||||
authors:
|
|
||||||
- Chris Olah: http://colah.github.io
|
|
||||||
- Shan Carter: http://shancarter.com
|
|
||||||
affiliations:
|
|
||||||
- Google Brain: http://g.co/brain
|
|
||||||
- Google Brain: http://g.co/brain
|
|
||||||
</script>
|
|
||||||
</dt-code>
|
|
||||||
<!-- <p>You can also use an external JSON file if you like. We will automatically make a request for a <dt-code>distill.json</dt-code> file if there is no <dt-code language="html"><script type="text/front-matter"></dt-code> element on the page, or you can point to another file with the <dt-code>src</dt-code> attribute. In production, these files will be inlined into the document.</p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<script type="text/front-matter" src="./distill.json"></script>
|
|
||||||
</dt-code> -->
|
|
||||||
<hr>
|
|
||||||
<h2>Citations</h2>
|
|
||||||
<p>Bibtex is the supported way of making academic citations. You first need have a global definition of all your possible citations. For this we’ll use the <dt-code language="html"><script type="text/bibliography"></dt-code> element.</p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<script type="text/bibliography">
|
|
||||||
@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={arXivreprint arXiv:1502.04623},
|
|
||||||
year={2015},
|
|
||||||
url={https://arxiv.org/pdf/1502.04623.pdf},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</dt-code>
|
|
||||||
<p>(We strongly encourage you to populate the <dt-code>url</dt-code> bibtex field where possible so that we can provide links for citations.)</p>
|
|
||||||
<!-- <p>Like with the <dt-code language="html"><script type="text/front-matter"></dt-code> element, you can alternatively reference an external file with the <dt-code>src</dt-code> attribute. If no <dt-code language="html"><script type="text/bibliography"></dt-code> element is found on the page, a request will automatically be made for <dt-code>bibliography.bib</dt-code>. In production, these files will be inlined into the document.</p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<script type="text/bibliography" src="bibliography.bib"></script>
|
|
||||||
</dt-code> -->
|
|
||||||
<p>Citations are then used in the article body with the <dt-code language="html"><dt-cite></dt-code> tag. The <dt-code>key</dt-code> attribute is a reference to the id provided in the bibiography. The <dt-code>key</dt-code> attribute can take multiple ids, separated by commas.</p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<dt-cite key="gregor2015draw"></dt-cite>
|
|
||||||
</dt-code>
|
|
||||||
<script type="text/bibliography">
|
|
||||||
@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={arXivreprint arXiv:1502.04623},
|
|
||||||
year={2015},
|
|
||||||
url={https://arxiv.org/pdf/1502.04623.pdf},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<p>The citation is presented inline like this: <dt-cite key="gregor2015draw"></dt-cite> (a number that displays more information on hover). If you have an appendix, a bibliography is automatically created and populated in it.</p>
|
|
||||||
<p>Distill chose a numerical inline citation style to improve readability of citation dense articles and because many of the benefits of longer citations are obviated by displaying more information on hover. However, we consider it good style to mention author last names if you discuss something at length and it fits into the flow well -- the authors are human and it's nice for them to have the community associate them with their work.</p>
|
|
||||||
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Footnotes</h2>
|
|
||||||
<p>Just wrap the text you would like to show up in a footnote in a <dt-code language="html"><dt-fn></dt-code> tag. The number of the footnote will be automatically generated. <dt-fn>This text will be shown on hover.</dt-fn></p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<dt-fn>This will become a hoverable footnote.</dt-fn>
|
|
||||||
</dt-code>
|
|
||||||
<dt-footnote-body ref="blah"></dt-footnote-body>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Code Blocks</h2>
|
|
||||||
<p>Syntax highlighting is provided within <dt-code language="html"><dt-code></dt-code> tags. An example of inline code snippets: <dt-code language="html"><dt-code language="html">let x = 10;</dt-code></dt-code>. For larger blocks of code, add a <dt-code>block</dt-code> attribute:</p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<dt-code block language="javascript">
|
|
||||||
var x = 25;
|
|
||||||
function(x){
|
|
||||||
return x * x;
|
|
||||||
}
|
|
||||||
</dt-code>
|
|
||||||
</dt-code>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<hr>
|
|
||||||
<h2>Math</h2>
|
|
||||||
-->
|
|
||||||
<hr>
|
|
||||||
<h2>Layouts</h2>
|
|
||||||
<p>The main text column is referred to as the body. It is the assumed layout of any direct descendents of the <code>dt-article</code> element.</p>
|
|
||||||
<div class="fake-img l-body"><p>.l-body</p></div>
|
|
||||||
<p>For images you want to display a little larger, try these:</p>
|
|
||||||
<div class="fake-img l-middle"><p>.l-middle</p></div>
|
|
||||||
<div class="fake-img l-page"><p>.l-page</p></div>
|
|
||||||
<p>All of these have an <dt-code>outset</dt-code> variant if you want to poke out from the body text a little bit. For instance:</p>
|
|
||||||
<div class="fake-img l-body-outset"><p>.l-body-outset</p></div>
|
|
||||||
<div class="fake-img l-middle-outset"><p>.l-middle-outset</p></div>
|
|
||||||
<div class="fake-img l-page-outset"><p>.l-page-outset</p></div>
|
|
||||||
<p>Occasionally you’ll want to use the full browser width. For this, use <dt-code>.l-screen</dt-code>. You can also inset the element a little from the edge of the browser by using the inset variant.</p>
|
|
||||||
<div class="fake-img l-screen"><p>.l-screen</p></div>
|
|
||||||
<div class="fake-img l-screen-inset"><p>.l-screen-inset</p></div>
|
|
||||||
<p>Often you want to position smaller images so as not to completely interrupt the flow of your text. Or perhaps you want to put some text in the margin as an aside or to signal that it’s optional content. For these cases we’ll use the float-based layouts.</p>
|
|
||||||
<div class="fake-img l-body side"><p>.l-body.side</p></div>
|
|
||||||
<div class="fake-img l-middle side"><p>.l-middle.side</p></div>
|
|
||||||
<div class="fake-img l-page side"><p>.l-page.side</p></div>
|
|
||||||
<p>They are all floated to the right and anchored to the right-hand edge of the position you specify. By default, each will take up approximately half of the width of the standard layout position, but you can override the width with a more specific selector. </p>
|
|
||||||
<div class="fake-img l-gutter"><p>.l-gutter</p></div>
|
|
||||||
<p>The final layout is for marginalia, asides, and footnotes. It does not interrupt the normal flow of <code>.l-body</code> sized text except on mobile screen sizes.</p>
|
|
||||||
<p>You can also use an alternate centered layout by adding a <dt-code>centered</dt-code> class to the <dt-code>dt-article</dt-code> element.</p>
|
|
||||||
<dt-code block language="html">
|
|
||||||
<dt-article class="centered">
|
|
||||||
<h1>Hello World</h1>
|
|
||||||
</dt-article>
|
|
||||||
</dt-code>
|
|
||||||
<p>You can toggle it on this article by <a onclick="document.querySelector('dt-article').classList.toggle('centered');">clicking here</a></p>
|
|
||||||
<section class="centered">
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Appendix</h2>
|
|
||||||
|
|
||||||
<p>An appendix can be added after your article, using the <dt-code language="html"><dt-appendix></dt-code> tag.</p>
|
|
||||||
|
|
||||||
<dt-code block language="html">
|
|
||||||
<dt-article>
|
|
||||||
...
|
|
||||||
</dt-article>
|
|
||||||
|
|
||||||
<dt-appendix>
|
|
||||||
<h3>Appendix Section Title</h3>
|
|
||||||
<p>section content<p>
|
|
||||||
</dt-appendix>
|
|
||||||
</dt-code>
|
|
||||||
|
|
||||||
<p>You may wish to include the following sections in your appendix:</p>
|
|
||||||
<ul>
|
|
||||||
<li><b>Acknowledgments</b>: This is a place to recognize people and institutions. It may also be a good place to acknowledge and cite software that makes your work possible (eg. TensorFlow, OpenAI Gym).</li>
|
|
||||||
<li><b>Author Contributions</b>: We strongly encourage you to include an author contributions statement briefly describing what each author did.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>And You’re Off</h2>
|
|
||||||
<p>That should do it. If you have any questions or bugs to file, feel free to <a href="https://github.com/distillpub/template/issues/new">open an issue on GitHub</a>.</p>
|
|
||||||
<!--
|
|
||||||
<hr>
|
|
||||||
<h2>Including External Files</h2> -->
|
|
||||||
|
|
||||||
</dt-article>
|
|
||||||
Generated
+3312
-4121
File diff suppressed because it is too large
Load Diff
+26
-26
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "distill-template",
|
"name": "distill-template",
|
||||||
"version": "2.2.22",
|
"version": "2.8.0",
|
||||||
"description": "Template for creating Distill articles.",
|
"description": "Template for creating Distill articles.",
|
||||||
"main": "dist/template.v2.js",
|
"main": "dist/template.v2.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -13,10 +13,10 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "rollup -c rollup.config.dev.js -w",
|
"dev": "rollup -c rollup.config.dev.js -w",
|
||||||
"serve": "python3 -m http.server --bind 127.0.0.1 8888",
|
"serve": "http-server",
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
"lint": "eslint",
|
"lint": "eslint",
|
||||||
"build": "rollup -c rollup.config.js",
|
"build": "rollup -c rollup.config.prod.js",
|
||||||
"prepare": "npm run build"
|
"prepare": "npm run build"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -24,42 +24,42 @@
|
|||||||
"type": "git"
|
"type": "git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.9.0",
|
||||||
|
"@rollup/plugin-babel": "^5.0.0",
|
||||||
"bibtex-parse-js": "^0.0.23",
|
"bibtex-parse-js": "^0.0.23",
|
||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
"eslint": "^4.3.0",
|
"eslint": "^4.19.1",
|
||||||
"eslint-config-google": "^0.9.1",
|
"eslint-config-google": "^0.9.1",
|
||||||
"js-yaml": "^3.7.0",
|
"js-yaml": "^3.13.1",
|
||||||
"jsdom": "11.3.0",
|
"jsdom": "11.3.0",
|
||||||
"jsdom-global": "3.0.2",
|
"jsdom-global": "3.0.2",
|
||||||
"marked": "^0.3.6",
|
"marked": "^0.8.2",
|
||||||
"mocha": "^3.5.3",
|
"mocha": "^5.2.0",
|
||||||
"prismjs": "^1.6.0",
|
"prismjs": "^1.20.0",
|
||||||
"rollup": "^0.50.0",
|
"rollup": "^2.7.3",
|
||||||
"rollup-plugin-babili": "^3.1.0",
|
"rollup-plugin-commonjs": "^10.1.0",
|
||||||
"rollup-plugin-buble": "^0.15.0",
|
|
||||||
"rollup-plugin-commonjs": "^7.0.0",
|
|
||||||
"rollup-plugin-copy": "^0.2.3",
|
"rollup-plugin-copy": "^0.2.3",
|
||||||
"rollup-plugin-grapher": "^0.2.0",
|
"rollup-plugin-grapher": "^0.2.0",
|
||||||
"rollup-plugin-gzip": "^1.2.0",
|
"rollup-plugin-gzip": "^1.4.0",
|
||||||
"rollup-plugin-node-resolve": "^2.0.0",
|
"rollup-plugin-node-resolve": "^2.0.0",
|
||||||
"rollup-plugin-serve": "^0.1.0",
|
"rollup-plugin-serve": "^1.0.1",
|
||||||
"rollup-plugin-string": "^2.0.2",
|
"rollup-plugin-string": "^2.0.2",
|
||||||
"rollup-plugin-uglify": "^1.0.1",
|
"rollup-plugin-uglify": "^1.0.1",
|
||||||
"rollup-watch": "^2.5.0",
|
"rollup-watch": "^4.3.1",
|
||||||
"should": "^13.1.2",
|
"should": "^13.2.3",
|
||||||
"webpack": "^2.2.1"
|
"source-map-support": "^0.5.19"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@webcomponents/webcomponentsjs": "^1.0.7",
|
"@webcomponents/webcomponentsjs": "^1.3.3",
|
||||||
"assert": "^1.4.1",
|
"assert": "^1.5.0",
|
||||||
"commander": "^2.9.0",
|
"commander": "^2.20.3",
|
||||||
"d3-array": "^1.2.1",
|
"d3-array": "^2.4.0",
|
||||||
"d3-drag": "^1.2.1",
|
"d3-drag": "^1.2.5",
|
||||||
"d3-scale": "^1.0.6",
|
"d3-scale": "^3.2.1",
|
||||||
"d3-selection": "^1.1.0",
|
"d3-selection": "^1.4.1",
|
||||||
"d3-time-format": "^2.0.3",
|
"d3-time-format": "^2.2.3",
|
||||||
"escape-html": "^1.0.3",
|
"escape-html": "^1.0.3",
|
||||||
"intersection-observer": "^0.4.0",
|
"intersection-observer": "^0.4.3",
|
||||||
"jsdom-wc": "^11.0.0-alpha-1",
|
"jsdom-wc": "^11.0.0-alpha-1",
|
||||||
"katex": "^0.8.3"
|
"katex": "^0.8.3"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2018 The Distill Template Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import resolve from "rollup-plugin-node-resolve";
|
||||||
|
import string from "rollup-plugin-string";
|
||||||
|
import commonjs from "rollup-plugin-commonjs";
|
||||||
|
import babel from '@rollup/plugin-babel';
|
||||||
|
|
||||||
|
// uncomment to show dependencies [1/2]
|
||||||
|
// import rollupGrapher from 'rollup-plugin-grapher'
|
||||||
|
|
||||||
|
const defaultConfig = {
|
||||||
|
plugins: [
|
||||||
|
resolve({
|
||||||
|
jsnext: true,
|
||||||
|
browser: true
|
||||||
|
}),
|
||||||
|
commonjs(),
|
||||||
|
string({
|
||||||
|
include: ["**/*.txt", "**/*.svg", "**/*.html", "**/*.css", "**/*.base64"]
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const componentsConfig = {
|
||||||
|
input: "src/components.js",
|
||||||
|
output: [{ format: "umd", name: "dl", file: "dist/template.v2.js", sourcemap: true }],
|
||||||
|
plugins: [
|
||||||
|
babel({
|
||||||
|
"babelHelpers": "bundled",
|
||||||
|
"targets": "defaults"
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const transformsConfig = {
|
||||||
|
input: "src/transforms.js",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
format: "umd",
|
||||||
|
name: "dl",
|
||||||
|
file: "dist/transforms.v2.js",
|
||||||
|
globals: { fs: "fs" },
|
||||||
|
sourcemap: true,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
external: ["fs"],
|
||||||
|
plugins: [
|
||||||
|
babel({
|
||||||
|
"babelHelpers": "bundled",
|
||||||
|
"targets": {
|
||||||
|
"node": "current"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.assign(componentsConfig, defaultConfig);
|
||||||
|
Object.assign(transformsConfig, defaultConfig);
|
||||||
|
|
||||||
|
export default [componentsConfig, transformsConfig];
|
||||||
+13
-51
@@ -12,59 +12,21 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import resolve from 'rollup-plugin-node-resolve';
|
import configs from "./rollup.config.common";
|
||||||
import string from 'rollup-plugin-string';
|
import serve from "rollup-plugin-serve";
|
||||||
import commonjs from 'rollup-plugin-commonjs';
|
|
||||||
import buble from 'rollup-plugin-buble';
|
|
||||||
|
|
||||||
// uncomment to show dependencies [1/2]
|
const [componentsConfig, transformsConfig] = configs;
|
||||||
// import rollupGrapher from 'rollup-plugin-grapher'
|
|
||||||
|
|
||||||
const componentsConfig = {
|
componentsConfig.plugins.push(
|
||||||
input: 'src/components.js',
|
serve({
|
||||||
output: [{ format: 'umd', name: 'dl', file: 'dist/template.v2.js' }],
|
open: true,
|
||||||
};
|
openPage: "/index.html",
|
||||||
|
contentBase: ["dist", "examples"],
|
||||||
const transformsConfig = {
|
headers: {
|
||||||
input: 'src/transforms.js',
|
"Access-Control-Allow-Origin": "*"
|
||||||
output: [{ format: 'umd', name: 'dl', file: 'dist/transforms.v2.js', globals: {fs: 'fs'} }],
|
},
|
||||||
external: ['fs']
|
port: 8088
|
||||||
};
|
|
||||||
|
|
||||||
const defaultConfig = {
|
|
||||||
sourcemap: true,
|
|
||||||
plugins: [
|
|
||||||
resolve({
|
|
||||||
jsnext: true,
|
|
||||||
browser: true,
|
|
||||||
}),
|
|
||||||
string({
|
|
||||||
include: ['**/*.txt', '**/*.svg', '**/*.html', '**/*.css', '**/*.base64']
|
|
||||||
}),
|
|
||||||
commonjs(),
|
|
||||||
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.assign(componentsConfig, defaultConfig);
|
|
||||||
Object.assign(transformsConfig, defaultConfig);
|
|
||||||
|
|
||||||
// transpile transforms so the node render script works…
|
|
||||||
transformsConfig.plugins.push(
|
|
||||||
buble({
|
|
||||||
target: { 'node': 6 }
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// uncomment to show dependencies [2/2]
|
export default [componentsConfig, transformsConfig];
|
||||||
// transformsConfig.plugins.push(
|
|
||||||
// rollupGrapher({
|
|
||||||
// dest: '/dev/null',
|
|
||||||
// verbose: true
|
|
||||||
// })
|
|
||||||
// );
|
|
||||||
|
|
||||||
export default [
|
|
||||||
componentsConfig,
|
|
||||||
transformsConfig,
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -12,17 +12,6 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import configs from './rollup.config.dev';
|
import configs from "./rollup.config.common";
|
||||||
import babili from 'rollup-plugin-babili';
|
|
||||||
|
|
||||||
const [componentsConfig, transformsConfig] = configs;
|
export default configs;
|
||||||
|
|
||||||
componentsConfig.plugins.push(babili({
|
|
||||||
comments: false, // means: *remove* comments
|
|
||||||
sourceMap: true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
export default [
|
|
||||||
componentsConfig,
|
|
||||||
transformsConfig,
|
|
||||||
];
|
|
||||||
+43
-34
@@ -13,6 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Controller } from './controller';
|
import { Controller } from './controller';
|
||||||
|
import { domContentLoaded } from './helpers/domContentLoaded.js';
|
||||||
|
|
||||||
/* Transforms */
|
/* Transforms */
|
||||||
import { makeStyleTag } from './styles/styles';
|
import { makeStyleTag } from './styles/styles';
|
||||||
@@ -44,38 +45,41 @@ import { DistillHeader } from './distill-components/distill-header';
|
|||||||
import { DistillAppendix } from './distill-components/distill-appendix';
|
import { DistillAppendix } from './distill-components/distill-appendix';
|
||||||
import { DistillFooter } from './distill-components/distill-footer';
|
import { DistillFooter } from './distill-components/distill-footer';
|
||||||
|
|
||||||
const distillMain = function() {
|
let templateIsLoading = false;
|
||||||
|
let runlevel = 0;
|
||||||
if (window.distillRunlevel < 1) {
|
const initialize = function() {
|
||||||
throw new Error('Insufficient Runlevel for Distill Template!');
|
if (window.distill.runlevel < 1) {
|
||||||
|
throw new Error("Insufficient Runlevel for Distill Template!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1. Flag that we're being loaded */
|
/* 1. Flag that we're being loaded */
|
||||||
if ('distillTemplateIsLoading' in window && window.distillTemplateIsLoading) {
|
if ("distill" in window && window.distill.templateIsLoading) {
|
||||||
throw new Error('Runlevel 1: Distill Template is getting loaded more than once, aborting!');
|
throw new Error(
|
||||||
|
"Runlevel 1: Distill Template is getting loaded more than once, aborting!"
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
window.distillTemplateIsLoading = true;
|
window.distill.templateIsLoading = true;
|
||||||
console.info('Runlevel 1: Distill Template has started loading.');
|
console.debug("Runlevel 1: Distill Template has started loading.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. Add styles if they weren't added during prerendering */
|
/* 2. Add styles if they weren't added during prerendering */
|
||||||
makeStyleTag(document);
|
makeStyleTag(document);
|
||||||
console.info('Runlevel 1: Static Distill styles have been added.');
|
console.debug("Runlevel 1: Static Distill styles have been added.");
|
||||||
console.info('Runlevel 1->2.');
|
console.debug("Runlevel 1->2.");
|
||||||
window.distillRunlevel += 1;
|
window.distill.runlevel += 1;
|
||||||
|
|
||||||
/* 3. Register Controller listener functions */
|
/* 3. Register Controller listener functions */
|
||||||
/* Needs to happen before components to their connected callbacks have a controller to talk to. */
|
/* Needs to happen before components to their connected callbacks have a controller to talk to. */
|
||||||
for (const [functionName, callback] of Object.entries(Controller.listeners)) {
|
for (const [functionName, callback] of Object.entries(Controller.listeners)) {
|
||||||
if (typeof callback === 'function') {
|
if (typeof callback === "function") {
|
||||||
document.addEventListener(functionName, callback);
|
document.addEventListener(functionName, callback);
|
||||||
} else {
|
} else {
|
||||||
console.error('Runlevel 2: Controller listeners need to be functions!');
|
console.error("Runlevel 2: Controller listeners need to be functions!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.info('Runlevel 2: We can now listen to controller events.');
|
console.debug("Runlevel 2: We can now listen to controller events.");
|
||||||
console.info('Runlevel 2->3.');
|
console.debug("Runlevel 2->3.");
|
||||||
window.distillRunlevel += 1;
|
window.distill.runlevel += 1;
|
||||||
|
|
||||||
/* 4. Register components */
|
/* 4. Register components */
|
||||||
const components = [
|
const components = [
|
||||||
@@ -84,38 +88,43 @@ const distillMain = function() {
|
|||||||
Slider, Interstitial
|
Slider, Interstitial
|
||||||
];
|
];
|
||||||
|
|
||||||
const distillComponents = [
|
const distillComponents = [DistillHeader, DistillAppendix, DistillFooter];
|
||||||
DistillHeader, DistillAppendix, DistillFooter,
|
|
||||||
];
|
|
||||||
|
|
||||||
if (window.distillRunlevel < 2) {
|
if (window.distill.runlevel < 2) {
|
||||||
throw new Error('Insufficient Runlevel for adding custom elements!');
|
throw new Error("Insufficient Runlevel for adding custom elements!");
|
||||||
}
|
}
|
||||||
const allComponents = components.concat(distillComponents);
|
const allComponents = components.concat(distillComponents);
|
||||||
for (const component of allComponents) {
|
for (const component of allComponents) {
|
||||||
console.info('Runlevel 2: Registering custom element: ' + component.is);
|
console.debug("Runlevel 2: Registering custom element: " + component.is);
|
||||||
customElements.define(component.is, component);
|
customElements.define(component.is, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info('Runlevel 3: Distill Template finished registering custom elements.');
|
console.debug(
|
||||||
console.info('Runlevel 3->4.');
|
"Runlevel 3: Distill Template finished registering custom elements."
|
||||||
window.distillRunlevel += 1;
|
);
|
||||||
|
console.debug("Runlevel 3->4.");
|
||||||
|
window.distill.runlevel += 1;
|
||||||
|
|
||||||
// If template was added after DOMContentLoaded we may have missed that event.
|
// If template was added after DOMContentLoaded we may have missed that event.
|
||||||
// Controller will check for that case, so trigger the event explicitly:
|
// Controller will check for that case, so trigger the event explicitly:
|
||||||
Controller.listeners.DOMContentLoaded();
|
if (domContentLoaded()) {
|
||||||
|
Controller.listeners.DOMContentLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
console.info('Runlevel 4: Distill Template initialisation complete.');
|
console.debug("Runlevel 4: Distill Template initialisation complete.");
|
||||||
|
window.distill.templateIsLoading = false;
|
||||||
|
window.distill.templateHasLoaded = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
window.distillRunlevel = 0;
|
window.distill = { runlevel, initialize, templateIsLoading };
|
||||||
|
|
||||||
/* 0. Check browser feature support; synchronously polyfill if needed */
|
/* 0. Check browser feature support; synchronously polyfill if needed */
|
||||||
if (Polyfills.browserSupportsAllFeatures()) {
|
if (Polyfills.browserSupportsAllFeatures()) {
|
||||||
console.info('Runlevel 0: No need for polyfills.');
|
console.debug("Runlevel 0: No need for polyfills.");
|
||||||
console.info('Runlevel 0->1.');
|
console.debug("Runlevel 0->1.");
|
||||||
window.distillRunlevel += 1;
|
window.distill.runlevel += 1;
|
||||||
distillMain();
|
window.distill.initialize();
|
||||||
} else {
|
} else {
|
||||||
console.info('Runlevel 0: Distill Template is loading polyfills.');
|
console.debug("Runlevel 0: Distill Template is loading polyfills.");
|
||||||
Polyfills.load(distillMain);
|
Polyfills.load(window.distill.initialize);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ export function bylineTemplate(frontMatter) {
|
|||||||
<p class="author">
|
<p class="author">
|
||||||
${author.personalURL ? `
|
${author.personalURL ? `
|
||||||
<a class="name" href="${author.personalURL}">${author.name}</a>` : `
|
<a class="name" href="${author.personalURL}">${author.name}</a>` : `
|
||||||
<div class="name">${author.name}</div>`}
|
<span class="name">${author.name}</span>`}
|
||||||
</p>
|
</p>
|
||||||
<p class="affiliation">
|
<p class="affiliation">
|
||||||
${author.affiliations.map(affiliation =>
|
${author.affiliations.map(affiliation =>
|
||||||
affiliation.url ? `<a class="affiliation" href="${affiliation.url}">${affiliation.name}</a>` : `<div class="affiliation">${affiliation.name}</div>`
|
affiliation.url ? `<a class="affiliation" href="${affiliation.url}">${affiliation.name}</a>` : `<span class="affiliation">${affiliation.name}</span>`
|
||||||
).join(', ')}
|
).join(', ')}
|
||||||
</p>
|
</p>
|
||||||
`).join('')}
|
`).join('')}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { bibliography_cite } from '../helpers/citation';
|
|||||||
|
|
||||||
const styles = `
|
const styles = `
|
||||||
d-citation-list {
|
d-citation-list {
|
||||||
contain: layout style;
|
contain: style;
|
||||||
}
|
}
|
||||||
|
|
||||||
d-citation-list .references {
|
d-citation-list .references {
|
||||||
|
|||||||
+66
-35
@@ -12,10 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Template } from '../mixins/template';
|
import { Template } from "../mixins/template";
|
||||||
import { hover_cite, bibliography_cite } from '../helpers/citation';
|
import { hover_cite, bibliography_cite } from "../helpers/citation";
|
||||||
|
|
||||||
const T = Template('d-cite', `
|
const T = Template(
|
||||||
|
"d-cite",
|
||||||
|
`
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
@@ -23,7 +25,6 @@ const T = Template('d-cite', `
|
|||||||
}
|
}
|
||||||
|
|
||||||
.citation {
|
.citation {
|
||||||
display: inline-block;
|
|
||||||
color: hsla(206, 90%, 20%, 0.7);
|
color: hsla(206, 90%, 20%, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,10 +49,6 @@ figcaption .citation-number {
|
|||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
d-hover-box {
|
|
||||||
margin-top: 1.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -71,74 +68,108 @@ ul li:last-of-type {
|
|||||||
|
|
||||||
<d-hover-box id="hover-box"></d-hover-box>
|
<d-hover-box id="hover-box"></d-hover-box>
|
||||||
|
|
||||||
<div id="citation-" class="citation"><slot></slot><span class="citation-number"></span></div>
|
<div id="citation-" class="citation">
|
||||||
`);
|
<span class="citation-number"></span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
export class Cite extends T(HTMLElement) {
|
export class Cite extends T(HTMLElement) {
|
||||||
|
|
||||||
/* Lifecycle */
|
/* Lifecycle */
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this._numbers = [];
|
||||||
|
this._entries = [];
|
||||||
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
this.outerSpan = this.root.querySelector('#citation-');
|
this.outerSpan = this.root.querySelector("#citation-");
|
||||||
this.innerSpan = this.root.querySelector('.citation-number');
|
this.innerSpan = this.root.querySelector(".citation-number");
|
||||||
this.hoverBox = this.root.querySelector('d-hover-box');
|
this.hoverBox = this.root.querySelector("d-hover-box");
|
||||||
window.customElements.whenDefined('d-hover-box').then(() => {
|
window.customElements.whenDefined("d-hover-box").then(() => {
|
||||||
this.hoverBox.listen(this);
|
this.hoverBox.listen(this);
|
||||||
});
|
});
|
||||||
|
// in case this component got connected after values were set
|
||||||
|
if (this.numbers) {
|
||||||
|
this.displayNumbers(this.numbers);
|
||||||
|
}
|
||||||
|
if (this.entries) {
|
||||||
|
this.displayEntries(this.entries);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO This causes an infinite loop on firefox with polyfills.
|
//TODO This causes an infinite loop on firefox with polyfills.
|
||||||
// This is only needed for interactive editing so no priority.
|
// This is only needed for interactive editing so no priority.
|
||||||
// disconnectedCallback() {
|
// disconnectedCallback() {
|
||||||
// const options = { detail: [this, this.keys], bubbles: true };
|
// const options = { detail: [this, this.keys], bubbles: true };
|
||||||
// const event = new CustomEvent('onCiteKeyRemoved', options);
|
// const event = new CustomEvent('onCiteKeyRemoved', options);
|
||||||
// document.dispatchEvent(event);
|
// document.dispatchEvent(event);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/* observe 'key' attribute */
|
/* observe 'key' attribute */
|
||||||
|
|
||||||
static get observedAttributes() {
|
static get observedAttributes() {
|
||||||
return ['key'];
|
return ["key", "bibtex-key"];
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback(name, oldValue, newValue) {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
const eventName = oldValue ? 'onCiteKeyChanged' : 'onCiteKeyCreated';
|
const eventName = oldValue ? "onCiteKeyChanged" : "onCiteKeyCreated";
|
||||||
const keys = newValue.split(',');
|
const keys = newValue.split(",").map(k => k.trim());
|
||||||
const options = { detail: [this, keys], bubbles: true };
|
const options = { detail: [this, keys], bubbles: true };
|
||||||
const event = new CustomEvent(eventName, options);
|
const event = new CustomEvent(eventName, options);
|
||||||
document.dispatchEvent(event);
|
document.dispatchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
set key(value) {
|
set key(value) {
|
||||||
this.setAttribute('key', value);
|
this.setAttribute("key", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
get key() {
|
get key() {
|
||||||
return this.getAttribute('key');
|
return this.getAttribute("key") || this.getAttribute("bibtex-key");
|
||||||
}
|
}
|
||||||
|
|
||||||
get keys() {
|
get keys() {
|
||||||
return this.getAttribute('key').split(',');
|
const result = this.key.split(",");
|
||||||
|
console.log(result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setters & Rendering */
|
/* Setters & Rendering */
|
||||||
|
|
||||||
set numbers(numbers) {
|
set numbers(numbers) {
|
||||||
const numberStrings = numbers.map( index => {
|
this._numbers = numbers;
|
||||||
return index == -1 ? '?' : index + 1 + '';
|
this.displayNumbers(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
get numbers() {
|
||||||
|
return this._numbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
displayNumbers(numbers) {
|
||||||
|
if (!this.innerSpan) return;
|
||||||
|
const numberStrings = numbers.map(index => {
|
||||||
|
return index == -1 ? "?" : index + 1 + "";
|
||||||
});
|
});
|
||||||
const textContent = '[' + numberStrings.join(', ') + ']';
|
const textContent = "[" + numberStrings.join(", ") + "]";
|
||||||
if (this.innerSpan) {
|
this.innerSpan.textContent = textContent;
|
||||||
this.innerSpan.textContent = textContent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set entries(entries) {
|
set entries(entries) {
|
||||||
if (this.hoverBox) {
|
this._entries = entries;
|
||||||
this.hoverBox.innerHTML = `<ul>
|
this.displayEntries(entries);
|
||||||
${entries.map(hover_cite).map(html => `<li>${html}</li>`).join('\n')}
|
|
||||||
</ul>`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get entries() {
|
||||||
|
return this._entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
displayEntries(entries) {
|
||||||
|
if (!this.hoverBox) return;
|
||||||
|
this.hoverBox.innerHTML = `<ul>
|
||||||
|
${entries
|
||||||
|
.map(hover_cite)
|
||||||
|
.map(html => `<li>${html}</li>`)
|
||||||
|
.join("\n")}
|
||||||
|
</ul>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ d-math[block] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sup {
|
sup {
|
||||||
@@ -37,13 +38,6 @@ span {
|
|||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
left: 0;
|
|
||||||
z-index: 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footnote-container {
|
.footnote-container {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,12 +30,11 @@ export function _moveLegacyAffiliationFormatIntoArray(frontMatter) {
|
|||||||
author.affiliations = [newAffiliation];
|
author.affiliations = [newAffiliation];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(frontMatter)
|
|
||||||
return frontMatter
|
return frontMatter
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseFrontmatter(element) {
|
export function parseFrontmatter(element) {
|
||||||
const scriptTag = element.querySelector('script');
|
const scriptTag = element.firstElementChild;
|
||||||
if (scriptTag) {
|
if (scriptTag) {
|
||||||
const type = scriptTag.getAttribute('type');
|
const type = scriptTag.getAttribute('type');
|
||||||
if (type.split('/')[1] == 'json') {
|
if (type.split('/')[1] == 'json') {
|
||||||
|
|||||||
@@ -20,9 +20,10 @@ const T = Template('d-hover-box', `
|
|||||||
:host {
|
:host {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
left: 0;
|
left: 0px;
|
||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
display: none;
|
display: none;
|
||||||
|
white-space: normal
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@@ -40,10 +41,13 @@ const T = Template('d-hover-box', `
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
background-color: rgb(250, 250, 250);
|
background-color: rgba(250, 250, 250, 0.95);
|
||||||
box-shadow: 0 0 7px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0 7px rgba(0, 0, 0, 0.1);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
backdrop-filter: blur(2px);
|
||||||
|
-webkit-backdrop-filter: blur(2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -117,11 +121,14 @@ export class HoverBox extends T(HTMLElement) {
|
|||||||
show(position) {
|
show(position) {
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
this.style.display = 'block';
|
this.style.display = 'block';
|
||||||
|
// 10px extra offset from element
|
||||||
|
this.style.top = Math.round(position[1] + 10) + 'px';
|
||||||
}
|
}
|
||||||
|
|
||||||
showAtNode(node) {
|
showAtNode(node) {
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop
|
||||||
const bbox = node.getBoundingClientRect();
|
const bbox = node.getBoundingClientRect();
|
||||||
this.show([bbox.right, bbox.bottom]);
|
this.show([node.offsetLeft + bbox.width, node.offsetTop + bbox.height]);
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ ${katexCSSTag}
|
|||||||
|
|
||||||
:host {
|
:host {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
contain: content;
|
contain: style;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host([block]) {
|
:host([block]) {
|
||||||
@@ -73,8 +73,7 @@ export class DMath extends Mutating(T(HTMLElement)) {
|
|||||||
}
|
}
|
||||||
// transform inline delimited math to d-math tags
|
// transform inline delimited math to d-math tags
|
||||||
if (DMath.katexOptions.delimiters) {
|
if (DMath.katexOptions.delimiters) {
|
||||||
const article = document.querySelector('d-article');
|
renderMathInElement(document.body, DMath.katexOptions);
|
||||||
renderMathInElement(article, DMath.katexOptions);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+62
-52
@@ -12,47 +12,46 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { FrontMatter, mergeFromYMLFrontmatter } from './front-matter';
|
import { FrontMatter, mergeFromYMLFrontmatter } from "./front-matter";
|
||||||
import { DMath } from './components/d-math';
|
import { DMath } from "./components/d-math";
|
||||||
import { collect_citations } from './helpers/citation.js';
|
import { collect_citations } from "./helpers/citation.js";
|
||||||
import { parseFrontmatter } from './components/d-front-matter';
|
import { domContentLoaded } from "./helpers/domContentLoaded.js";
|
||||||
import optionalComponents from './transforms/optional-components';
|
import { parseFrontmatter } from "./components/d-front-matter";
|
||||||
|
import optionalComponents from "./transforms/optional-components";
|
||||||
|
|
||||||
const frontMatter = new FrontMatter();
|
const frontMatter = new FrontMatter();
|
||||||
|
|
||||||
function domContentLoaded() {
|
|
||||||
return ['interactive', 'complete'].indexOf(document.readyState) !== -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Controller = {
|
export const Controller = {
|
||||||
|
|
||||||
frontMatter: frontMatter,
|
frontMatter: frontMatter,
|
||||||
waitingOn: {
|
waitingOn: {
|
||||||
bibliography: [],
|
bibliography: [],
|
||||||
citations: [],
|
citations: []
|
||||||
},
|
},
|
||||||
listeners: {
|
listeners: {
|
||||||
|
|
||||||
onCiteKeyCreated(event) {
|
onCiteKeyCreated(event) {
|
||||||
const [citeTag, keys] = event.detail;
|
const [citeTag, keys] = event.detail;
|
||||||
|
|
||||||
// ensure we have citations
|
// ensure we have citations
|
||||||
if (!frontMatter.citationsCollected) {
|
if (!frontMatter.citationsCollected) {
|
||||||
// console.debug('onCiteKeyCreated, but unresolved dependency ("citations"). Enqueing.');
|
// console.debug('onCiteKeyCreated, but unresolved dependency ("citations"). Enqueing.');
|
||||||
Controller.waitingOn.citations.push(() => Controller.listeners.onCiteKeyCreated(event));
|
Controller.waitingOn.citations.push(() =>
|
||||||
|
Controller.listeners.onCiteKeyCreated(event)
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure we have a loaded bibliography
|
// ensure we have a loaded bibliography
|
||||||
if (!frontMatter.bibliographyParsed) {
|
if (!frontMatter.bibliographyParsed) {
|
||||||
// console.debug('onCiteKeyCreated, but unresolved dependency ("bibliography"). Enqueing.');
|
// console.debug('onCiteKeyCreated, but unresolved dependency ("bibliography"). Enqueing.');
|
||||||
Controller.waitingOn.bibliography.push(() => Controller.listeners.onCiteKeyCreated(event));
|
Controller.waitingOn.bibliography.push(() =>
|
||||||
|
Controller.listeners.onCiteKeyCreated(event)
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const numbers = keys.map( key => frontMatter.citations.indexOf(key) );
|
const numbers = keys.map(key => frontMatter.citations.indexOf(key));
|
||||||
citeTag.numbers = numbers;
|
citeTag.numbers = numbers;
|
||||||
const entries = keys.map( key => frontMatter.bibliography.get(key) );
|
const entries = keys.map(key => frontMatter.bibliography.get(key));
|
||||||
citeTag.entries = entries;
|
citeTag.entries = entries;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -67,21 +66,23 @@ export const Controller = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update bibliography
|
// update bibliography
|
||||||
const citationListTag = document.querySelector('d-citation-list');
|
const citationListTag = document.querySelector("d-citation-list");
|
||||||
const bibliographyEntries = new Map(frontMatter.citations.map( citationKey => {
|
const bibliographyEntries = new Map(
|
||||||
return [citationKey, frontMatter.bibliography.get(citationKey)];
|
frontMatter.citations.map(citationKey => {
|
||||||
}));
|
return [citationKey, frontMatter.bibliography.get(citationKey)];
|
||||||
|
})
|
||||||
|
);
|
||||||
citationListTag.citations = bibliographyEntries;
|
citationListTag.citations = bibliographyEntries;
|
||||||
|
|
||||||
const citeTags = document.querySelectorAll('d-cite');
|
const citeTags = document.querySelectorAll("d-cite");
|
||||||
for (const citeTag of citeTags) {
|
for (const citeTag of citeTags) {
|
||||||
|
console.log(citeTag);
|
||||||
const keys = citeTag.keys;
|
const keys = citeTag.keys;
|
||||||
const numbers = keys.map( key => frontMatter.citations.indexOf(key) );
|
const numbers = keys.map(key => frontMatter.citations.indexOf(key));
|
||||||
citeTag.numbers = numbers;
|
citeTag.numbers = numbers;
|
||||||
const entries = keys.map( key => frontMatter.bibliography.get(key) );
|
const entries = keys.map(key => frontMatter.bibliography.get(key));
|
||||||
citeTag.entries = entries;
|
citeTag.entries = entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onCiteKeyRemoved(event) {
|
onCiteKeyRemoved(event) {
|
||||||
@@ -89,7 +90,7 @@ export const Controller = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onBibliographyChanged(event) {
|
onBibliographyChanged(event) {
|
||||||
const citationListTag = document.querySelector('d-citation-list');
|
const citationListTag = document.querySelector("d-citation-list");
|
||||||
|
|
||||||
const bibliography = event.detail;
|
const bibliography = event.detail;
|
||||||
|
|
||||||
@@ -101,19 +102,23 @@ export const Controller = {
|
|||||||
|
|
||||||
// ensure we have citations
|
// ensure we have citations
|
||||||
if (!frontMatter.citationsCollected) {
|
if (!frontMatter.citationsCollected) {
|
||||||
Controller.waitingOn.citations.push( function() {
|
Controller.waitingOn.citations.push(function() {
|
||||||
Controller.listeners.onBibliographyChanged({target: event.target, detail: event.detail});
|
Controller.listeners.onBibliographyChanged({
|
||||||
|
target: event.target,
|
||||||
|
detail: event.detail
|
||||||
|
});
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (citationListTag.hasAttribute("distill-prerendered")) {
|
||||||
if (citationListTag.hasAttribute('distill-prerendered')) {
|
console.debug("Citation list was prerendered; not updating it.");
|
||||||
console.info('Citation list was prerendered; not updating it.');
|
|
||||||
} else {
|
} else {
|
||||||
const entries = new Map(frontMatter.citations.map( citationKey => {
|
const entries = new Map(
|
||||||
return [citationKey, frontMatter.bibliography.get(citationKey)];
|
frontMatter.citations.map(citationKey => {
|
||||||
}));
|
return [citationKey, frontMatter.bibliography.get(citationKey)];
|
||||||
|
})
|
||||||
|
);
|
||||||
citationListTag.citations = entries;
|
citationListTag.citations = entries;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -121,9 +126,9 @@ export const Controller = {
|
|||||||
onFootnoteChanged() {
|
onFootnoteChanged() {
|
||||||
// const footnote = event.detail;
|
// const footnote = event.detail;
|
||||||
//TODO: optimize to only update current footnote
|
//TODO: optimize to only update current footnote
|
||||||
const footnotesList = document.querySelector('d-footnote-list');
|
const footnotesList = document.querySelector("d-footnote-list");
|
||||||
if (footnotesList) {
|
if (footnotesList) {
|
||||||
const footnotes = document.querySelectorAll('d-footnote');
|
const footnotes = document.querySelectorAll("d-footnote");
|
||||||
footnotesList.footnotes = footnotes;
|
footnotesList.footnotes = footnotes;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -132,25 +137,25 @@ export const Controller = {
|
|||||||
const data = event.detail;
|
const data = event.detail;
|
||||||
mergeFromYMLFrontmatter(frontMatter, data);
|
mergeFromYMLFrontmatter(frontMatter, data);
|
||||||
|
|
||||||
const interstitial = document.querySelector('d-interstitial');
|
const interstitial = document.querySelector("d-interstitial");
|
||||||
if (interstitial) {
|
if (interstitial) {
|
||||||
if (typeof frontMatter.password !== 'undefined') {
|
if (typeof frontMatter.password !== "undefined") {
|
||||||
interstitial.password = frontMatter.password;
|
interstitial.password = frontMatter.password;
|
||||||
} else {
|
} else {
|
||||||
interstitial.parentElement.removeChild(interstitial);
|
interstitial.parentElement.removeChild(interstitial);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const prerendered = document.body.hasAttribute('distill-prerendered');
|
const prerendered = document.body.hasAttribute("distill-prerendered");
|
||||||
if (!prerendered && domContentLoaded()) {
|
if (!prerendered && domContentLoaded()) {
|
||||||
optionalComponents(document, frontMatter);
|
optionalComponents(document, frontMatter);
|
||||||
|
|
||||||
const appendix = document.querySelector('distill-appendix');
|
const appendix = document.querySelector("distill-appendix");
|
||||||
if (appendix) {
|
if (appendix) {
|
||||||
appendix.frontMatter = frontMatter;
|
appendix.frontMatter = frontMatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
const byline = document.querySelector('d-byline');
|
const byline = document.querySelector("d-byline");
|
||||||
if (byline) {
|
if (byline) {
|
||||||
byline.frontMatter = frontMatter;
|
byline.frontMatter = frontMatter;
|
||||||
}
|
}
|
||||||
@@ -159,24 +164,31 @@ export const Controller = {
|
|||||||
DMath.katexOptions = data.katex;
|
DMath.katexOptions = data.katex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
DOMContentLoaded() {
|
DOMContentLoaded() {
|
||||||
if (Controller.loaded) {
|
if (Controller.loaded) {
|
||||||
console.warn('Controller received DOMContentLoaded but was already loaded!');
|
console.warn(
|
||||||
|
"Controller received DOMContentLoaded but was already loaded!"
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
} else if (!domContentLoaded()) {
|
} else if (!domContentLoaded()) {
|
||||||
console.warn('Controller received DOMContentLoaded before appropriate document.readyState!');
|
console.warn(
|
||||||
|
"Controller received DOMContentLoaded at document.readyState: " +
|
||||||
|
document.readyState +
|
||||||
|
"!"
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
Controller.loaded = true;
|
Controller.loaded = true;
|
||||||
console.log('Runlevel 4: Controller running DOMContentLoaded');
|
console.debug("Runlevel 4: Controller running DOMContentLoaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
const frontMatterTag = document.querySelector('d-front-matter');
|
const frontMatterTag = document.querySelector("d-front-matter");
|
||||||
const data = parseFrontmatter(frontMatterTag);
|
if (frontMatterTag) {
|
||||||
Controller.listeners.onFrontMatterChanged({detail: data});
|
const data = parseFrontmatter(frontMatterTag);
|
||||||
|
Controller.listeners.onFrontMatterChanged({ detail: data });
|
||||||
|
}
|
||||||
|
|
||||||
// Resolving "citations" dependency due to initial DOM load
|
// Resolving "citations" dependency due to initial DOM load
|
||||||
frontMatter.citations = collect_citations();
|
frontMatter.citations = collect_citations();
|
||||||
@@ -191,13 +203,11 @@ export const Controller = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const footnotesList = document.querySelector('d-footnote-list');
|
const footnotesList = document.querySelector("d-footnote-list");
|
||||||
if (footnotesList) {
|
if (footnotesList) {
|
||||||
const footnotes = document.querySelectorAll('d-footnote');
|
const footnotes = document.querySelectorAll("d-footnote");
|
||||||
footnotesList.footnotes = footnotes;
|
footnotesList.footnotes = footnotes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // listeners
|
||||||
}, // listeners
|
|
||||||
|
|
||||||
}; // Controller
|
}; // Controller
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import logo from '../assets/distill-logo.svg';
|
||||||
|
|
||||||
|
export const footerTemplate = `
|
||||||
|
<style>
|
||||||
|
|
||||||
|
:host {
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
font-weight: 300;
|
||||||
|
padding: 2rem 0;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-container .logo svg {
|
||||||
|
width: 24px;
|
||||||
|
position: relative;
|
||||||
|
top: 4px;
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-container .logo svg path {
|
||||||
|
fill: none;
|
||||||
|
stroke: rgba(255, 255, 255, 0.8);
|
||||||
|
stroke-width: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-container .logo {
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 200;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
text-decoration: none;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-container {
|
||||||
|
grid-column: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-container .nav {
|
||||||
|
font-size: 0.9em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-container .nav a {
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
margin-right: 6px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class='footer-container'>
|
||||||
|
|
||||||
|
<a href="/" class="logo">
|
||||||
|
${logo}
|
||||||
|
Distill
|
||||||
|
</a> is dedicated to clear explanations of machine learning
|
||||||
|
|
||||||
|
<div class="nav">
|
||||||
|
<a href="https://distill.pub/about/">About</a>
|
||||||
|
<a href="https://distill.pub/journal/">Submit</a>
|
||||||
|
<a href="https://distill.pub/prize/">Prize</a>
|
||||||
|
<a href="https://distill.pub/archive/">Archive</a>
|
||||||
|
<a href="https://distill.pub/rss.xml">RSS</a>
|
||||||
|
<a href="https://github.com/distillpub">GitHub</a>
|
||||||
|
<a href="https://twitter.com/distillpub">Twitter</a>
|
||||||
|
ISSN 2476-0757
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
`;
|
||||||
@@ -13,80 +13,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Template } from '../mixins/template';
|
import { Template } from '../mixins/template';
|
||||||
import logo from '../assets/distill-logo.svg';
|
|
||||||
|
|
||||||
const T = Template('distill-footer', `
|
import {footerTemplate} from './distill-footer-template';
|
||||||
<style>
|
|
||||||
|
|
||||||
:host {
|
const T = Template('distill-footer', footerTemplate);
|
||||||
color: rgba(255, 255, 255, 0.5);
|
|
||||||
font-weight: 300;
|
|
||||||
padding: 2rem 0;
|
|
||||||
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 {
|
|
||||||
width: 24px;
|
|
||||||
position: relative;
|
|
||||||
top: 4px;
|
|
||||||
margin-right: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo svg path {
|
|
||||||
fill: none;
|
|
||||||
stroke: rgba(255, 255, 255, 0.8);
|
|
||||||
stroke-width: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
font-size: 17px;
|
|
||||||
font-weight: 200;
|
|
||||||
color: rgba(255, 255, 255, 0.8);
|
|
||||||
text-decoration: none;
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
grid-column: text;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav {
|
|
||||||
font-size: 0.9em;
|
|
||||||
margin-top: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav a {
|
|
||||||
color: rgba(255, 255, 255, 0.8);
|
|
||||||
margin-right: 6px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class='container'>
|
|
||||||
|
|
||||||
<a href="/" class="logo">
|
|
||||||
${logo}
|
|
||||||
Distill
|
|
||||||
</a> is dedicated to clear explanations of machine learning
|
|
||||||
|
|
||||||
<div class="nav">
|
|
||||||
<a href="https://distill.pub/about/">About</a>
|
|
||||||
<a href="https://distill.pub/journal/">Submit</a>
|
|
||||||
<a href="https://distill.pub/prize/">Prize</a>
|
|
||||||
<a href="https://distill.pub/archive/">Archive</a>
|
|
||||||
<a href="https://distill.pub/rss.xml">RSS</a>
|
|
||||||
<a href="https://github.com/distillpub">GitHub</a>
|
|
||||||
<a href="https://twitter.com/distillpub">Twitter</a>
|
|
||||||
ISSN 2476-0757
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
`);
|
|
||||||
|
|
||||||
export class DistillFooter extends T(HTMLElement) {
|
export class DistillFooter extends T(HTMLElement) {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import logo from '../assets/distill-logo.svg';
|
||||||
|
|
||||||
|
export const headerTemplate = `
|
||||||
|
<style>
|
||||||
|
distill-header {
|
||||||
|
position: relative;
|
||||||
|
height: 60px;
|
||||||
|
background-color: hsl(200, 60%, 15%);
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 2;
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||||
|
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
distill-header .content {
|
||||||
|
height: 70px;
|
||||||
|
grid-column: page;
|
||||||
|
}
|
||||||
|
distill-header a {
|
||||||
|
font-size: 16px;
|
||||||
|
height: 60px;
|
||||||
|
line-height: 60px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
padding: 22px 0;
|
||||||
|
}
|
||||||
|
distill-header a:hover {
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
distill-header svg {
|
||||||
|
width: 24px;
|
||||||
|
position: relative;
|
||||||
|
top: 4px;
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
@media(min-width: 1080px) {
|
||||||
|
distill-header {
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
distill-header a {
|
||||||
|
height: 70px;
|
||||||
|
line-height: 70px;
|
||||||
|
padding: 28px 0;
|
||||||
|
}
|
||||||
|
distill-header .logo {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
distill-header svg path {
|
||||||
|
fill: none;
|
||||||
|
stroke: rgba(255, 255, 255, 0.8);
|
||||||
|
stroke-width: 3px;
|
||||||
|
}
|
||||||
|
distill-header .logo {
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 200;
|
||||||
|
}
|
||||||
|
distill-header .nav {
|
||||||
|
float: right;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
distill-header .nav a {
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: 24px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="content">
|
||||||
|
<a href="/" class="logo">
|
||||||
|
${logo}
|
||||||
|
Distill
|
||||||
|
</a>
|
||||||
|
<nav class="nav">
|
||||||
|
<a href="/about/">About</a>
|
||||||
|
<a href="/prize/">Prize</a>
|
||||||
|
<a href="/journal/">Submit</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
@@ -14,86 +14,9 @@
|
|||||||
|
|
||||||
import { Template } from '../mixins/template';
|
import { Template } from '../mixins/template';
|
||||||
|
|
||||||
import logo from '../assets/distill-logo.svg';
|
import {headerTemplate} from './distill-header-template';
|
||||||
|
|
||||||
const T = Template('distill-header', `
|
|
||||||
<style>
|
|
||||||
distill-header {
|
|
||||||
position: relative;
|
|
||||||
height: 60px;
|
|
||||||
background-color: hsl(200, 60%, 15%);
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
z-index: 2;
|
|
||||||
color: rgba(0, 0, 0, 0.8);
|
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
|
||||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
distill-header .content {
|
|
||||||
height: 70px;
|
|
||||||
grid-column: page;
|
|
||||||
}
|
|
||||||
distill-header a {
|
|
||||||
font-size: 16px;
|
|
||||||
height: 60px;
|
|
||||||
line-height: 60px;
|
|
||||||
text-decoration: none;
|
|
||||||
color: rgba(255, 255, 255, 0.8);
|
|
||||||
padding: 22px 0;
|
|
||||||
}
|
|
||||||
distill-header a:hover {
|
|
||||||
color: rgba(255, 255, 255, 1);
|
|
||||||
}
|
|
||||||
distill-header svg {
|
|
||||||
width: 24px;
|
|
||||||
position: relative;
|
|
||||||
top: 4px;
|
|
||||||
margin-right: 2px;
|
|
||||||
}
|
|
||||||
@media(min-width: 1080px) {
|
|
||||||
distill-header {
|
|
||||||
height: 70px;
|
|
||||||
}
|
|
||||||
distill-header a {
|
|
||||||
height: 70px;
|
|
||||||
line-height: 70px;
|
|
||||||
padding: 28px 0;
|
|
||||||
}
|
|
||||||
distill-header .logo {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
distill-header svg path {
|
|
||||||
fill: none;
|
|
||||||
stroke: rgba(255, 255, 255, 0.8);
|
|
||||||
stroke-width: 3px;
|
|
||||||
}
|
|
||||||
distill-header .logo {
|
|
||||||
font-size: 17px;
|
|
||||||
font-weight: 200;
|
|
||||||
}
|
|
||||||
distill-header .nav {
|
|
||||||
float: right;
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
distill-header .nav a {
|
|
||||||
font-size: 12px;
|
|
||||||
margin-left: 24px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div class="content">
|
|
||||||
<a href="/" class="logo">
|
|
||||||
${logo}
|
|
||||||
Distill
|
|
||||||
</a>
|
|
||||||
<nav class="nav">
|
|
||||||
<a href="/about/">About</a>
|
|
||||||
<a href="/prize/">Prize</a>
|
|
||||||
<a href="/journal/">Submit</a>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
`, false);
|
|
||||||
|
|
||||||
|
const T = Template('distill-header', headerTemplate, false);
|
||||||
|
|
||||||
export class DistillHeader extends T(HTMLElement) {
|
export class DistillHeader extends T(HTMLElement) {
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,13 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { footerTemplate } from '../distill-components/distill-footer-template';
|
||||||
|
|
||||||
export default function(dom) {
|
export default function(dom) {
|
||||||
const footerTag = dom.querySelector('distill-footer');
|
const footerTag = dom.querySelector('distill-footer');
|
||||||
if(!footerTag) {
|
if(!footerTag) {
|
||||||
const footer = dom.createElement('distill-footer');
|
const footer = dom.createElement('distill-footer');
|
||||||
|
footer.innerHTML = footerTemplate;
|
||||||
const body = dom.querySelector('body');
|
const body = dom.querySelector('body');
|
||||||
body.appendChild(footer);
|
body.appendChild(footer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,15 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
export default function(dom) {
|
|
||||||
|
import { headerTemplate } from '../distill-components/distill-header-template';
|
||||||
|
|
||||||
|
export default function(dom, data) {
|
||||||
const headerTag = dom.querySelector('distill-header');
|
const headerTag = dom.querySelector('distill-header');
|
||||||
if (!headerTag) {
|
if (!headerTag) {
|
||||||
const header = dom.createElement('distill-header');
|
const header = dom.createElement('distill-header');
|
||||||
|
header.innerHTML = headerTemplate;
|
||||||
|
header.setAttribute('distill-prerendered', "");
|
||||||
const body = dom.querySelector('body');
|
const body = dom.querySelector('body');
|
||||||
body.insertBefore(header, body.firstChild);
|
body.insertBefore(header, body.firstChild);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,9 @@ export function mergeFromYMLFrontmatter(target, source) {
|
|||||||
target.authors = source.authors.map( (authorObject) => new Author(authorObject));
|
target.authors = source.authors.map( (authorObject) => new Author(authorObject));
|
||||||
target.katex = source.katex;
|
target.katex = source.katex;
|
||||||
target.password = source.password;
|
target.password = source.password;
|
||||||
|
if (source.doi) {
|
||||||
|
target.doi = source.doi;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FrontMatter {
|
export class FrontMatter {
|
||||||
@@ -160,6 +163,7 @@ export class FrontMatter {
|
|||||||
// githubCompareUpdatesUrl: 'https://github.com/distillpub/post--augmented-rnns/compare/1596e094d8943d2dc0ea445d92071129c6419c59...3bd9209e0c24d020f87cf6152dcecc6017cbc193',
|
// githubCompareUpdatesUrl: 'https://github.com/distillpub/post--augmented-rnns/compare/1596e094d8943d2dc0ea445d92071129c6419c59...3bd9209e0c24d020f87cf6152dcecc6017cbc193',
|
||||||
// updatedDate: 2017-03-21T07:13:16.000Z,
|
// updatedDate: 2017-03-21T07:13:16.000Z,
|
||||||
// doi: '10.23915/distill.00001',
|
// doi: '10.23915/distill.00001',
|
||||||
|
this.doi = undefined;
|
||||||
this.publishedDate = undefined;
|
this.publishedDate = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,6 +322,7 @@ export class FrontMatter {
|
|||||||
Object.assign(target, this);
|
Object.assign(target, this);
|
||||||
target.bibliography = objectFromMap(this.bibliographyEntries);
|
target.bibliography = objectFromMap(this.bibliographyEntries);
|
||||||
target.url = this.url;
|
target.url = this.url;
|
||||||
|
target.doi = this.doi;
|
||||||
target.githubUrl = this.githubUrl;
|
target.githubUrl = this.githubUrl;
|
||||||
target.previewURL = this.previewURL;
|
target.previewURL = this.previewURL;
|
||||||
if (this.publishedDate) {
|
if (this.publishedDate) {
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ function normalizeTag(string) {
|
|||||||
return string
|
return string
|
||||||
.replace(/[\t\n ]+/g, ' ')
|
.replace(/[\t\n ]+/g, ' ')
|
||||||
.replace(/{\\["^`.'acu~Hvs]( )?([a-zA-Z])}/g, (full, x, char) => char)
|
.replace(/{\\["^`.'acu~Hvs]( )?([a-zA-Z])}/g, (full, x, char) => char)
|
||||||
.replace(/{\\([a-zA-Z])}/g, (full, char) => char);
|
.replace(/{\\([a-zA-Z])}/g, (full, char) => char)
|
||||||
|
.replace(/[{}]/gi,''); // Replace curly braces forcing plaintext in latex.
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseBibtex(bibtex) {
|
export function parseBibtex(bibtex) {
|
||||||
|
|||||||
+106
-88
@@ -12,11 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
export function collect_citations(dom=document) {
|
export function collect_citations(dom = document) {
|
||||||
const citations = new Set();
|
const citations = new Set();
|
||||||
const citeTags = dom.querySelectorAll('d-cite');
|
const citeTags = dom.querySelectorAll("d-cite");
|
||||||
for (const tag of citeTags) {
|
for (const tag of citeTags) {
|
||||||
const keys = tag.getAttribute('key').split(',');
|
const keyString = tag.getAttribute("key") || tag.getAttribute("bibtex-key");
|
||||||
|
const keys = keyString.split(",").map(k => k.trim());
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
citations.add(key);
|
citations.add(key);
|
||||||
}
|
}
|
||||||
@@ -24,59 +25,74 @@ export function collect_citations(dom=document) {
|
|||||||
return [...citations];
|
return [...citations];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function inline_cite_short(keys){
|
export function inline_cite_short(keys) {
|
||||||
function cite_string(key){
|
function cite_string(key) {
|
||||||
if (key in data.bibliography){
|
if (key in data.bibliography) {
|
||||||
var n = data.citations.indexOf(key)+1;
|
var n = data.citations.indexOf(key) + 1;
|
||||||
return ''+n;
|
return "" + n;
|
||||||
} else {
|
} else {
|
||||||
return '?';
|
return "?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '['+keys.map(cite_string).join(', ')+']';
|
return "[" + keys.map(cite_string).join(", ") + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function inline_cite_long(keys){
|
export function inline_cite_long(keys) {
|
||||||
function cite_string(key){
|
function cite_string(key) {
|
||||||
if (key in data.bibliography){
|
if (key in data.bibliography) {
|
||||||
var ent = data.bibliography[key];
|
var ent = data.bibliography[key];
|
||||||
var names = ent.author.split(' and ');
|
var names = ent.author.split(" and ");
|
||||||
names = names.map(name => name.split(',')[0].trim());
|
names = names.map(name => name.split(",")[0].trim());
|
||||||
var year = ent.year;
|
var year = ent.year;
|
||||||
if (names.length == 1) return names[0] + ', ' + 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] + " & " + names[1] + ", " + year;
|
||||||
if (names.length > 2) return names[0] + ', et al., ' + year;
|
if (names.length > 2) return names[0] + ", et al., " + year;
|
||||||
} else {
|
} else {
|
||||||
return '?';
|
return "?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return keys.map(cite_string).join(', ');
|
return keys.map(cite_string).join(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
function author_string(ent, template, sep, finalSep){
|
function author_string(ent, template, sep, finalSep) {
|
||||||
if (ent.author == null) { return ''; }
|
if (ent.author == null) {
|
||||||
var names = ent.author.split(' and ');
|
return "";
|
||||||
|
}
|
||||||
|
var names = ent.author.split(" and ");
|
||||||
let name_strings = names.map(name => {
|
let name_strings = names.map(name => {
|
||||||
name = name.trim();
|
name = name.trim();
|
||||||
if (name.indexOf(',') != -1){
|
if (name.indexOf(",") != -1) {
|
||||||
var last = name.split(',')[0].trim();
|
var last = name.split(",")[0].trim();
|
||||||
var firsts = name.split(',')[1];
|
var firsts = name.split(",")[1];
|
||||||
|
} else if (name.indexOf(" ") != -1) {
|
||||||
|
var last = name
|
||||||
|
.split(" ")
|
||||||
|
.slice(-1)[0]
|
||||||
|
.trim();
|
||||||
|
var firsts = name
|
||||||
|
.split(" ")
|
||||||
|
.slice(0, -1)
|
||||||
|
.join(" ");
|
||||||
} else {
|
} else {
|
||||||
var last = name.split(' ').slice(-1)[0].trim();
|
var last = name.trim();
|
||||||
var firsts = name.split(' ').slice(0,-1).join(' ');
|
|
||||||
}
|
}
|
||||||
var initials = '';
|
var initials = "";
|
||||||
if (firsts != undefined) {
|
if (firsts != undefined) {
|
||||||
initials = firsts.trim().split(' ').map(s => s.trim()[0]);
|
initials = firsts
|
||||||
initials = initials.join('.')+'.';
|
.trim()
|
||||||
|
.split(" ")
|
||||||
|
.map(s => s.trim()[0]);
|
||||||
|
initials = initials.join(".") + ".";
|
||||||
}
|
}
|
||||||
return template.replace('${F}', firsts)
|
return template
|
||||||
.replace('${L}', last)
|
.replace("${F}", firsts)
|
||||||
.replace('${I}', initials);
|
.replace("${L}", last)
|
||||||
|
.replace("${I}", initials)
|
||||||
|
.trim(); // in case one of first or last was empty
|
||||||
});
|
});
|
||||||
if (names.length > 1) {
|
if (names.length > 1) {
|
||||||
var str = name_strings.slice(0, names.length-1).join(sep);
|
var str = name_strings.slice(0, names.length - 1).join(sep);
|
||||||
str += (finalSep || sep) + name_strings[names.length-1];
|
str += (finalSep || sep) + name_strings[names.length - 1];
|
||||||
return str;
|
return str;
|
||||||
} else {
|
} else {
|
||||||
return name_strings[0];
|
return name_strings[0];
|
||||||
@@ -84,69 +100,71 @@ function author_string(ent, template, sep, finalSep){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function venue_string(ent) {
|
function venue_string(ent) {
|
||||||
var cite = (ent.journal || ent.booktitle || '');
|
var cite = ent.journal || ent.booktitle || "";
|
||||||
if ('volume' in ent){
|
if ("volume" in ent) {
|
||||||
var issue = ent.issue || ent.number;
|
var issue = ent.issue || ent.number;
|
||||||
issue = (issue != undefined)? '('+issue+')' : '';
|
issue = issue != undefined ? "(" + issue + ")" : "";
|
||||||
cite += ', Vol ' + ent.volume + issue;
|
cite += ", Vol " + ent.volume + issue;
|
||||||
}
|
}
|
||||||
if ('pages' in ent){
|
if ("pages" in ent) {
|
||||||
cite += ', pp. ' + ent.pages;
|
cite += ", pp. " + ent.pages;
|
||||||
}
|
}
|
||||||
if (cite != '') cite += '. ';
|
if (cite != "") cite += ". ";
|
||||||
if ('publisher' in ent){
|
if ("publisher" in ent) {
|
||||||
cite += ent.publisher;
|
cite += ent.publisher;
|
||||||
if (cite[cite.length-1] != '.') cite += '.';
|
if (cite[cite.length - 1] != ".") cite += ".";
|
||||||
}
|
}
|
||||||
return cite;
|
return cite;
|
||||||
}
|
}
|
||||||
|
|
||||||
function link_string(ent){
|
function link_string(ent) {
|
||||||
if ('url' in ent){
|
if ("url" in ent) {
|
||||||
var url = ent.url;
|
var url = ent.url;
|
||||||
var arxiv_match = (/arxiv\.org\/abs\/([0-9\.]*)/).exec(url);
|
var arxiv_match = /arxiv\.org\/abs\/([0-9\.]*)/.exec(url);
|
||||||
if (arxiv_match != null){
|
if (arxiv_match != null) {
|
||||||
url = `http://arxiv.org/pdf/${arxiv_match[1]}.pdf`;
|
url = `http://arxiv.org/pdf/${arxiv_match[1]}.pdf`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.slice(-4) == '.pdf'){
|
if (url.slice(-4) == ".pdf") {
|
||||||
var label = 'PDF';
|
var label = "PDF";
|
||||||
} else if (url.slice(-5) == '.html') {
|
} else if (url.slice(-5) == ".html") {
|
||||||
var label = 'HTML';
|
var label = "HTML";
|
||||||
}
|
}
|
||||||
return `  <a href="${url}">[${label||'link'}]</a>`;
|
return `  <a href="${url}">[${label || "link"}]</a>`;
|
||||||
}/* else if ("doi" in ent){
|
} /* else if ("doi" in ent){
|
||||||
return `  <a href="https://doi.org/${ent.doi}" >[DOI]</a>`;
|
return `  <a href="https://doi.org/${ent.doi}" >[DOI]</a>`;
|
||||||
}*/ else {
|
}*/ else {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function doi_string(ent, new_line){
|
function doi_string(ent, new_line) {
|
||||||
if ('doi' in ent) {
|
if ("doi" in ent) {
|
||||||
return `${new_line?'<br>':''} <a href="https://doi.org/${ent.doi}" style="text-decoration:inherit;">DOI: ${ent.doi}</a>`;
|
return `${new_line ? "<br>" : ""} <a href="https://doi.org/${
|
||||||
|
ent.doi
|
||||||
|
}" style="text-decoration:inherit;">DOI: ${ent.doi}</a>`;
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function title_string(ent) {
|
function title_string(ent) {
|
||||||
return '<span class="title">' + ent.title + '</span> ';
|
return '<span class="title">' + ent.title + "</span> ";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bibliography_cite(ent, fancy){
|
export function bibliography_cite(ent, fancy) {
|
||||||
if (ent){
|
if (ent) {
|
||||||
var cite = title_string(ent);
|
var cite = title_string(ent);
|
||||||
cite += link_string(ent) + '<br>';
|
cite += link_string(ent) + "<br>";
|
||||||
if (ent.author) {
|
if (ent.author) {
|
||||||
cite += author_string(ent, '${L}, ${I}', ', ', ' and ');
|
cite += author_string(ent, "${L}, ${I}", ", ", " and ");
|
||||||
if (ent.year || ent.date) {
|
if (ent.year || ent.date) {
|
||||||
cite += ', ';
|
cite += ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ent.year || ent.date) {
|
if (ent.year || ent.date) {
|
||||||
cite += (ent.year || ent.date) + '. ';
|
cite += (ent.year || ent.date) + ". ";
|
||||||
} else {
|
} else {
|
||||||
cite += '. ';
|
cite += ". ";
|
||||||
}
|
}
|
||||||
cite += venue_string(ent);
|
cite += venue_string(ent);
|
||||||
cite += doi_string(ent);
|
cite += doi_string(ent);
|
||||||
@@ -163,39 +181,39 @@ export function bibliography_cite(ent, fancy){
|
|||||||
cite += link_string(ent);
|
cite += link_string(ent);
|
||||||
return cite*/
|
return cite*/
|
||||||
} else {
|
} else {
|
||||||
return '?';
|
return "?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hover_cite(ent){
|
export function hover_cite(ent) {
|
||||||
if (ent){
|
if (ent) {
|
||||||
var cite = '';
|
var cite = "";
|
||||||
cite += '<strong>' + ent.title + '</strong>';
|
cite += "<strong>" + ent.title + "</strong>";
|
||||||
cite += link_string(ent);
|
cite += link_string(ent);
|
||||||
cite += '<br>';
|
cite += "<br>";
|
||||||
|
|
||||||
var a_str = author_string(ent, '${I} ${L}', ', ') + '.';
|
var a_str = author_string(ent, "${I} ${L}", ", ") + ".";
|
||||||
var v_str = venue_string(ent).trim() + ' ' + ent.year + '. ' + doi_string(ent, true);
|
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)) {
|
if ((a_str + v_str).length < Math.min(40, ent.title.length)) {
|
||||||
cite += a_str + ' ' + v_str;
|
cite += a_str + " " + v_str;
|
||||||
} else {
|
} else {
|
||||||
cite += a_str + '<br>' + v_str;
|
cite += a_str + "<br>" + v_str;
|
||||||
}
|
}
|
||||||
return cite;
|
return cite;
|
||||||
} else {
|
} else {
|
||||||
return '?';
|
return "?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//https://scholar.google.com/scholar?q=allintitle%3ADocument+author%3Aolah
|
//https://scholar.google.com/scholar?q=allintitle%3ADocument+author%3Aolah
|
||||||
function get_GS_URL(ent){
|
function get_GS_URL(ent) {
|
||||||
if (ent){
|
if (ent) {
|
||||||
var names = ent.author.split(' and ');
|
var names = ent.author.split(" and ");
|
||||||
names = names.map(name => name.split(',')[0].trim());
|
names = names.map(name => name.split(",")[0].trim());
|
||||||
var title = ent.title.split(' ');//.replace(/[,:]/, "")
|
var title = ent.title.split(" "); //.replace(/[,:]/, "")
|
||||||
var url = 'http://search.labs.crossref.org/dois?';//""https://scholar.google.com/scholar?"
|
var url = "http://search.labs.crossref.org/dois?"; //""https://scholar.google.com/scholar?"
|
||||||
url += uris({q: names.join(' ') + ' ' + title.join(' ')});
|
url += uris({ q: names.join(" ") + " " + title.join(" ") });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export function domContentLoaded() {
|
||||||
|
return ['interactive', 'complete'].indexOf(document.readyState) !== -1;
|
||||||
|
}
|
||||||
@@ -28,14 +28,16 @@ const findEndOfMath = function(delimiter, text, startIndex) {
|
|||||||
while (index < text.length) {
|
while (index < text.length) {
|
||||||
const character = text[index];
|
const character = text[index];
|
||||||
|
|
||||||
if (braceLevel <= 0 &&
|
if (
|
||||||
text.slice(index, index + delimLength) === delimiter) {
|
braceLevel <= 0 &&
|
||||||
|
text.slice(index, index + delimLength) === delimiter
|
||||||
|
) {
|
||||||
return index;
|
return index;
|
||||||
} else if (character === '\\') {
|
} else if (character === "\\") {
|
||||||
index++;
|
index++;
|
||||||
} else if (character === '{') {
|
} else if (character === "{") {
|
||||||
braceLevel++;
|
braceLevel++;
|
||||||
} else if (character === '}') {
|
} else if (character === "}") {
|
||||||
braceLevel--;
|
braceLevel--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +51,7 @@ const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
|
|||||||
const finalData = [];
|
const finalData = [];
|
||||||
|
|
||||||
for (let i = 0; i < startData.length; i++) {
|
for (let i = 0; i < startData.length; i++) {
|
||||||
if (startData[i].type === 'text') {
|
if (startData[i].type === "text") {
|
||||||
const text = startData[i].data;
|
const text = startData[i].data;
|
||||||
|
|
||||||
let lookingForLeft = true;
|
let lookingForLeft = true;
|
||||||
@@ -60,13 +62,14 @@ const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
|
|||||||
if (nextIndex !== -1) {
|
if (nextIndex !== -1) {
|
||||||
currIndex = nextIndex;
|
currIndex = nextIndex;
|
||||||
finalData.push({
|
finalData.push({
|
||||||
type: 'text',
|
type: "text",
|
||||||
data: text.slice(0, currIndex),
|
data: text.slice(0, currIndex)
|
||||||
});
|
});
|
||||||
lookingForLeft = false;
|
lookingForLeft = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) { // eslint-disable-line no-constant-condition
|
while (true) {
|
||||||
|
// eslint-disable-line no-constant-condition
|
||||||
if (lookingForLeft) {
|
if (lookingForLeft) {
|
||||||
nextIndex = text.indexOf(leftDelim, currIndex);
|
nextIndex = text.indexOf(leftDelim, currIndex);
|
||||||
if (nextIndex === -1) {
|
if (nextIndex === -1) {
|
||||||
@@ -74,8 +77,8 @@ const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
finalData.push({
|
finalData.push({
|
||||||
type: 'text',
|
type: "text",
|
||||||
data: text.slice(currIndex, nextIndex),
|
data: text.slice(currIndex, nextIndex)
|
||||||
});
|
});
|
||||||
|
|
||||||
currIndex = nextIndex;
|
currIndex = nextIndex;
|
||||||
@@ -83,20 +86,17 @@ const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
|
|||||||
nextIndex = findEndOfMath(
|
nextIndex = findEndOfMath(
|
||||||
rightDelim,
|
rightDelim,
|
||||||
text,
|
text,
|
||||||
currIndex + leftDelim.length);
|
currIndex + leftDelim.length
|
||||||
|
);
|
||||||
if (nextIndex === -1) {
|
if (nextIndex === -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
finalData.push({
|
finalData.push({
|
||||||
type: 'math',
|
type: "math",
|
||||||
data: text.slice(
|
data: text.slice(currIndex + leftDelim.length, nextIndex),
|
||||||
currIndex + leftDelim.length,
|
rawData: text.slice(currIndex, nextIndex + rightDelim.length),
|
||||||
nextIndex),
|
display: display
|
||||||
rawData: text.slice(
|
|
||||||
currIndex,
|
|
||||||
nextIndex + rightDelim.length),
|
|
||||||
display: display,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
currIndex = nextIndex + rightDelim.length;
|
currIndex = nextIndex + rightDelim.length;
|
||||||
@@ -106,8 +106,8 @@ const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
finalData.push({
|
finalData.push({
|
||||||
type: 'text',
|
type: "text",
|
||||||
data: text.slice(currIndex),
|
data: text.slice(currIndex)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
finalData.push(startData[i]);
|
finalData.push(startData[i]);
|
||||||
@@ -117,14 +117,16 @@ const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
|
|||||||
return finalData;
|
return finalData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const splitWithDelimiters = function(text, delimiters) {
|
const splitWithDelimiters = function(text, delimiters) {
|
||||||
let data = [{type: 'text', data: text}];
|
let data = [{ type: "text", data: text }];
|
||||||
for (let i = 0; i < delimiters.length; i++) {
|
for (let i = 0; i < delimiters.length; i++) {
|
||||||
const delimiter = delimiters[i];
|
const delimiter = delimiters[i];
|
||||||
data = splitAtDelimiters(
|
data = splitAtDelimiters(
|
||||||
data, delimiter.left, delimiter.right,
|
data,
|
||||||
delimiter.display || false);
|
delimiter.left,
|
||||||
|
delimiter.right,
|
||||||
|
delimiter.display || false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
@@ -137,10 +139,10 @@ const renderMathInText = function(text, optionsCopy) {
|
|||||||
const fragment = document.createDocumentFragment();
|
const fragment = document.createDocumentFragment();
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
if (data[i].type === 'text') {
|
if (data[i].type === "text") {
|
||||||
fragment.appendChild(document.createTextNode(data[i].data));
|
fragment.appendChild(document.createTextNode(data[i].data));
|
||||||
} else {
|
} else {
|
||||||
const tag = document.createElement('d-math');
|
const tag = document.createElement("d-math");
|
||||||
const math = data[i].data;
|
const math = data[i].data;
|
||||||
// Override any display mode defined in the settings with that
|
// Override any display mode defined in the settings with that
|
||||||
// defined by the text itself
|
// defined by the text itself
|
||||||
@@ -148,15 +150,14 @@ const renderMathInText = function(text, optionsCopy) {
|
|||||||
try {
|
try {
|
||||||
tag.textContent = math;
|
tag.textContent = math;
|
||||||
if (optionsCopy.displayMode) {
|
if (optionsCopy.displayMode) {
|
||||||
tag.setAttribute('block', '');
|
tag.setAttribute("block", "");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!(e instanceof katex.ParseError)) {
|
if (!(e instanceof katex.ParseError)) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
optionsCopy.errorCallback(
|
optionsCopy.errorCallback(
|
||||||
'KaTeX auto-render: Failed to parse `' + data[i].data +
|
"KaTeX auto-render: Failed to parse `" + data[i].data + "` with ",
|
||||||
'` with ',
|
|
||||||
e
|
e
|
||||||
);
|
);
|
||||||
fragment.appendChild(document.createTextNode(data[i].rawData));
|
fragment.appendChild(document.createTextNode(data[i].rawData));
|
||||||
@@ -174,13 +175,17 @@ const renderElem = function(elem, optionsCopy) {
|
|||||||
const childNode = elem.childNodes[i];
|
const childNode = elem.childNodes[i];
|
||||||
if (childNode.nodeType === 3) {
|
if (childNode.nodeType === 3) {
|
||||||
// Text node
|
// Text node
|
||||||
const frag = renderMathInText(childNode.textContent, optionsCopy);
|
const text = childNode.textContent;
|
||||||
i += frag.childNodes.length - 1;
|
if (optionsCopy.mightHaveMath(text)) {
|
||||||
elem.replaceChild(frag, childNode);
|
const frag = renderMathInText(text, optionsCopy);
|
||||||
|
i += frag.childNodes.length - 1;
|
||||||
|
elem.replaceChild(frag, childNode);
|
||||||
|
}
|
||||||
} else if (childNode.nodeType === 1) {
|
} else if (childNode.nodeType === 1) {
|
||||||
// Element node
|
// Element node
|
||||||
const shouldRender = optionsCopy.ignoredTags.indexOf(
|
const shouldRender =
|
||||||
childNode.nodeName.toLowerCase()) === -1;
|
optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) ===
|
||||||
|
-1;
|
||||||
|
|
||||||
if (shouldRender) {
|
if (shouldRender) {
|
||||||
renderElem(childNode, optionsCopy);
|
renderElem(childNode, optionsCopy);
|
||||||
@@ -192,27 +197,40 @@ const renderElem = function(elem, optionsCopy) {
|
|||||||
|
|
||||||
const defaultAutoRenderOptions = {
|
const defaultAutoRenderOptions = {
|
||||||
delimiters: [
|
delimiters: [
|
||||||
{left: '$$', right: '$$', display: true},
|
{ left: "$$", right: "$$", display: true },
|
||||||
{left: '\\[', right: '\\]', display: true},
|
{ left: "\\[", right: "\\]", display: true },
|
||||||
{left: '\\(', right: '\\)', display: false},
|
{ left: "\\(", right: "\\)", display: false }
|
||||||
// LaTeX uses this, but it ruins the display of normal `$` in text:
|
// LaTeX uses this, but it ruins the display of normal `$` in text:
|
||||||
// {left: '$', right: '$', display: false},
|
// {left: '$', right: '$', display: false},
|
||||||
],
|
],
|
||||||
|
|
||||||
ignoredTags: [
|
ignoredTags: [
|
||||||
'script', 'noscript', 'style', 'textarea', 'pre', 'code', 'svg',
|
"script",
|
||||||
|
"noscript",
|
||||||
|
"style",
|
||||||
|
"textarea",
|
||||||
|
"pre",
|
||||||
|
"code",
|
||||||
|
"svg"
|
||||||
],
|
],
|
||||||
|
|
||||||
errorCallback: function(msg, err) {
|
errorCallback: function(msg, err) {
|
||||||
console.error(msg, err);
|
console.error(msg, err);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const renderMathInElement = function(elem, options) {
|
export const renderMathInElement = function(elem, options) {
|
||||||
if (!elem) {
|
if (!elem) {
|
||||||
throw new Error('No element provided to render');
|
throw new Error("No element provided to render");
|
||||||
}
|
}
|
||||||
|
|
||||||
const optionsCopy = Object.assign({}, defaultAutoRenderOptions, options);
|
const optionsCopy = Object.assign({}, defaultAutoRenderOptions, options);
|
||||||
|
const delimiterStrings = optionsCopy.delimiters.flatMap(d => [
|
||||||
|
d.left,
|
||||||
|
d.right
|
||||||
|
]);
|
||||||
|
const mightHaveMath = text =>
|
||||||
|
delimiterStrings.some(d => text.indexOf(d) !== -1);
|
||||||
|
optionsCopy.mightHaveMath = mightHaveMath;
|
||||||
renderElem(elem, optionsCopy);
|
renderElem(elem, optionsCopy);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
export function addPolyfill(polyfill, polyfillLoadedCallback) {
|
export function addPolyfill(polyfill, polyfillLoadedCallback) {
|
||||||
console.info('Runlevel 0: Polyfill required: ' + polyfill.name);
|
console.debug('Runlevel 0: Polyfill required: ' + polyfill.name);
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
script.src = polyfill.url;
|
script.src = polyfill.url;
|
||||||
script.async = false;
|
script.async = false;
|
||||||
@@ -58,11 +58,11 @@ export class Polyfills {
|
|||||||
// Define an intermediate callback that checks if all is loaded.
|
// Define an intermediate callback that checks if all is loaded.
|
||||||
const polyfillLoaded = function(polyfill) {
|
const polyfillLoaded = function(polyfill) {
|
||||||
polyfill.loaded = true;
|
polyfill.loaded = true;
|
||||||
console.info('Runlevel 0: Polyfill has finished loading: ' + polyfill.name);
|
console.debug('Runlevel 0: Polyfill has finished loading: ' + polyfill.name);
|
||||||
// console.info(window[polyfill.name]);
|
// console.debug(window[polyfill.name]);
|
||||||
if (Polyfills.neededPolyfills.every((poly) => poly.loaded)) {
|
if (Polyfills.neededPolyfills.every((poly) => poly.loaded)) {
|
||||||
console.info('Runlevel 0: All required polyfills have finished loading.');
|
console.debug('Runlevel 0: All required polyfills have finished loading.');
|
||||||
console.info('Runlevel 0->1.');
|
console.debug('Runlevel 0->1.');
|
||||||
window.distillRunlevel = 1;
|
window.distillRunlevel = 1;
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ export const Template = (name, templateString, useShadow = true) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
|
if (this.hasAttribute('distill-prerendered')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (useShadow) {
|
if (useShadow) {
|
||||||
if ('ShadyCSS' in window) {
|
if ('ShadyCSS' in window) {
|
||||||
ShadyCSS.styleElement(this);
|
ShadyCSS.styleElement(this);
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ d-figure {
|
|||||||
/* KaTeX */
|
/* KaTeX */
|
||||||
|
|
||||||
.katex, .katex-prerendered {
|
.katex, .katex-prerendered {
|
||||||
contain: content;
|
contain: style;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
d-byline {
|
d-byline {
|
||||||
contain: content;
|
contain: style;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
|||||||
@@ -17,20 +17,20 @@ import { renderMathInElement } from '../helpers/katex-auto-render';
|
|||||||
|
|
||||||
export default function(dom, data) {
|
export default function(dom, data) {
|
||||||
let needsCSS = false;
|
let needsCSS = false;
|
||||||
const article = dom.querySelector('d-article');
|
const body = dom.querySelector('body');
|
||||||
|
|
||||||
if (!article) {
|
if (!body) {
|
||||||
console.warn("No d-article tag found!");
|
console.warn("No body tag found!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.katex && data.katex.delimiters) {
|
if (data.katex && data.katex.delimiters) {
|
||||||
global.document = dom;
|
global.document = dom;
|
||||||
renderMathInElement(article, data.katex);
|
renderMathInElement(body, data.katex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// render d-math tags
|
// render d-math tags
|
||||||
const mathTags = article.querySelectorAll('d-math');
|
const mathTags = body.querySelectorAll('d-math');
|
||||||
if (mathTags.length > 0) {
|
if (mathTags.length > 0) {
|
||||||
needsCSS = true;
|
needsCSS = true;
|
||||||
console.warn(`Prerendering ${mathTags.length} math tags...`);
|
console.warn(`Prerendering ${mathTags.length} math tags...`);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export default function(dom, data) {
|
|||||||
|
|
||||||
let title = dom.querySelector('d-title');
|
let title = dom.querySelector('d-title');
|
||||||
if (!title) {
|
if (!title) {
|
||||||
let title = dom.createElement('d-title');
|
title = dom.createElement('d-title');
|
||||||
body.insertBefore(title, byline);
|
body.insertBefore(title, byline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default function render(dom) {
|
|||||||
if (templateTag) {
|
if (templateTag) {
|
||||||
templateTag.parentNode.removeChild(templateTag);
|
templateTag.parentNode.removeChild(templateTag);
|
||||||
} else {
|
} else {
|
||||||
console.info('FYI: Did not find template tag when trying to remove it. You may not have added it. Be aware that our polyfills will add it.')
|
console.debug('FYI: Did not find template tag when trying to remove it. You may not have added it. Be aware that our polyfills will add it.')
|
||||||
}
|
}
|
||||||
|
|
||||||
// add loader
|
// add loader
|
||||||
|
|||||||
@@ -24,12 +24,17 @@ export default function(dom) {
|
|||||||
if (text && acceptNode(n)) {
|
if (text && acceptNode(n)) {
|
||||||
text = quotes(text);
|
text = quotes(text);
|
||||||
text = punctuation(text);
|
text = punctuation(text);
|
||||||
text = ligatures(text);
|
// TODO: Add back support for ligatures once their uppercased versions don't hang Chrome search anymore
|
||||||
|
// see: https://bugs.chromium.org/p/chromium/issues/detail?id=862648
|
||||||
|
// text = ligatures(text);
|
||||||
n.nodeValue = text;
|
n.nodeValue = text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2018-07-11 shancarter@ and ludwigschubert@ no longer know what this was meant to accomplish
|
||||||
|
// if it was trying to not replace text in any child nodes of those listed here,
|
||||||
|
// then it does not accomplish that.
|
||||||
function acceptNode(node) {
|
function acceptNode(node) {
|
||||||
var parent = node.parentElement;
|
var parent = node.parentElement;
|
||||||
var isMath = (parent && parent.getAttribute && parent.getAttribute('class')) ? parent.getAttribute('class').includes('katex') || parent.getAttribute('class').includes('MathJax') : false;
|
var isMath = (parent && parent.getAttribute && parent.getAttribute('class')) ? parent.getAttribute('class').includes('katex') || parent.getAttribute('class').includes('MathJax') : false;
|
||||||
|
|||||||
+157
-114
@@ -14,75 +14,88 @@
|
|||||||
|
|
||||||
/* global it, describe, before, beforeEach, after, afterEach */
|
/* global it, describe, before, beforeEach, after, afterEach */
|
||||||
|
|
||||||
const jsdom = require('jsdom');
|
const jsdom = require("jsdom");
|
||||||
const { JSDOM } = jsdom;
|
const { JSDOM } = jsdom;
|
||||||
|
|
||||||
const expect = require('chai').expect;
|
const expect = require("chai").expect;
|
||||||
const distill = require('../dist/transforms.v2.js');
|
const distill = require("../dist/transforms.v2.js");
|
||||||
|
|
||||||
// omitJSDOMErrors as JSDOM routinely can't parse modern CSS
|
// omitJSDOMErrors as JSDOM routinely can't parse modern CSS
|
||||||
const virtualConsole = new jsdom.VirtualConsole();
|
const virtualConsole = new jsdom.VirtualConsole();
|
||||||
virtualConsole.sendTo(console, { omitJSDOMErrors: true });
|
virtualConsole.sendTo(console, { omitJSDOMErrors: true });
|
||||||
const options = { runScripts: 'outside-only', QuerySelector: true, virtualConsole: virtualConsole };
|
const options = {
|
||||||
|
runScripts: "outside-only",
|
||||||
|
QuerySelector: true,
|
||||||
|
virtualConsole: virtualConsole
|
||||||
|
};
|
||||||
|
|
||||||
describe('Distill V2 (transforms)', function() {
|
describe("Distill V2 (transforms)", function() {
|
||||||
|
it("should export its expected interface", function() {
|
||||||
it('should export its expected interface', function() {
|
expect(distill.testing).to.be.an("object");
|
||||||
expect(distill.testing).to.be.an('object');
|
expect(distill.usesTemplateV2).to.be.a("function");
|
||||||
expect(distill.usesTemplateV2).to.be.a('function');
|
expect(distill.render).to.be.a("function");
|
||||||
expect(distill.render).to.be.a('function');
|
expect(distill.distillify).to.be.a("function");
|
||||||
expect(distill.distillify).to.be.a('function');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#usesTemplateV2()', function() {
|
describe("#usesTemplateV2()", function() {
|
||||||
|
it("should detect v1", function() {
|
||||||
it('should detect v1', function() {
|
const frag = JSDOM.fragment(
|
||||||
const frag = JSDOM.fragment('<script src="https://distill.pub/template.v1.js"></script>');
|
'<script src="https://distill.pub/template.v1.js"></script>'
|
||||||
|
);
|
||||||
expect(distill.usesTemplateV2(frag)).to.be.false;
|
expect(distill.usesTemplateV2(frag)).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect v2', function() {
|
it("should detect v2", function() {
|
||||||
const frag = JSDOM.fragment('<script src="https://distill.pub/template.v2.js"></script>');
|
const frag = JSDOM.fragment(
|
||||||
|
'<script src="https://distill.pub/template.v2.js"></script>'
|
||||||
|
);
|
||||||
expect(distill.usesTemplateV2(frag)).to.be.true;
|
expect(distill.usesTemplateV2(frag)).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect local scripts as well', function() {
|
it("should detect local scripts as well", function() {
|
||||||
const frag = JSDOM.fragment('<script src="/template.v2.js"></script>');
|
const frag = JSDOM.fragment('<script src="/template.v2.js"></script>');
|
||||||
expect(distill.usesTemplateV2(frag)).to.be.true;
|
expect(distill.usesTemplateV2(frag)).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error on unknown distill script', function() {
|
it("should error on unknown distill script", function() {
|
||||||
const frag = JSDOM.fragment('<script src="https://distill.pub/template.v42.js"></script>');
|
const frag = JSDOM.fragment(
|
||||||
expect(()=> distill.usesTemplateV2(frag)).to.throw('unknown');
|
'<script src="https://distill.pub/template.v42.js"></script>'
|
||||||
|
);
|
||||||
|
expect(() => distill.usesTemplateV2(frag)).to.throw("unknown");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error on no distill script', function() {
|
it("should error on no distill script", function() {
|
||||||
const frag = JSDOM.fragment('<script src="https://code.jquery.com/jquery-3.2.1.js"></script>');
|
const frag = JSDOM.fragment(
|
||||||
expect(()=> distill.usesTemplateV2(frag)).to.throw('at all');
|
'<script src="https://code.jquery.com/jquery-3.2.1.js"></script>'
|
||||||
|
);
|
||||||
|
expect(() => distill.usesTemplateV2(frag)).to.throw("at all");
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#render()', function() {
|
describe("#render()", function() {
|
||||||
|
describe("should extract metadata", function() {
|
||||||
describe('should extract metadata', function() {
|
it("should extract citations", function() {
|
||||||
|
const dom = new JSDOM(
|
||||||
it('should extract citations', function() {
|
'<d-cite key="test-citation-key">sth</d-cite>',
|
||||||
const dom = new JSDOM('<d-cite key="test-citation-key">sth</d-cite>', options);
|
options
|
||||||
|
);
|
||||||
const data = {};
|
const data = {};
|
||||||
const extractCitations = distill.testing.extractors.get('ExtractCitations');
|
const extractCitations = distill.testing.extractors.get(
|
||||||
expect(extractCitations).to.be.a('function');
|
"ExtractCitations"
|
||||||
|
);
|
||||||
|
expect(extractCitations).to.be.a("function");
|
||||||
extractCitations(dom.window.document, data);
|
extractCitations(dom.window.document, data);
|
||||||
expect(data).to.have.property('citations');
|
expect(data).to.have.property("citations");
|
||||||
const citations = data.citations;
|
const citations = data.citations;
|
||||||
expect(citations).to.be.an.instanceof(Array);
|
expect(citations).to.be.an.instanceof(Array);
|
||||||
expect(citations).to.have.lengthOf(1);
|
expect(citations).to.have.lengthOf(1);
|
||||||
const citation = citations[0];
|
const citation = citations[0];
|
||||||
expect(citation).to.equal('test-citation-key');
|
expect(citation).to.equal("test-citation-key");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extract bibliography', function() {
|
it("should extract bibliography", function() {
|
||||||
const dom = new JSDOM(`
|
const dom = new JSDOM(
|
||||||
|
`
|
||||||
<d-cite key="mercier2011humans">sth</d-cite>
|
<d-cite key="mercier2011humans">sth</d-cite>
|
||||||
<d-bibliography>
|
<d-bibliography>
|
||||||
<script type="text/bibtex">
|
<script type="text/bibtex">
|
||||||
@@ -99,44 +112,58 @@ describe('Distill V2 (transforms)', function() {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</d-bibliography>
|
</d-bibliography>
|
||||||
`, options);
|
`,
|
||||||
|
options
|
||||||
|
);
|
||||||
const data = {};
|
const data = {};
|
||||||
const extractBibliography = distill.testing.extractors.get('ExtractBibliography');
|
const extractBibliography = distill.testing.extractors.get(
|
||||||
|
"ExtractBibliography"
|
||||||
|
);
|
||||||
extractBibliography(dom.window.document, data);
|
extractBibliography(dom.window.document, data);
|
||||||
expect(data.bibliography).to.be.an.instanceof(Map);
|
expect(data.bibliography).to.be.an.instanceof(Map);
|
||||||
const entry = data.bibliography.get('mercier2011humans');
|
const entry = data.bibliography.get("mercier2011humans");
|
||||||
expect(entry).to.be.an('object');
|
expect(entry).to.be.an("object");
|
||||||
expect(entry).to.have.property('year', '2011');
|
expect(entry).to.have.property("year", "2011");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extract front-matter');
|
it("should extract front-matter");
|
||||||
|
|
||||||
}); // metadata
|
}); // metadata
|
||||||
|
|
||||||
describe('should transform the DOM', function() {
|
describe("should transform the DOM", function() {
|
||||||
|
it("should add Google scholar citation information", function() {
|
||||||
it('should add Google scholar citation information', function() {
|
const dom = new JSDOM("", options);
|
||||||
const dom = new JSDOM('', options);
|
|
||||||
const data = {
|
const data = {
|
||||||
authors: [
|
authors: [
|
||||||
{firstName: 'Frank', lastName: 'Underwood', affiliation: 'Google Brain', affiliationURL: 'https://g.co/brain'},
|
{
|
||||||
{firstName: 'Shan', lastName: 'Carter', affiliation: 'Google Brain', affiliationURL: 'https://g.co/brain'},
|
firstName: "Frank",
|
||||||
|
lastName: "Underwood",
|
||||||
|
affiliation: "Google Brain",
|
||||||
|
affiliationURL: "https://g.co/brain"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
firstName: "Shan",
|
||||||
|
lastName: "Carter",
|
||||||
|
affiliation: "Google Brain",
|
||||||
|
affiliationURL: "https://g.co/brain"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
doiSuffix: 'test-doi-suffix'
|
doiSuffix: "test-doi-suffix"
|
||||||
};
|
};
|
||||||
const firstAuthorName = data.authors[0].firstName + ' ' + data.authors[0].lastName;
|
const firstAuthorName =
|
||||||
const GSfirstAuthorName = data.authors[0].lastName + ', ' + data.authors[0].firstName;
|
data.authors[0].firstName + " " + data.authors[0].lastName;
|
||||||
|
const GSfirstAuthorName =
|
||||||
|
data.authors[0].lastName + ", " + data.authors[0].firstName;
|
||||||
|
|
||||||
const meta = distill.testing.transforms.get('Meta');
|
const meta = distill.testing.transforms.get("Meta");
|
||||||
expect(meta).to.be.a('function');
|
expect(meta).to.be.a("function");
|
||||||
|
|
||||||
meta(dom.window.document, data);
|
meta(dom.window.document, data);
|
||||||
const metaTags = dom.window.document.querySelectorAll('meta');
|
const metaTags = dom.window.document.querySelectorAll("meta");
|
||||||
expect(metaTags).to.not.be.empty;
|
expect(metaTags).to.not.be.empty;
|
||||||
|
|
||||||
// Google Scholar
|
// Google Scholar
|
||||||
const GSAuthorTags = Array.prototype.filter.call(metaTags, (tag) => {
|
const GSAuthorTags = Array.prototype.filter.call(metaTags, tag => {
|
||||||
return tag.name === 'citation_author';
|
return tag.name === "citation_author";
|
||||||
});
|
});
|
||||||
expect(GSAuthorTags).to.have.lengthOf(2);
|
expect(GSAuthorTags).to.have.lengthOf(2);
|
||||||
const GSFirstAuthorTag = GSAuthorTags[0];
|
const GSFirstAuthorTag = GSAuthorTags[0];
|
||||||
@@ -144,74 +171,89 @@ describe('Distill V2 (transforms)', function() {
|
|||||||
expect(GSFirstAuthorTag.content).to.equal(GSfirstAuthorName);
|
expect(GSFirstAuthorTag.content).to.equal(GSfirstAuthorName);
|
||||||
|
|
||||||
// Schema.org Author tags
|
// Schema.org Author tags
|
||||||
const SOAuthorTags = Array.prototype.filter.call(metaTags, (tag) => {
|
const SOAuthorTags = Array.prototype.filter.call(metaTags, tag => {
|
||||||
return tag.getAttribute('property') === 'article:author';
|
return tag.getAttribute("property") === "article:author";
|
||||||
});
|
});
|
||||||
expect(SOAuthorTags).to.have.lengthOf(2);
|
expect(SOAuthorTags).to.have.lengthOf(2);
|
||||||
const SOFirstAuthorTag = SOAuthorTags[0];
|
const SOFirstAuthorTag = SOAuthorTags[0];
|
||||||
expect(SOFirstAuthorTag.content).to.equal(firstAuthorName);
|
expect(SOFirstAuthorTag.content).to.equal(firstAuthorName);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('given already correct data, it should add Google scholar references information', function() {
|
it("given already correct data, it should add Google scholar references information", function() {
|
||||||
const dom = new JSDOM('', options);
|
const dom = new JSDOM("", options);
|
||||||
const data = {
|
const data = {
|
||||||
doiSuffix: 'test-doi-suffix',
|
doiSuffix: "test-doi-suffix",
|
||||||
citations: ['test-citation-key'],
|
citations: ["test-citation-key"],
|
||||||
bibliography: new Map([[
|
bibliography: new Map([
|
||||||
'test-citation-key', {
|
[
|
||||||
title: 'Why do humans reason? Arguments for an argumentative theory',
|
"test-citation-key",
|
||||||
author: 'Mercier, Hugo and Sperber, Dan',
|
{
|
||||||
journal: 'Behavioral and brain sciences',
|
title:
|
||||||
volume: 34,
|
"Why do humans reason? Arguments for an argumentative theory",
|
||||||
number: 2
|
author: "Mercier, Hugo and Sperber, Dan",
|
||||||
}
|
journal: "Behavioral and brain sciences",
|
||||||
]])
|
volume: 34,
|
||||||
|
number: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
])
|
||||||
};
|
};
|
||||||
const meta = distill.testing.transforms.get('Meta');
|
const meta = distill.testing.transforms.get("Meta");
|
||||||
expect(meta).to.be.a('function');
|
expect(meta).to.be.a("function");
|
||||||
meta(dom.window.document, data);
|
meta(dom.window.document, data);
|
||||||
const metaTags = [].slice.call(dom.window.document.querySelectorAll('meta[name="citation_reference"]'));
|
const metaTags = [].slice.call(
|
||||||
|
dom.window.document.querySelectorAll(
|
||||||
|
'meta[name="citation_reference"]'
|
||||||
|
)
|
||||||
|
);
|
||||||
expect(metaTags).to.not.be.empty;
|
expect(metaTags).to.not.be.empty;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('given an arxiv article, it should add a special Google scholar arxiv citation', function() {
|
it("given an arxiv article, it should add a special Google scholar arxiv citation", function() {
|
||||||
const dom = new JSDOM('', options);
|
const dom = new JSDOM("", options);
|
||||||
const data = {
|
const data = {
|
||||||
doiSuffix: 'test-doi-suffix',
|
doiSuffix: "test-doi-suffix",
|
||||||
citations: ['dumoulin2016guide'],
|
citations: ["dumoulin2016guide"],
|
||||||
bibliography: new Map([[
|
bibliography: new Map([
|
||||||
'dumoulin2016guide', {
|
[
|
||||||
title: 'A guide to convolution arithmetic for deep learning',
|
"dumoulin2016guide",
|
||||||
author: 'Dumoulin, Vincent and Visin, Francesco',
|
{
|
||||||
journal: 'arXiv preprint arXiv:1603.07285',
|
title: "A guide to convolution arithmetic for deep learning",
|
||||||
year: '2016',
|
author: "Dumoulin, Vincent and Visin, Francesco",
|
||||||
url: 'https://arxiv.org/pdf/1603.07285.pdf'
|
journal: "arXiv preprint arXiv:1603.07285",
|
||||||
}
|
year: "2016",
|
||||||
]])
|
url: "https://arxiv.org/pdf/1603.07285.pdf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
])
|
||||||
};
|
};
|
||||||
|
|
||||||
const meta = distill.testing.transforms.get('Meta');
|
const meta = distill.testing.transforms.get("Meta");
|
||||||
expect(meta).to.be.a('function');
|
expect(meta).to.be.a("function");
|
||||||
meta(dom.window.document, data);
|
meta(dom.window.document, data);
|
||||||
|
|
||||||
const metaTags = [].slice.call(dom.window.document.querySelectorAll('meta[name="citation_reference"]'));
|
const metaTags = [].slice.call(
|
||||||
|
dom.window.document.querySelectorAll(
|
||||||
|
'meta[name="citation_reference"]'
|
||||||
|
)
|
||||||
|
);
|
||||||
expect(metaTags).to.not.be.empty;
|
expect(metaTags).to.not.be.empty;
|
||||||
|
|
||||||
const metaTag = metaTags[0];
|
const metaTag = metaTags[0];
|
||||||
expect(metaTag).to.have.property('content');
|
expect(metaTag).to.have.property("content");
|
||||||
|
|
||||||
const content = metaTag.content;
|
const content = metaTag.content;
|
||||||
expect(content).to.include('citation_title');
|
expect(content).to.include("citation_title");
|
||||||
expect(content).to.include('citation_author');
|
expect(content).to.include("citation_author");
|
||||||
expect(content.match(/citation_author=/g).length).to.equal(2);
|
expect(content.match(/citation_author=/g).length).to.equal(2);
|
||||||
expect(content).to.include('citation_publication_date');
|
expect(content).to.include("citation_publication_date");
|
||||||
expect(content).to.include('citation_arxiv_id');
|
expect(content).to.include("citation_arxiv_id");
|
||||||
expect(content).to.not.include('journal');
|
expect(content).to.not.include("journal");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('given only a DOM (and publish data), it should add Google scholar references information', function() {
|
it("given only a DOM (and publish data), it should add Google scholar references information", function() {
|
||||||
const dom = new JSDOM(`
|
const dom = new JSDOM(
|
||||||
|
`
|
||||||
<d-cite key="mercier2011humans">sth</d-cite>
|
<d-cite key="mercier2011humans">sth</d-cite>
|
||||||
<d-bibliography>
|
<d-bibliography>
|
||||||
<script type="text/bibtex">
|
<script type="text/bibtex">
|
||||||
@@ -228,27 +270,28 @@ describe('Distill V2 (transforms)', function() {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</d-bibliography>
|
</d-bibliography>
|
||||||
`, options);
|
`,
|
||||||
|
options
|
||||||
|
);
|
||||||
const data = { publishedDate: new Date(), updatedDate: new Date() };
|
const data = { publishedDate: new Date(), updatedDate: new Date() };
|
||||||
distill.render(dom.window.document, data, false);
|
distill.render(dom.window.document, data, false);
|
||||||
const metaTags = [].slice.call(dom.window.document.querySelectorAll('meta[name="citation_reference"]'));
|
const metaTags = [].slice.call(
|
||||||
|
dom.window.document.querySelectorAll(
|
||||||
|
'meta[name="citation_reference"]'
|
||||||
|
)
|
||||||
|
);
|
||||||
expect(metaTags).to.not.be.empty;
|
expect(metaTags).to.not.be.empty;
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}); // render
|
}); // render
|
||||||
|
|
||||||
it('should export #distillify()', function() {
|
it("should export #distillify()", function() {
|
||||||
expect(distill.distillify).to.be.a('function');
|
expect(distill.distillify).to.be.a("function");
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#distillify()', function() {
|
describe("#distillify()", function() {
|
||||||
|
it("should ensure existence of header");
|
||||||
it('should ensure existence of header');
|
it("should ensure existence of footer");
|
||||||
it('should ensure existence of footer');
|
it("should ensure existence of distill appendix");
|
||||||
it('should ensure existence of distill appendix');
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}); // describe 'Transform'
|
}); // describe 'Transform'
|
||||||
|
|||||||
Reference in New Issue
Block a user