mirror of
https://github.com/wassname/template.git
synced 2026-06-28 01:32:06 +08:00
Compare commits
36 Commits
v1
..
v2.0.0-alpha2
| Author | SHA1 | Date | |
|---|---|---|---|
| 9041141bf8 | |||
| 361b6940aa | |||
| a8d0e143cf | |||
| a778d30946 | |||
| daf07f1f39 | |||
| 9d180de631 | |||
| 8d23e288ae | |||
| 50a3a49fd5 | |||
| 75cca6c7cd | |||
| a15a9ba7a3 | |||
| 9993a679c1 | |||
| 08fafcf2ee | |||
| 5e237be027 | |||
| dea6f27995 | |||
| a53817cd43 | |||
| 8f4722173a | |||
| 991ed9bd11 | |||
| b4f2c4863f | |||
| a1800ca2b3 | |||
| 27fbe9a932 | |||
| 11eda0fc49 | |||
| 07c7527734 | |||
| 9fe826447b | |||
| 929b159aaa | |||
| 41764d28ba | |||
| 09d60579d2 | |||
| 7d48a5d6e8 | |||
| 291864acae | |||
| 4f3ddce184 | |||
| 031e3b52b9 | |||
| 560f8bb4bf | |||
| 38aadd3332 | |||
| f544f1ec2d | |||
| 5b2e2867f0 | |||
| feea10ed4e | |||
| 8807bb1778 |
@@ -0,0 +1,15 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = spaces
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{json,yml}]
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"no-unused-vars": ["warn", { "vars": "all", "args": "after-used" }],
|
||||
"no-console": ["off", { "allow": ["warn", "error"] } ],
|
||||
"no-empty": ["error", { "allowEmptyCatch": true }],
|
||||
"indent": [ "warn", 2 ],
|
||||
"linebreak-style": [ "error", "unix" ],
|
||||
"quotes": [ "warn", "single" ],
|
||||
"semi": [ "warn", "always" ],
|
||||
"no-extra-semi": [ "warn" ],
|
||||
"no-debugger": [ "warn" ]
|
||||
}
|
||||
}
|
||||
+5
-12
@@ -9,18 +9,6 @@ pids
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
@@ -29,6 +17,7 @@ build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
bower_components
|
||||
jspm_packages
|
||||
|
||||
# Optional npm cache directory
|
||||
@@ -45,3 +34,7 @@ jspm_packages
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# Copied fonts
|
||||
examples/fonts
|
||||
dist
|
||||
|
||||
+1
-1
@@ -15,4 +15,4 @@ deploy:
|
||||
skip_cleanup: true
|
||||
overwrite: true
|
||||
on:
|
||||
tags: true
|
||||
tags: true
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# This is the list of The Distill Template authors for copyright purposes.
|
||||
#
|
||||
# This does not necessarily list everyone who has contributed code, since in
|
||||
# some cases, their employer may be the copyright holder. To see the full list
|
||||
# of contributors, see the revision history in source control.
|
||||
Google LLC
|
||||
@@ -1,28 +0,0 @@
|
||||
# How to Contribute
|
||||
|
||||
We'd love to accept your patches and contributions to this project. There are
|
||||
just a few small guidelines you need to follow.
|
||||
|
||||
## Contributor License Agreement
|
||||
|
||||
Contributions to this project must be accompanied by a Contributor License
|
||||
Agreement. You (or your employer) retain the copyright to your contribution,
|
||||
this simply gives us permission to use and redistribute your contributions as
|
||||
part of the project. Head over to <https://cla.developers.google.com/> to see
|
||||
your current agreements on file or to sign a new one.
|
||||
|
||||
You generally only need to submit a CLA once, so if you've already submitted one
|
||||
(even if it was for a different project), you probably don't need to do it
|
||||
again.
|
||||
|
||||
## Code reviews
|
||||
|
||||
All submissions, including submissions by project members, require review. We
|
||||
use GitHub pull requests for this purpose. Consult
|
||||
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
|
||||
information on using pull requests.
|
||||
|
||||
## Community Guidelines
|
||||
|
||||
This project follows [Google's Open Source Community
|
||||
Guidelines](https://opensource.google.com/conduct/).
|
||||
@@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
@@ -1,27 +1,28 @@
|
||||
_This is an outdated version of the Distill template. Please switch to the master branch for the current version._
|
||||
# Distill Templates
|
||||
|
||||
# Distill Template v1
|
||||
## Development
|
||||
|
||||
This is the repository for the Distill web framework.
|
||||
Run `yarn start` to start a watching build rollup server.
|
||||
|
||||
## Contributing
|
||||
## Testing
|
||||
|
||||
Run `yarn test`. That's it.
|
||||
|
||||
|
||||
To give feedback, report a bug, or request a feature, please open an issue.
|
||||
## TODO:
|
||||
|
||||
To contribute a change, [check out the contributing guide](CONTRIBUTING.md).
|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
Licensed under the Apache License, Version 2.0
|
||||
|
||||
See the [full license](LICENSE).
|
||||
-[ ] auto detection/adding behavior
|
||||
* title
|
||||
* appendix
|
||||
* footnote list ?
|
||||
-[x] should work without distill-appendix
|
||||
-[x] YML author without ":" should work?
|
||||
-[ ] throw warning on <hr>
|
||||
-[ ] h numbering:
|
||||
h2: position relative
|
||||
a: position: absolute;
|
||||
right: calc(100% + 16px);
|
||||
/* text-align: right; */
|
||||
/* width: 80px; */
|
||||
/* font-size: 20px; */
|
||||
/* font-weight: 200; */
|
||||
|
||||
+11
-9
@@ -1,18 +1,20 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var fs = require("fs"),
|
||||
jsdom = require("jsdom").jsdom,
|
||||
serializeDocument = require("jsdom").serializeDocument,
|
||||
distill = require("../dist/template.js"),
|
||||
program = require('commander');
|
||||
const fs = require('fs');
|
||||
const jsdom = require('jsdom').jsdom;
|
||||
const serialize = require('jsdom').serializeDocument;
|
||||
const program = require('commander');
|
||||
const transforms = require('../dist/transforms.js');
|
||||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-i, --input <path>', 'path to input file.')
|
||||
.parse(process.argv);
|
||||
|
||||
let htmlString = fs.readFileSync(program.input, "utf8");
|
||||
var dom = jsdom(htmlString, {features: {ProcessExternalResources: false, FetchExternalResources: false}});
|
||||
distill.render(dom, {});
|
||||
let transformedHtml = serializeDocument(dom);
|
||||
const htmlString = fs.readFileSync(program.input, 'utf8');
|
||||
const data = {};
|
||||
const dom = jsdom(htmlString, {features: {ProcessExternalResources: false, FetchExternalResources: false, runScripts: 'dangerously'}});
|
||||
transforms.render(dom, data);
|
||||
transforms.distillify(dom, data);
|
||||
const transformedHtml = serialize(dom);
|
||||
process.stdout.write(transformedHtml);
|
||||
|
||||
@@ -1,42 +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.
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector('dt-appendix > div');
|
||||
if (el) {
|
||||
let newHTML = "";
|
||||
|
||||
newHTML += `<h3>Updates and Corrections</h3>
|
||||
<p><a href="${data.githubCompareUpdatesUrl}">View all changes</a> to this article since it was first published. If you see a mistake or want to suggest a change, please <a class="github-issue" href="${data.githubUrl}/issues/new">create an issue on GitHub</a>.</p>`;
|
||||
|
||||
newHTML += `<h3 id="citation">Citations and Reuse</h3>
|
||||
<p>Diagrams and text are licensed under Creative Commons Attribution <a href="https://creativecommons.org/licenses/by/2.0/">CC-BY 2.0</a>, unless noted otherwise, with the <a class="github" href="${data.githubUrl}">source available on GitHub</a>. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: “Figure from …”.</p>
|
||||
|
||||
<p>For attribution in academic contexts, please cite this work as</p>
|
||||
<pre class="citation short">${data.concatenatedAuthors}, "${data.title}", ${data.journal.title}, ${data.publishedYear}. http://doi.org/${data.doi}</pre>
|
||||
|
||||
<p>BibTeX citation</p>
|
||||
<pre class="citation long">@article{${data.slug},
|
||||
author = {${data.bibtexAuthors}},
|
||||
title = {${data.title}},
|
||||
journal = {${data.journal.title}},
|
||||
year = {${data.publishedYear}},
|
||||
url = {${data.url}},
|
||||
doi = {${data.doi}}
|
||||
}</pre>`;
|
||||
|
||||
let existingHTML = el.innerHTML;
|
||||
el.innerHTML = existingHTML + newHTML;
|
||||
}
|
||||
}
|
||||
@@ -1,86 +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.
|
||||
|
||||
const templateHTML = `
|
||||
<style>
|
||||
dt-appendix {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
margin-bottom: 0;
|
||||
border-top: 1px solid rgba(0,0,0,0.1);
|
||||
color: rgba(0,0,0,0.5);
|
||||
background: rgb(250, 250, 250);
|
||||
padding-top: 36px;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
dt-appendix h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-top: 18px;
|
||||
margin-bottom: 18px;
|
||||
color: rgba(0,0,0,0.65);
|
||||
}
|
||||
dt-appendix .citation {
|
||||
font-size: 11px;
|
||||
line-height: 15px;
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding-left: 18px;
|
||||
border: 1px solid rgba(0,0,0,0.1);
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
padding: 10px 18px;
|
||||
border-radius: 3px;
|
||||
color: rgba(150, 150, 150, 1);
|
||||
overflow: hidden;
|
||||
margin-top: -12px;
|
||||
}
|
||||
dt-appendix .references {
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
dt-appendix a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
dt-appendix ol,
|
||||
dt-appendix ul {
|
||||
padding-left: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="l-body">
|
||||
</div>
|
||||
`;
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector('dt-appendix')
|
||||
if (el) {
|
||||
let userHTML = el.innerHTML;
|
||||
el.innerHTML = templateHTML;
|
||||
let newHTML = "";
|
||||
|
||||
// If we have some footnotes on the page, render a container for the footnote list.
|
||||
if (dom.querySelector("dt-fn")) {
|
||||
newHTML = newHTML + `<h3>Footnotes</h3><dt-fn-list></dt-fn-list>`;
|
||||
}
|
||||
|
||||
// If we have any citations on the page, render a container for the bibliography.
|
||||
if (dom.querySelector("dt-cite")) {
|
||||
newHTML = newHTML + `<h3>References</h3><dt-bibliography></dt-bibliography>`;
|
||||
}
|
||||
|
||||
let div = el.querySelector("div.l-body")
|
||||
div.innerHTML = userHTML + newHTML;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +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.
|
||||
|
||||
const html = `
|
||||
<style>
|
||||
dt-banner {
|
||||
background: #FFF59D;
|
||||
display: block;
|
||||
text-align: center;
|
||||
color: black;
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
}
|
||||
</style>
|
||||
<div>This article is a draft, awaiting review for publication in Distill</div>
|
||||
`;
|
||||
|
||||
export default function(dom, data) {
|
||||
let banner = dom.createElement("dt-banner");
|
||||
banner.innerHTML = html;
|
||||
let b = dom.querySelector("body");
|
||||
b.insertBefore(banner, b.firstChild);
|
||||
banner.addEventListener("click", function() {
|
||||
banner.style.display = "none";
|
||||
});
|
||||
}
|
||||
@@ -1,41 +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.
|
||||
|
||||
import bibtexParse from "bibtex-parse-js";
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector('script[type="text/bibliography"]');
|
||||
let bibliography = {};
|
||||
//TODO If we don't have a local element, make a request for the document.
|
||||
if (el) {
|
||||
let rawBib = el.textContent;
|
||||
let parsed = bibtexParse.toJSON(rawBib);
|
||||
if(parsed) {
|
||||
parsed.forEach(e => {
|
||||
for (var k in e.entryTags){
|
||||
var val = e.entryTags[k];
|
||||
val = val.replace(/[\t\n ]+/g, " ");
|
||||
val = val.replace(/{\\["^`\.'acu~Hvs]( )?([a-zA-Z])}/g,
|
||||
(full, x, char) => char);
|
||||
val = val.replace(/{\\([a-zA-Z])}/g,
|
||||
(full, char) => char);
|
||||
e.entryTags[k.toLowerCase()] = val;
|
||||
}
|
||||
bibliography[e.citationKey] = e.entryTags;
|
||||
bibliography[e.citationKey].type = e.entryType;
|
||||
});
|
||||
}
|
||||
}
|
||||
data.bibliography = bibliography;
|
||||
}
|
||||
@@ -1,268 +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.
|
||||
|
||||
export default function(dom, data) {
|
||||
let css = `
|
||||
dt-cite {
|
||||
color: hsla(206, 90%, 20%, 0.7);
|
||||
}
|
||||
dt-cite .citation-number {
|
||||
cursor: default;
|
||||
white-space: nowrap;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Roboto", Helvetica, sans-serif;
|
||||
font-size: 75%;
|
||||
color: hsla(206, 90%, 20%, 0.7);
|
||||
display: inline-block;
|
||||
line-height: 1.1em;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
figcaption dt-cite .citation-number {
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
top: -2px;
|
||||
line-height: 1em;
|
||||
}
|
||||
`;
|
||||
|
||||
let style = dom.createElement("style");
|
||||
style.textContent = css;
|
||||
dom.querySelector("body").appendChild(style);
|
||||
|
||||
let citations = data.citations;
|
||||
/*if (data.citations) {
|
||||
citations = Object.keys(data.citations).map(c => data.citations[c]);
|
||||
citations.sort((a, b) => {
|
||||
return a.author.localeCompare(b.author);
|
||||
});
|
||||
}*/
|
||||
|
||||
var appendCiteHoverDiv = (function() {
|
||||
function nodeFromString(str) {
|
||||
var div = dom.createElement("div");
|
||||
div.innerHTML = str;
|
||||
return div.firstChild;
|
||||
}
|
||||
var hover_boxes_container = nodeFromString(`<div id="cite-hover-boxes-container"></div>`)
|
||||
dom.querySelector("body").appendChild(hover_boxes_container);
|
||||
var hover_n = 0;
|
||||
return function appendHoverDiv(content) {
|
||||
var id = `dt-cite-hover-box-${hover_n}`;
|
||||
hover_n += 1;
|
||||
var str = `<div style="display:none;" class="dt-hover-box" id="${id}" >${content}</div>`;
|
||||
var div = nodeFromString(str);
|
||||
hover_boxes_container.appendChild(div);
|
||||
return id;
|
||||
}
|
||||
})();
|
||||
|
||||
var citeTags = [].slice.apply(dom.querySelectorAll("dt-cite"));
|
||||
citeTags.forEach((el,n) => {
|
||||
var key = el.getAttribute("key");
|
||||
if (key) {
|
||||
var keys = key.split(",");
|
||||
var cite_string = inline_cite_short(keys);
|
||||
var cite_hover_str = "";
|
||||
keys.map((key,n) => {
|
||||
if (n>0) cite_hover_str += "<br><br>";
|
||||
cite_hover_str += hover_cite(data.bibliography[key]);
|
||||
});
|
||||
var ref_id = appendCiteHoverDiv(cite_hover_str);
|
||||
//cite_hover_str = cite_hover_str.replace(/"/g, "'")
|
||||
var orig_string = el.innerHTML;
|
||||
if (orig_string != "") orig_string += " ";
|
||||
el.innerHTML = `<span id="citation-${n}" data-hover-ref="${ref_id}">${orig_string}<span class="citation-number">${cite_string}</span></span>`;
|
||||
}
|
||||
});
|
||||
|
||||
let bibEl = dom.querySelector("dt-bibliography");
|
||||
if (bibEl) {
|
||||
let ol = dom.createElement("ol");
|
||||
citations.forEach(key => {
|
||||
let el = dom.createElement("li");
|
||||
el.innerHTML = bibliography_cite(data.bibliography[key]);
|
||||
ol.appendChild(el);
|
||||
})
|
||||
bibEl.appendChild(ol);
|
||||
}
|
||||
|
||||
function inline_cite_short(keys){
|
||||
function cite_string(key){
|
||||
if (key in data.bibliography){
|
||||
var n = data.citations.indexOf(key)+1;
|
||||
return ""+n;
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
return "["+keys.map(cite_string).join(", ")+"]";
|
||||
}
|
||||
|
||||
function inline_cite_long(keys){
|
||||
function cite_string(key){
|
||||
if (key in data.bibliography){
|
||||
var ent = data.bibliography[key];
|
||||
var names = ent.author.split(" and ");
|
||||
names = names.map(name => name.split(",")[0].trim())
|
||||
var year = ent.year;
|
||||
if (names.length == 1) return names[0] + ", " + year;
|
||||
if (names.length == 2) return names[0] + " & " + names[1] + ", " + year;
|
||||
if (names.length > 2) return names[0] + ", et al., " + year;
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
return keys.map(cite_string).join(", ");
|
||||
}
|
||||
|
||||
function author_string(ent, template, sep, finalSep){
|
||||
var names = ent.author.split(" and ");
|
||||
let name_strings = names.map(name => {
|
||||
name = name.trim();
|
||||
if (name.indexOf(",") != -1){
|
||||
var last = name.split(",")[0].trim();
|
||||
var firsts = name.split(",")[1];
|
||||
} else {
|
||||
var last = name.split(" ").slice(-1)[0].trim();
|
||||
var firsts = name.split(" ").slice(0,-1).join(" ");
|
||||
}
|
||||
var initials = "";
|
||||
if (firsts != undefined) {
|
||||
initials = firsts.trim().split(" ").map(s => s.trim()[0]);
|
||||
initials = initials.join(".")+".";
|
||||
}
|
||||
return template.replace("${F}", firsts)
|
||||
.replace("${L}", last)
|
||||
.replace("${I}", initials);
|
||||
});
|
||||
if (names.length > 1) {
|
||||
var str = name_strings.slice(0, names.length-1).join(sep);
|
||||
str += (finalSep || sep) + name_strings[names.length-1];
|
||||
return str;
|
||||
} else {
|
||||
return name_strings[0];
|
||||
}
|
||||
}
|
||||
|
||||
function venue_string(ent) {
|
||||
var cite = (ent.journal || ent.booktitle || "")
|
||||
if ("volume" in ent){
|
||||
var issue = ent.issue || ent.number;
|
||||
issue = (issue != undefined)? "("+issue+")" : "";
|
||||
cite += ", Vol " + ent.volume + issue;
|
||||
}
|
||||
if ("pages" in ent){
|
||||
cite += ", pp. " + ent.pages
|
||||
}
|
||||
if (cite != "") cite += ". "
|
||||
if ("publisher" in ent){
|
||||
cite += ent.publisher;
|
||||
if (cite[cite.length-1] != ".") cite += ".";
|
||||
}
|
||||
return cite;
|
||||
}
|
||||
|
||||
function link_string(ent){
|
||||
if ("url" in ent){
|
||||
var url = ent.url;
|
||||
var arxiv_match = (/arxiv\.org\/abs\/([0-9\.]*)/).exec(url);
|
||||
if (arxiv_match != null){
|
||||
url = `http://arxiv.org/pdf/${arxiv_match[1]}.pdf`;
|
||||
}
|
||||
|
||||
if (url.slice(-4) == ".pdf"){
|
||||
var label = "PDF";
|
||||
} else if (url.slice(-5) == ".html") {
|
||||
var label = "HTML";
|
||||
}
|
||||
return `  <a href="${url}">[${label||"link"}]</a>`;
|
||||
}/* else if ("doi" in ent){
|
||||
return `  <a href="https://doi.org/${ent.doi}" >[DOI]</a>`;
|
||||
}*/ else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
function doi_string(ent, new_line){
|
||||
if ("doi" in ent) {
|
||||
return `${new_line?"<br>":""} <a href="https://doi.org/${ent.doi}" style="text-decoration:inherit;">DOI: ${ent.doi}</a>`;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function bibliography_cite(ent, fancy){
|
||||
if (ent){
|
||||
var cite = "<b>" + ent.title + "</b> "
|
||||
cite += link_string(ent) + "<br>";
|
||||
cite += author_string(ent, "${L}, ${I}", ", ", " and ");
|
||||
if (ent.year || ent.date){
|
||||
cite += ", " + (ent.year || ent.date) + ". "
|
||||
} else {
|
||||
cite += ". "
|
||||
}
|
||||
cite += venue_string(ent);
|
||||
cite += doi_string(ent);
|
||||
return cite
|
||||
/*var cite = author_string(ent, "${L}, ${I}", ", ", " and ");
|
||||
if (ent.year || ent.date){
|
||||
cite += ", " + (ent.year || ent.date) + ". "
|
||||
} else {
|
||||
cite += ". "
|
||||
}
|
||||
cite += "<b>" + ent.title + "</b>. ";
|
||||
cite += venue_string(ent);
|
||||
cite += doi_string(ent);
|
||||
cite += link_string(ent);
|
||||
return cite*/
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
function hover_cite(ent){
|
||||
if (ent){
|
||||
var cite = "";
|
||||
cite += "<b>" + ent.title + "</b>";
|
||||
cite += link_string(ent);
|
||||
cite += "<br>"
|
||||
|
||||
var a_str = author_string(ent, "${I} ${L}", ", ") + ".";
|
||||
var v_str = venue_string(ent).trim() + " " + ent.year + ". " + doi_string(ent, true);
|
||||
|
||||
if ((a_str+v_str).length < Math.min(40, ent.title.length)) {
|
||||
cite += a_str + " " + v_str;
|
||||
} else {
|
||||
cite += a_str + "<br>" + v_str;
|
||||
}
|
||||
return cite;
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//https://scholar.google.com/scholar?q=allintitle%3ADocument+author%3Aolah
|
||||
function get_GS_URL(ent){
|
||||
if (ent){
|
||||
var names = ent.author.split(" and ");
|
||||
names = names.map(name => name.split(",")[0].trim())
|
||||
var title = ent.title.split(" ")//.replace(/[,:]/, "")
|
||||
var url = "http://search.labs.crossref.org/dois?"//""https://scholar.google.com/scholar?"
|
||||
url += uris({q: names.join(" ") + " " + title.join(" ")})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,51 +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.
|
||||
|
||||
import Prism from "prismjs";
|
||||
import "prismjs/components/prism-python";
|
||||
import "prismjs/components/prism-clike";
|
||||
import "prismjs/components/prism-lua";
|
||||
import "prismjs/components/prism-bash";
|
||||
import "prismjs/components/prism-go";
|
||||
import "prismjs/components/prism-markdown";
|
||||
import "prismjs/components/prism-julia";
|
||||
|
||||
|
||||
export default function(dom, data) {
|
||||
let codeElements = [].slice.call(dom.querySelectorAll("dt-code"));
|
||||
codeElements.forEach(el => {
|
||||
let content = el.textContent;
|
||||
el.innerHTML = "";
|
||||
let language = el.getAttribute("language");
|
||||
let c = dom.createElement("code");
|
||||
if (el.getAttribute("block") === "") {
|
||||
// Let's normalize the tab indents
|
||||
content = content.replace(/\n/, "");
|
||||
let tabs = content.match(/\s*/);
|
||||
content = content.replace(new RegExp("\n" + tabs, "g"), "\n");
|
||||
content = content.trim();
|
||||
let p = dom.createElement("pre");
|
||||
p.appendChild(c);
|
||||
el.appendChild(p);
|
||||
} else {
|
||||
el.appendChild(c);
|
||||
}
|
||||
let highlighted = content;
|
||||
if (Prism.languages[language]) {
|
||||
c.setAttribute("class", "language-" + language);
|
||||
highlighted = Prism.highlight(content, Prism.languages[language]);
|
||||
}
|
||||
c.innerHTML = highlighted;
|
||||
});
|
||||
}
|
||||
@@ -1,166 +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.
|
||||
|
||||
import {timeFormat} from "d3-time-format";
|
||||
|
||||
export default function(dom, data) {
|
||||
|
||||
//
|
||||
// Properties from source
|
||||
//
|
||||
|
||||
// title: 'Attention and Augmented Recurrent Neural Networks',
|
||||
// description: 'A visual overview of neural attention, and the powerful extensions of neural networks being built on top of it.',
|
||||
// url: 'http://distill.pub/2016/augmented-rnns',
|
||||
// tags: [ 'rnn' ],
|
||||
// doiSuffix: 1,
|
||||
// doi: '10.23915/distill.00001',
|
||||
// volume: 1,
|
||||
// issue: 9,
|
||||
// distillPath: '2016/augmented-rnns',
|
||||
// githubPath: 'distillpub/post--augmented-rnns',
|
||||
// githubCompareUpdatesUrl: 'https://github.com/distillpub/post--augmented-rnns/compare/1596e094d8943d2dc0ea445d92071129c6419c59...3bd9209e0c24d020f87cf6152dcecc6017cbc193',
|
||||
// updatedDate: 2017-03-21T07:13:16.000Z,
|
||||
// publishedDate: 2016-09-08T07:00:00.000Z,
|
||||
// journal: {
|
||||
// "title": "Distill",
|
||||
// "full_title": "Distill",
|
||||
// "abbrev_title": "Distill",
|
||||
// "url": "http://distill.pub",
|
||||
// "doi": "10.23915/distill",
|
||||
// "publisherName": "Distill Working Group",
|
||||
// "publisherEmail": "admin@distill.pub",
|
||||
// "issn": "2476-0757",
|
||||
// "editors": [...],
|
||||
// "committee": [...]
|
||||
// }
|
||||
|
||||
//
|
||||
// Computed Properties
|
||||
//
|
||||
|
||||
// githubUrl: 'https://github.com/distillpub/post--augmented-rnns',
|
||||
// previewURL: 'http://distill.pub/2016/augmented-rnns/thumbnail.jpg',
|
||||
// publishedDateRFC: 'Thu, 08 Sep 2016 00:00:00 -0700',
|
||||
// publishedYear: 2016,
|
||||
// publishedMonth: 'Sept',
|
||||
// publishedDay: 8,
|
||||
// publishedMonthPadded: '09',
|
||||
// publishedDayPadded: '08',
|
||||
// updatedDateRFC: 'Tue, 21 Mar 2017 00:13:16 -0700',
|
||||
// concatenatedAuthors: 'Olah & Carter',
|
||||
// bibtexAuthors: 'Olah, Chris and Carter, Shan',
|
||||
// slug: 'olah2016attention'
|
||||
// authors: [
|
||||
// {
|
||||
// "personalURL": null,
|
||||
// "name": "Chris Olah",
|
||||
// "firstName": "Chris",
|
||||
// "lastName": "Olah",
|
||||
// "affiliationURL": null,
|
||||
// "affiliation": "Google Brain"
|
||||
// }
|
||||
// ],
|
||||
// bibliography: {
|
||||
// "gregor2015draw": {
|
||||
// "title": "DRAW: A recurrent neural network for image generation",
|
||||
// "author": "Gregor, Karol and Danihelka, Ivo and Graves, Alex and Rezende, Danilo Jimenez and Wierstra, Daan",
|
||||
// "journal": "arXiv preprint arXiv:1502.04623",
|
||||
// "year": "2015",
|
||||
// "url": "https://arxiv.org/pdf/1502.04623.pdf",
|
||||
// "type": "article"
|
||||
// },
|
||||
// ...
|
||||
// },
|
||||
// citations: [
|
||||
// "gregor2015draw",
|
||||
// "mercier2011humans",
|
||||
// "dong2014image",
|
||||
// "dumoulin2016guide",
|
||||
// "mordvintsev2015inceptionism"
|
||||
// ],
|
||||
|
||||
|
||||
// citations:
|
||||
let citations = [];
|
||||
var citeTags = [].slice.apply(dom.querySelectorAll("dt-cite"));
|
||||
citeTags.forEach(el => {
|
||||
let key = el.getAttribute("key");
|
||||
if (key) {
|
||||
let citationKeys = key.split(",");
|
||||
citationKeys.forEach(key => {
|
||||
if (citations.indexOf(key) == -1){
|
||||
citations.push(key);
|
||||
if (!(key in data.bibliography)){
|
||||
console.warn("No bibliography entry found for: " + key);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
data.citations = citations;
|
||||
|
||||
|
||||
data.authors = data.authors || [];
|
||||
|
||||
// paths
|
||||
if (!data.distillPath && !data.url) {
|
||||
data.url = "http://distill.pub/";
|
||||
} else if (!data.url) {
|
||||
data.url = "http://distill.pub/" + data.distillPath;
|
||||
}
|
||||
data.githubUrl = "https://github.com/" + data.githubPath;
|
||||
|
||||
data.previewURL = data.previewURL ? data.previewURL : data.url + "/thumbnail.jpg"
|
||||
|
||||
// Homepage
|
||||
//data.homepage = !post.noHomepage;
|
||||
data.journal = data.journal || {};
|
||||
|
||||
// Dates
|
||||
if (data.publishedDate){//} && data.journal) {
|
||||
data.volume = data.publishedDate.getFullYear() - 2015;
|
||||
data.issue = data.publishedDate.getMonth() + 1;
|
||||
}
|
||||
|
||||
data.publishedDate = data.publishedDate ? data.publishedDate : new Date("Invalid");
|
||||
data.updatedDate = data.updatedDate ? data.updatedDate : new Date("Invalid");
|
||||
|
||||
data.publishedDateRFC
|
||||
let RFC = timeFormat("%a, %d %b %Y %H:%M:%S %Z");
|
||||
let months = ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"];
|
||||
let zeroPad = (n) => { return n < 10 ? "0" + n : n; };
|
||||
data.publishedDateRFC = RFC(data.publishedDate);
|
||||
data.publishedYear = data.publishedDate.getFullYear();
|
||||
data.publishedMonth = months[data.publishedDate.getMonth()];
|
||||
data.publishedDay = data.publishedDate.getDate();
|
||||
data.publishedMonthPadded = zeroPad(data.publishedDate.getMonth() + 1);
|
||||
data.publishedDayPadded = zeroPad(data.publishedDate.getDate());
|
||||
data.updatedDateRFC = RFC(data.updatedDate);
|
||||
|
||||
if (data.authors.length > 2) {
|
||||
data.concatenatedAuthors = data.authors[0].lastName + ", et al.";
|
||||
} else if (data.authors.length === 2) {
|
||||
data.concatenatedAuthors = data.authors[0].lastName + " & " + data.authors[1].lastName;
|
||||
} else if (data.authors.length === 1) {
|
||||
data.concatenatedAuthors = data.authors[0].lastName
|
||||
}
|
||||
|
||||
data.bibtexAuthors = data.authors.map(function(author){
|
||||
return author.lastName + ", " + author.firstName;
|
||||
}).join(" and ");
|
||||
|
||||
data.slug = data.authors.length ? data.authors[0].lastName.toLowerCase() + data.publishedYear + data.title.split(" ")[0].toLowerCase() : "Untitled";
|
||||
|
||||
}
|
||||
@@ -1,32 +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.
|
||||
|
||||
import katex from "katex";
|
||||
|
||||
const html = `
|
||||
<style>
|
||||
dt-math[block] {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
|
||||
export default function(dom, data) {
|
||||
let equationElements = [].slice.call(dom.querySelectorAll("dt-math"));
|
||||
equationElements.forEach(el => {
|
||||
let content = el.textContent;
|
||||
let displayMode = el.hasAttribute("block") ? true : false;
|
||||
el.innerHTML = html + katex.renderToString(content, {displayMode: displayMode});
|
||||
});
|
||||
}
|
||||
@@ -1,86 +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.
|
||||
|
||||
import logo from "./distill-logo.svg";
|
||||
|
||||
let html = `
|
||||
<style>
|
||||
dt-footer {
|
||||
display: block;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-weight: 300;
|
||||
padding: 40px 0;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
background-color: hsl(200, 60%, 15%);
|
||||
text-align: center;
|
||||
}
|
||||
dt-footer .logo svg {
|
||||
width: 24px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
dt-footer .logo svg path {
|
||||
fill: none;
|
||||
stroke: rgba(255, 255, 255, 0.8);
|
||||
stroke-width: 3px;
|
||||
}
|
||||
dt-footer .logo {
|
||||
font-size: 17px;
|
||||
font-weight: 200;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-decoration: none;
|
||||
margin-right: 6px;
|
||||
}
|
||||
dt-footer .nav {
|
||||
margin-top: 12px;
|
||||
}
|
||||
dt-footer .nav a {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
margin-right: 6px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="l-page">
|
||||
<div class="description">
|
||||
<a href="/" class="logo">
|
||||
${logo}
|
||||
Distill
|
||||
</a>
|
||||
is dedicated to clear explanations of machine learning
|
||||
</div>
|
||||
<div class="nav">
|
||||
<a href="http://distill.pub/about/">About</a>
|
||||
<a href="http://distill.pub/journal/">Submit</a>
|
||||
<a href="http://distill.pub/prize/">Prize</a>
|
||||
<a href="http://distill.pub/archive/">Archive</a>
|
||||
<a href="http://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 default function(dom, data) {
|
||||
let el = dom.querySelector("dt-footer");
|
||||
if(el) {
|
||||
el.innerHTML = html;
|
||||
} else {
|
||||
let footer = dom.createElement("dt-footer");
|
||||
footer.innerHTML = html;
|
||||
let b = dom.querySelector("body");
|
||||
b.appendChild(footer);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +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.
|
||||
|
||||
export default function(dom, data) {
|
||||
|
||||
var appendFootnoteHoverDiv = (function() {
|
||||
function nodeFromString(str) {
|
||||
var div = dom.createElement("div");
|
||||
div.innerHTML = str;
|
||||
return div.firstChild;
|
||||
}
|
||||
var hover_boxes_container = nodeFromString(`<div id="footnote-hover-boxes-container"></div>`)
|
||||
dom.querySelector("body").appendChild(hover_boxes_container);
|
||||
var hover_n = 0;
|
||||
return function appendHoverDiv(content) {
|
||||
var id = `dt-fn-hover-box-${hover_n}`;
|
||||
hover_n += 1;
|
||||
var str = `<div style="display:none;" class="dt-hover-box" id="${id}" >${content}</div>`;
|
||||
var div = nodeFromString(str);
|
||||
hover_boxes_container.appendChild(div);
|
||||
return id;
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
var fnTags = [].slice.apply(dom.querySelectorAll("dt-fn"));
|
||||
var fnContent = [];
|
||||
fnTags.forEach((el,n) => {
|
||||
var content = el.innerHTML;
|
||||
var ref_id = appendFootnoteHoverDiv(content)
|
||||
fnContent.push(content);
|
||||
n = (n+1)+"";
|
||||
var key = "fn-"+n;
|
||||
var escaped_content = content.replace(/"/g, "'");
|
||||
el.innerHTML = `<sup><span id="${key}" data-hover-ref="${ref_id}" style="cursor:pointer">${n}</span></sup>`;
|
||||
});
|
||||
|
||||
let fnList = dom.querySelector("dt-fn-list");
|
||||
if (fnList) {
|
||||
let ol = dom.createElement("ol");
|
||||
fnContent.forEach(content => {
|
||||
let el = dom.createElement("li");
|
||||
el.innerHTML = content;
|
||||
ol.appendChild(el);
|
||||
})
|
||||
fnList.appendChild(ol);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +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.
|
||||
|
||||
import ymlParse from "js-yaml";
|
||||
|
||||
export default function(dom, data) {
|
||||
let localData = {};
|
||||
let el = dom.querySelector('script[type="text/front-matter"]');
|
||||
if (el) {
|
||||
let text = el.textContent;
|
||||
localData = ymlParse.safeLoad(text);
|
||||
}
|
||||
|
||||
data.title = localData.title ? localData.title : "Untitled";
|
||||
data.description = localData.description ? localData.description : "No description.";
|
||||
|
||||
data.authors = localData.authors ? localData.authors : [];
|
||||
|
||||
data.authors = data.authors.map((author, i) =>{
|
||||
let a = {};
|
||||
let name = Object.keys(author)[0];
|
||||
if ((typeof author) === "string") {
|
||||
name = author;
|
||||
} else {
|
||||
a.personalURL = author[name];
|
||||
}
|
||||
let names = name.split(" ");
|
||||
a.name = name;
|
||||
a.firstName = names.slice(0, names.length - 1).join(" ");
|
||||
a.lastName = names[names.length -1];
|
||||
if(localData.affiliations[i]) {
|
||||
let affiliation = Object.keys(localData.affiliations[i])[0];
|
||||
if ((typeof localData.affiliations[i]) === "string") {
|
||||
affiliation = localData.affiliations[i]
|
||||
} else {
|
||||
a.affiliationURL = localData.affiliations[i][affiliation];
|
||||
}
|
||||
a.affiliation = affiliation;
|
||||
}
|
||||
return a;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
@@ -1,106 +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.
|
||||
|
||||
import logo from "./distill-logo.svg";
|
||||
|
||||
const html = `
|
||||
<style>
|
||||
dt-header {
|
||||
display: block;
|
||||
position: relative;
|
||||
height: 60px;
|
||||
background-color: hsl(200, 60%, 15%);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
z-index: 2;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
dt-header .content {
|
||||
height: 70px;
|
||||
}
|
||||
dt-header a {
|
||||
font-size: 16px;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
text-decoration: none;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
padding: 22px 0;
|
||||
}
|
||||
dt-header a:hover {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
dt-header svg {
|
||||
width: 24px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
@media(min-width: 1080px) {
|
||||
dt-header {
|
||||
height: 70px;
|
||||
}
|
||||
dt-header a {
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
padding: 28px 0;
|
||||
}
|
||||
dt-header .logo {
|
||||
}
|
||||
}
|
||||
dt-header svg path {
|
||||
fill: none;
|
||||
stroke: rgba(255, 255, 255, 0.8);
|
||||
stroke-width: 3px;
|
||||
}
|
||||
dt-header .logo {
|
||||
font-size: 17px;
|
||||
font-weight: 200;
|
||||
}
|
||||
dt-header .nav {
|
||||
float: right;
|
||||
font-weight: 300;
|
||||
}
|
||||
dt-header .nav a {
|
||||
font-size: 12px;
|
||||
margin-left: 24px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="content l-page">
|
||||
<a href="/" class="logo">
|
||||
${logo}
|
||||
Distill
|
||||
</a>
|
||||
<div class="nav">
|
||||
<a href="/about/">About</a>
|
||||
<a href="/prize/">Prize</a>
|
||||
<a href="/journal/">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector("dt-header");
|
||||
if(el) {
|
||||
el.innerHTML = html;
|
||||
} else {
|
||||
let header = dom.createElement("dt-header");
|
||||
header.innerHTML = html;
|
||||
let b = dom.querySelector("body");
|
||||
b.insertBefore(header, b.firstChild);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +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.
|
||||
|
||||
import code from './hover-box.txt';
|
||||
|
||||
export default function(dom) {
|
||||
let s = dom.createElement("script");
|
||||
s.textContent = code;
|
||||
dom.querySelector("body").appendChild(s);
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
|
||||
|
||||
function nodeFromString(str) {
|
||||
var div = document.createElement("div");
|
||||
div.innerHTML = str;
|
||||
return div.firstChild;
|
||||
}
|
||||
|
||||
function make_hover_css(pos) {
|
||||
var pretty = window.innerWidth > 600;
|
||||
var padding = pretty? 18 : 12;
|
||||
var outer_padding = pretty ? 18 : 0;
|
||||
var bbox = document.querySelector("body").getBoundingClientRect();
|
||||
var left = pos[0] - bbox.left, top = pos[1] - bbox.top;
|
||||
var width = Math.min(window.innerWidth-2*outer_padding, 648);
|
||||
left = Math.min(left, window.innerWidth-width-outer_padding);
|
||||
width = width - 2*padding;
|
||||
return (`position: absolute;
|
||||
background-color: #FFF;
|
||||
opacity: 0.95;
|
||||
max-width: ${width}px;
|
||||
top: ${top}px;
|
||||
left: ${left}px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||
padding: ${padding}px;
|
||||
border-radius: ${pretty? 3 : 0}px;
|
||||
box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2);
|
||||
z-index: ${1e6};`);
|
||||
}
|
||||
|
||||
|
||||
function DtHoverBox(div_id) {
|
||||
this.div = document.querySelector("#"+div_id);
|
||||
this.visible = false;
|
||||
this.bindDivEvents();
|
||||
DtHoverBox.box_map[div_id] = this;
|
||||
}
|
||||
|
||||
DtHoverBox.box_map = {};
|
||||
|
||||
DtHoverBox.get_box = function get_box(div_id) {
|
||||
if (div_id in DtHoverBox.box_map) {
|
||||
return DtHoverBox.box_map[div_id];
|
||||
} else {
|
||||
return new DtHoverBox(div_id);
|
||||
}
|
||||
}
|
||||
|
||||
DtHoverBox.prototype.show = function show(pos){
|
||||
this.visible = true;
|
||||
this.div.setAttribute("style", make_hover_css(pos) );
|
||||
for (var box_id in DtHoverBox.box_map) {
|
||||
var box = DtHoverBox.box_map[box_id];
|
||||
if (box != this) box.hide();
|
||||
}
|
||||
}
|
||||
|
||||
DtHoverBox.prototype.showAtNode = function showAtNode(node){
|
||||
var bbox = node.getBoundingClientRect();
|
||||
this.show([bbox.right, bbox.bottom]);
|
||||
}
|
||||
|
||||
DtHoverBox.prototype.hide = function hide(){
|
||||
this.visible = false;
|
||||
if (this.div) this.div.setAttribute("style", "display:none");
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
DtHoverBox.prototype.stopTimeout = function stopTimeout() {
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
DtHoverBox.prototype.extendTimeout = function extendTimeout(T) {
|
||||
//console.log("extend", T)
|
||||
var this_ = this;
|
||||
this.stopTimeout();
|
||||
this.timeout = setTimeout(function(){this_.hide();}.bind(this), T);
|
||||
}
|
||||
|
||||
// Bind events to a link to open this box
|
||||
DtHoverBox.prototype.bind = function bind(node) {
|
||||
if (typeof node == "string"){
|
||||
node = document.querySelector(node);
|
||||
}
|
||||
|
||||
node.addEventListener("mouseover", function(){
|
||||
if (!this.visible) this.showAtNode(node);
|
||||
this.stopTimeout();
|
||||
}.bind(this));
|
||||
|
||||
node.addEventListener("mouseout", function(){this.extendTimeout(250);}.bind(this));
|
||||
|
||||
node.addEventListener("touchstart", function(e) {
|
||||
if (this.visible) {
|
||||
this.hide();
|
||||
} else {
|
||||
this.showAtNode(node);
|
||||
}
|
||||
// Don't trigger body touchstart event when touching link
|
||||
e.stopPropagation();
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
DtHoverBox.prototype.bindDivEvents = function bindDivEvents(){
|
||||
// For mice, same behavior as hovering on links
|
||||
this.div.addEventListener("mouseover", function(){
|
||||
if (!this.visible) this.showAtNode(node);
|
||||
this.stopTimeout();
|
||||
}.bind(this));
|
||||
this.div.addEventListener("mouseout", function(){this.extendTimeout(250);}.bind(this));
|
||||
|
||||
// Don't trigger body touchstart event when touching within box
|
||||
this.div.addEventListener("touchstart", function(e){e.stopPropagation();});
|
||||
// Close box when touching outside box
|
||||
document.body.addEventListener("touchstart", function(){this.hide();}.bind(this));
|
||||
}
|
||||
|
||||
var hover_es = document.querySelectorAll("span[data-hover-ref]");
|
||||
hover_es = [].slice.apply(hover_es);
|
||||
hover_es.forEach(function(e,n){
|
||||
var ref_id = e.getAttribute("data-hover-ref");
|
||||
DtHoverBox.get_box(ref_id).bind(e);
|
||||
})
|
||||
@@ -1,33 +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.
|
||||
|
||||
export default function(dom) {
|
||||
if (!dom.querySelector("html").getAttribute("lang")) {
|
||||
dom.querySelector("html").setAttribute("lang", "en")
|
||||
}
|
||||
|
||||
let head = dom.querySelector("head");
|
||||
|
||||
if (!dom.querySelector("meta[charset]")) {
|
||||
let meta = dom.createElement("meta");
|
||||
meta.setAttribute("charset", "utf-8");
|
||||
head.appendChild(meta);
|
||||
}
|
||||
if (!dom.querySelector("meta[name=viewport]")) {
|
||||
let meta = dom.createElement("meta");
|
||||
meta.setAttribute("name", "viewport");
|
||||
meta.setAttribute("content", "width=device-width, initial-scale=1");
|
||||
head.appendChild(meta);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +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.
|
||||
|
||||
import fetch from "fetch";
|
||||
let fetchUrl = fetch.fetchUrl
|
||||
|
||||
export default function(dom, data) {
|
||||
|
||||
var includeTags = [].slice.apply(dom.querySelectorAll("dt-include"));
|
||||
|
||||
includeTags.forEach(el => {
|
||||
let src = el.getAttribute("src");
|
||||
fetchUrl(src, (err, meta, body) => {
|
||||
console.log(err, meta, body);
|
||||
el.innerHTML = body.toString();
|
||||
})
|
||||
});
|
||||
data.bibliography = bibliography;
|
||||
data.citations = citations;
|
||||
|
||||
}
|
||||
@@ -1,14 +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.
|
||||
|
||||
@@ -1,34 +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.
|
||||
|
||||
import marked from 'marked';
|
||||
|
||||
marked.setOptions({
|
||||
gfm: true,
|
||||
smartypants: true
|
||||
});
|
||||
|
||||
export default function(dom, data) {
|
||||
let markdownElements = [].slice.call(dom.querySelectorAll('[markdown]'));
|
||||
markdownElements.forEach(el => {
|
||||
let content = el.innerHTML;
|
||||
// Set default indents
|
||||
content = content.replace(/\n/, "");
|
||||
let tabs = content.match(/\s*/);
|
||||
content = content.replace(new RegExp("\n" + tabs, "g"), "\n");
|
||||
content = content.trim();
|
||||
|
||||
el.innerHTML = marked(content);
|
||||
});
|
||||
}
|
||||
@@ -1,155 +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.
|
||||
|
||||
import favicon from './distill-favicon.base64';
|
||||
import escape from 'escape-html';
|
||||
|
||||
export default function(dom, data) {
|
||||
let head = dom.querySelector("head");
|
||||
let appendHead = html => appendHtml(head, html);
|
||||
|
||||
function meta(name, content, force) {
|
||||
if (content || force)
|
||||
appendHead(` <meta name="${name}" content="${escape(content)}" >\n`);
|
||||
}
|
||||
|
||||
appendHead(`
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,${favicon}">
|
||||
<link href="/rss.xml" rel="alternate" type="application/rss+xml" title="Articles from Distill">
|
||||
<link rel="canonical" href="${data.url}">
|
||||
<title>${data.title}</title>
|
||||
`);
|
||||
|
||||
appendHead(`
|
||||
<!-- https://schema.org/Article -->
|
||||
<meta property="article:published" itemprop="datePublished" content="${data.publishedYear}-${data.publishedMonthPadded}-${data.publishedDayPadded}" />
|
||||
<meta property="article:created" itemprop="dateCreated" content="${data.publishedDate}" />
|
||||
<meta property="article:modified" itemprop="dateModified" content="${data.updatedDate}" />
|
||||
`);
|
||||
data.authors.forEach((a) => {
|
||||
appendHtml(head, `
|
||||
<meta property="article:author" content="${a.firstName} ${a.lastName}" />`)
|
||||
});
|
||||
|
||||
appendHead(`
|
||||
<!-- https://developers.facebook.com/docs/sharing/webmasters#markup -->
|
||||
<meta property="og:type" content="article"/>
|
||||
<meta property="og:title" content="${data.title}"/>
|
||||
<meta property="og:description" content="${data.description}">
|
||||
<meta property="og:url" content="${data.url}"/>
|
||||
<meta property="og:image" content="${data.previewURL}"/>
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta property="og:site_name" content="Distill" />
|
||||
`);
|
||||
|
||||
appendHead(`
|
||||
<!-- https://dev.twitter.com/cards/types/summary -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="${data.title}">
|
||||
<meta name="twitter:description" content="${data.description}">
|
||||
<meta name="twitter:url" content="${data.url}">
|
||||
<meta name="twitter:image" content="${data.previewURL}">
|
||||
<meta name="twitter:image:width" content="560">
|
||||
<meta name="twitter:image:height" content="295">
|
||||
`);
|
||||
|
||||
// if this is a proprer article, generate Google Scholar meta data
|
||||
if (data.doiSuffix){
|
||||
appendHead(`
|
||||
<!-- https://scholar.google.com/intl/en/scholar/inclusion.html#indexing -->\n`);
|
||||
|
||||
meta("citation_title", data.title);
|
||||
//meta("citation_fulltext_html_url", data.url);
|
||||
meta("citation_volume", data.volume);
|
||||
meta("citation_issue", data.issue);
|
||||
meta("citation_firstpage", data.doiSuffix? `e${data.doiSuffix}` : undefined);
|
||||
meta("citation_doi", data.doi);
|
||||
|
||||
let journal = data.journal || {};
|
||||
meta("citation_journal_title", journal.full_title || journal.title);
|
||||
meta("citation_journal_abbrev", journal.abbrev_title);
|
||||
meta("citation_issn", journal.issn);
|
||||
meta("citation_publisher", journal.publisher);
|
||||
meta("citation_fulltext_world_readable", "", true);
|
||||
|
||||
if (data.publishedDate){
|
||||
let zeroPad = (n) => { return n < 10 ? "0" + n : n; };
|
||||
meta("citation_online_date", `${data.publishedYear}/${data.publishedMonthPadded}/${data.publishedDayPadded}`);
|
||||
// Should we do something different here?
|
||||
meta("citation_publication_date", `${data.publishedYear}/${data.publishedMonthPadded}/${data.publishedDayPadded}`);
|
||||
}
|
||||
|
||||
(data.authors || []).forEach((a) => {
|
||||
meta("citation_author", `${a.lastName}, ${a.firstName}`);
|
||||
meta("citation_author_institution", a.affiliation);
|
||||
});
|
||||
|
||||
if (data.citations) {
|
||||
data.citations.forEach(key => {
|
||||
let d = data.bibliography[key];
|
||||
if(!d) {
|
||||
console.warn("No bibliography data fround for " + key)
|
||||
} else {
|
||||
meta("citation_reference", citation_meta_content(data.bibliography[key]) )
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function appendHtml(el, html) {
|
||||
el.innerHTML += html;
|
||||
}
|
||||
|
||||
function citation_meta_content(ref){
|
||||
// Special test for arxiv
|
||||
var content = `citation_title=${ref.title};`;
|
||||
|
||||
let name_strings = ref.author.split(" and ").forEach(name => {
|
||||
name = name.trim();
|
||||
if (name.indexOf(",") != -1){
|
||||
var last = name.split(",")[0].trim();
|
||||
var firsts = name.split(",")[1].trim();
|
||||
} else {
|
||||
var last = name.split(" ").slice(-1)[0].trim();
|
||||
var firsts = name.split(" ").slice(0,-1).join(" ");
|
||||
}
|
||||
content += `citation_author=${firsts} ${last};`;
|
||||
});
|
||||
|
||||
if ("year" in ref) {
|
||||
content += `citation_publication_date=${ref.year};`;
|
||||
}
|
||||
|
||||
var arxiv_id_search = /https?:\/\/arxiv\.org\/pdf\/([0-9]*\.[0-9]*)\.pdf/.exec(ref.url);
|
||||
arxiv_id_search = arxiv_id_search || /https?:\/\/arxiv\.org\/abs\/([0-9]*\.[0-9]*)/.exec(ref.url);
|
||||
arxiv_id_search = arxiv_id_search || /arXiv preprint arXiv:([0-9]*\.[0-9]*)/.exec(ref.journal);
|
||||
if (arxiv_id_search && arxiv_id_search[1]){
|
||||
content += `citation_arxiv_id=${arxiv_id_search[1]};`;
|
||||
return content;
|
||||
}
|
||||
if ("journal" in ref){
|
||||
content += `citation_journal_title=${ref.journal};`;
|
||||
}
|
||||
if ("volume" in ref) {
|
||||
content += `citation_volume=${ref.volume};`;
|
||||
}
|
||||
if ("issue" in ref || "number" in ref){
|
||||
content += `citation_number=${ref.issue || ref.number};`;
|
||||
}
|
||||
/*content += `citation_first_page=${};`;
|
||||
content += `citation_publication_date=${};`;*/
|
||||
return content;
|
||||
}
|
||||
@@ -1,25 +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.
|
||||
|
||||
import base from './styles-base.css';
|
||||
import layout from './styles-layout.css';
|
||||
import article from './styles-article.css';
|
||||
import code from './styles-code.css';
|
||||
import print from './styles-print.css';
|
||||
|
||||
export default function(dom) {
|
||||
let s = dom.createElement("style");
|
||||
s.textContent = base + layout + article + code + print;
|
||||
dom.querySelector("head").appendChild(s);
|
||||
}
|
||||
@@ -1,115 +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.
|
||||
|
||||
export default function(dom, data) {
|
||||
|
||||
var textNodes = dom.createTreeWalker(
|
||||
dom.body,
|
||||
dom.defaultView.NodeFilter.SHOW_TEXT
|
||||
);
|
||||
while (textNodes.nextNode()) {
|
||||
var n = textNodes.currentNode,
|
||||
text = n.nodeValue;
|
||||
if (text && acceptNode(n)) {
|
||||
text = quotes(text);
|
||||
text = punctuation(text);
|
||||
n.nodeValue = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function acceptNode(node) {
|
||||
var parent = node.parentElement;
|
||||
var isMath = (parent && parent.getAttribute && parent.getAttribute("class")) ? parent.getAttribute("class").includes("katex") || parent.getAttribute("class").includes("MathJax") : false;
|
||||
return parent &&
|
||||
parent.nodeName !== "SCRIPT" &&
|
||||
parent.nodeName !== "STYLE" &&
|
||||
parent.nodeName !== "CODE" &&
|
||||
parent.nodeName !== "PRE" &&
|
||||
parent.nodeName !== "SPAN" &&
|
||||
parent.nodeName !== "DT-HEADER" &&
|
||||
parent.nodeName !== "DT-BYLINE" &&
|
||||
parent.nodeName !== "DT-MATH" &&
|
||||
parent.nodeName !== "DT-CODE" &&
|
||||
parent.nodeName !== "DT-BIBLIOGRAPHY" &&
|
||||
parent.nodeName !== "DT-FOOTER" &&
|
||||
parent.nodeType !== 8 && //comment nodes
|
||||
!isMath;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* typeset - Typesetting for the web
|
||||
* @version v0.1.6
|
||||
* @link https://github.com/davidmerfield/Typeset.js
|
||||
* @author David Merfield
|
||||
*/
|
||||
// which has a CC0 license
|
||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
|
||||
function punctuation(text){
|
||||
|
||||
// Dashes
|
||||
text = text.replace(/--/g, '\u2014');
|
||||
text = text.replace(/ \u2014 /g,"\u2009\u2014\u2009"); //this has thin spaces
|
||||
|
||||
// The following are temporary commented out because incompatibility
|
||||
// with katex
|
||||
|
||||
// Elipses
|
||||
// text = text.replace(/\.\.\./g,'…');
|
||||
|
||||
// Nbsp for punc with spaces
|
||||
// var NBSP = "\u00a0";
|
||||
// var NBSP_PUNCTUATION_START = /([«¿¡]) /g;
|
||||
// var NBSP_PUNCTUATION_END = / ([\!\?:;\.,‽»])/g;
|
||||
|
||||
// text = text.replace(NBSP_PUNCTUATION_START, '$1' + NBSP);
|
||||
// text = text.replace(NBSP_PUNCTUATION_END, NBSP + '$1');
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
function quotes(text) {
|
||||
|
||||
text = text
|
||||
.replace(/(\W|^)"([^\s\!\?:;\.,‽»])/g, '$1\u201c$2') // beginning "
|
||||
.replace(/(\u201c[^"]*)"([^"]*$|[^\u201c"]*\u201c)/g, '$1\u201d$2') // ending "
|
||||
.replace(/([^0-9])"/g,'$1\u201d') // remaining " at end of word
|
||||
.replace(/(\W|^)'(\S)/g, '$1\u2018$2') // beginning '
|
||||
.replace(/([a-z])'([a-z])/ig, '$1\u2019$2') // conjunction's possession
|
||||
.replace(/((\u2018[^']*)|[a-z])'([^0-9]|$)/ig, '$1\u2019$3') // ending '
|
||||
.replace(/(\u2018)([0-9]{2}[^\u2019]*)(\u2018([^0-9]|$)|$|\u2019[a-z])/ig, '\u2019$2$3') // abbrev. years like '93
|
||||
.replace(/(\B|^)\u2018(?=([^\u2019]*\u2019\b)*([^\u2019\u2018]*\W[\u2019\u2018]\b|[^\u2019\u2018]*$))/ig, '$1\u2019') // backwards apostrophe
|
||||
.replace(/'''/g, '\u2034') // triple prime
|
||||
.replace(/("|'')/g, '\u2033') // double prime
|
||||
.replace(/'/g, '\u2032');
|
||||
|
||||
// Allow escaped quotes
|
||||
text = text.replace(/\\“/, '\"');
|
||||
text = text.replace(/\\”/, '\"');
|
||||
text = text.replace(/\\’/, '\'');
|
||||
text = text.replace(/\\‘/, '\'');
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
function ligatures(text){
|
||||
|
||||
// text = text.replace(/fi/g, 'fi');
|
||||
// text = text.replace(/fl/g, 'fl');
|
||||
|
||||
return text;
|
||||
};
|
||||
Vendored
-18277
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,188 @@
|
||||
<!doctype html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
|
||||
<script src="../dist/components.js"></script>
|
||||
|
||||
<d-front-matter>
|
||||
<script type="text/yml">
|
||||
title: Demo Title Attention and Augmented Recurrent Neural Networks
|
||||
published: Jan 10, 2017
|
||||
authors:
|
||||
- Chris Olah:
|
||||
- Shan Carter: http://shancarter.com
|
||||
affiliations:
|
||||
- Google Brain
|
||||
- Google Brain: http://g.co/brain
|
||||
</script>
|
||||
</d-front-matter>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<d-article>
|
||||
<d-title>
|
||||
<h1>Attention and Augmented Recurrent Neural Networks</h1>
|
||||
<!-- <h2>Some people want a deck</h2> -->
|
||||
<d-byline></d-byline>
|
||||
</d-title>
|
||||
<d-abstract>
|
||||
<p>This is the first paragraph of the article. Test a long — dash -- here it is.</p>
|
||||
</d-abstract>
|
||||
<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>
|
||||
<hr>
|
||||
<div style="max-width: 800px; background-color: red; height: 100px; border-radius: 50px;"></div>
|
||||
<p>Here's a test of an inline equation <d-math>c = a^2 + b^2</d-math>. And then there's a block equation:</p>
|
||||
<d-math block>
|
||||
c = \pm \sqrt{ \sum_{i=0}^{n}{a^{222} + b^2}}
|
||||
</d-math>
|
||||
<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>
|
||||
<h2>Displaying code snippets</h2>
|
||||
<p>Some inline javascript:<d-code language="javascript">var x = 25;</d-code></p>
|
||||
<p>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>That's it for the example article!</p>
|
||||
<aside>Some text.</aside>
|
||||
</d-article>
|
||||
|
||||
<d-appendix>
|
||||
<d-acknowledgements>
|
||||
<h3>Contributions</h3>
|
||||
<p>Some text describing who did what.</p>
|
||||
<h4>Reviewers</h4>
|
||||
<p>Some text with links describing who reviewed the article.</p>
|
||||
</d-acknowledgements>
|
||||
|
||||
<d-footnote-list></d-footnote-list>
|
||||
|
||||
<d-bibliography><script type="text/bibtex">
|
||||
|
||||
@article{gregor2015draw,
|
||||
title={DRAW: A recurrent neural network for image generation},
|
||||
author={Gregor, Karol and Danihelka, Ivo and Graves, Alex and Rezende, Danilo Jimenez and Wierstra, Daan},
|
||||
journal={arXiv preprint arXiv:1502.04623},
|
||||
year={2015},
|
||||
url ={https://arxiv.org/pdf/1502.04623.pdf}
|
||||
}
|
||||
@article{mercier2011humans,
|
||||
title={Why do humans reason? Arguments for an argumentative theory},
|
||||
author={Mercier, Hugo and Sperber, Dan},
|
||||
journal={Behavioral and brain sciences},
|
||||
volume={34},
|
||||
number={02},
|
||||
pages={57--74},
|
||||
year={2011},
|
||||
publisher={Cambridge Univ Press},
|
||||
doi={10.1017/S0140525X10000968}
|
||||
}
|
||||
|
||||
@article{dong2014image,
|
||||
title={Image super-resolution using deep convolutional networks},
|
||||
author={Dong, Chao and Loy, Chen Change and He, Kaiming and Tang, Xiaoou},
|
||||
journal={arXiv preprint arXiv:1501.00092},
|
||||
year={2014},
|
||||
url={https://arxiv.org/pdf/1501.00092.pdf}
|
||||
}
|
||||
|
||||
@article{dumoulin2016adversarially,
|
||||
title={Adversarially Learned Inference},
|
||||
author={Dumoulin, Vincent and Belghazi, Ishmael and Poole, Ben and Lamb, Alex and Arjovsky, Martin and Mastropietro, Olivier and Courville, Aaron},
|
||||
journal={arXiv preprint arXiv:1606.00704},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1606.00704.pdf}
|
||||
}
|
||||
|
||||
@article{dumoulin2016guide,
|
||||
title={A guide to convolution arithmetic for deep learning},
|
||||
author={Dumoulin, Vincent and Visin, Francesco},
|
||||
journal={arXiv preprint arXiv:1603.07285},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1603.07285.pdf}
|
||||
}
|
||||
|
||||
@article{gauthier2014conditional,
|
||||
title={Conditional generative adversarial nets for convolutional face generation},
|
||||
author={Gauthier, Jon},
|
||||
journal={Class Project for Stanford CS231N: Convolutional Neural Networks for Visual Recognition, Winter semester},
|
||||
volume={2014},
|
||||
year={2014},
|
||||
url={http://www.foldl.me/uploads/papers/tr-cgans.pdf}
|
||||
}
|
||||
|
||||
@article{johnson2016perceptual,
|
||||
title={Perceptual losses for real-time style transfer and super-resolution},
|
||||
author={Johnson, Justin and Alahi, Alexandre and Fei-Fei, Li},
|
||||
journal={arXiv preprint arXiv:1603.08155},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1603.08155.pdf}
|
||||
}
|
||||
|
||||
@article{mordvintsev2015inceptionism,
|
||||
title={Inceptionism: Going deeper into neural networks},
|
||||
author={Mordvintsev, Alexander and Olah, Christopher and Tyka, Mike},
|
||||
journal={Google Research Blog},
|
||||
year={2015},
|
||||
url={https://research.googleblog.com/2015/06/inceptionism-going-deeper-into-neural.html}
|
||||
}
|
||||
|
||||
@misc{mordvintsev2016deepdreaming,
|
||||
title={DeepDreaming with TensorFlow},
|
||||
author={Mordvintsev, Alexander},
|
||||
year={2016},
|
||||
url={https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/deepdream/deepdream.ipynb},
|
||||
}
|
||||
|
||||
@article{radford2015unsupervised,
|
||||
title={Unsupervised representation learning with deep convolutional generative adversarial networks},
|
||||
author={Radford, Alec and Metz, Luke and Chintala, Soumith},
|
||||
journal={arXiv preprint arXiv:1511.06434},
|
||||
year={2015},
|
||||
url={https://arxiv.org/pdf/1511.06434.pdf}
|
||||
}
|
||||
|
||||
@inproceedings{salimans2016improved,
|
||||
title={Improved techniques for training gans},
|
||||
author={Salimans, Tim and Goodfellow, Ian and Zaremba, Wojciech and Cheung, Vicki and Radford, Alec and Chen, Xi},
|
||||
booktitle={Advances in Neural Information Processing Systems},
|
||||
pages={2226--2234},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1606.03498.pdf}
|
||||
}
|
||||
|
||||
@article{shi2016deconvolution,
|
||||
title={Is the deconvolution layer the same as a convolutional layer?},
|
||||
author={Shi, Wenzhe and Caballero, Jose and Theis, Lucas and Huszar, Ferenc and Aitken, Andrew and Ledig, Christian and Wang, Zehan},
|
||||
journal={arXiv preprint arXiv:1609.07009},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1609.07009.pdf}
|
||||
}
|
||||
|
||||
</script></d-bibliography>
|
||||
|
||||
<distill-appendix> </distill-appendix>
|
||||
</d-appendix>
|
||||
</body>
|
||||
@@ -0,0 +1,232 @@
|
||||
<!DOCTYPE html><html lang="en"><head>
|
||||
<meta charset="utf8">
|
||||
|
||||
<script id="polyfills">
|
||||
if ('registerElement' in document &&
|
||||
'import' in document.createElement('link') &&
|
||||
'content' in document.createElement('template')) {
|
||||
// Platform supports webcomponents natively! :-)
|
||||
} else {
|
||||
// Platform does not support webcomponents--loading polyfills synchronously.
|
||||
const scriptTag = document.createElement('script');
|
||||
scriptTag.src = '../dist/webcomponents-lite.js';
|
||||
scriptTag.async = false;
|
||||
document.currentScript.parentNode.insertBefore(scriptTag, document.currentScript.nextSibling);
|
||||
}
|
||||
</script><script src="../dist/components.js"></script>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA99JREFUeNrsG4t1ozDMzQSM4A2ODUonKBucN2hugtIJ6E1AboLcBiQTkJsANiAb9OCd/OpzMWBJBl5TvaeXPiiyJetry0J8wW3D3QpjRh3GjneXDq+fSQA9s2mH9x3KDhN4foJfCb8N/Jrv+2fnDn8vLRQOplWHVYdvHZYdZsBcZP1vBmh/n8DzEmhUQDPaOuP9pFuY+JwJHwHnCLQE2tnWBGEyXozY9xCUgHMhhjE2I4heVWtgIkZ83wL6Qgxj1obfWBxymPwe+b00BCCRNPbwfb60yleAkkBHGT5AEehIYz7eJrFDMF9CvH4wwhcGHiHMneFvLDQwlwvMLQq58trRcYBWfYn0A0OgHWQUSu25mE+BnoYKnnEJoeIWAifzOv7vLWd2ZKRfWAIme3tOiUaQ3UnLkb0xj1FxRIeEGKaGIHOs9nEgLaaA9i0JRYo1Ic67wJW86KSKE/ZAM8KuVMk8ITVhmxUxJ3Cl2xlm9Vtkeju1+mpCQNxaEGNCY8bs9X2YqwNoQeGjBWut/ma0QAWy/TqAsHx9wSya3I5IRxOfTC+leG+kA/4vSeEcGBtNUN6byhu3+keEZCQJUNh8MAO7HL6H8pQLnsW/Hd4T4lv93TPjfM7A46iEEqbB5EDOvwYNW6tGNZzT/o+CZ6sqZ6wUtR/wf7mi/VL8iNciT6rHih48Y55b4nKCHJCCzb4y0nwFmin3ZEMIoLfZF8F7nncFmvnWBaBj7CGAYA/WGJsUwHdYqVDwAmNsUgAx4CGgAA7GOOxADYOFWOaIKifuVYzmOpREqA21Mo7aPsgiY1PhOMAmxtR+AUbYH3Id2wc0SAFIQTsn9IUGWR8k9jx3vtXSiAacFxTAGakBk9UudkNECd6jLe+6HrshshvIuC6IlLMRy7er+JpcKma24SlE4cFZSZJDGVVrsNvitQhQrDhW0jfiOLfFd47C42eHT56D/BK0To+58Ahj+cAT8HT1UWlfLZCCd/uKawzU0Rh2EyIX/Icqth3niG8ybNroezwe6khdCNxRN+l4XGdOLVLlOOt2hTRJlr1ETIuMAltVTMz70mJrkdGAaZLSmnBEqmAE32JCMmuTlCnRgsBENtOUpHhvvsYIL0ibnBkaC6QvKcR7738GKp0AKnim7xgUSNv1bpS8QwhBt8r+EP47v/oyRK/S34yJ9nT+AN0Tkm4OdB9E4BsmXM3SnMlRFUrtp6IDpV2eKzdYvF3etm3KhQksbOLChGkSmcBdmcEwvqkrMy5BzL00NZeu3qPYJOOuCc+5NjcWKXQxFvTa3NoXJ4d8in7fiAUuTt781dkvuHX4K8AA2Usy7yNKLy0AAAAASUVORK5CYII=
|
||||
">
|
||||
<link href="/rss.xml" rel="alternate" type="application/rss+xml" title="Articles from Distill">
|
||||
<link rel="canonical" href="undefined">
|
||||
<title>Demo Title Attention and Augmented Recurrent Neural Networks</title>
|
||||
|
||||
<!-- https://schema.org/Article -->
|
||||
<meta property="article:published" itemprop="datePublished" content="undefined-undefined-undefined">
|
||||
<meta property="article:modified" itemprop="dateModified" content="undefined">
|
||||
|
||||
<meta property="article:author" content="undefined undefined">
|
||||
<meta property="article:author" content="undefined undefined">
|
||||
<!-- https://developers.facebook.com/docs/sharing/webmasters#markup -->
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:title" content="Demo Title Attention and Augmented Recurrent Neural Networks">
|
||||
<meta property="og:description" content="undefined">
|
||||
<meta property="og:url" content="undefined">
|
||||
<meta property="og:image" content="undefined/thumbnail.jpg">
|
||||
<meta property="og:locale" content="en_US">
|
||||
<meta property="og:site_name" content="Distill">
|
||||
|
||||
<!-- https://dev.twitter.com/cards/types/summary -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="Demo Title Attention and Augmented Recurrent Neural Networks">
|
||||
<meta name="twitter:description" content="undefined">
|
||||
<meta name="twitter:url" content="undefined">
|
||||
<meta name="twitter:image" content="undefined/thumbnail.jpg">
|
||||
<meta name="twitter:image:width" content="560">
|
||||
<meta name="twitter:image:height" content="295">
|
||||
</head><body><distill-header></distill-header><d-front-matter>
|
||||
<script type="text/yml">
|
||||
title: Demo Title Attention and Augmented Recurrent Neural Networks
|
||||
published: Jan 10, 2017
|
||||
authors:
|
||||
- Chris Olah:
|
||||
- Shan Carter: http://shancarter.com
|
||||
affiliations:
|
||||
- Google Brain:
|
||||
- Google Brain: http://g.co/brain
|
||||
</script>
|
||||
</d-front-matter>
|
||||
|
||||
|
||||
|
||||
<d-article>
|
||||
<d-title>
|
||||
<h1>Attention and Augmented Recurrent Neural Networks</h1>
|
||||
<!-- <h2>Some people want a deck</h2> -->
|
||||
<d-byline></d-byline>
|
||||
</d-title>
|
||||
|
||||
<d-abstract>
|
||||
<p>This is the first paragraph of the article. Test a long — dash — here it is.</p>
|
||||
</d-abstract>
|
||||
<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>
|
||||
<p>Here’s a test of an inline equation <d-math>c = a^2 + b^2</d-math>. 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>We can<d-cite key="mercier2011humans"></d-cite> also cite <d-cite key="gregor2015draw,mercier2011humans"></d-cite> external publications. <d-cite key="dong2014image,dumoulin2016guide,mordvintsev2015inceptionism"></d-cite></p>
|
||||
<p>We should also be testing footnotes<d-footnote>This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote.</d-footnote>. There are multiple footnotes, and they appear in the appendix<d-footnote>Given I have coded them right. Also, here’s math in a footnote: <d-math>c = \sum_0^i{x}</d-math>. Also, a citation. Box-ception<d-cite key="gregor2015draw"></d-cite>!</d-footnote> as well.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>First</th><th>Second</th><th>Third</th></tr>
|
||||
</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>
|
||||
<h2>Displaying code snippets</h2>
|
||||
<p>Some inline javascript:<d-code language="javascript">var x = 25;</d-code></p>
|
||||
<p>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>That’s it for the example article!</p>
|
||||
</d-article>
|
||||
|
||||
<d-appendix>
|
||||
<d-acknowledgements>
|
||||
<h3>Contributions</h3>
|
||||
<p>Some text describing who did what.</p>
|
||||
<h4>Reviewers</h4>
|
||||
<p>Some text with links describing who reviewed the article.</p>
|
||||
</d-acknowledgements>
|
||||
|
||||
<d-footnote-list></d-footnote-list>
|
||||
|
||||
<d-bibliography>
|
||||
<script type="text/bibtex">
|
||||
|
||||
@article{gregor2015draw,
|
||||
title={DRAW: A recurrent neural network for image generation},
|
||||
author={Gregor, Karol and Danihelka, Ivo and Graves, Alex and Rezende, Danilo Jimenez and Wierstra, Daan},
|
||||
journal={arXiv preprint arXiv:1502.04623},
|
||||
year={2015},
|
||||
url ={https://arxiv.org/pdf/1502.04623.pdf}
|
||||
}
|
||||
@article{mercier2011humans,
|
||||
title={Why do humans reason? Arguments for an argumentative theory},
|
||||
author={Mercier, Hugo and Sperber, Dan},
|
||||
journal={Behavioral and brain sciences},
|
||||
volume={34},
|
||||
number={02},
|
||||
pages={57--74},
|
||||
year={2011},
|
||||
publisher={Cambridge Univ Press},
|
||||
doi={10.1017/S0140525X10000968}
|
||||
}
|
||||
|
||||
@article{dong2014image,
|
||||
title={Image super-resolution using deep convolutional networks},
|
||||
author={Dong, Chao and Loy, Chen Change and He, Kaiming and Tang, Xiaoou},
|
||||
journal={arXiv preprint arXiv:1501.00092},
|
||||
year={2014},
|
||||
url={https://arxiv.org/pdf/1501.00092.pdf}
|
||||
}
|
||||
|
||||
@article{dumoulin2016adversarially,
|
||||
title={Adversarially Learned Inference},
|
||||
author={Dumoulin, Vincent and Belghazi, Ishmael and Poole, Ben and Lamb, Alex and Arjovsky, Martin and Mastropietro, Olivier and Courville, Aaron},
|
||||
journal={arXiv preprint arXiv:1606.00704},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1606.00704.pdf}
|
||||
}
|
||||
|
||||
@article{dumoulin2016guide,
|
||||
title={A guide to convolution arithmetic for deep learning},
|
||||
author={Dumoulin, Vincent and Visin, Francesco},
|
||||
journal={arXiv preprint arXiv:1603.07285},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1603.07285.pdf}
|
||||
}
|
||||
|
||||
@article{gauthier2014conditional,
|
||||
title={Conditional generative adversarial nets for convolutional face generation},
|
||||
author={Gauthier, Jon},
|
||||
journal={Class Project for Stanford CS231N: Convolutional Neural Networks for Visual Recognition, Winter semester},
|
||||
volume={2014},
|
||||
year={2014},
|
||||
url={http://www.foldl.me/uploads/papers/tr-cgans.pdf}
|
||||
}
|
||||
|
||||
@article{johnson2016perceptual,
|
||||
title={Perceptual losses for real-time style transfer and super-resolution},
|
||||
author={Johnson, Justin and Alahi, Alexandre and Fei-Fei, Li},
|
||||
journal={arXiv preprint arXiv:1603.08155},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1603.08155.pdf}
|
||||
}
|
||||
|
||||
@article{mordvintsev2015inceptionism,
|
||||
title={Inceptionism: Going deeper into neural networks},
|
||||
author={Mordvintsev, Alexander and Olah, Christopher and Tyka, Mike},
|
||||
journal={Google Research Blog},
|
||||
year={2015},
|
||||
url={https://research.googleblog.com/2015/06/inceptionism-going-deeper-into-neural.html}
|
||||
}
|
||||
|
||||
@misc{mordvintsev2016deepdreaming,
|
||||
title={DeepDreaming with TensorFlow},
|
||||
author={Mordvintsev, Alexander},
|
||||
year={2016},
|
||||
url={https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/deepdream/deepdream.ipynb},
|
||||
}
|
||||
|
||||
@article{radford2015unsupervised,
|
||||
title={Unsupervised representation learning with deep convolutional generative adversarial networks},
|
||||
author={Radford, Alec and Metz, Luke and Chintala, Soumith},
|
||||
journal={arXiv preprint arXiv:1511.06434},
|
||||
year={2015},
|
||||
url={https://arxiv.org/pdf/1511.06434.pdf}
|
||||
}
|
||||
|
||||
@inproceedings{salimans2016improved,
|
||||
title={Improved techniques for training gans},
|
||||
author={Salimans, Tim and Goodfellow, Ian and Zaremba, Wojciech and Cheung, Vicki and Radford, Alec and Chen, Xi},
|
||||
booktitle={Advances in Neural Information Processing Systems},
|
||||
pages={2226--2234},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1606.03498.pdf}
|
||||
}
|
||||
|
||||
@article{shi2016deconvolution,
|
||||
title={Is the deconvolution layer the same as a convolutional layer?},
|
||||
author={Shi, Wenzhe and Caballero, Jose and Theis, Lucas and Huszar, Ferenc and Aitken, Andrew and Ledig, Christian and Wang, Zehan},
|
||||
journal={arXiv preprint arXiv:1609.07009},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1609.07009.pdf}
|
||||
}
|
||||
|
||||
</script>
|
||||
</d-bibliography>
|
||||
|
||||
<distill-appendix> </distill-appendix>
|
||||
</d-appendix>
|
||||
|
||||
<distill-footer></distill-footer></body></html>
|
||||
+187
-154
@@ -1,30 +1,52 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf8">
|
||||
<script src="../dist/template.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" integrity="sha384-wITovz90syo1dJWVh32uuETPVEtGigN07tkttEqPv+uR2SE/mbQcG7ATL28aI9H0" crossorigin="anonymous">
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<script src="../dist/template.v2.js"></script>
|
||||
|
||||
<script type="text/front-matter">
|
||||
title: Article Title
|
||||
published: Jan 10, 2017
|
||||
authors:
|
||||
- Chris Olah:
|
||||
- Shan Carter: http://shancarter.com
|
||||
affiliations:
|
||||
- Google Brain:
|
||||
- Google Brain: http://g.co/brain
|
||||
</script>
|
||||
<d-front-matter>
|
||||
<script type="text/yml">
|
||||
title: Demo Title Attention and Augmented Recurrent Neural Networks
|
||||
published: Jan 10, 2017
|
||||
authors:
|
||||
- Chris Olah:
|
||||
- Shan Carter: http://shancarter.com
|
||||
affiliations:
|
||||
- Google Brain
|
||||
- Google Brain: http://g.co/brain
|
||||
</script>
|
||||
</d-front-matter>
|
||||
</head>
|
||||
|
||||
<dt-article>
|
||||
<script type="text/article"></script>
|
||||
<h1>Hello World</h1>
|
||||
<h2>A description of the article</h2>
|
||||
<dt-byline></dt-byline>
|
||||
<body>
|
||||
<d-article>
|
||||
<d-title>
|
||||
<h1>Attention and Augmented Recurrent Neural Networks</h1>
|
||||
<h2>Some people want a deck</h2>
|
||||
<d-byline></d-byline>
|
||||
</d-title>
|
||||
<d-abstract>
|
||||
<p>This is the first paragraph of the article. Test a long — dash -- here it is.</p>
|
||||
</d-abstract>
|
||||
<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.</p>
|
||||
<p>Here's a test of an inline equation <dt-math>c = a^2 + b^2</dt-math>.</p>
|
||||
<dt-math block>c = \pm\sqrt{a^2 + b^2}</dt-math>
|
||||
<p>We can also cite <dt-cite key="gregor2015draw,mercier2011humans"></dt-cite> external publications. <dt-cite key="dong2014image,dumoulin2016guide,mordvintsev2015inceptionism"></dt-cite> We should also be testing footnotes<dt-fn>This will become a hoverable footnote.</dt-fn>.</p>
|
||||
<p>Test for owner's possessive. Test for "quoting a passage." And another sentence. Or two. Some flopping fins; for diving.</p>
|
||||
<hr>
|
||||
<div style="max-width: 800px; background-color: red; height: 100px; border-radius: 50px;"></div>
|
||||
<p>Here's a test of an inline equation <d-math>c = a^2 + b^2</d-math>. 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:
|
||||
<d-math block>
|
||||
f(x) = \int_{-\infty}^\infty\hat f(\xi)\,e^{2 \pi i \xi x}\,d\xi
|
||||
</d-math>
|
||||
<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>
|
||||
</p>
|
||||
<p>We can<d-cite key="mercier2011humans"></d-cite> also cite <d-cite key="gregor2015draw,mercier2011humans"></d-cite> external publications. <d-cite key="dong2014image,dumoulin2016guide,mordvintsev2015inceptionism"></d-cite></p>
|
||||
<p>We should also be testing footnotes<d-footnote>This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote.</d-footnote>. There are multiple footnotes, and they appear in the appendix<d-footnote>Given I have coded them right. Also, here's math in a footnote: <d-math>c = \sum_0^i{x}</d-math>. Also, a citation. Box-ception<d-cite key='gregor2015draw'></d-cite>!</d-footnote> as well.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>First</th><th>Second</th><th>Third</th></tr>
|
||||
@@ -35,153 +57,164 @@
|
||||
<tr><td>234</td><td>54</td><td>23</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2>Displaying code snippets</h2>
|
||||
<p>Some inline javascript:<d-code language="javascript">var x = 25;</d-code></p>
|
||||
<p>Here's a javascript code block.</p>
|
||||
<dt-code block language="javascript">
|
||||
var x = 25;
|
||||
function(x){
|
||||
return x * x;
|
||||
}
|
||||
</dt-code>
|
||||
<d-code block language="javascript">
|
||||
var x = 25;
|
||||
function(x){
|
||||
return x * x;
|
||||
}
|
||||
</d-code>
|
||||
<p>We also support python.</p>
|
||||
<dt-code block language="python">
|
||||
<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
|
||||
</dt-code>
|
||||
</dt-article>
|
||||
def fib(n):
|
||||
a, b = 0, 1
|
||||
while a < n:
|
||||
print(a, end=' ')
|
||||
a, b = b, a+b
|
||||
</d-code>
|
||||
<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>
|
||||
<aside>Some text.</aside>
|
||||
</d-article>
|
||||
|
||||
<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={arXiv preprint arXiv:1502.04623},
|
||||
year={2015},
|
||||
url ={https://arxiv.org/pdf/1502.04623.pdf}
|
||||
}
|
||||
@article{mercier2011humans,
|
||||
title={Why do humans reason? Arguments for an argumentative theory},
|
||||
author={Mercier, Hugo and Sperber, Dan},
|
||||
journal={Behavioral and brain sciences},
|
||||
volume={34},
|
||||
number={02},
|
||||
pages={57--74},
|
||||
year={2011},
|
||||
publisher={Cambridge Univ Press},
|
||||
doi={10.1017/S0140525X10000968}
|
||||
}
|
||||
<d-appendix>
|
||||
<d-acknowledgements>
|
||||
<h3>Contributions</h3>
|
||||
<p>Some text describing who did what.</p>
|
||||
<h4>Reviewers</h4>
|
||||
<p>Some text with links describing who reviewed the article.</p>
|
||||
</d-acknowledgements>
|
||||
|
||||
@article{dong2014image,
|
||||
title={Image super-resolution using deep convolutional networks},
|
||||
author={Dong, Chao and Loy, Chen Change and He, Kaiming and Tang, Xiaoou},
|
||||
journal={arXiv preprint arXiv:1501.00092},
|
||||
year={2014},
|
||||
url={https://arxiv.org/pdf/1501.00092.pdf}
|
||||
}
|
||||
<d-footnote-list></d-footnote-list>
|
||||
|
||||
@article{dumoulin2016adversarially,
|
||||
title={Adversarially Learned Inference},
|
||||
author={Dumoulin, Vincent and Belghazi, Ishmael and Poole, Ben and Lamb, Alex and Arjovsky, Martin and Mastropietro, Olivier and Courville, Aaron},
|
||||
journal={arXiv preprint arXiv:1606.00704},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1606.00704.pdf}
|
||||
}
|
||||
<d-bibliography><script type="text/bibtex">
|
||||
|
||||
@article{dumoulin2016guide,
|
||||
title={A guide to convolution arithmetic for deep learning},
|
||||
author={Dumoulin, Vincent and Visin, Francesco},
|
||||
journal={arXiv preprint arXiv:1603.07285},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1603.07285.pdf}
|
||||
}
|
||||
@article{gregor2015draw,
|
||||
title={DRAW: A recurrent neural network for image generation},
|
||||
author={Gregor, Karol and Danihelka, Ivo and Graves, Alex and Rezende, Danilo Jimenez and Wierstra, Daan},
|
||||
journal={arXiv preprint arXiv:1502.04623},
|
||||
year={2015},
|
||||
url ={https://arxiv.org/pdf/1502.04623.pdf}
|
||||
}
|
||||
@article{mercier2011humans,
|
||||
title={Why do humans reason? Arguments for an argumentative theory},
|
||||
author={Mercier, Hugo and Sperber, Dan},
|
||||
journal={Behavioral and brain sciences},
|
||||
volume={34},
|
||||
number={02},
|
||||
pages={57--74},
|
||||
year={2011},
|
||||
publisher={Cambridge Univ Press},
|
||||
doi={10.1017/S0140525X10000968}
|
||||
}
|
||||
|
||||
@article{donahue2016adversarial,
|
||||
title={Adversarial Feature Learning},
|
||||
author={Donahue, Jeff and Kr{\"a}henb{\"u}hl, Philipp and Darrell, Trevor},
|
||||
journal={arXiv preprint arXiv:1605.09782},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1605.09782.pdf}
|
||||
}
|
||||
@article{dong2014image,
|
||||
title={Image super-resolution using deep convolutional networks},
|
||||
author={Dong, Chao and Loy, Chen Change and He, Kaiming and Tang, Xiaoou},
|
||||
journal={arXiv preprint arXiv:1501.00092},
|
||||
year={2014},
|
||||
url={https://arxiv.org/pdf/1501.00092.pdf}
|
||||
}
|
||||
|
||||
@article{gauthier2014conditional,
|
||||
title={Conditional generative adversarial nets for convolutional face generation},
|
||||
author={Gauthier, Jon},
|
||||
journal={Class Project for Stanford CS231N: Convolutional Neural Networks for Visual Recognition, Winter semester},
|
||||
volume={2014},
|
||||
year={2014},
|
||||
url={http://www.foldl.me/uploads/papers/tr-cgans.pdf}
|
||||
}
|
||||
@article{dumoulin2016adversarially,
|
||||
title={Adversarially Learned Inference},
|
||||
author={Dumoulin, Vincent and Belghazi, Ishmael and Poole, Ben and Lamb, Alex and Arjovsky, Martin and Mastropietro, Olivier and Courville, Aaron},
|
||||
journal={arXiv preprint arXiv:1606.00704},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1606.00704.pdf}
|
||||
}
|
||||
|
||||
@article{henaff2015geodesics,
|
||||
title={Geodesics of learned representations},
|
||||
author={H{\'e}naff, Olivier J and Simoncelli, Eero P},
|
||||
journal={arXiv preprint arXiv:1511.06394},
|
||||
year={2015},
|
||||
url={https://arxiv.org/pdf/1511.06394.pdf}
|
||||
}
|
||||
@article{dumoulin2016guide,
|
||||
title={A guide to convolution arithmetic for deep learning},
|
||||
author={Dumoulin, Vincent and Visin, Francesco},
|
||||
journal={arXiv preprint arXiv:1603.07285},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1603.07285.pdf}
|
||||
}
|
||||
|
||||
@article{johnson2016perceptual,
|
||||
title={Perceptual losses for real-time style transfer and super-resolution},
|
||||
author={Johnson, Justin and Alahi, Alexandre and Fei-Fei, Li},
|
||||
journal={arXiv preprint arXiv:1603.08155},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1603.08155.pdf}
|
||||
}
|
||||
@article{gauthier2014conditional,
|
||||
title={Conditional generative adversarial nets for convolutional face generation},
|
||||
author={Gauthier, Jon},
|
||||
journal={Class Project for Stanford CS231N: Convolutional Neural Networks for Visual Recognition, Winter semester},
|
||||
volume={2014},
|
||||
year={2014},
|
||||
url={http://www.foldl.me/uploads/papers/tr-cgans.pdf}
|
||||
}
|
||||
|
||||
@article{mordvintsev2015inceptionism,
|
||||
title={Inceptionism: Going deeper into neural networks},
|
||||
author={Mordvintsev, Alexander and Olah, Christopher and Tyka, Mike},
|
||||
journal={Google Research Blog},
|
||||
year={2015},
|
||||
url={https://research.googleblog.com/2015/06/inceptionism-going-deeper-into-neural.html}
|
||||
}
|
||||
@article{johnson2016perceptual,
|
||||
title={Perceptual losses for real-time style transfer and super-resolution},
|
||||
author={Johnson, Justin and Alahi, Alexandre and Fei-Fei, Li},
|
||||
journal={arXiv preprint arXiv:1603.08155},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1603.08155.pdf}
|
||||
}
|
||||
|
||||
@misc{mordvintsev2016deepdreaming,
|
||||
title={DeepDreaming with TensorFlow},
|
||||
author={Mordvintsev, Alexander},
|
||||
year={2016},
|
||||
url={https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/deepdream/deepdream.ipynb},
|
||||
}
|
||||
@article{mordvintsev2015inceptionism,
|
||||
title={Inceptionism: Going deeper into neural networks},
|
||||
author={Mordvintsev, Alexander and Olah, Christopher and Tyka, Mike},
|
||||
journal={Google Research Blog},
|
||||
year={2015},
|
||||
url={https://research.googleblog.com/2015/06/inceptionism-going-deeper-into-neural.html}
|
||||
}
|
||||
|
||||
@article{radford2015unsupervised,
|
||||
title={Unsupervised representation learning with deep convolutional generative adversarial networks},
|
||||
author={Radford, Alec and Metz, Luke and Chintala, Soumith},
|
||||
journal={arXiv preprint arXiv:1511.06434},
|
||||
year={2015},
|
||||
url={https://arxiv.org/pdf/1511.06434.pdf}
|
||||
}
|
||||
@misc{mordvintsev2016deepdreaming,
|
||||
title={DeepDreaming with TensorFlow},
|
||||
author={Mordvintsev, Alexander},
|
||||
year={2016},
|
||||
url={https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/deepdream/deepdream.ipynb},
|
||||
}
|
||||
|
||||
@inproceedings{salimans2016improved,
|
||||
title={Improved techniques for training gans},
|
||||
author={Salimans, Tim and Goodfellow, Ian and Zaremba, Wojciech and Cheung, Vicki and Radford, Alec and Chen, Xi},
|
||||
booktitle={Advances in Neural Information Processing Systems},
|
||||
pages={2226--2234},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1606.03498.pdf}
|
||||
}
|
||||
@article{radford2015unsupervised,
|
||||
title={Unsupervised representation learning with deep convolutional generative adversarial networks},
|
||||
author={Radford, Alec and Metz, Luke and Chintala, Soumith},
|
||||
journal={arXiv preprint arXiv:1511.06434},
|
||||
year={2015},
|
||||
url={https://arxiv.org/pdf/1511.06434.pdf}
|
||||
}
|
||||
|
||||
@article{shi2016deconvolution,
|
||||
title={Is the deconvolution layer the same as a convolutional layer?},
|
||||
author={Shi, Wenzhe and Caballero, Jose and Theis, Lucas and Huszar, Ferenc and Aitken, Andrew and Ledig, Christian and Wang, Zehan},
|
||||
journal={arXiv preprint arXiv:1609.07009},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1609.07009.pdf}
|
||||
}
|
||||
@inproceedings{salimans2016improved,
|
||||
title={Improved techniques for training gans},
|
||||
author={Salimans, Tim and Goodfellow, Ian and Zaremba, Wojciech and Cheung, Vicki and Radford, Alec and Chen, Xi},
|
||||
booktitle={Advances in Neural Information Processing Systems},
|
||||
pages={2226--2234},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1606.03498.pdf}
|
||||
}
|
||||
|
||||
@inproceedings{shi2016real,
|
||||
title={Real-time single image and video super-resolution using an efficient sub-pixel convolutional neural network},
|
||||
author={Shi, Wenzhe and Caballero, Jose and Husz{\'a}r, Ferenc and Totz, Johannes and Aitken, Andrew P and Bishop, Rob and Rueckert, Daniel and Wang, Zehan},
|
||||
booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},
|
||||
pages={1874--1883},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1609.05158.pdf},
|
||||
doi={10.1109/cvpr.2016.207}
|
||||
}
|
||||
@article{shi2016deconvolution,
|
||||
title={Is the deconvolution layer the same as a convolutional layer?},
|
||||
author={Shi, Wenzhe and Caballero, Jose and Theis, Lucas and Huszar, Ferenc and Aitken, Andrew and Ledig, Christian and Wang, Zehan},
|
||||
journal={arXiv preprint arXiv:1609.07009},
|
||||
year={2016},
|
||||
url={https://arxiv.org/pdf/1609.07009.pdf}
|
||||
}
|
||||
|
||||
</script>
|
||||
<dt-appendix>
|
||||
<h3>Contributions</h3>
|
||||
<p>List of who did what</p>
|
||||
</dt-appendix>
|
||||
</script></d-bibliography>
|
||||
|
||||
<distill-appendix> </distill-appendix>
|
||||
</d-appendix>
|
||||
</body>
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
}
|
||||
</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>
|
||||
<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 dispalying 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>
|
||||
|
||||
@@ -1,95 +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.
|
||||
|
||||
import html from "./components/html";
|
||||
import styles from "./components/styles";
|
||||
import frontMatter from "./components/front-matter";
|
||||
import bibliography from "./components/bibliography";
|
||||
import expandData from "./components/data";
|
||||
import meta from "./components/meta";
|
||||
import banner from "./components/banner";
|
||||
import byline from "./components/byline";
|
||||
import appendix from "./components/appendix";
|
||||
import appendixDistill from "./components/appendix-distill";
|
||||
import citation from "./components/citation";
|
||||
import footnote from "./components/footnote";
|
||||
import DTMath from "./components/dt-math";
|
||||
import markdown from "./components/markdown";
|
||||
import code from "./components/code";
|
||||
import typeset from "./components/typeset";
|
||||
import hoverBox from "./components/hover-box-include";
|
||||
import generateCrossref from "./components/generate-crossref";
|
||||
import header from "./components/header";
|
||||
import footer from "./components/footer";
|
||||
|
||||
function renderImmediately(dom) {
|
||||
html(dom);
|
||||
styles(dom);
|
||||
}
|
||||
|
||||
function renderOnLoad(dom, data) {
|
||||
frontMatter(dom, data);
|
||||
bibliography(dom, data);
|
||||
expandData(dom, data);
|
||||
meta(dom, data);
|
||||
byline(dom, data);
|
||||
appendix(dom, data);
|
||||
markdown(dom, data);
|
||||
DTMath(dom, data);
|
||||
code(dom, data);
|
||||
citation(dom, data);
|
||||
footnote(dom, data);
|
||||
typeset(dom, data);
|
||||
hoverBox(dom, data);
|
||||
}
|
||||
|
||||
// If we are in a browser, render automatically...
|
||||
var browser = new Function("try { return this === window; }catch(e){ return false; }");
|
||||
if (browser) {
|
||||
try {
|
||||
var data = {};
|
||||
renderImmediately(window.document);
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
renderOnLoad(window.document, data);
|
||||
// Add a banner if we're not on localhost.
|
||||
if (window.location.hostname !== "localhost" && window.location.origin !== "file://") {
|
||||
banner(window.document, data);
|
||||
}
|
||||
generateCrossref(data);
|
||||
// console.log(data);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Window not defined");
|
||||
}
|
||||
}
|
||||
|
||||
// If we are in node...
|
||||
function render(dom, data) {
|
||||
renderImmediately(dom);
|
||||
renderOnLoad(dom, data);
|
||||
// Remove script tag so it doesn't run again in the client
|
||||
let s = dom.querySelector('script[src*="distill.pub/template"]');
|
||||
if (s) { s.parentElement.removeChild(s); };
|
||||
}
|
||||
|
||||
// Distill specific rendering
|
||||
function distillify(dom, data) {
|
||||
header(dom, data);
|
||||
appendixDistill(dom, data);
|
||||
footer(dom, data);
|
||||
}
|
||||
|
||||
export {render as render};
|
||||
export {distillify as distillify};
|
||||
export {generateCrossref as generateCrossref};
|
||||
Generated
+5763
File diff suppressed because it is too large
Load Diff
+31
-19
@@ -1,41 +1,53 @@
|
||||
{
|
||||
"name": "distill-template",
|
||||
"version": "1.1.1",
|
||||
"version": "2.0.0-alpha",
|
||||
"description": "Template for creating Distill articles.",
|
||||
"main": "dist/template.js",
|
||||
"scripts": {
|
||||
"serve": "python3 -m http.server",
|
||||
"start": "rollup -c -w",
|
||||
"build": "rollup -c",
|
||||
"test": "mocha"
|
||||
},
|
||||
"author": "Shan Carter",
|
||||
"homepage": "https://github.com/distillpub/distill-template#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/distillpub/distill-template/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "rollup -c rollup.config.dev.js -w",
|
||||
"serve": "python3 -m http.server --bind 127.0.0.1",
|
||||
"test": "mocha",
|
||||
"lint": "eslint",
|
||||
"build": "rollup -c rollup.config.js"
|
||||
},
|
||||
"repository": {
|
||||
"url": "git+https://github.com/distillpub/distill-template.git",
|
||||
"type": "git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/distillpub/distill-template/issues"
|
||||
},
|
||||
"homepage": "https://github.com/distillpub/distill-template#readme",
|
||||
"dependencies": {
|
||||
"devDependencies": {
|
||||
"bibtex-parse-js": "^0.0.23",
|
||||
"chai": "^3.5.0",
|
||||
"commander": "^2.9.0",
|
||||
"d3-time-format": "^2.0.3",
|
||||
"escape-html": "^1.0.3",
|
||||
"eslint": "^4.3.0",
|
||||
"eslint-config-google": "^0.9.1",
|
||||
"js-yaml": "^3.7.0",
|
||||
"jsdom": "^9.10.0",
|
||||
"katex": "^0.7.1",
|
||||
"marked": "^0.3.6",
|
||||
"mocha": "^3.2.0",
|
||||
"mustache": "^2.3.0",
|
||||
"prismjs": "^1.6.0",
|
||||
"rollup": "^0.36.4",
|
||||
"rollup-plugin-buble": "^0.14.0",
|
||||
"rollup": "latest",
|
||||
"rollup-plugin-babili": "^3.1.0",
|
||||
"rollup-plugin-commonjs": "^7.0.0",
|
||||
"rollup-plugin-copy": "^0.2.3",
|
||||
"rollup-plugin-gzip": "^1.2.0",
|
||||
"rollup-plugin-node-resolve": "^2.0.0",
|
||||
"rollup-plugin-serve": "^0.1.0",
|
||||
"rollup-plugin-string": "^2.0.2",
|
||||
"rollup-watch": "^2.5.0"
|
||||
"rollup-plugin-uglify": "^1.0.1",
|
||||
"rollup-watch": "^2.5.0",
|
||||
"webpack": "^2.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@webcomponents/webcomponentsjs": "^1.0.7",
|
||||
"assert": "^1.4.1",
|
||||
"d3-time-format": "^2.0.3",
|
||||
"intersection-observer": "^0.4.0",
|
||||
"jsdom-wc": "^11.0.0-alpha-1",
|
||||
"katex": "^0.7.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import string from 'rollup-plugin-string';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
|
||||
const componentsConfig = {
|
||||
entry: 'src/components.js',
|
||||
targets: [{format: 'umd', moduleName: 'dl', dest: 'dist/template.v2.js'}],
|
||||
};
|
||||
|
||||
const transformsConfig = {
|
||||
entry: 'src/transforms.js',
|
||||
targets: [{format: 'umd', moduleName: 'dl', dest: 'dist/transforms.v2.js'}],
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
export default [
|
||||
componentsConfig,
|
||||
transformsConfig,
|
||||
];
|
||||
+11
-47
@@ -1,50 +1,14 @@
|
||||
// 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 configs from './rollup.config.dev';
|
||||
import babili from 'rollup-plugin-babili';
|
||||
|
||||
import buble from 'rollup-plugin-buble';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import string from 'rollup-plugin-string';
|
||||
const [componentsConfig, transformsConfig] = configs;
|
||||
|
||||
// const PORT = 8080;
|
||||
// console.log(`open http://localhost:${PORT}/`);
|
||||
|
||||
export default {
|
||||
entry: 'index.js',
|
||||
componentsConfig.plugins.push(babili({
|
||||
comments: false, // means: *remove* comments
|
||||
sourceMap: true,
|
||||
targets: [
|
||||
{
|
||||
format: 'umd',
|
||||
moduleName: 'dl',
|
||||
dest: `dist/template.v1.js`,
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
resolve({
|
||||
jsnext: true,
|
||||
browser: true,
|
||||
}),
|
||||
string({
|
||||
include: ["**/*.txt", "**/*.svg", "**/*.html", "**/*.css", "**/*.base64"]
|
||||
}),
|
||||
buble({
|
||||
exclude: 'node_modules',
|
||||
target: { chrome: 52, safari: 8, edge: 13, firefox: 48, }
|
||||
}),
|
||||
commonjs(),
|
||||
// uglify(),
|
||||
// liveReload(),
|
||||
// serve({port: PORT}),
|
||||
]
|
||||
};
|
||||
}));
|
||||
|
||||
export default [
|
||||
componentsConfig,
|
||||
transformsConfig,
|
||||
];
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Gulp with Mustache Templates
|
||||
|
||||
To get started, make sure to run `yarn install` or `npm install` to install dependencies.
|
||||
|
||||
Run `gulp` to build the project. Running `gulp serve` will run a watching server.
|
||||
|
||||
There is very little processing going on, the only thing we've added is support for mustache partials.
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 740 B After Width: | Height: | Size: 740 B |
|
Before Width: | Height: | Size: 163 B After Width: | Height: | Size: 163 B |
@@ -0,0 +1,44 @@
|
||||
/* Static styles and other modules */
|
||||
import './styles/styles';
|
||||
|
||||
/* Components */
|
||||
import { Abstract } from './components/d-abstract';
|
||||
import { Acknowledgements } from './components/d-acknowledgements';
|
||||
import { Appendix } from './components/d-appendix';
|
||||
import { Article } from './components/d-article';
|
||||
import { Bibliography } from './components/d-bibliography';
|
||||
import { Byline } from './components/d-byline';
|
||||
import { Cite } from './components/d-cite';
|
||||
import { Code } from './components/d-code';
|
||||
import { Footnote } from './components/d-footnote';
|
||||
import { FootnoteList } from './components/d-footnote-list';
|
||||
import { FrontMatter } from './components/d-front-matter';
|
||||
import { DMath } from './components/d-math';
|
||||
import { References } from './components/d-references';
|
||||
import { Title } from './components/d-title';
|
||||
import { TOC } from './components/d-toc';
|
||||
import { Figure } from './components/d-figure';
|
||||
|
||||
const components = [
|
||||
Abstract, Acknowledgements, Appendix, Article, Bibliography,
|
||||
Byline, Cite, Code, Footnote, FootnoteList, FrontMatter, DMath,
|
||||
References, Title, TOC, Figure,
|
||||
];
|
||||
|
||||
/* Distill website specific components */
|
||||
import { DistillHeader } from './distill-components/distill-header';
|
||||
import { DistillAppendix } from './distill-components/distill-appendix';
|
||||
import { DistillFooter } from './distill-components/distill-footer';
|
||||
|
||||
const distillComponents = [
|
||||
DistillHeader, DistillAppendix, DistillFooter,
|
||||
];
|
||||
|
||||
function defineComponents() {
|
||||
const allComponents = components.concat(distillComponents);
|
||||
for (const component of allComponents) {
|
||||
customElements.define(component.is, component);
|
||||
}
|
||||
}
|
||||
|
||||
defineComponents();
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Template } from '../mixins/template';
|
||||
import { body } from '../helpers/layout';
|
||||
|
||||
const T = Template('d-abstract', `
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
font-size: 23px;
|
||||
line-height: 1.7em;
|
||||
margin-bottom: 140px;
|
||||
}
|
||||
${body('d-abstract')}
|
||||
</style>
|
||||
|
||||
<slot></slot>
|
||||
`);
|
||||
|
||||
export class Abstract extends T(HTMLElement) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Template } from '../mixins/template';
|
||||
|
||||
const T = Template('d-acknowledgements', `
|
||||
<style>
|
||||
::slotted(h3) {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0;
|
||||
color: rgba(0,0,0,0.65);
|
||||
line-height: 1em;
|
||||
}
|
||||
::slotted(*) a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
</style>
|
||||
|
||||
<slot></slot>
|
||||
`);
|
||||
|
||||
export class Acknowledgements extends T(HTMLElement) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Template } from '../mixins/template';
|
||||
import { body } from '../helpers/layout';
|
||||
|
||||
const T = Template('d-appendix', `
|
||||
<style>
|
||||
|
||||
:host {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
font-size: 13px;
|
||||
line-height: 1.7em;
|
||||
margin-bottom: 0;
|
||||
border-top: 1px solid rgba(0,0,0,0.1);
|
||||
color: rgba(0,0,0,0.5);
|
||||
background: hsl(180, 5%, 98%);
|
||||
padding-top: 36px;
|
||||
padding-bottom: 48px;
|
||||
}
|
||||
|
||||
${body('.content')}
|
||||
|
||||
</style>
|
||||
|
||||
<div class='content'>
|
||||
<slot></slot>
|
||||
</div>
|
||||
`, true);
|
||||
|
||||
export class Appendix extends T(HTMLElement) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Template } from '../mixins/template';
|
||||
import { Controller } from '../controller';
|
||||
|
||||
const T = Template('d-article', `
|
||||
<style></style>
|
||||
`, false);
|
||||
|
||||
// export function addInferableTags(dom, frontMatter) {
|
||||
// const title = frontMatter.title;
|
||||
// if (title) {
|
||||
// const titleTag = document.querySelector()
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
const isOnlyWhitespace = /^\s*$/;
|
||||
|
||||
export class Article extends T(HTMLElement) {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
new MutationObserver( (mutations) => {
|
||||
for (const mutation of mutations) {
|
||||
for (const addedNode of mutation.addedNodes) {
|
||||
switch (addedNode.nodeName) {
|
||||
case 'HR':
|
||||
console.warn('Use of <hr> tags in distill articles is discouraged as they interfere with layout! To separate sections, please just use h2 or h3 tags.');
|
||||
break;
|
||||
case '#text': { // usually text nodes are only linebreaks.
|
||||
const text = addedNode.nodeValue;
|
||||
if (!isOnlyWhitespace.test(text)) {
|
||||
console.warn('Use of unwrapped text in distill articles is discouraged as it breaks layout! Please wrap any text in a <span> or <p> tag. We found the following text: ' + text);
|
||||
const wrapper = document.createElement('span');
|
||||
wrapper.innerHTML = addedNode.nodeValue;
|
||||
addedNode.parentNode.insertBefore(wrapper, addedNode);
|
||||
addedNode.parentNode.removeChild(addedNode);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}).observe(this, {childList: true});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
for (const [functionName, callback] of Object.entries(Controller.listeners)) {
|
||||
if (typeof callback === 'function') {
|
||||
document.addEventListener(functionName, callback);
|
||||
} else {
|
||||
console.error('Controller listeners need to be functions!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import { Template } from '../mixins/template';
|
||||
import { parseBibtex } from '../helpers/bibtex';
|
||||
import { bibliography_cite } from '../helpers/citation';
|
||||
|
||||
export const templateString = `
|
||||
<style>
|
||||
.references {
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.title {
|
||||
font-weight: 600;
|
||||
}
|
||||
ol {
|
||||
padding: 0 0 0 18px;
|
||||
}
|
||||
li {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0;
|
||||
color: rgba(0,0,0,0.65);
|
||||
line-height: 1em;
|
||||
}
|
||||
a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
</style>
|
||||
|
||||
<h3>References</h3>
|
||||
<ol class='references' id='references-list' ></ol>
|
||||
`;
|
||||
const T = Template('d-bibliography', templateString);
|
||||
|
||||
export function parseBibliography(element) {
|
||||
if (element.firstElementChild && element.firstElementChild.tagName === 'SCRIPT') {
|
||||
const bibtex = element.firstElementChild.textContent;
|
||||
const bibliography = parseBibtex(bibtex);
|
||||
return bibliography;
|
||||
}
|
||||
}
|
||||
|
||||
export function renderBibliography(element, entries) {
|
||||
if (entries.size) {
|
||||
element.host.style.display = 'initial';
|
||||
let list = element.querySelector('#references-list');
|
||||
list.innerHTML = '';
|
||||
|
||||
for (const [key, entry] of entries) {
|
||||
const listItem = document.createElement('li');
|
||||
listItem.id = key;
|
||||
listItem.innerHTML = bibliography_cite(entry);
|
||||
list.appendChild(listItem);
|
||||
}
|
||||
} else {
|
||||
element.host.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
export class Bibliography extends T(HTMLElement) {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// set up mutation observer
|
||||
const options = {childList: true, characterData: true, subtree: true};
|
||||
const observer = new MutationObserver( () => {
|
||||
observer.disconnect();
|
||||
this.parseIfPossible();
|
||||
observer.observe(this, options);
|
||||
});
|
||||
this.parseIfPossible();
|
||||
// ...and listen for changes
|
||||
observer.observe(this, options);
|
||||
}
|
||||
|
||||
parseIfPossible() {
|
||||
if (this.firstElementChild && this.firstElementChild.tagName === 'SCRIPT') {
|
||||
const newBibtex = this.firstElementChild.textContent;
|
||||
if (this.bibtex !== newBibtex) {
|
||||
this.bibtex = newBibtex;
|
||||
const bibliography = parseBibtex(this.bibtex);
|
||||
this.notify(bibliography);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notify(bibliography) {
|
||||
const options = { detail: bibliography, bubbles: true };
|
||||
const event = new CustomEvent('onBibliographyChanged', options);
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
set entries(newEntries) {
|
||||
renderBibliography(this.root, newEntries);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
import { Template } from '../mixins/template';
|
||||
import { page } from '../helpers/layout';
|
||||
|
||||
const T = Template('d-byline', `
|
||||
<style>
|
||||
:host {
|
||||
box-sizing: border-box;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
display: block;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
${page('.byline')}
|
||||
d-article.centered {
|
||||
text-align: center;
|
||||
}
|
||||
a,
|
||||
d-article a {
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
d-article a:hover {
|
||||
text-decoration: underline;
|
||||
border-bottom: none;
|
||||
}
|
||||
.authors {
|
||||
text-align: left;
|
||||
}
|
||||
.name {
|
||||
font-weight: 600;
|
||||
display: inline;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.affiliation {
|
||||
display: inline;
|
||||
}
|
||||
.date {
|
||||
display: block;
|
||||
text-align: left;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.year, .month {
|
||||
display: inline;
|
||||
}
|
||||
.citation {
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
.citation div {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px), print {
|
||||
d-byline {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
.authors {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.author {
|
||||
display: inline-block;
|
||||
margin-right: 12px;
|
||||
/*padding-left: 20px;*/
|
||||
/*border-left: 1px solid #ddd;*/
|
||||
}
|
||||
|
||||
.affiliation {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.author:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.name {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.date {
|
||||
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding-left: 15px;
|
||||
margin-left: 15px;
|
||||
margin-top: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
.year, .month {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.citation {
|
||||
align-self: flex-end;
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.15);
|
||||
padding-left: 15px;
|
||||
margin-left: 15px;
|
||||
display: inline-block;
|
||||
}
|
||||
.citation div {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.byline {
|
||||
display: flex;
|
||||
min-height: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='byline'>
|
||||
</div>
|
||||
`, true);
|
||||
|
||||
export function bylineTemplate(frontMatter) {
|
||||
return `
|
||||
<div class="authors">
|
||||
${frontMatter.authors.map( author => `<div class="author">
|
||||
${author.personalURL ?
|
||||
`<a class="name" href="${author.personalURL}">${author.name}</a>`
|
||||
:
|
||||
`<div class="name">${author.name}</div>`
|
||||
}
|
||||
${author.affiliationURL ?
|
||||
`<a class="affiliation" href="${author.affiliationURL}">${author.affiliation}</a>`
|
||||
:
|
||||
`<div class="affiliation">${author.affiliation}</div>`
|
||||
}
|
||||
</div>`).join('\n')}
|
||||
</div>
|
||||
<div class="date">
|
||||
<div class="month">${frontMatter.publishedMonth}. ${frontMatter.publishedDay}</div>
|
||||
<div class="year">${frontMatter.publishedYear}</div>
|
||||
</div>
|
||||
<a class="citation" href="#citation">
|
||||
<div>Citation:</div>
|
||||
<div>${frontMatter.concatenatedAuthors}, ${frontMatter.publishedYear}</div>
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
|
||||
export class Byline extends T(HTMLElement) {
|
||||
|
||||
set frontMatter(frontMatter) {
|
||||
const container = this.root.querySelector('.byline');
|
||||
container.innerHTML = bylineTemplate(frontMatter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
import { Template } from '../mixins/template';
|
||||
import { hover_cite } from '../helpers/citation';
|
||||
import { HoverBox } from '../helpers/hover-box';
|
||||
|
||||
const T = Template('d-cite', `
|
||||
<style>
|
||||
.citation {
|
||||
color: hsla(206, 90%, 20%, 0.7);
|
||||
}
|
||||
.citation-number {
|
||||
cursor: default;
|
||||
white-space: nowrap;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Roboto", Helvetica, sans-serif;
|
||||
font-size: 75%;
|
||||
color: hsla(206, 90%, 20%, 0.7);
|
||||
display: inline-block;
|
||||
line-height: 1.1em;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
figcaption .citation-number {
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
top: -2px;
|
||||
line-height: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="hover-box" class="dt-hover-box">
|
||||
</div>
|
||||
|
||||
<span id="citation-" class="citation">
|
||||
<slot></slot>
|
||||
<span class="citation-number"></span>
|
||||
</span>
|
||||
`);
|
||||
|
||||
export function collectCitations(dom=document) {
|
||||
const citations = new Set();
|
||||
const citeTags = dom.querySelectorAll('d-cite');
|
||||
for (const tag of citeTags) {
|
||||
const keys = tag.getAttribute('key').split(',');
|
||||
for (const key of keys) {
|
||||
citations.add(key);
|
||||
}
|
||||
}
|
||||
return [...citations];
|
||||
}
|
||||
|
||||
export class Cite extends T(HTMLElement) {
|
||||
|
||||
/* Lifecycle */
|
||||
|
||||
// constructor() {
|
||||
// super();
|
||||
// // Cite.currentId += 1;
|
||||
// // this.citeId = Cite.currentId;
|
||||
// }
|
||||
|
||||
connectedCallback() {
|
||||
// this.notify();
|
||||
|
||||
this.hoverDiv = this.root.querySelector('.dt-hover-box');
|
||||
this.outerSpan = this.root.querySelector('#citation-');
|
||||
this.innerSpan = this.root.querySelector('.citation-number');
|
||||
// this.outerSpan.id = `citation-${this.citeId}`;
|
||||
// this.hoverDiv.id = `dt-cite-hover-box-${this.citeId}`;
|
||||
// console.log(this, this.hoverDiv, this.outerSpan, this.innerSpan);
|
||||
this.hoverbox = new HoverBox(this.hoverDiv, this.outerSpan);
|
||||
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
const options = { detail: [this, this.keys], bubbles: true };
|
||||
const event = new CustomEvent('onCiteKeyRemoved', options);
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
/* Observed Attributes */
|
||||
|
||||
// renderCitationNumbers(citations) {
|
||||
// const numbers = this._keys.map( (key) => {
|
||||
// const index = citations.indexOf(key);
|
||||
// return index == -1 ? '?' : index + 1 + '';
|
||||
// });
|
||||
// const text = "[" + numbers.join(", ") + "]";
|
||||
// this.innerSpan.textContent = text;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
/* observe 'key' attribute */
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['key'];
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
const eventName = oldValue ? 'onCiteKeyChanged' : 'onCiteKeyCreated';
|
||||
const keys = newValue.split(',');
|
||||
const options = { detail: [this, keys], bubbles: true };
|
||||
const event = new CustomEvent(eventName, options);
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
set key(value) {
|
||||
this.setAttribute('key', value);
|
||||
}
|
||||
|
||||
get key() {
|
||||
return this.getAttribute('key');
|
||||
}
|
||||
|
||||
get keys() {
|
||||
return this.getAttribute('key').split(',');
|
||||
}
|
||||
|
||||
/* Setters & Rendering */
|
||||
|
||||
set numbers(numbers) {
|
||||
const numberStrings = numbers.map( index => {
|
||||
return index == -1 ? '?' : index + 1 + '';
|
||||
});
|
||||
const textContent = '[' + numberStrings.join(', ') + ']';
|
||||
const innerSpan = this.root.querySelector('.citation-number');
|
||||
innerSpan.textContent = textContent;
|
||||
}
|
||||
|
||||
set entries(entries) {
|
||||
const div = this.root.querySelector('#hover-box');
|
||||
div.innerHTML = entries.map(hover_cite).join('<br><br>');
|
||||
}
|
||||
|
||||
// renderContent() {
|
||||
// const bibliography = document.querySelector('d-bibliography');
|
||||
// if (bibliography && bibliography.finishedLoading) {
|
||||
// customElements.whenDefined('d-bibliography').then( () => {
|
||||
// const keys = this.key.split(",");
|
||||
//
|
||||
// // set up hidden hover box
|
||||
// const div = this.root.querySelector('.dt-hover-box');
|
||||
// div.innerHTML = keys.map( (key) => {
|
||||
// return bibliography.getEntry(key);
|
||||
// }).map(hover_cite).join('<br><br>');
|
||||
// div.id ='dt-cite-hover-box-' + this.citeId;
|
||||
//
|
||||
// // set up visible citation marker
|
||||
// const outerSpan = this.root.querySelector('#citation-');
|
||||
// outerSpan.id = `citation-${this.citeId}`;
|
||||
// // outerSpan.setAttribute('data-hover', dataHoverString); // directly tell HoverBox instead?
|
||||
// const innerSpan = this.root.querySelector('.citation-number');
|
||||
// innerSpan.textContent = inline_cite_short(keys, bibliography);
|
||||
//
|
||||
// HoverBox.get_box(div).bind(outerSpan);
|
||||
// });
|
||||
// } else {
|
||||
// console.error(`You used a d-cite tag (${key}) without including a d-bibliography tag in your article. We can't lookup your citation this way.`)
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import Prism from 'prismjs';
|
||||
import 'prismjs/components/prism-python';
|
||||
import 'prismjs/components/prism-clike';
|
||||
import css from 'prismjs/themes/prism.css';
|
||||
|
||||
import { Template } from '../mixins/template.js';
|
||||
import { Mutating } from '../mixins/mutating.js';
|
||||
|
||||
const T = Template('d-code', `
|
||||
<style>
|
||||
|
||||
code {
|
||||
white-space: nowrap;
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
border-radius: 2px;
|
||||
padding: 4px 7px;
|
||||
font-size: 15px;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
background: white;
|
||||
border-left: 3px solid rgba(0, 0, 0, 0.05);
|
||||
padding: 0 0 0 24px;
|
||||
}
|
||||
|
||||
${css}
|
||||
</style>
|
||||
|
||||
<code id="code-container"></code>
|
||||
|
||||
`);
|
||||
|
||||
export class Code extends Mutating(T(HTMLElement)) {
|
||||
|
||||
renderContent() {
|
||||
|
||||
// check if language can be highlighted
|
||||
this.languageName = this.getAttribute('language');
|
||||
if (!this.languageName) {
|
||||
console.warn('You need to provide a language attribute to your <d-code> block to let us know how to highlight your code; e.g.:\n <d-code language="python">zeros = np.zeros(shape)</d-code>.');
|
||||
return;
|
||||
}
|
||||
const language = Prism.languages[this.languageName];
|
||||
if (language == undefined) {
|
||||
console.warn(`Distill does not yet support highlighting your code block in "${this.languageName}".`);
|
||||
return;
|
||||
}
|
||||
|
||||
let content = this.textContent;
|
||||
const codeTag = this.shadowRoot.querySelector('#code-container');
|
||||
|
||||
if (this.hasAttribute('block')) {
|
||||
// normalize the tab indents
|
||||
content = content.replace(/\n/, '');
|
||||
const tabs = content.match(/\s*/);
|
||||
content = content.replace(new RegExp('\n' + tabs, 'g'), '\n');
|
||||
content = content.trim();
|
||||
// wrap code block in pre tag if needed
|
||||
if (codeTag.parentNode instanceof ShadowRoot) {
|
||||
const preTag = document.createElement('pre');
|
||||
this.shadowRoot.removeChild(codeTag);
|
||||
preTag.appendChild(codeTag);
|
||||
this.shadowRoot.appendChild(preTag);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
codeTag.className = `language-${this.languageName}`;
|
||||
codeTag.innerHTML = Prism.highlight(content, language);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// Figure
|
||||
//
|
||||
// d-figure provides a state-machine of visibility events:
|
||||
//
|
||||
// scroll out of view
|
||||
// +----------------+
|
||||
// *do work here* | |
|
||||
// +----------------+ +-+---------+ +-v---------+
|
||||
// | ready +----> onscreen | | offscreen |
|
||||
// +----------------+ +---------^-+ +---------+-+
|
||||
// | |
|
||||
// +----------------+
|
||||
// scroll into view
|
||||
//
|
||||
|
||||
export class Figure extends HTMLElement {
|
||||
|
||||
static get is() { return 'd-figure'; }
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._ready = false;
|
||||
this._onscreen = false;
|
||||
this._offscreen = true;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
Figure.marginObserver.observe(this);
|
||||
Figure.directObserver.observe(this);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
Figure.marginObserver.unobserve(this);
|
||||
Figure.directObserver.unobserve(this);
|
||||
}
|
||||
|
||||
// We use two separate observers:
|
||||
// One with an extra 1000px margin to warn if the viewpoint gets close,
|
||||
// And one for the actual on/off screen events
|
||||
|
||||
static get marginObserver() {
|
||||
if (!Figure._marginObserver) {
|
||||
const viewportHeight = window.innerHeight;
|
||||
const margin = Math.floor(2 * viewportHeight);
|
||||
Figure._marginObserver = new IntersectionObserver(
|
||||
Figure.didObserveMarginIntersection, {
|
||||
rootMargin: margin + 'px 0px ' + margin + 'px 0px', threshold: 0.01,
|
||||
});
|
||||
}
|
||||
return Figure._marginObserver;
|
||||
}
|
||||
|
||||
static didObserveMarginIntersection(entries) {
|
||||
for (const entry of entries) {
|
||||
const figure = entry.target;
|
||||
if (entry.isIntersecting && !figure._ready) {
|
||||
figure.ready();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static get directObserver() {
|
||||
if (!Figure._directObserver) {
|
||||
Figure._directObserver = new IntersectionObserver(
|
||||
Figure.didObserveDirectIntersection, {
|
||||
rootMargin: '0px', threshold: [0, 1.0],
|
||||
}
|
||||
);
|
||||
}
|
||||
return Figure._directObserver;
|
||||
}
|
||||
|
||||
static didObserveDirectIntersection(entries) {
|
||||
for (const entry of entries) {
|
||||
const figure = entry.target;
|
||||
if (entry.isIntersecting) {
|
||||
if (!figure._ready) { figure.ready(); }
|
||||
if (figure._offscreen) { figure.onscreen(); }
|
||||
} else {
|
||||
if (figure._onscreen) { figure.offscreen(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notify listeners that registered late, too:
|
||||
|
||||
addEventListener(eventName, callback) {
|
||||
super.addEventListener(eventName, callback);
|
||||
// if we had already dispatched something while presumingly no one was listening, we do so again
|
||||
setTimeout(() => {
|
||||
if (this._ready && eventName === 'ready') {
|
||||
this.ready();
|
||||
}
|
||||
if (this._onscreen && eventName === 'onscreen') {
|
||||
this.onscreen();
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
// Custom Events
|
||||
|
||||
ready() {
|
||||
this._ready = true;
|
||||
Figure.marginObserver.unobserve(this);
|
||||
const event = new CustomEvent('ready');
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
onscreen() {
|
||||
this._onscreen = true;
|
||||
this._offscreen = false;
|
||||
const event = new CustomEvent('onscreen');
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
offscreen() {
|
||||
this._onscreen = false;
|
||||
this._offscreen = true;
|
||||
const event = new CustomEvent('offscreen');
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import { Template } from '../mixins/template';
|
||||
|
||||
const T = Template('d-footnote-list', `
|
||||
<style>
|
||||
ol {
|
||||
padding: 0 0 0 18px;
|
||||
}
|
||||
li {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0;
|
||||
color: rgba(0,0,0,0.65);
|
||||
line-height: 1em;
|
||||
}
|
||||
a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
a.footnote-backlink {
|
||||
color: rgba(0,0,0,0.3);
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<h3>Footnotes</h3>
|
||||
<ol></ol>
|
||||
`);
|
||||
|
||||
export class FootnoteList extends T(HTMLElement) {
|
||||
|
||||
connectedCallback() {
|
||||
this.list = this.root.querySelector('ol');
|
||||
// footnotes list is initially hidden
|
||||
this.root.host.style.display = 'none';
|
||||
// look through document and register existing footnotes
|
||||
// Store.subscribeTo('footnotes', (footnote) => {
|
||||
// this.renderFootnote(footnote);
|
||||
// });
|
||||
}
|
||||
|
||||
// TODO: could optimize this to accept individual footnotes?
|
||||
set footnotes(footnotes) {
|
||||
this.list.innerHTML = '';
|
||||
if (footnotes.length) {
|
||||
// ensure footnote list is visible
|
||||
this.root.host.style.display = 'initial';
|
||||
|
||||
for (const footnote of footnotes) {
|
||||
// construct and append list item to show footnote
|
||||
const listItem = document.createElement('li');
|
||||
listItem.id = footnote.id + '-listing';
|
||||
listItem.innerHTML = footnote.innerHTML;
|
||||
|
||||
const backlink = document.createElement('a');
|
||||
backlink.setAttribute('class', 'footnote-backlink');
|
||||
backlink.textContent = '[↩]';
|
||||
backlink.href = '#' + footnote.id;
|
||||
|
||||
listItem.appendChild(backlink);
|
||||
this.list.appendChild(listItem);
|
||||
}
|
||||
} else {
|
||||
// ensure footnote list is invisible
|
||||
this.shadowRoot.host.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import { Template } from '../mixins/template.js';
|
||||
import { HoverBox } from '../helpers/hover-box';
|
||||
// import { Store } from './store';
|
||||
|
||||
const T = Template('d-footnote', `
|
||||
<style>
|
||||
|
||||
d-math[block] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div id="hover-box" class="dt-hover-box">
|
||||
<slot id="slot"></slot>
|
||||
</div>
|
||||
|
||||
<sup><span id="fn-" data-hover-ref="" style="cursor:pointer"></span></sup>
|
||||
|
||||
`);
|
||||
|
||||
export class Footnote extends T(HTMLElement) {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const options = {childList: true, characterData: true, subtree: true};
|
||||
const observer = new MutationObserver(this.notify);
|
||||
observer.observe(this, options);
|
||||
}
|
||||
|
||||
notify() {
|
||||
const options = { detail: this, bubbles: true };
|
||||
const event = new CustomEvent('onFootnoteChanged', options);
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
// listen and notify about changes to slotted content
|
||||
// const slot = this.shadowRoot.querySelector('#slot');
|
||||
// slot.addEventListener('slotchange', this.notify);
|
||||
|
||||
// create numeric ID
|
||||
Footnote.currentFootnoteId += 1;
|
||||
const IdString = Footnote.currentFootnoteId.toString();
|
||||
this.root.host.id = 'd-footnote-' + IdString;
|
||||
|
||||
// set up hidden hover box
|
||||
const div = this.root.querySelector('.dt-hover-box');
|
||||
div.id = 'dt-fn-hover-box-' + IdString;
|
||||
|
||||
// set up visible footnote marker
|
||||
const span = this.root.querySelector('#fn-');
|
||||
span.setAttribute('id', 'fn-' + IdString);
|
||||
span.setAttribute('data-hover-ref', div.id);
|
||||
span.textContent = IdString;
|
||||
|
||||
this.hoverbox = new HoverBox(div, span);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Footnote.currentFootnoteId = 0;
|
||||
@@ -0,0 +1,40 @@
|
||||
import ymlParse from 'js-yaml';
|
||||
|
||||
export function parseFrontmatter(element) {
|
||||
const scriptTag = element.querySelector('script');
|
||||
if (scriptTag) {
|
||||
const yml = scriptTag.textContent;
|
||||
const data = ymlParse.safeLoad(yml);
|
||||
return data;
|
||||
} else {
|
||||
console.error('You added a frontmatter tag but did not provide a script tag with front matter data in it. Please take a look at our templates.');
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export class FrontMatter extends HTMLElement {
|
||||
|
||||
static get is() { return 'd-front-matter'; }
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const options = {childList: true};
|
||||
const observer = new MutationObserver( (entries) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.target.nodeName === 'SCRIPT') {
|
||||
const data = parseFrontmatter(this);
|
||||
this.notify(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
observer.observe(this, options);
|
||||
}
|
||||
|
||||
notify(data) {
|
||||
const options = { detail: data, bubbles: true };
|
||||
const event = new CustomEvent('onFrontMatterChanged', options);
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*global katex */
|
||||
import { Mutating } from '../mixins/mutating.js';
|
||||
import { Template } from '../mixins/template.js';
|
||||
|
||||
const katexJSURL = 'https://distill.pub/third-party/katex/katex.min.js';
|
||||
const katexCSSTag = '<link rel="stylesheet" href="https://distill.pub/third-party/katex/katex.min.css" crossorigin="anonymous">';
|
||||
|
||||
const T = Template('d-math', `
|
||||
<style>
|
||||
|
||||
d-math[block] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
${katexCSSTag}
|
||||
|
||||
<span id="katex-container"></span>
|
||||
`);
|
||||
|
||||
|
||||
// DMath, not Math, because that's a JS built-in
|
||||
export class DMath extends Mutating(T(HTMLElement)) {
|
||||
|
||||
static katexLoadedCallback() {
|
||||
const mathTags = document.querySelectorAll('d-math');
|
||||
for (const mathTag of mathTags) {
|
||||
mathTag.renderContent();
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (!DMath.katexAdded) {
|
||||
// script tag has to be created to work properly
|
||||
const scriptTag = document.createElement('script');
|
||||
scriptTag.src = katexJSURL;
|
||||
scriptTag.async = true;
|
||||
scriptTag.onload = DMath.katexLoadedCallback;
|
||||
scriptTag.crossorigin = 'anonymous';
|
||||
document.head.appendChild(scriptTag);
|
||||
// css tag can use this convenience function
|
||||
document.head.insertAdjacentHTML('beforeend', katexCSSTag);
|
||||
|
||||
DMath.katexAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
if (typeof katex !== 'undefined') {
|
||||
const options = { displayMode: this.hasAttribute('block') };
|
||||
const container = this.root.querySelector('#katex-container');
|
||||
katex.render(this.textContent, container, options);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DMath.katexAdded = false;
|
||||
window.DMath = DMath; // TODO: check if this can be removed, or if we should expose a distill global
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Template } from '../mixins/template';
|
||||
|
||||
const T = Template('d-references', `
|
||||
<style>
|
||||
d-references {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
`, false);
|
||||
|
||||
export class References extends T(HTMLElement) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import { Template } from '../mixins/template';
|
||||
import { page } from '../helpers/layout';
|
||||
|
||||
const T = Template('d-title', `
|
||||
<style>
|
||||
|
||||
:host {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-bottom: 64px;
|
||||
}
|
||||
|
||||
|
||||
::slotted(h1) {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
margin: 0;
|
||||
line-height: 1.3;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
::slotted(h2) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px), print {
|
||||
::slotted(h1) {
|
||||
font-size: 42px;
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
::slotted(h1) {
|
||||
padding-top: 64px;
|
||||
padding-bottom: 32px;
|
||||
font-size: 48px;
|
||||
}
|
||||
}
|
||||
@media(min-width: 1280px) {
|
||||
::slotted(h1) {
|
||||
padding-top: 96px;
|
||||
padding-bottom: 32px;
|
||||
font-size: 56px;
|
||||
}
|
||||
}
|
||||
|
||||
d-byline {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
${page('::slotted(h1), ::slotted(h2)')}
|
||||
|
||||
</style>
|
||||
|
||||
<slot></slot>
|
||||
`);
|
||||
|
||||
export class Title extends T(HTMLElement) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import {Template} from '../mixins/template';
|
||||
|
||||
const T = Template('d-toc', `
|
||||
<style>
|
||||
d-toc {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
`, false);
|
||||
|
||||
export class TOC extends T(HTMLElement) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
import { FrontMatter } from './front-matter';
|
||||
import { collectCitations } from './components/d-cite';
|
||||
import { parseFrontmatter } from './components/d-front-matter';
|
||||
|
||||
const frontMatter = new FrontMatter();
|
||||
|
||||
export const Controller = {
|
||||
|
||||
frontMatter: frontMatter,
|
||||
waitingOn: {
|
||||
bibliography: [],
|
||||
citations: [],
|
||||
},
|
||||
listeners: {
|
||||
|
||||
onCiteKeyCreated(event) {
|
||||
const [citeTag, keys] = event.detail;
|
||||
|
||||
// ensure we have citations
|
||||
if (!frontMatter.citationsCollected) {
|
||||
// console.debug('onCiteKeyCreated, but unresolved dependency ("citations"). Enqueing.');
|
||||
Controller.waitingOn.citations.push(() => Controller.listeners.onCiteKeyCreated(event));
|
||||
return;
|
||||
}
|
||||
|
||||
// ensure we have a loaded bibliography
|
||||
if (!frontMatter.bibliographyParsed) {
|
||||
// console.debug('onCiteKeyCreated, but unresolved dependency ("bibliography"). Enqueing.');
|
||||
Controller.waitingOn.bibliography.push(() => Controller.listeners.onCiteKeyCreated(event));
|
||||
return;
|
||||
}
|
||||
|
||||
const numbers = keys.map( key => frontMatter.citations.indexOf(key) );
|
||||
citeTag.numbers = numbers;
|
||||
const entries = keys.map( key => frontMatter.bibliography.get(key) );
|
||||
citeTag.entries = entries;
|
||||
},
|
||||
|
||||
onCiteKeyChanged(event) {
|
||||
// const [citeTag, keys] = event.detail;
|
||||
|
||||
// update citations
|
||||
frontMatter.citations = collectCitations();
|
||||
frontMatter.citationsCollected = true;
|
||||
for (const waitingCallback of Controller.waitingOn.citations.slice()) {
|
||||
waitingCallback();
|
||||
}
|
||||
|
||||
// update bibliography
|
||||
const bibliographyTag = document.querySelector('d-bibliography');
|
||||
const bibliographyEntries = new Map(frontMatter.citations.map( citationKey => {
|
||||
return [citationKey, frontMatter.bibliography.get(citationKey)];
|
||||
}));
|
||||
bibliographyTag.entries = bibliographyEntries;
|
||||
|
||||
const citeTags = document.querySelectorAll('d-cite');
|
||||
for (const citeTag of citeTags) {
|
||||
const keys = citeTag.keys;
|
||||
const numbers = keys.map( key => frontMatter.citations.indexOf(key) );
|
||||
citeTag.numbers = numbers;
|
||||
const entries = keys.map( key => frontMatter.bibliography.get(key) );
|
||||
citeTag.entries = entries;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
onCiteKeyRemoved(event) {
|
||||
Controller.listeners.onCiteKeyChanged(event);
|
||||
},
|
||||
|
||||
onBibliographyChanged(event) {
|
||||
const bibliographyTag = event.target;
|
||||
const bibliography = event.detail;
|
||||
|
||||
frontMatter.bibliography = bibliography;
|
||||
frontMatter.bibliographyParsed = true;
|
||||
for (const waitingCallback of Controller.waitingOn.bibliography.slice()) {
|
||||
waitingCallback();
|
||||
}
|
||||
|
||||
// ensure we have citations
|
||||
if (!frontMatter.citationsCollected) {
|
||||
Controller.waitingOn.citations.push( function() {
|
||||
Controller.listeners.onBibliographyChanged({target: event.target, detail: event.detail});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const entries = new Map(frontMatter.citations.map( citationKey => {
|
||||
return [citationKey, frontMatter.bibliography.get(citationKey)];
|
||||
}));
|
||||
|
||||
bibliographyTag.entries = entries;
|
||||
},
|
||||
|
||||
onFootnoteChanged() {
|
||||
// const footnote = event.detail;
|
||||
//TODO: optimize to only update current footnote
|
||||
const footnotesList = document.querySelector('d-footnote-list');
|
||||
if (footnotesList) {
|
||||
const footnotes = document.querySelectorAll('d-footnote');
|
||||
footnotesList.footnotes = footnotes;
|
||||
}
|
||||
},
|
||||
|
||||
onFrontMatterChanged(event) {
|
||||
const data = event.detail;
|
||||
frontMatter.mergeFromYMLFrontmatter(data);
|
||||
|
||||
const appendix = document.querySelector('distill-appendix');
|
||||
if (appendix) {
|
||||
appendix.frontMatter = frontMatter;
|
||||
}
|
||||
|
||||
const byline = document.querySelector('d-byline');
|
||||
if (byline) {
|
||||
byline.frontMatter = frontMatter;
|
||||
}
|
||||
},
|
||||
|
||||
DOMContentLoaded() {
|
||||
// console.debug('DOMContentLoaded.');
|
||||
|
||||
const frontMatterTag = document.querySelector('d-front-matter');
|
||||
const data = parseFrontmatter(frontMatterTag);
|
||||
Controller.listeners.onFrontMatterChanged({detail: data});
|
||||
|
||||
// console.debug('Resolving "citations" dependency due to initial DOM load.');
|
||||
frontMatter.citations = collectCitations();
|
||||
frontMatter.citationsCollected = true;
|
||||
for (const waitingCallback of Controller.waitingOn.citations.slice()) {
|
||||
waitingCallback();
|
||||
}
|
||||
|
||||
const footnotesList = document.querySelector('d-footnote-list');
|
||||
if (footnotesList) {
|
||||
const footnotes = document.querySelectorAll('d-footnote');
|
||||
footnotesList.footnotes = footnotes;
|
||||
}
|
||||
}
|
||||
|
||||
}, // listeners
|
||||
|
||||
}; // Controller
|
||||
@@ -0,0 +1,64 @@
|
||||
import { serializeFrontmatterToBibtex } from '../helpers/bibtex';
|
||||
|
||||
const styles = `
|
||||
<style>
|
||||
distill-appendix h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0;
|
||||
color: rgba(0,0,0,0.65);
|
||||
line-height: 1em;
|
||||
}
|
||||
distill-appendix a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
distill-appendix ol,
|
||||
distill-appendix ul {
|
||||
padding-left: 24px;
|
||||
}
|
||||
distill-appendix .citation {
|
||||
font-size: 11px;
|
||||
line-height: 15px;
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding-left: 18px;
|
||||
border: 1px solid rgba(0,0,0,0.1);
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
padding: 10px 18px;
|
||||
border-radius: 3px;
|
||||
color: rgba(150, 150, 150, 1);
|
||||
overflow: hidden;
|
||||
margin-top: -12px;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
|
||||
export function appendixTemplate(frontMatter) {
|
||||
return `
|
||||
${styles}
|
||||
|
||||
<h3 id="updates-and-corrections">Updates and Corrections</h3>
|
||||
<p><a href="">View all changes</a> to this article since it was first published. If you see mistakes or want to suggest changes, please <a href="${frontMatter.githubUrl + '/issues/new'}">create an issue on GitHub</a>. </p>
|
||||
|
||||
<h3 id="reuse">Reuse</h3>
|
||||
<p>Diagrams and text are licensed under Creative Commons Attribution <a href="https://creativecommons.org/licenses/by/2.0/">CC-BY 2.0</a> with the <a class="github" href="${frontMatter.githubUrl}">source available on GitHub</a>, unless noted otherwise. The figures that have been reused from other sources don’t fall under this license and can be recognized by a note in their caption: “Figure from …”.</p>
|
||||
|
||||
<h3 id="citation">Citation</h3>
|
||||
<p>For attribution in academic contexts, please cite this work as</p>
|
||||
<pre class="citation short">${frontMatter.concatenatedAuthors}, "${frontMatter.title}", Distill, ${frontMatter.publishedYear}.</pre>
|
||||
<p>BibTeX citation</p>
|
||||
<pre class="citation long">${serializeFrontmatterToBibtex(frontMatter)}</pre>
|
||||
`;
|
||||
}
|
||||
|
||||
export class DistillAppendix extends HTMLElement {
|
||||
|
||||
static get is() { return 'distill-appendix'; }
|
||||
|
||||
set frontMatter(frontMatter) {
|
||||
this.innerHTML = appendixTemplate(frontMatter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { Template } from '../mixins/template';
|
||||
import logo from '../assets/distill-logo.svg';
|
||||
|
||||
const T = Template('distill-footer', `
|
||||
<style>
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
font-weight: 300;
|
||||
padding: 40px 0;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
background-color: hsl(180, 5%, 15%); /*hsl(200, 60%, 15%);*/
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.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: margin-left / body;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='container'>
|
||||
<a href="/" class="logo">
|
||||
${logo}
|
||||
Distill
|
||||
</a> is dedicated to clear explanations of machine learning
|
||||
</div>
|
||||
`);
|
||||
|
||||
export class DistillFooter extends T(HTMLElement) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
import { Template } from '../mixins/template';
|
||||
|
||||
import logo from '../assets/distill-logo.svg';
|
||||
|
||||
const T = Template('distill-header', `
|
||||
<style>
|
||||
:host {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: transparent;
|
||||
z-index: ${1e6};
|
||||
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);*/
|
||||
}
|
||||
.content {
|
||||
height: 70px;
|
||||
}
|
||||
a {
|
||||
font-size: 16px;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
text-decoration: none;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
padding: 22px 0;
|
||||
}
|
||||
a:hover {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
svg {
|
||||
background-color: hsl(0, 0%, 15%);;
|
||||
padding: 8px;
|
||||
border-radius: 12px;
|
||||
width: 24px;
|
||||
position: relative;
|
||||
top: 16px;
|
||||
left: 16px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
@media(min-width: 768px) {
|
||||
svg {
|
||||
top: 40px;
|
||||
left: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@media(min-width: 1080px) {
|
||||
:host {
|
||||
height: 70px;
|
||||
}
|
||||
a {
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
padding: 28px 0;
|
||||
}
|
||||
.logo {
|
||||
}
|
||||
}
|
||||
svg path {
|
||||
fill: white;
|
||||
stroke: rgba(255, 255, 255, 1.0);
|
||||
stroke-width: 3px;
|
||||
}
|
||||
.logo {
|
||||
font-size: 17px;
|
||||
font-weight: 200;
|
||||
}
|
||||
.nav {
|
||||
float: right;
|
||||
font-weight: 300;
|
||||
}
|
||||
.nav a {
|
||||
font-size: 12px;
|
||||
margin-left: 24px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.name {
|
||||
opacity: 0.0;
|
||||
transition: opacity 0.5s
|
||||
}
|
||||
|
||||
a:hover .name {
|
||||
opacity: 1.0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="content l-page">
|
||||
<a href="/" class="logo">
|
||||
${logo}
|
||||
</a>
|
||||
<span class='name'>
|
||||
Distill
|
||||
</span>
|
||||
</div>
|
||||
`);
|
||||
|
||||
// <div class="nav">
|
||||
// <a href="/faq">About</a>
|
||||
// <a href="https://github.com/distillpub">GitHub</a>
|
||||
// <!-- https://twitter.com/distillpub -->
|
||||
// </div>
|
||||
|
||||
export class DistillHeader extends T(HTMLElement) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export default function(dom) {
|
||||
|
||||
const appendixTag = dom.querySelector('d-appendix');
|
||||
if (!appendixTag) {
|
||||
console.warn('No appendix tag found!');
|
||||
return;
|
||||
}
|
||||
const distillAppendixTag = appendixTag.querySelector('distill-appendix');
|
||||
if (!distillAppendixTag) {
|
||||
const distillAppendix = dom.createElement('distill-appendix');
|
||||
appendixTag.appendChild(distillAppendix);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export default function(dom) {
|
||||
const footerTag = dom.querySelector('distill-footer');
|
||||
if(!footerTag) {
|
||||
const footer = dom.createElement('distill-footer');
|
||||
const body = dom.querySelector('body');
|
||||
body.appendChild(footer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export default function(dom) {
|
||||
const headerTag = dom.querySelector('distill-header');
|
||||
if (!headerTag) {
|
||||
const header = dom.createElement('distill-header');
|
||||
const body = dom.querySelector('body');
|
||||
body.insertBefore(header, body.firstChild);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { parseBibliography } from '../components/d-bibliography';
|
||||
|
||||
export default function(dom, data) {
|
||||
const bibliographyTag = dom.querySelector('d-bibliography');
|
||||
if (!bibliographyTag) {
|
||||
console.warn('No bibliography tag found!');
|
||||
return;
|
||||
}
|
||||
data.bibliography = parseBibliography(bibliographyTag);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { collectCitations } from '../components/d-cite';
|
||||
|
||||
export default function(dom, data) {
|
||||
data.citations = collectCitations(dom);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { parseFrontmatter } from '../components/d-front-matter';
|
||||
|
||||
export default function(dom, data) {
|
||||
const frontMatterTag = dom.querySelector('d-front-matter');
|
||||
if (!frontMatterTag) {
|
||||
console.warn('No front matter tag found!');
|
||||
return;
|
||||
}
|
||||
const extractedData = parseFrontmatter(frontMatterTag);
|
||||
Object.assign(data, extractedData);
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
import {timeFormat} from 'd3-time-format';
|
||||
|
||||
const zeroPad = n => n < 10 ? '0' + n : n;
|
||||
const RFC = timeFormat('%a, %d %b %Y %H:%M:%S %Z');
|
||||
const months = ['Jan', 'Feb', 'March', 'April', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];
|
||||
|
||||
class Author {
|
||||
|
||||
constructor(name='', personalURL='', affiliation='', affiliationURL='') {
|
||||
this.name = name; // "Chris Olah"
|
||||
this.personalURL = personalURL; // "https://colah.github.io"
|
||||
this.affiliation = affiliation; // "Google Brain"
|
||||
this.affiliationURL = affiliationURL; // "https://g.co/brain"
|
||||
}
|
||||
|
||||
// "Chris"
|
||||
get firstName() {
|
||||
const names = this.name.split(' ');
|
||||
return names.slice(0, names.length - 1).join(' ');
|
||||
}
|
||||
|
||||
// "Olah"
|
||||
get lastName() {
|
||||
const names = this.name.split(' ');
|
||||
return names[names.length -1];
|
||||
}
|
||||
}
|
||||
|
||||
export class FrontMatter {
|
||||
constructor() {
|
||||
this.title = ''; // "Attention and Augmented Recurrent Neural Networks"
|
||||
this.description = ''; // "A visual overview of neural attention..."
|
||||
this.authors = []; // Array of Author(s)
|
||||
|
||||
this.bibliography = new Map();
|
||||
this.bibliographyParsed = false;
|
||||
// {
|
||||
// "gregor2015draw": {
|
||||
// "title": "DRAW: A recurrent neural network for image generation",
|
||||
// "author": "Gregor, Karol and Danihelka, Ivo and Graves, Alex and Rezende, Danilo Jimenez and Wierstra, Daan",
|
||||
// "journal": "arXiv preprint arXiv:1502.04623",
|
||||
// "year": "2015",
|
||||
// "url": "https://arxiv.org/pdf/1502.04623.pdf",
|
||||
// "type": "article"
|
||||
// },
|
||||
// }
|
||||
|
||||
// Citation keys should be listed in the order that they are appear in the document.
|
||||
// Each key refers to a key in the bibliography dictionary.
|
||||
this.citations = []; // [ "gregor2015draw", "mercier2011humans" ]
|
||||
this.citationsCollected = false;
|
||||
|
||||
//
|
||||
// Assigned from posts.csv
|
||||
//
|
||||
|
||||
// publishedDate: 2016-09-08T07:00:00.000Z,
|
||||
// tags: [ 'rnn' ],
|
||||
// distillPath: '2016/augmented-rnns',
|
||||
// githubPath: 'distillpub/post--augmented-rnns',
|
||||
// doiSuffix: 1,
|
||||
|
||||
//
|
||||
// Assigned from journal
|
||||
//
|
||||
this.journal = {};
|
||||
// journal: {
|
||||
// "title": "Distill",
|
||||
// "full_title": "Distill",
|
||||
// "abbrev_title": "Distill",
|
||||
// "url": "http://distill.pub",
|
||||
// "doi": "10.23915/distill",
|
||||
// "publisherName": "Distill Working Group",
|
||||
// "publisherEmail": "admin@distill.pub",
|
||||
// "issn": "2476-0757",
|
||||
// "editors": [...],
|
||||
// "committee": [...]
|
||||
// }
|
||||
// volume: 1,
|
||||
// issue: 9,
|
||||
this.publishedDate = new Date();
|
||||
|
||||
//
|
||||
// Assigned from publishing process
|
||||
//
|
||||
|
||||
// githubCompareUpdatesUrl: 'https://github.com/distillpub/post--augmented-rnns/compare/1596e094d8943d2dc0ea445d92071129c6419c59...3bd9209e0c24d020f87cf6152dcecc6017cbc193',
|
||||
// updatedDate: 2017-03-21T07:13:16.000Z,
|
||||
// doi: '10.23915/distill.00001',
|
||||
|
||||
}
|
||||
|
||||
// Example:
|
||||
// title: Demo Title Attention and Augmented Recurrent Neural Networks
|
||||
// published: Jan 10, 2017
|
||||
// authors:
|
||||
// - Chris Olah:
|
||||
// - Shan Carter: http://shancarter.com
|
||||
// affiliations:
|
||||
// - Google Brain:
|
||||
// - Google Brain: http://g.co/brain
|
||||
|
||||
mergeFromYMLFrontmatter(data) {
|
||||
this.title = data.title;
|
||||
this.publishedDate = new Date(data.published);
|
||||
this.description = data.description;
|
||||
const zipped = data.authors.map( (author, index) => [author, data.affiliations[index]]);
|
||||
this.authors = zipped.map( ([authorEntry, affiliationEntry]) => {
|
||||
const author = new Author();
|
||||
|
||||
// try to get name and personal url
|
||||
switch (typeof authorEntry) {
|
||||
case 'object':
|
||||
author.name = Object.keys(authorEntry)[0];
|
||||
author.personalURL = authorEntry[author.name];
|
||||
break;
|
||||
case 'string':
|
||||
author.name = authorEntry;
|
||||
break;
|
||||
default:
|
||||
throw new Error('Invalid type in frontmatter author field: ' + authorEntry);
|
||||
}
|
||||
|
||||
// try to get affiliation name and affiliation url
|
||||
switch (typeof affiliationEntry) {
|
||||
case 'object':
|
||||
author.affiliation = Object.keys(affiliationEntry)[0];
|
||||
author.affiliationURL = affiliationEntry[author.affiliation];
|
||||
break;
|
||||
case 'string':
|
||||
author.affiliation = affiliationEntry;
|
||||
break;
|
||||
default:
|
||||
throw new Error('Invalid type in frontmatter affiliation field: ' + affiliationEntry);
|
||||
}
|
||||
|
||||
return author;
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Computed Properties
|
||||
//
|
||||
|
||||
// 'http://distill.pub/2016/augmented-rnns',
|
||||
set url(value) {
|
||||
this._url = value;
|
||||
}
|
||||
get url() {
|
||||
if (this._url) {
|
||||
return this._url;
|
||||
} else if (this.distillPath && this.journal.url) {
|
||||
return this.journal.url + '/' + this.distillPath;
|
||||
} else if (this.journal.url) {
|
||||
return this.journal.url;
|
||||
}
|
||||
}
|
||||
|
||||
// 'https://github.com/distillpub/post--augmented-rnns',
|
||||
get githubUrl() {
|
||||
return 'https://github.com/' + this.githubPath;
|
||||
}
|
||||
|
||||
// TODO resolve differences in naming of URL/Url/url.
|
||||
// 'http://distill.pub/2016/augmented-rnns/thumbnail.jpg',
|
||||
set previewURL(value) {
|
||||
this._previewURL = value;
|
||||
}
|
||||
get previewURL() {
|
||||
return this._previewURL ? this._previewURL : this.url + '/thumbnail.jpg';
|
||||
}
|
||||
|
||||
// 'Thu, 08 Sep 2016 00:00:00 -0700',
|
||||
get publishedDateRFC() {
|
||||
return RFC(this.publishedDate);
|
||||
}
|
||||
|
||||
// 'Thu, 08 Sep 2016 00:00:00 -0700',
|
||||
get updatedDateRFC() {
|
||||
return RFC(this.updatedDate);
|
||||
}
|
||||
|
||||
// 2016,
|
||||
get publishedYear() {
|
||||
return this.publishedDate.getFullYear();
|
||||
}
|
||||
|
||||
// 'Sept',
|
||||
get publishedMonth() {
|
||||
return months[this.publishedDate.getMonth()];
|
||||
}
|
||||
|
||||
// 8,
|
||||
get publishedDay() {
|
||||
return this.publishedDate.getDate();
|
||||
}
|
||||
|
||||
// '09',
|
||||
get publishedMonthPadded() {
|
||||
return zeroPad(this.publishedDate.getMonth() + 1);
|
||||
}
|
||||
|
||||
// '08',
|
||||
get publishedDayPadded() {
|
||||
return zeroPad(this.publishedDate.getDate());
|
||||
}
|
||||
|
||||
// 'Olah & Carter',
|
||||
get concatenatedAuthors() {
|
||||
if (this.authors.length > 2) {
|
||||
return this.authors[0].lastName + ', et al.';
|
||||
} else if (this.authors.length === 2) {
|
||||
return this.authors[0].lastName + ' & ' + this.authors[1].lastName;
|
||||
} else if (this.authors.length === 1) {
|
||||
return this.authors[0].lastName;
|
||||
}
|
||||
}
|
||||
|
||||
// 'Olah, Chris and Carter, Shan',
|
||||
get bibtexAuthors() {
|
||||
return this.authors.map(author => {
|
||||
return author.lastName + ', ' + author.firstName;
|
||||
}).join(' and ');
|
||||
}
|
||||
|
||||
// 'olah2016attention'
|
||||
get slug() {
|
||||
let slug = '';
|
||||
if (this.authors.length) {
|
||||
slug += this.authors[0].lastName.toLowerCase();
|
||||
slug += this.publishedYear;
|
||||
slug += this.title.split(' ')[0].toLowerCase();
|
||||
}
|
||||
return slug || 'Untitled';
|
||||
}
|
||||
|
||||
get bibliographyEntries() {
|
||||
return new Map(this.citations.map( citationKey => {
|
||||
const entry = this.bibliography.get(citationKey);
|
||||
return [citationKey, entry];
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import bibtexParse from 'bibtex-parse-js';
|
||||
|
||||
function normalizeTag(string) {
|
||||
return string
|
||||
.replace(/[\t\n ]+/g, ' ')
|
||||
.replace(/{\\["^`.'acu~Hvs]( )?([a-zA-Z])}/g, (full, x, char) => char)
|
||||
.replace(/{\\([a-zA-Z])}/g, (full, char) => char);
|
||||
}
|
||||
|
||||
export function parseBibtex(bibtex) {
|
||||
const bibliography = new Map();
|
||||
const parsedEntries = bibtexParse.toJSON(bibtex);
|
||||
for (const entry of parsedEntries) {
|
||||
// normalize tags; note entryTags is an object, not Map
|
||||
for (const [key, value] of Object.entries(entry.entryTags)) {
|
||||
entry.entryTags[key] = normalizeTag(value);
|
||||
}
|
||||
entry.entryTags.type = entry.entryType;
|
||||
// add to bibliography
|
||||
bibliography.set(entry.citationKey, entry.entryTags);
|
||||
}
|
||||
return bibliography;
|
||||
}
|
||||
|
||||
export function serializeFrontmatterToBibtex(frontMatter) {
|
||||
return `@article{${frontMatter.slug},
|
||||
author = {${frontMatter.bibtexAuthors}},
|
||||
title = {${frontMatter.title}},
|
||||
journal = {${frontMatter.journal.title}},
|
||||
year = {${frontMatter.publishedYear}},
|
||||
note = {${frontMatter.url}}
|
||||
}`;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
export function inline_cite_short(keys){
|
||||
function cite_string(key){
|
||||
if (key in data.bibliography){
|
||||
var n = data.citations.indexOf(key)+1;
|
||||
return ''+n;
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
return '['+keys.map(cite_string).join(', ')+']';
|
||||
}
|
||||
|
||||
export function inline_cite_long(keys){
|
||||
function cite_string(key){
|
||||
if (key in data.bibliography){
|
||||
var ent = data.bibliography[key];
|
||||
var names = ent.author.split(' and ');
|
||||
names = names.map(name => name.split(',')[0].trim());
|
||||
var year = ent.year;
|
||||
if (names.length == 1) return names[0] + ', ' + year;
|
||||
if (names.length == 2) return names[0] + ' & ' + names[1] + ', ' + year;
|
||||
if (names.length > 2) return names[0] + ', et al., ' + year;
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
return keys.map(cite_string).join(', ');
|
||||
}
|
||||
|
||||
function author_string(ent, template, sep, finalSep){
|
||||
var names = ent.author.split(' and ');
|
||||
let name_strings = names.map(name => {
|
||||
name = name.trim();
|
||||
if (name.indexOf(',') != -1){
|
||||
var last = name.split(',')[0].trim();
|
||||
var firsts = name.split(',')[1];
|
||||
} else {
|
||||
var last = name.split(' ').slice(-1)[0].trim();
|
||||
var firsts = name.split(' ').slice(0,-1).join(' ');
|
||||
}
|
||||
var initials = '';
|
||||
if (firsts != undefined) {
|
||||
initials = firsts.trim().split(' ').map(s => s.trim()[0]);
|
||||
initials = initials.join('.')+'.';
|
||||
}
|
||||
return template.replace('${F}', firsts)
|
||||
.replace('${L}', last)
|
||||
.replace('${I}', initials);
|
||||
});
|
||||
if (names.length > 1) {
|
||||
var str = name_strings.slice(0, names.length-1).join(sep);
|
||||
str += (finalSep || sep) + name_strings[names.length-1];
|
||||
return str;
|
||||
} else {
|
||||
return name_strings[0];
|
||||
}
|
||||
}
|
||||
|
||||
function venue_string(ent) {
|
||||
var cite = (ent.journal || ent.booktitle || '');
|
||||
if ('volume' in ent){
|
||||
var issue = ent.issue || ent.number;
|
||||
issue = (issue != undefined)? '('+issue+')' : '';
|
||||
cite += ', Vol ' + ent.volume + issue;
|
||||
}
|
||||
if ('pages' in ent){
|
||||
cite += ', pp. ' + ent.pages;
|
||||
}
|
||||
if (cite != '') cite += '. ';
|
||||
if ('publisher' in ent){
|
||||
cite += ent.publisher;
|
||||
if (cite[cite.length-1] != '.') cite += '.';
|
||||
}
|
||||
return cite;
|
||||
}
|
||||
|
||||
function link_string(ent){
|
||||
if ('url' in ent){
|
||||
var url = ent.url;
|
||||
var arxiv_match = (/arxiv\.org\/abs\/([0-9\.]*)/).exec(url);
|
||||
if (arxiv_match != null){
|
||||
url = `http://arxiv.org/pdf/${arxiv_match[1]}.pdf`;
|
||||
}
|
||||
|
||||
if (url.slice(-4) == '.pdf'){
|
||||
var label = 'PDF';
|
||||
} else if (url.slice(-5) == '.html') {
|
||||
var label = 'HTML';
|
||||
}
|
||||
return `  <a href="${url}">[${label||'link'}]</a>`;
|
||||
}/* else if ("doi" in ent){
|
||||
return `  <a href="https://doi.org/${ent.doi}" >[DOI]</a>`;
|
||||
}*/ else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
function doi_string(ent, new_line){
|
||||
if ('doi' in ent) {
|
||||
return `${new_line?'<br>':''} <a href="https://doi.org/${ent.doi}" style="text-decoration:inherit;">DOI: ${ent.doi}</a>`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export function bibliography_cite(ent, fancy){
|
||||
if (ent){
|
||||
var cite = '<b>' + ent.title + '</b> ';
|
||||
cite += link_string(ent) + '<br>';
|
||||
cite += author_string(ent, '${L}, ${I}', ', ', ' and ');
|
||||
if (ent.year || ent.date){
|
||||
cite += ', ' + (ent.year || ent.date) + '. ';
|
||||
} else {
|
||||
cite += '. ';
|
||||
}
|
||||
cite += venue_string(ent);
|
||||
cite += doi_string(ent);
|
||||
return cite;
|
||||
/*var cite = author_string(ent, "${L}, ${I}", ", ", " and ");
|
||||
if (ent.year || ent.date){
|
||||
cite += ", " + (ent.year || ent.date) + ". "
|
||||
} else {
|
||||
cite += ". "
|
||||
}
|
||||
cite += "<b>" + ent.title + "</b>. ";
|
||||
cite += venue_string(ent);
|
||||
cite += doi_string(ent);
|
||||
cite += link_string(ent);
|
||||
return cite*/
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
export function hover_cite(ent){
|
||||
if (ent){
|
||||
var cite = '';
|
||||
cite += '<b>' + ent.title + '</b>';
|
||||
cite += link_string(ent);
|
||||
cite += '<br>';
|
||||
|
||||
var a_str = author_string(ent, '${I} ${L}', ', ') + '.';
|
||||
var v_str = venue_string(ent).trim() + ' ' + ent.year + '. ' + doi_string(ent, true);
|
||||
|
||||
if ((a_str+v_str).length < Math.min(40, ent.title.length)) {
|
||||
cite += a_str + ' ' + v_str;
|
||||
} else {
|
||||
cite += a_str + '<br>' + v_str;
|
||||
}
|
||||
return cite;
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//https://scholar.google.com/scholar?q=allintitle%3ADocument+author%3Aolah
|
||||
function get_GS_URL(ent){
|
||||
if (ent){
|
||||
var names = ent.author.split(' and ');
|
||||
names = names.map(name => name.split(',')[0].trim());
|
||||
var title = ent.title.split(' ');//.replace(/[,:]/, "")
|
||||
var url = 'http://search.labs.crossref.org/dois?';//""https://scholar.google.com/scholar?"
|
||||
url += uris({q: names.join(' ') + ' ' + title.join(' ')});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
function make_hover_css(pos) {
|
||||
const pretty = window.innerWidth > 600;
|
||||
const padding = pretty? 18 : 12;
|
||||
const outer_padding = pretty ? 18 : 0;
|
||||
const bbox = document.querySelector('body').getBoundingClientRect();
|
||||
let left = pos[0] - bbox.left, top = pos[1] - bbox.top;
|
||||
let width = Math.min(window.innerWidth-2*outer_padding, 648);
|
||||
left = Math.min(left, window.innerWidth-width-outer_padding);
|
||||
width = width - 2 * padding;
|
||||
return (`position: absolute;
|
||||
background-color: #FFF;
|
||||
opacity: 0.95;
|
||||
max-width: ${width}px;
|
||||
top: ${top}px;
|
||||
left: ${left}px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||
padding: ${padding}px;
|
||||
border-radius: ${pretty? 3 : 0}px;
|
||||
box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2);
|
||||
z-index: ${1e6};`);
|
||||
}
|
||||
|
||||
export class HoverBox {
|
||||
|
||||
constructor(contentHTML, triggerElement) {
|
||||
this.visible = false;
|
||||
// div hold teh contents of the box that will become visible
|
||||
this.div = contentHTML;
|
||||
this.bindDivEvents(this.div);
|
||||
// triggerElement holds the element that needs to be hovered etc to show contents
|
||||
this.triggerElement = triggerElement;
|
||||
this.bindTriggerEvents(this.triggerElement);
|
||||
this.hide();
|
||||
}
|
||||
|
||||
bindDivEvents(node) {
|
||||
// For mice, same behavior as hovering on links
|
||||
this.div.addEventListener('mouseover', () => {
|
||||
if (!this.visible) this.showAtNode(node);
|
||||
this.stopTimeout();
|
||||
});
|
||||
this.div.addEventListener('mouseout', () => {
|
||||
this.extendTimeout(250);
|
||||
});
|
||||
// Don't trigger body touchstart event when touching within box
|
||||
this.div.addEventListener('touchstart', (event) => {
|
||||
event.stopPropagation();
|
||||
}, {passive: true});
|
||||
// Close box when touching outside box
|
||||
document.body.addEventListener('touchstart', () => {
|
||||
this.hide();
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
bindTriggerEvents(node) {
|
||||
node.addEventListener('mouseover', () => {
|
||||
if (!this.visible) {
|
||||
this.showAtNode(node);
|
||||
}
|
||||
this.stopTimeout();
|
||||
});
|
||||
|
||||
node.addEventListener('mouseout', () => {
|
||||
this.extendTimeout(250);
|
||||
});
|
||||
|
||||
node.addEventListener('touchstart', (event) => {
|
||||
if (this.visible) {
|
||||
this.hide();
|
||||
} else {
|
||||
this.showAtNode(node);
|
||||
}
|
||||
// Don't trigger body touchstart event when touching link
|
||||
event.stopPropagation();
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
show(position) {
|
||||
this.visible = true;
|
||||
const css = make_hover_css(position);
|
||||
this.div.setAttribute('style', css );
|
||||
}
|
||||
|
||||
showAtNode(node) {
|
||||
const bbox = node.getBoundingClientRect();
|
||||
this.show([bbox.right, bbox.bottom]);
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.visible = false;
|
||||
this.div.setAttribute('style', 'display:none');
|
||||
this.stopTimeout();
|
||||
}
|
||||
|
||||
stopTimeout() {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
extendTimeout(time) {
|
||||
this.stopTimeout();
|
||||
this.timeout = setTimeout(() => {
|
||||
this.hide();
|
||||
}, time);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// const marginSmall = 16;
|
||||
// const marginLarge = 3 * marginSmall;
|
||||
// const margin = marginSmall + marginLarge;
|
||||
// const gutter = marginSmall;
|
||||
// const outsetAmount = margin / 2;
|
||||
// const numCols = 4;
|
||||
// const numGutters = numCols - 1;
|
||||
// const columnWidth = (768 - 2 * marginLarge - numGutters * gutter) / numCols;
|
||||
//
|
||||
// const screenwidth = 768;
|
||||
// const pageWidth = screenwidth - 2 * marginLarge;
|
||||
// const bodyWidth = pageWidth - columnWidth - gutter;
|
||||
|
||||
export function body(selector) {
|
||||
return `${selector} {
|
||||
grid-column: margin-left / body;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
export function page(selector) {
|
||||
return `${selector} {
|
||||
grid-column: margin-left / page;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
export function screen(selector) {
|
||||
return `${selector} {
|
||||
grid-column: start / end;
|
||||
}
|
||||
`;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
export const Mutating = (superclass) => {
|
||||
return class extends superclass {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// set up mutation observer
|
||||
const options = {childList: true, characterData: true, subtree: true};
|
||||
const observer = new MutationObserver( () => {
|
||||
observer.disconnect();
|
||||
this.renderIfPossible();
|
||||
observer.observe(this, options);
|
||||
});
|
||||
|
||||
// ...and listen for changes
|
||||
observer.observe(this, options);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
this.renderIfPossible();
|
||||
}
|
||||
|
||||
// potential TODO: check if this is enough for all our usecases
|
||||
// maybe provide a custom function to tell if we have enough information to render
|
||||
renderIfPossible() {
|
||||
if (this.textContent && this.root) {
|
||||
this.renderContent();
|
||||
}
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
console.error(`Your class ${this.constructor.name} must provide a custom renderContent() method!` );
|
||||
}
|
||||
|
||||
}; // end class
|
||||
}; // end mixin function
|
||||
@@ -0,0 +1,85 @@
|
||||
export function propName(attr) {
|
||||
return attr.replace(/(-[a-z])/g, (s) => s.toUpperCase().replace('-', ''));
|
||||
}
|
||||
|
||||
export function attrName(prop) {
|
||||
return prop.replace(/([A-Z])/g, (s) => '-' + s.toLowerCase());
|
||||
}
|
||||
|
||||
export function deserializeAttribute(value, type) {
|
||||
switch (type) {
|
||||
case String:
|
||||
break;
|
||||
case Array:
|
||||
case Object:
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (e) {}
|
||||
break;
|
||||
case Boolean:
|
||||
value = value != 'false' && value != '0' && value;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
const immediately = window.setImmediate || function(fn, args) {
|
||||
window.setTimeout(function() {
|
||||
fn.apply(this, args);
|
||||
}, 0);
|
||||
};
|
||||
|
||||
export const Properties = (properties) => {
|
||||
const keys = Object.keys(properties);
|
||||
const attrs = keys.map((k) => attrName(k));
|
||||
return (superclass) => {
|
||||
const cls = class extends superclass {
|
||||
static get observedAttributes() {
|
||||
return attrs;
|
||||
}
|
||||
attributeChangedCallback(attr, oldValue, newValue) {
|
||||
const prop = propName(attr);
|
||||
const value = deserializeAttribute(newValue, properties[prop].type);
|
||||
this[prop] = value;
|
||||
}
|
||||
_propertiesChanged() {
|
||||
if (!this.propertiesChangedCallback) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(this._propertiesChangedTimeout);
|
||||
this._propertiesChangedTimeout = immediately(() => {
|
||||
this.propertiesChangedCallback(this);
|
||||
});
|
||||
}
|
||||
};
|
||||
keys.forEach(function(k) {
|
||||
const secret = `_${k}`;
|
||||
const callback = `${k}Changed`;
|
||||
const defaultValue = properties[k].value;
|
||||
Object.defineProperty(cls.prototype, k, {
|
||||
get: function() {
|
||||
let value = this[secret];
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
if (defaultValue && typeof defaultValue == 'function') {
|
||||
this[secret] = defaultValue();
|
||||
} else {
|
||||
this[secret] = defaultValue;
|
||||
}
|
||||
return this[secret];
|
||||
},
|
||||
set: function(value) {
|
||||
const oldValue = this[secret];
|
||||
this[secret] = value;
|
||||
if (this[callback]) {
|
||||
this[callback](value, oldValue);
|
||||
}
|
||||
this._propertiesChanged();
|
||||
}
|
||||
});
|
||||
});
|
||||
return cls;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
/*global ShadyCSS*/
|
||||
|
||||
export const Template = (name, templateString, useShadow = true) => {
|
||||
|
||||
return (superclass) => {
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = templateString;
|
||||
|
||||
if (useShadow && 'ShadyCSS' in window) {
|
||||
ShadyCSS.prepareTemplate(template, name);
|
||||
}
|
||||
|
||||
return class extends superclass {
|
||||
|
||||
static get is() { return name; }
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.clone = document.importNode(template.content, true);
|
||||
if (useShadow) {
|
||||
this.attachShadow({mode: 'open'});
|
||||
this.shadowRoot.appendChild(this.clone);
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (useShadow) {
|
||||
if ('ShadyCSS' in window) {
|
||||
ShadyCSS.styleElement(this);
|
||||
}
|
||||
} else {
|
||||
this.insertBefore(this.clone, this.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
get root() {
|
||||
if (useShadow) {
|
||||
return this.shadowRoot;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Are we using these? Should we even? */
|
||||
$(query) {
|
||||
return this.root.querySelector(query);
|
||||
}
|
||||
|
||||
$$(query) {
|
||||
return this.root.querySelectorAll(query);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,201 @@
|
||||
|
||||
d-article {
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
padding-top: 0;
|
||||
padding-bottom: 72px;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
line-height: 1.6em;
|
||||
/*border-top: 1px solid rgba(0, 0, 0, 0.2);*/
|
||||
}
|
||||
@media(min-width: 768px) {
|
||||
d-article {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H2 */
|
||||
|
||||
d-article h2 {
|
||||
font-weight: 600;
|
||||
font-size: 26px;
|
||||
line-height: 1.25em;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 24px;
|
||||
padding-bottom: 24px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article h2 {
|
||||
margin-top: 2em;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
d-article h1 + h2 {
|
||||
font-weight: 300;
|
||||
font-size: 20px;
|
||||
line-height: 1.4em;
|
||||
margin-top: 8px;
|
||||
font-style: normal;
|
||||
}
|
||||
@media(min-width: 1080px) {
|
||||
.centered h1 + h2 {
|
||||
text-align: center;
|
||||
}
|
||||
d-article h1 + h2 {
|
||||
margin-top: 12px;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H3 */
|
||||
|
||||
d-article h3 {
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
line-height: 1.4em;
|
||||
margin-top: 36px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
d-article h1 + h3 {
|
||||
margin-top: 48px;
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article h3 {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
/* H4 */
|
||||
|
||||
d-article h4 {
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
d-article a {
|
||||
color: inherit;
|
||||
}
|
||||
d-article p,
|
||||
d-article ul,
|
||||
d-article ol {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
d-article p b,
|
||||
d-article ul b,
|
||||
d-article ol b {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
d-article a {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.4);
|
||||
text-decoration: none;
|
||||
}
|
||||
d-article a:hover {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
d-article .link {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
d-article ul,
|
||||
d-article ol {
|
||||
padding-left: 24px;
|
||||
}
|
||||
d-article li {
|
||||
margin-bottom: 24px;
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
d-article pre {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
d-article hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
|
||||
margin-top: 60px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
d-article section {
|
||||
margin-top: 60px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
/* Figure */
|
||||
|
||||
d-article figure {
|
||||
position: relative;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article figure {
|
||||
margin-top: 48px;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
}
|
||||
d-article figure img {
|
||||
width: 100%;
|
||||
}
|
||||
d-article figure svg text,
|
||||
d-article figure svg tspan {
|
||||
}
|
||||
d-article figure figcaption {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
font-size: 12px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
@media(min-width: 1024px) {
|
||||
d-article figure figcaption {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
d-article figure.external img {
|
||||
background: white;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.1);
|
||||
padding: 18px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
d-article figure figcaption a {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
/*d-article figure figcaption::before {
|
||||
position: relative;
|
||||
display: block;
|
||||
top: -20px;
|
||||
content: "";
|
||||
width: 25px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.3);
|
||||
}*/
|
||||
d-article span.equation-mimic {
|
||||
font-family: georgia;
|
||||
font-size: 115%;
|
||||
font-style: italic;
|
||||
}
|
||||
d-article figure figcaption b {
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 1.0);
|
||||
}
|
||||
d-article > d-code,
|
||||
d-article section > d-code {
|
||||
display: block;
|
||||
}
|
||||
d-article > d-math[block],
|
||||
d-article section > d-math[block] {
|
||||
display: block;
|
||||
}
|
||||
d-article .citation {
|
||||
color: #668;
|
||||
cursor: pointer;
|
||||
}
|
||||
d-include {
|
||||
width: auto;
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
html {
|
||||
font-size: 20px;
|
||||
line-height: 1rem;
|
||||
font-family: "Libre Franklin", "Helvetica Neue", sans-serif;
|
||||
text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #004276;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
table th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table thead {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
table thead th {
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
table tbody :first-child td {
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
@supports not (display: grid) {
|
||||
d-article,
|
||||
d-title,
|
||||
d-byline,
|
||||
d-appendix,
|
||||
distill-footer {
|
||||
display: block;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
d-article,
|
||||
d-title,
|
||||
d-byline,
|
||||
d-appendix,
|
||||
distill-footer {
|
||||
display: grid;
|
||||
justify-items: stretch;
|
||||
grid-template-columns: [start] 8px [margin-left-outset] 8px [margin-left] 1fr [body] 0px [page] 8px [body-outset] 0px [page-outset] 8px [end];
|
||||
}
|
||||
|
||||
@media(min-width: 768px) {
|
||||
|
||||
d-article,
|
||||
d-title,
|
||||
d-byline,
|
||||
d-appendix,
|
||||
distill-footer {
|
||||
grid-template-columns: [start] 32px [margin-left-outset] 32px [margin-left] 3fr [body] 32px [body-outset] 1fr [page] 32px [page-outset] 32px [end];
|
||||
}
|
||||
}
|
||||
|
||||
@media(min-width: 1024px) {
|
||||
d-article,
|
||||
d-title,
|
||||
d-byline,
|
||||
d-appendix,
|
||||
distill-footer {
|
||||
grid-template-columns: [start] 1fr [margin-left-outset] 32px [margin-left] 672px [body] 32px [body-outset] 224px [page] 32px [page-outset] 1fr [end];
|
||||
}
|
||||
}
|
||||
|
||||
d-appendix,
|
||||
d-article > d-title,
|
||||
d-article > d-title > d-byline,
|
||||
d-article > distill-footer {
|
||||
grid-column: start / end;
|
||||
}
|
||||
|
||||
.l-body,
|
||||
d-article > * {
|
||||
grid-column: margin-left / body;
|
||||
}
|
||||
|
||||
.l-page,
|
||||
d-figure {
|
||||
grid-column: margin-left / page;
|
||||
}
|
||||
|
||||
.l-body-outset {
|
||||
grid-column: margin-left-outset / body-outset;
|
||||
}
|
||||
|
||||
.l-page-outset {
|
||||
grid-column: margin-left-outset / page-outset;
|
||||
}
|
||||
|
||||
.l-screen {
|
||||
grid-column: start / end;
|
||||
}
|
||||
|
||||
.l-screen-inset {
|
||||
grid-column: start / end;
|
||||
padding-left: 16px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
|
||||
/* Aside */
|
||||
|
||||
aside {
|
||||
grid-column: margin-left / body;
|
||||
}
|
||||
|
||||
@media(min-width: 768px) {
|
||||
aside {
|
||||
grid-column: body-outset / page;
|
||||
font-size: 14px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
/*
|
||||
.l-body,
|
||||
.l-page,
|
||||
.l-middle,
|
||||
d-article > div,
|
||||
d-article > p,
|
||||
d-article > h1,
|
||||
d-article > h2,
|
||||
d-article > h3,
|
||||
d-article > h4,
|
||||
d-article > figure,
|
||||
d-article > ul,
|
||||
d-article > d-abstract,
|
||||
d-article > d-code,
|
||||
d-article > d-math,
|
||||
d-article > table,
|
||||
d-article section > div,
|
||||
d-article section > p,
|
||||
d-article section > h1,
|
||||
d-article section > h2,
|
||||
d-article section > h3,
|
||||
d-article section > h4,
|
||||
d-article section > figure,
|
||||
d-article section > ul,
|
||||
d-article section > d-abstract,
|
||||
d-article section > d-code,
|
||||
d-article section > d-math,
|
||||
d-article section > table {
|
||||
width: calc(100% - 32px);
|
||||
margin-left: 16px;
|
||||
margin-right: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.l-body-outset,
|
||||
.l-page-outset,
|
||||
.l-middle-outset {
|
||||
width: calc(100% - 16px);
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.l-screen {
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
width: 100%;
|
||||
background-color: #F8F8FC;
|
||||
border-top: 1px solid #E8E8EC;
|
||||
border-bottom: 1px solid #E8E8EC;
|
||||
}
|
||||
|
||||
@media(min-width: 768px) {
|
||||
.l-body,
|
||||
d-article > div,
|
||||
d-article > p,
|
||||
d-article > h1,
|
||||
d-article > h2,
|
||||
d-article > h3,
|
||||
d-article > h4,
|
||||
d-article > figure,
|
||||
d-article > ul,
|
||||
d-article > d-abstract,
|
||||
d-article > d-code,
|
||||
d-article > d-math,
|
||||
d-article > d-math,
|
||||
d-article section > div,
|
||||
d-article section > p,
|
||||
d-article section > h1,
|
||||
d-article section > h2,
|
||||
d-article section > h3,
|
||||
d-article section > h4,
|
||||
d-article section > figure,
|
||||
d-article section > ul,
|
||||
d-article section > d-abstract,
|
||||
d-article section > d-code,
|
||||
d-article section > d-math,
|
||||
d-article section > table {
|
||||
margin-left: 64px;
|
||||
width: calc((100% - 2 * 64px - 3 * 16px)/4*3 + 2*16px );
|
||||
}
|
||||
|
||||
.l-body-outset {
|
||||
margin-left: 32px;
|
||||
width: calc((100% - 2 * 64px - 3 * 16px)/4*3 + 2*16px + 64px );;
|
||||
}
|
||||
|
||||
.l-middle,
|
||||
.l-middle-outset,
|
||||
.l-page {
|
||||
margin-left: 64px;
|
||||
margin-right: 64px;
|
||||
width: calc(100% - 2*64px);
|
||||
}
|
||||
|
||||
.l-page-outset {
|
||||
margin-left: 32px;
|
||||
margin-right: 32px;
|
||||
width: calc(100% - 64px);
|
||||
}
|
||||
|
||||
.margin {
|
||||
font-size: 14px;
|
||||
line-height: normal;
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 0;
|
||||
margin-right: 64px;
|
||||
width: calc((100% - 2 * 64px - 3 * 16px)/4);
|
||||
}
|
||||
}
|
||||
|
||||
@media(min-width: 1024px) {
|
||||
.l-body,
|
||||
d-article > div,
|
||||
d-article > p,
|
||||
d-article > h2,
|
||||
d-article > h3,
|
||||
d-article > h4,
|
||||
d-article > figure,
|
||||
d-article > ul,
|
||||
d-article > d-abstract,
|
||||
d-article > d-code,
|
||||
d-article > d-math,
|
||||
d-article > table,
|
||||
d-article section > div,
|
||||
d-article section > p,
|
||||
d-article section > h2,
|
||||
d-article section > h3,
|
||||
d-article section > h4,
|
||||
d-article section > figure,
|
||||
d-article section > ul,
|
||||
d-article section > d-abstract,
|
||||
d-article section > d-code,
|
||||
d-article section > d-math,
|
||||
d-article section > table {
|
||||
margin-left: calc(50% - (1024px - 2*64px) / 2);
|
||||
width: 668px;
|
||||
}
|
||||
|
||||
.l-body-outset {
|
||||
margin-left: calc((50% - (1024px - 2*64px) / 2) - 32px);
|
||||
width: calc(668px + 64px)
|
||||
}
|
||||
|
||||
.l-middle,
|
||||
.l-middle-outset,
|
||||
.l-page {
|
||||
margin-left: calc(50% - (1024px - 2*64px) / 2);
|
||||
width: calc(100% - 2* (50% - (1024px - 2*64px) / 2));
|
||||
}
|
||||
|
||||
.l-page-outset {
|
||||
margin-left: calc((50% - (1024px - 2*64px) / 2) - 32px);
|
||||
width: calc(100% - 2* (50% - (1024px - 2*64px) / 2) + 64px);
|
||||
}
|
||||
|
||||
.margin {
|
||||
font-size: 14px;
|
||||
line-height: normal;
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 0;
|
||||
margin-right: calc(50% - (1024px - 2*64px) / 2);
|
||||
width: 206px;
|
||||
}
|
||||
|
||||
|
||||
/* Side */
|
||||
|
||||
/*
|
||||
.side.l-body,
|
||||
d-article .side.l-body {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px + 648px) / 2);
|
||||
width: calc(648px / 2 - 24px - 84px);
|
||||
}
|
||||
.side.l-body-outset,
|
||||
d-article .side.l-body-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px + 648px - 48px) / 2);
|
||||
width: calc(648px / 2 - 48px + 24px);
|
||||
}
|
||||
.side.l-middle,
|
||||
d-article .side.l-middle {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: calc(456px - 84px);
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px) / 2 + 168px);
|
||||
}
|
||||
.side.l-middle-outset,
|
||||
d-article .side.l-middle-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: 456px;
|
||||
margin-left: 48px;
|
||||
margin-right: calc((100vw - 984px) / 2 + 168px);
|
||||
}
|
||||
.side.l-page,
|
||||
d-article .side.l-page {
|
||||
clear: both;
|
||||
float: right;
|
||||
margin-left: 48px;
|
||||
width: calc(624px - 84px);
|
||||
margin-right: calc((100vw - 984px) / 2);
|
||||
}
|
||||
.side.l-page-outset,
|
||||
d-article .side.l-page-outset {
|
||||
clear: both;
|
||||
float: right;
|
||||
width: 624px;
|
||||
margin-right: calc((100vw - 984px) / 2);
|
||||
}
|
||||
}*/
|
||||
|
||||
/* Rows and Columns */
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
}
|
||||
.column {
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
margin-right: 24px;
|
||||
margin-left: 24px;
|
||||
}
|
||||
.row > .column:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
.row > .column:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
@media print {
|
||||
|
||||
@page {
|
||||
size: 8in 11in;
|
||||
@bottom-right {
|
||||
content: counter(page) " of " counter(pages);
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
/* no general margins -- CSS Grid takes care of those */
|
||||
}
|
||||
|
||||
p, code {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
h2, h3 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
|
||||
d-header {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
d-footer {
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import base from './styles-base.css';
|
||||
import layout from './styles-layout.css';
|
||||
import article from './styles-article.css';
|
||||
import print from './styles-print.css';
|
||||
|
||||
let s = document.createElement('style');
|
||||
s.textContent = base + layout + print + article;
|
||||
document.querySelector('head').appendChild(s);
|
||||
export default s;
|
||||
@@ -0,0 +1,53 @@
|
||||
/* eslint-env node, mocha */
|
||||
|
||||
/* Extractors */
|
||||
import ExtractFrontmatter from './extractors/front-matter';
|
||||
import ExtractBibliography from './extractors/bibliography';
|
||||
import ExtractCitations from './extractors/citations';
|
||||
|
||||
const extractors = [
|
||||
ExtractFrontmatter,
|
||||
ExtractBibliography,
|
||||
ExtractCitations,
|
||||
];
|
||||
|
||||
/* Transforms */
|
||||
import HTML from './transforms/html';
|
||||
import Polyfills from './transforms/polyfills';
|
||||
import Meta from './transforms/meta';
|
||||
import Typeset from './transforms/typeset';
|
||||
// import Bibliography from './transforms/bibliography';
|
||||
|
||||
const transforms = [
|
||||
HTML, Polyfills, Meta, Typeset//, Bibliography
|
||||
];
|
||||
|
||||
/* Distill Transforms */
|
||||
import DistillHeader from './distill-transforms/distill-header';
|
||||
import DistillAppendix from './distill-transforms/distill-appendix';
|
||||
import DistillFooter from './distill-transforms/distill-footer';
|
||||
|
||||
const distillTransforms = [
|
||||
DistillHeader, DistillAppendix, DistillFooter,
|
||||
];
|
||||
|
||||
/* Exported functions */
|
||||
|
||||
export function render(dom, data) {
|
||||
// first, we collect static data from the dom
|
||||
for (const extract of extractors) {
|
||||
extract(dom, data);
|
||||
}
|
||||
// secondly we use it to transform parts of the dom
|
||||
for (const transform of transforms) {
|
||||
transform(dom, data);
|
||||
}
|
||||
// the function calling us can now use the transformed dom and filled data object
|
||||
}
|
||||
|
||||
export function distillify(dom, data) {
|
||||
// thirdly, we optionally use these additional transforms when publishing on the Distill website
|
||||
for (const transform of distillTransforms) {
|
||||
transform(dom, data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
const html = `
|
||||
<style>
|
||||
dt-banner {
|
||||
background: #FFF59D;
|
||||
display: block;
|
||||
text-align: center;
|
||||
color: black;
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
}
|
||||
</style>
|
||||
<div>This article is a draft, awaiting review for publication in Distill</div>
|
||||
`;
|
||||
|
||||
export default function(dom, data) {
|
||||
let banner = dom.createElement('dt-banner');
|
||||
banner.innerHTML = html;
|
||||
let b = dom.querySelector('body');
|
||||
b.insertBefore(banner, b.firstChild);
|
||||
banner.addEventListener('click', function() {
|
||||
banner.style.display = 'none';
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { renderBibliography, templateString } from '../components/d-bibliography';
|
||||
|
||||
export default function(dom, data) {
|
||||
const bibliographyTag = dom.querySelector('d-bibliography');
|
||||
if (!bibliographyTag) {
|
||||
console.warn('No bibliography tag found!');
|
||||
return;
|
||||
}
|
||||
|
||||
const bibliographyEntries = new Map(data.citations.map( citationKey => {
|
||||
const entry = data.bibliography.get(citationKey);
|
||||
return [citationKey, entry];
|
||||
}));
|
||||
|
||||
const prerenderedBibliography = dom.createElement('d-bibliography-prerendered');
|
||||
|
||||
|
||||
const template = dom.createElement('template');
|
||||
template.innerHTML = templateString;
|
||||
const clone = dom.importNode(template.content, true);
|
||||
prerenderedBibliography.innerHTML = template.content;
|
||||
renderBibliography(prerenderedBibliography, bibliographyEntries, dom);
|
||||
|
||||
bibliographyTag.parentElement.insertBefore(bibliographyTag, prerenderedBibliography);
|
||||
bibliographyTag.parentElement.removeChild(bibliographyTag);
|
||||
|
||||
}
|
||||
@@ -1,18 +1,4 @@
|
||||
// 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 mustache from "mustache";
|
||||
import mustache from 'mustache';
|
||||
|
||||
const html = `
|
||||
<style>
|
||||
@@ -25,6 +11,8 @@ const html = `
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
min-height: 90px;
|
||||
|
||||
}
|
||||
dt-article.centered dt-byline {
|
||||
text-align: center;
|
||||
@@ -148,20 +136,16 @@ const template = `
|
||||
</div>
|
||||
{{/authors}}
|
||||
</div>
|
||||
{{#publishedYear}}
|
||||
<div class="date">
|
||||
<div class="month">{{publishedMonth}}. {{publishedDay}}</div>
|
||||
<div class="year">{{publishedYear}}</div>
|
||||
</div>
|
||||
{{/publishedYear}}
|
||||
{{#publishedYear}}
|
||||
<a class="citation" href="#citation">
|
||||
<div>Citation:</div>
|
||||
<div>{{concatenatedAuthors}}, {{publishedYear}}</div>
|
||||
</a>
|
||||
{{/publishedYear}}
|
||||
</div>
|
||||
`
|
||||
`;
|
||||
|
||||
export default function(dom, data) {
|
||||
let el = dom.querySelector('dt-byline');
|
||||
@@ -0,0 +1,234 @@
|
||||
export default function(dom, data) {
|
||||
let css = `
|
||||
dt-cite {
|
||||
color: hsla(206, 90%, 20%, 0.7);
|
||||
}
|
||||
dt-cite .citation-number {
|
||||
cursor: default;
|
||||
white-space: nowrap;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Roboto", Helvetica, sans-serif;
|
||||
font-size: 75%;
|
||||
color: hsla(206, 90%, 20%, 0.7);
|
||||
display: inline-block;
|
||||
line-height: 1.1em;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
figcaption dt-cite .citation-number {
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
top: -2px;
|
||||
line-height: 1em;
|
||||
}
|
||||
`;
|
||||
|
||||
let style = dom.createElement('style');
|
||||
style.textContent = css;
|
||||
dom.querySelector('body').appendChild(style);
|
||||
|
||||
let citations = data.citations;
|
||||
/*if (data.citations) {
|
||||
citations = Object.keys(data.citations).map(c => data.citations[c]);
|
||||
citations.sort((a, b) => {
|
||||
return a.author.localeCompare(b.author);
|
||||
});
|
||||
}*/
|
||||
|
||||
var citeTags = [].slice.apply(dom.querySelectorAll('dt-cite'));
|
||||
citeTags.forEach((el,n) => {
|
||||
var key = el.getAttribute('key');
|
||||
if (key) {
|
||||
var keys = key.split(',');
|
||||
var cite_string = inline_cite_short(keys);
|
||||
var cite_hover_str = '';
|
||||
keys.map((key,n) => {
|
||||
if (n>0) cite_hover_str += '<br><br>';
|
||||
cite_hover_str += hover_cite(data.bibliography[key]);
|
||||
});
|
||||
cite_hover_str = cite_hover_str.replace(/"/g, ''');
|
||||
var orig_string = el.innerHTML;
|
||||
if (orig_string != '') orig_string += ' ';
|
||||
el.innerHTML = `<span id="citation-${n}" data-hover="${cite_hover_str}">${orig_string}<span class="citation-number">${cite_string}</span></span>`;
|
||||
}
|
||||
});
|
||||
|
||||
let bibEl = dom.querySelector('dt-bibliography');
|
||||
if (bibEl) {
|
||||
let ol = dom.createElement('ol');
|
||||
citations.forEach(key => {
|
||||
let el = dom.createElement('li');
|
||||
el.innerHTML = bibliography_cite(data.bibliography[key]);
|
||||
ol.appendChild(el);
|
||||
});
|
||||
bibEl.appendChild(ol);
|
||||
}
|
||||
|
||||
function inline_cite_short(keys){
|
||||
function cite_string(key){
|
||||
if (key in data.bibliography){
|
||||
var n = data.citations.indexOf(key)+1;
|
||||
return ''+n;
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
return '['+keys.map(cite_string).join(', ')+']';
|
||||
}
|
||||
|
||||
function inline_cite_long(keys){
|
||||
function cite_string(key){
|
||||
if (key in data.bibliography){
|
||||
var ent = data.bibliography[key];
|
||||
var names = ent.author.split(' and ');
|
||||
names = names.map(name => name.split(',')[0].trim());
|
||||
var year = ent.year;
|
||||
if (names.length == 1) return names[0] + ', ' + year;
|
||||
if (names.length == 2) return names[0] + ' & ' + names[1] + ', ' + year;
|
||||
if (names.length > 2) return names[0] + ', et al., ' + year;
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
return keys.map(cite_string).join(', ');
|
||||
}
|
||||
|
||||
function author_string(ent, template, sep, finalSep){
|
||||
var names = ent.author.split(' and ');
|
||||
let name_strings = names.map(name => {
|
||||
name = name.trim();
|
||||
if (name.indexOf(',') != -1){
|
||||
var last = name.split(',')[0].trim();
|
||||
var firsts = name.split(',')[1];
|
||||
} else {
|
||||
var last = name.split(' ').slice(-1)[0].trim();
|
||||
var firsts = name.split(' ').slice(0,-1).join(' ');
|
||||
}
|
||||
var initials = '';
|
||||
if (firsts != undefined) {
|
||||
initials = firsts.trim().split(' ').map(s => s.trim()[0]);
|
||||
initials = initials.join('.')+'.';
|
||||
}
|
||||
return template.replace('${F}', firsts)
|
||||
.replace('${L}', last)
|
||||
.replace('${I}', initials);
|
||||
});
|
||||
if (names.length > 1) {
|
||||
var str = name_strings.slice(0, names.length-1).join(sep);
|
||||
str += (finalSep || sep) + name_strings[names.length-1];
|
||||
return str;
|
||||
} else {
|
||||
return name_strings[0];
|
||||
}
|
||||
}
|
||||
|
||||
function venue_string(ent) {
|
||||
var cite = (ent.journal || ent.booktitle || '');
|
||||
if ('volume' in ent){
|
||||
var issue = ent.issue || ent.number;
|
||||
issue = (issue != undefined)? '('+issue+')' : '';
|
||||
cite += ', Vol ' + ent.volume + issue;
|
||||
}
|
||||
if ('pages' in ent){
|
||||
cite += ', pp. ' + ent.pages;
|
||||
}
|
||||
if (cite != '') cite += '. ';
|
||||
if ('publisher' in ent){
|
||||
cite += ent.publisher;
|
||||
if (cite[cite.length-1] != '.') cite += '.';
|
||||
}
|
||||
return cite;
|
||||
}
|
||||
|
||||
function link_string(ent){
|
||||
if ('url' in ent){
|
||||
var url = ent.url;
|
||||
var arxiv_match = (/arxiv\.org\/abs\/([0-9\.]*)/).exec(url);
|
||||
if (arxiv_match != null){
|
||||
url = `http://arxiv.org/pdf/${arxiv_match[1]}.pdf`;
|
||||
}
|
||||
|
||||
if (url.slice(-4) == '.pdf'){
|
||||
var label = 'PDF';
|
||||
} else if (url.slice(-5) == '.html') {
|
||||
var label = 'HTML';
|
||||
}
|
||||
return `  <a href="${url}">[${label||'link'}]</a>`;
|
||||
}/* else if ("doi" in ent){
|
||||
return `  <a href="https://doi.org/${ent.doi}" >[DOI]</a>`;
|
||||
}*/ else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
function doi_string(ent, new_line){
|
||||
if ('doi' in ent) {
|
||||
return `${new_line?'<br>':''} <a href="https://doi.org/${ent.doi}" style="text-decoration:inherit;">DOI: ${ent.doi}</a>`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function bibliography_cite(ent, fancy){
|
||||
if (ent){
|
||||
var cite = '<b>' + ent.title + '</b> ';
|
||||
cite += link_string(ent) + '<br>';
|
||||
cite += author_string(ent, '${L}, ${I}', ', ', ' and ');
|
||||
if (ent.year || ent.date){
|
||||
cite += ', ' + (ent.year || ent.date) + '. ';
|
||||
} else {
|
||||
cite += '. ';
|
||||
}
|
||||
cite += venue_string(ent);
|
||||
cite += doi_string(ent);
|
||||
return cite;
|
||||
/*var cite = author_string(ent, "${L}, ${I}", ", ", " and ");
|
||||
if (ent.year || ent.date){
|
||||
cite += ", " + (ent.year || ent.date) + ". "
|
||||
} else {
|
||||
cite += ". "
|
||||
}
|
||||
cite += "<b>" + ent.title + "</b>. ";
|
||||
cite += venue_string(ent);
|
||||
cite += doi_string(ent);
|
||||
cite += link_string(ent);
|
||||
return cite*/
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
function hover_cite(ent){
|
||||
if (ent){
|
||||
var cite = '';
|
||||
cite += '<b>' + ent.title + '</b>';
|
||||
cite += link_string(ent);
|
||||
cite += '<br>';
|
||||
|
||||
var a_str = author_string(ent, '${I} ${L}', ', ') + '.';
|
||||
var v_str = venue_string(ent).trim() + ' ' + ent.year + '. ' + doi_string(ent, true);
|
||||
|
||||
if ((a_str+v_str).length < Math.min(40, ent.title.length)) {
|
||||
cite += a_str + ' ' + v_str;
|
||||
} else {
|
||||
cite += a_str + '<br>' + v_str;
|
||||
}
|
||||
return cite;
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//https://scholar.google.com/scholar?q=allintitle%3ADocument+author%3Aolah
|
||||
function get_GS_URL(ent){
|
||||
if (ent){
|
||||
var names = ent.author.split(' and ');
|
||||
names = names.map(name => name.split(',')[0].trim());
|
||||
var title = ent.title.split(' ');//.replace(/[,:]/, "")
|
||||
var url = 'http://search.labs.crossref.org/dois?';//""https://scholar.google.com/scholar?"
|
||||
url += uris({q: names.join(' ') + ' ' + title.join(' ')});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import Prism from 'prismjs';
|
||||
|
||||
export default function(dom, data) {
|
||||
let codeElements = [].slice.call(dom.querySelectorAll('dt-code'));
|
||||
codeElements.forEach(el => {
|
||||
let content = el.textContent;
|
||||
el.innerHTML = '';
|
||||
let language = el.getAttribute('language');
|
||||
let c = dom.createElement('code');
|
||||
if (el.getAttribute('block') === '') {
|
||||
// Let's normalize the tab indents
|
||||
content = content.replace(/\n/, '');
|
||||
let tabs = content.match(/\s*/);
|
||||
content = content.replace(new RegExp('\n' + tabs, 'g'), '\n');
|
||||
content = content.trim();
|
||||
let p = dom.createElement('pre');
|
||||
p.appendChild(c);
|
||||
el.appendChild(p);
|
||||
} else {
|
||||
el.appendChild(c);
|
||||
}
|
||||
let highlighted = content;
|
||||
if (Prism.languages[language]) {
|
||||
c.setAttribute('class', 'language-' + language);
|
||||
highlighted = Prism.highlight(content, Prism.languages[language]);
|
||||
}
|
||||
c.innerHTML = highlighted;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
export default function(dom, data) {
|
||||
|
||||
var fnTags = [].slice.apply(dom.querySelectorAll('dt-fn'));
|
||||
var fnContent = [];
|
||||
fnTags.forEach((el,n) => {
|
||||
var content = el.innerHTML;
|
||||
fnContent.push(content);
|
||||
n = (n+1)+'';
|
||||
var key = 'fn-'+n;
|
||||
var escaped_content = content.replace(/"/g, ''');
|
||||
el.innerHTML = `<sup><span id="${key}" data-hover="${escaped_content}" style="cursor:pointer">${n}</span></sup>`;
|
||||
});
|
||||
|
||||
let fnList = dom.querySelector('dt-fn-list');
|
||||
if (fnList) {
|
||||
let ol = dom.createElement('ol');
|
||||
fnContent.forEach(content => {
|
||||
let el = dom.createElement('li');
|
||||
el.innerHTML = content;
|
||||
ol.appendChild(el);
|
||||
});
|
||||
fnList.appendChild(ol);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import ymlParse from 'js-yaml';
|
||||
|
||||
export default function(dom, data) {
|
||||
let localData = {};
|
||||
let el = dom.querySelector('script[type="text/front-matter"]');
|
||||
if (el) {
|
||||
let text = el.textContent;
|
||||
localData = ymlParse.safeLoad(text);
|
||||
}
|
||||
|
||||
data.title = localData.title ? localData.title : 'Untitled';
|
||||
data.description = localData.description ? localData.description : 'No description.';
|
||||
|
||||
data.authors = localData.authors ? localData.authors : [];
|
||||
|
||||
data.authors = data.authors.map((author, i) =>{
|
||||
let a = {};
|
||||
let name = Object.keys(author)[0];
|
||||
if ((typeof author) === 'string') {
|
||||
name = author;
|
||||
} else {
|
||||
a.personalURL = author[name];
|
||||
}
|
||||
let names = name.split(' ');
|
||||
a.name = name;
|
||||
a.firstName = names.slice(0, names.length - 1).join(' ');
|
||||
a.lastName = names[names.length -1];
|
||||
if(localData.affiliations[i]) {
|
||||
let affiliation = Object.keys(localData.affiliations[i])[0];
|
||||
if ((typeof localData.affiliations[i]) === 'string') {
|
||||
affiliation = localData.affiliations[i];
|
||||
} else {
|
||||
a.affiliationURL = localData.affiliations[i][affiliation];
|
||||
}
|
||||
a.affiliation = affiliation;
|
||||
}
|
||||
return a;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
@@ -1,17 +1,3 @@
|
||||
// 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 xml from "xml";
|
||||
|
||||
export default function(data) {
|
||||
@@ -20,18 +6,18 @@ export default function(data) {
|
||||
var date = data.publishedDate;
|
||||
|
||||
var batch_timestamp = Math.floor(Date.now() / 1000);
|
||||
var batch_id = data.authors.length ? data.authors[0].lastName.toLowerCase().slice(0,20) : "Anonymous";
|
||||
batch_id += "_" + date.getFullYear();
|
||||
batch_id += "_" + data.title.split(" ")[0].toLowerCase().slice(0,20) + "_" + batch_timestamp;
|
||||
var batch_id = data.authors.length ? data.authors[0].lastName.toLowerCase().slice(0,20) : 'Anonymous';
|
||||
batch_id += '_' + date.getFullYear();
|
||||
batch_id += '_' + data.title.split(' ')[0].toLowerCase().slice(0,20) + '_' + batch_timestamp;
|
||||
// generate XML
|
||||
var crf_data =
|
||||
{doi_batch : [
|
||||
|
||||
{ _attr: {
|
||||
version: "4.3.7",
|
||||
xmlns: "http://www.crossref.org/schema/4.3.7",
|
||||
"xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
|
||||
"xsi:schemaLocation": "http://www.crossref.org/schema/4.3.7 http://www.crossref.org/schemas/crossref4.3.7.xsd",
|
||||
version: '4.3.7',
|
||||
xmlns: 'http://www.crossref.org/schema/4.3.7',
|
||||
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'xsi:schemaLocation': 'http://www.crossref.org/schema/4.3.7 http://www.crossref.org/schemas/crossref4.3.7.xsd',
|
||||
}},
|
||||
|
||||
{ head: [
|
||||
@@ -76,8 +62,8 @@ export default function(data) {
|
||||
data.authors.map((author, ind) => (
|
||||
{person_name: [
|
||||
{ _attr: {
|
||||
contributor_role: "author",
|
||||
sequence: (ind == 0)? "first" : "additional"
|
||||
contributor_role: 'author',
|
||||
sequence: (ind == 0)? 'first' : 'additional'
|
||||
}},
|
||||
{given_name: author.firstName},
|
||||
{surname: author.lastName},
|
||||
@@ -87,9 +73,9 @@ export default function(data) {
|
||||
))
|
||||
},
|
||||
{publication_date: [
|
||||
{month: date.getMonth()+1},
|
||||
{day: date.getDate()},
|
||||
{year: date.getFullYear()}
|
||||
{month: date.getMonth()+1},
|
||||
{day: date.getDate()},
|
||||
{year: date.getFullYear()}
|
||||
]},
|
||||
{ publisher_item: [
|
||||
{item_number: data.doi}
|
||||
@@ -101,7 +87,7 @@ export default function(data) {
|
||||
]},
|
||||
{citation_list:
|
||||
data.citations.map(key =>
|
||||
citation_xml(key, data.bibliography[key]))
|
||||
citation_xml(key, data.bibliography[key]))
|
||||
}
|
||||
|
||||
]},
|
||||
@@ -117,29 +103,29 @@ function citation_xml(key, ent){
|
||||
if (ent == undefined) return {};
|
||||
var info = [];
|
||||
info.push({_attr: {key: key}});
|
||||
if ("title" in ent)
|
||||
if ('title' in ent)
|
||||
info.push({article_title: ent.title});
|
||||
if ("author" in ent)
|
||||
info.push({author: ent.author.split(" and ")[0].split(",")[0].trim()});
|
||||
if ("journal" in ent)
|
||||
if ('author' in ent)
|
||||
info.push({author: ent.author.split(' and ')[0].split(',')[0].trim()});
|
||||
if ('journal' in ent)
|
||||
info.push({journal_title: ent.journal});
|
||||
if ("booktitle" in ent)
|
||||
if ('booktitle' in ent)
|
||||
info.push({volume_title: ent.booktitle});
|
||||
if ("volume" in ent)
|
||||
if ('volume' in ent)
|
||||
info.push({volume: ent.volume});
|
||||
if ("issue" in ent)
|
||||
if ('issue' in ent)
|
||||
info.push({issue: ent.issue});
|
||||
if ("doi" in ent)
|
||||
if ('doi' in ent)
|
||||
info.push({doi: ent.doi});
|
||||
return {citation: info}
|
||||
return {citation: info};
|
||||
}
|
||||
|
||||
function xml(obj) {
|
||||
//console.log(typeof(obj), obj)
|
||||
if (typeof obj === 'string') return obj;
|
||||
if (typeof obj === 'number') return ""+obj;
|
||||
if (typeof obj === 'number') return ''+obj;
|
||||
let keys = Object.keys(obj);
|
||||
if (keys.length != 1) console.error("can't interpret ", obj, "as xml");
|
||||
if (keys.length != 1) console.error('can\'t interpret ', obj, 'as xml');
|
||||
let name = keys[0];
|
||||
var full_content = obj[name];
|
||||
var attr = {};
|
||||
@@ -148,8 +134,8 @@ function xml(obj) {
|
||||
for (var i in full_content) {
|
||||
var obj = full_content[i];
|
||||
var obj_name = Object.keys(obj)[0];
|
||||
if ("_attr" == obj_name) {
|
||||
attr = obj["_attr"];
|
||||
if ('_attr' == obj_name) {
|
||||
attr = obj['_attr'];
|
||||
} else {
|
||||
//console.log(Object.keys(obj)[0])
|
||||
content.push(obj);
|
||||
@@ -159,19 +145,19 @@ function xml(obj) {
|
||||
content = full_content;
|
||||
}
|
||||
if (content == undefined){
|
||||
content = "undefined"
|
||||
content = 'undefined';
|
||||
}
|
||||
|
||||
let attr_string = "";
|
||||
let attr_string = '';
|
||||
for (var k in attr) {
|
||||
attr_string += ` ${k}=\"${attr[k]}\"`
|
||||
attr_string += ` ${k}=\"${attr[k]}\"`;
|
||||
}
|
||||
|
||||
//console.log(typeof content, Array.isArray(content), content instanceof String, content)
|
||||
if (Array.isArray(content)){
|
||||
content = content.map(xml);
|
||||
content = content.join("\n").split("\n");
|
||||
content = content.map(s => " " + s).join("\n")
|
||||
content = content.join('\n').split('\n');
|
||||
content = content.map(s => ' ' + s).join('\n');
|
||||
var result = `<${name}${attr_string}>\n${content}\n</${name}>`;
|
||||
} else {
|
||||
content = xml(content);
|
||||
@@ -0,0 +1,33 @@
|
||||
import bibtexParse from 'bibtex-parse-js';
|
||||
|
||||
function normalizeTag(string) {
|
||||
return string
|
||||
.replace(/[\t\n ]+/g, ' ')
|
||||
.replace(/{\\["^`.'acu~Hvs]( )?([a-zA-Z])}/g, (full, x, char) => char)
|
||||
.replace(/{\\([a-zA-Z])}/g, (full, char) => char);
|
||||
}
|
||||
|
||||
export function parseBibtex(bibtex) {
|
||||
const bibliography = new Map();
|
||||
const parsedEntries = bibtexParse.toJSON(bibtex);
|
||||
for (const entry of parsedEntries) {
|
||||
// normalize tags; note entryTags is an object, not Map
|
||||
for (const [key, value] of Object.entries(entry.entryTags)) {
|
||||
entry.entryTags[key] = normalizeTag(value);
|
||||
}
|
||||
entry.entryTags.type = entry.entryType;
|
||||
// add to bibliography
|
||||
bibliography.set(entry.citationKey, entry.entryTags);
|
||||
}
|
||||
return bibliography;
|
||||
}
|
||||
|
||||
export function serializeFrontmatterToBibtex(frontMatter) {
|
||||
return `@article{${frontMatter.slug},
|
||||
author = {${frontMatter.bibtexAuthors}},
|
||||
title = {${frontMatter.title}},
|
||||
journal = {${frontMatter.journal.title}},
|
||||
year = {${frontMatter.publishedYear}},
|
||||
note = {${frontMatter.url}}
|
||||
}`;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
export function inline_cite_short(keys){
|
||||
function cite_string(key){
|
||||
if (key in data.bibliography){
|
||||
var n = data.citations.indexOf(key)+1;
|
||||
return ''+n;
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
return '['+keys.map(cite_string).join(', ')+']';
|
||||
}
|
||||
|
||||
export function inline_cite_long(keys){
|
||||
function cite_string(key){
|
||||
if (key in data.bibliography){
|
||||
var ent = data.bibliography[key];
|
||||
var names = ent.author.split(' and ');
|
||||
names = names.map(name => name.split(',')[0].trim());
|
||||
var year = ent.year;
|
||||
if (names.length == 1) return names[0] + ', ' + year;
|
||||
if (names.length == 2) return names[0] + ' & ' + names[1] + ', ' + year;
|
||||
if (names.length > 2) return names[0] + ', et al., ' + year;
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
return keys.map(cite_string).join(', ');
|
||||
}
|
||||
|
||||
function author_string(ent, template, sep, finalSep){
|
||||
var names = ent.author.split(' and ');
|
||||
let name_strings = names.map(name => {
|
||||
name = name.trim();
|
||||
if (name.indexOf(',') != -1){
|
||||
var last = name.split(',')[0].trim();
|
||||
var firsts = name.split(',')[1];
|
||||
} else {
|
||||
var last = name.split(' ').slice(-1)[0].trim();
|
||||
var firsts = name.split(' ').slice(0,-1).join(' ');
|
||||
}
|
||||
var initials = '';
|
||||
if (firsts != undefined) {
|
||||
initials = firsts.trim().split(' ').map(s => s.trim()[0]);
|
||||
initials = initials.join('.')+'.';
|
||||
}
|
||||
return template.replace('${F}', firsts)
|
||||
.replace('${L}', last)
|
||||
.replace('${I}', initials);
|
||||
});
|
||||
if (names.length > 1) {
|
||||
var str = name_strings.slice(0, names.length-1).join(sep);
|
||||
str += (finalSep || sep) + name_strings[names.length-1];
|
||||
return str;
|
||||
} else {
|
||||
return name_strings[0];
|
||||
}
|
||||
}
|
||||
|
||||
function venue_string(ent) {
|
||||
var cite = (ent.journal || ent.booktitle || '');
|
||||
if ('volume' in ent){
|
||||
var issue = ent.issue || ent.number;
|
||||
issue = (issue != undefined)? '('+issue+')' : '';
|
||||
cite += ', Vol ' + ent.volume + issue;
|
||||
}
|
||||
if ('pages' in ent){
|
||||
cite += ', pp. ' + ent.pages;
|
||||
}
|
||||
if (cite != '') cite += '. ';
|
||||
if ('publisher' in ent){
|
||||
cite += ent.publisher;
|
||||
if (cite[cite.length-1] != '.') cite += '.';
|
||||
}
|
||||
return cite;
|
||||
}
|
||||
|
||||
function link_string(ent){
|
||||
if ('url' in ent){
|
||||
var url = ent.url;
|
||||
var arxiv_match = (/arxiv\.org\/abs\/([0-9\.]*)/).exec(url);
|
||||
if (arxiv_match != null){
|
||||
url = `http://arxiv.org/pdf/${arxiv_match[1]}.pdf`;
|
||||
}
|
||||
|
||||
if (url.slice(-4) == '.pdf'){
|
||||
var label = 'PDF';
|
||||
} else if (url.slice(-5) == '.html') {
|
||||
var label = 'HTML';
|
||||
}
|
||||
return `  <a href="${url}">[${label||'link'}]</a>`;
|
||||
}/* else if ("doi" in ent){
|
||||
return `  <a href="https://doi.org/${ent.doi}" >[DOI]</a>`;
|
||||
}*/ else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
function doi_string(ent, new_line){
|
||||
if ('doi' in ent) {
|
||||
return `${new_line?'<br>':''} <a href="https://doi.org/${ent.doi}" style="text-decoration:inherit;">DOI: ${ent.doi}</a>`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export function bibliography_cite(ent, fancy){
|
||||
if (ent){
|
||||
var cite = '<b>' + ent.title + '</b> ';
|
||||
cite += link_string(ent) + '<br>';
|
||||
cite += author_string(ent, '${L}, ${I}', ', ', ' and ');
|
||||
if (ent.year || ent.date){
|
||||
cite += ', ' + (ent.year || ent.date) + '. ';
|
||||
} else {
|
||||
cite += '. ';
|
||||
}
|
||||
cite += venue_string(ent);
|
||||
cite += doi_string(ent);
|
||||
return cite;
|
||||
/*var cite = author_string(ent, "${L}, ${I}", ", ", " and ");
|
||||
if (ent.year || ent.date){
|
||||
cite += ", " + (ent.year || ent.date) + ". "
|
||||
} else {
|
||||
cite += ". "
|
||||
}
|
||||
cite += "<b>" + ent.title + "</b>. ";
|
||||
cite += venue_string(ent);
|
||||
cite += doi_string(ent);
|
||||
cite += link_string(ent);
|
||||
return cite*/
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
export function hover_cite(ent){
|
||||
if (ent){
|
||||
var cite = '';
|
||||
cite += '<b>' + ent.title + '</b>';
|
||||
cite += link_string(ent);
|
||||
cite += '<br>';
|
||||
|
||||
var a_str = author_string(ent, '${I} ${L}', ', ') + '.';
|
||||
var v_str = venue_string(ent).trim() + ' ' + ent.year + '. ' + doi_string(ent, true);
|
||||
|
||||
if ((a_str+v_str).length < Math.min(40, ent.title.length)) {
|
||||
cite += a_str + ' ' + v_str;
|
||||
} else {
|
||||
cite += a_str + '<br>' + v_str;
|
||||
}
|
||||
return cite;
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//https://scholar.google.com/scholar?q=allintitle%3ADocument+author%3Aolah
|
||||
function get_GS_URL(ent){
|
||||
if (ent){
|
||||
var names = ent.author.split(' and ');
|
||||
names = names.map(name => name.split(',')[0].trim());
|
||||
var title = ent.title.split(' ');//.replace(/[,:]/, "")
|
||||
var url = 'http://search.labs.crossref.org/dois?';//""https://scholar.google.com/scholar?"
|
||||
url += uris({q: names.join(' ') + ' ' + title.join(' ')});
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user