From ab57a90b291763089693d79b269e3b5d26f48e38 Mon Sep 17 00:00:00 2001 From: Ludwig Schubert Date: Tue, 5 Sep 2017 13:54:35 -0700 Subject: [PATCH] Auto-add optional components, rename grid & disentangle d-bibliography and d-citation-list --- .gitignore | 1 + README.md | 11 ++++ examples/article.html | 59 +++++++++---------- src/components.js | 6 +- src/components/d-appendix.js | 2 +- src/components/d-bibliography.js | 73 +++--------------------- src/components/d-byline.js | 2 +- src/components/d-citation-list.js | 68 ++++++++++++++++++++++ src/components/d-cite.js | 3 +- src/components/d-footnote.js | 18 +++++- src/components/d-math.js | 4 +- src/controller.js | 41 +++++++------ src/distill-components/distill-footer.js | 2 +- src/helpers/layout.js | 4 +- src/styles/d-math.css | 4 +- src/styles/styles-article.css | 4 +- src/styles/styles-layout.css | 31 ++++++---- src/transforms.js | 5 +- src/transforms/bibliography.js | 2 +- src/transforms/byline.js | 2 +- src/transforms/optional-components.js | 60 +++++++++++++++++++ src/transforms/typeset.js | 2 +- 22 files changed, 253 insertions(+), 151 deletions(-) create mode 100644 src/components/d-citation-list.js create mode 100644 src/transforms/optional-components.js diff --git a/.gitignore b/.gitignore index 70a801e..eb30721 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ jspm_packages # Copied fonts examples/fonts dist +article-rendered.html diff --git a/README.md b/README.md index 249982d..50f6c2a 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,14 @@ Run `yarn test`. That's it. /* width: 80px; */ /* font-size: 20px; */ /* font-weight: 200; */ + + +auto-added elements: + title in front, no h1 -> add it + no title in front, h1 -> read and put into frontMatter + footnote -> footnote list + break up bib + if citation, no bib-list -> add citation-list + if authors, no byline -> add byline + no appendix -> add appendix + \ No newline at end of file diff --git a/examples/article.html b/examples/article.html index 7575219..ee328c9 100644 --- a/examples/article.html +++ b/examples/article.html @@ -2,40 +2,37 @@ - - - - - + + + -

Although extremely useful for visualizing high-dimensional data, t-SNE plots can sometimes be mysterious or misleading.

- @@ -121,12 +118,8 @@

Some text with links describing who reviewed the article.

- - - - diff --git a/src/components.js b/src/components.js index fcfdd03..6c1a819 100644 --- a/src/components.js +++ b/src/components.js @@ -9,6 +9,7 @@ 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 { CitationList } from './components/d-citation-list'; import { Code } from './components/d-code'; import { Footnote } from './components/d-footnote'; import { FootnoteList } from './components/d-footnote-list'; @@ -19,9 +20,8 @@ import { TOC } from './components/d-toc'; import { Figure } from './components/d-figure'; const components = [ - Abstract, Appendix, Article, Bibliography, - Byline, Cite, Code, Footnote, FootnoteList, FrontMatter, DMath, - References, TOC, Figure, + Abstract, Appendix, Article, Bibliography, Byline, Cite, CitationList, Code, + Footnote, FootnoteList, FrontMatter, DMath, References, TOC, Figure, ]; /* Distill website specific components */ diff --git a/src/components/d-appendix.js b/src/components/d-appendix.js index b9a45ac..c9a7958 100644 --- a/src/components/d-appendix.js +++ b/src/components/d-appendix.js @@ -30,7 +30,7 @@ d-appendix a { } d-appendix > * { - grid-column: margin-left / body; + grid-column: left / text; } diff --git a/src/components/d-bibliography.js b/src/components/d-bibliography.js index a1fa463..6b6135e 100644 --- a/src/components/d-bibliography.js +++ b/src/components/d-bibliography.js @@ -1,41 +1,4 @@ -import { Template } from '../mixins/template'; import { parseBibtex } from '../helpers/bibtex'; -import { bibliography_cite } from '../helpers/citation'; - -export const templateString = ` - - -

References

-
    -`; export function parseBibliography(element) { if (element.firstElementChild && element.firstElementChild.tagName === 'SCRIPT') { @@ -44,38 +7,22 @@ export function parseBibliography(element) { } } -export function renderBibliography(element, entries) { - if (entries.size) { - element.host.style.display = 'initial'; - let list = element.querySelector('#references-list'); - list.innerHTML = ''; +export class Bibliography extends HTMLElement { - 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'; - } -} - -const T = Template('d-bibliography', templateString); -export class Bibliography extends T(HTMLElement) { + static get is() { return 'd-bibliography'; } 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); + const observer = new MutationObserver( (entries) => { + for (const entry of entries) { + if (entry.target.nodeName === 'SCRIPT' || entry.type === 'characterData') { + this.parseIfPossible(); + } + } }); - this.parseIfPossible(); - // ...and listen for changes observer.observe(this, options); } @@ -103,10 +50,6 @@ export class Bibliography extends T(HTMLElement) { this.dispatchEvent(event); } - set entries(newEntries) { - renderBibliography(this.root, newEntries); - } - /* observe 'src' attribute */ static get observedAttributes() { diff --git a/src/components/d-byline.js b/src/components/d-byline.js index 52a9b8b..8c4f564 100644 --- a/src/components/d-byline.js +++ b/src/components/d-byline.js @@ -4,7 +4,7 @@ d-byline { } d-byline .byline { - grid-column: margin-left / page; + grid-column: left / page; font-size: 13px; line-height: 1.8em; color: rgba(0, 0, 0, 0.6); diff --git a/src/components/d-citation-list.js b/src/components/d-citation-list.js new file mode 100644 index 0000000..385a75f --- /dev/null +++ b/src/components/d-citation-list.js @@ -0,0 +1,68 @@ +import { Template } from '../mixins/template'; +import { bibliography_cite } from '../helpers/citation'; + +const T = Template('d-citation-list', ` + + +

    References

    +
      +`); + +export function renderCitationList(element, entries) { + if (entries.size > 0) { + element.host.style.display = 'initial'; + const 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 CitationList extends T(HTMLElement) { + + connectedCallback() { + this.root.host.style.display = 'none'; + } + + set citations(citations) { + renderCitationList(this.root, citations); + } + +} diff --git a/src/components/d-cite.js b/src/components/d-cite.js index 659a4dc..c3d18da 100644 --- a/src/components/d-cite.js +++ b/src/components/d-cite.js @@ -1,5 +1,5 @@ import { Template } from '../mixins/template'; -import { hover_cite } from '../helpers/citation'; +import { hover_cite, bibliography_cite } from '../helpers/citation'; import { HoverBox } from '../helpers/hover-box'; const T = Template('d-cite', ` @@ -69,7 +69,6 @@ export class Cite extends T(HTMLElement) { // 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() { diff --git a/src/components/d-footnote.js b/src/components/d-footnote.js index 0c7163c..6ea6bda 100644 --- a/src/components/d-footnote.js +++ b/src/components/d-footnote.js @@ -1,6 +1,5 @@ import { Template } from '../mixins/template.js'; import { HoverBox } from '../helpers/hover-box'; -// import { Store } from './store'; const T = Template('d-footnote', `
      - + `); diff --git a/src/components/d-math.js b/src/components/d-math.js index ba10a8b..3b4ad76 100644 --- a/src/components/d-math.js +++ b/src/components/d-math.js @@ -61,6 +61,8 @@ export class DMath extends Mutating(T(HTMLElement)) { } static addKatex() { + // css tag can use this convenience function + document.head.insertAdjacentHTML('beforeend', katexCSSTag); // script tag has to be created to work properly const scriptTag = document.createElement('script'); scriptTag.src = katexJSURL; @@ -68,8 +70,6 @@ export class DMath extends Mutating(T(HTMLElement)) { 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; } diff --git a/src/controller.js b/src/controller.js index 6ef77db..e0a7ea8 100644 --- a/src/controller.js +++ b/src/controller.js @@ -2,6 +2,7 @@ import { FrontMatter } from './front-matter'; import { DMath } from './components/d-math'; import { collectCitations } from './components/d-cite'; import { parseFrontmatter } from './components/d-front-matter'; +import optionalComponents from './transforms/optional-components'; const frontMatter = new FrontMatter(); @@ -48,11 +49,11 @@ export const Controller = { } // update bibliography - const bibliographyTag = document.querySelector('d-bibliography'); + const citationListTag = document.querySelector('d-citation-list'); const bibliographyEntries = new Map(frontMatter.citations.map( citationKey => { return [citationKey, frontMatter.bibliography.get(citationKey)]; })); - bibliographyTag.entries = bibliographyEntries; + citationListTag.citations = bibliographyEntries; const citeTags = document.querySelectorAll('d-cite'); for (const citeTag of citeTags) { @@ -70,7 +71,7 @@ export const Controller = { }, onBibliographyChanged(event) { - const bibliographyTag = event.target; + const citationListTag = document.querySelector('d-citation-list'); const bibliography = event.detail; frontMatter.bibliography = bibliography; @@ -91,7 +92,7 @@ export const Controller = { return [citationKey, frontMatter.bibliography.get(citationKey)]; })); - bibliographyTag.entries = entries; + citationListTag.citations = entries; }, onFootnoteChanged() { @@ -108,23 +109,25 @@ export const Controller = { const data = event.detail; frontMatter.mergeFromYMLFrontmatter(data); - const appendix = document.querySelector('distill-appendix'); - if (appendix && !appendix.getAttribute('prerendered')) { - appendix.frontMatter = frontMatter; + const prerendered = document.body.hasAttribute('distill-prerendered'); + if (!prerendered) { + optionalComponents(document, frontMatter); + + const appendix = document.querySelector('distill-appendix'); + if (appendix) { + appendix.frontMatter = frontMatter; + } + + const byline = document.querySelector('d-byline'); + if (byline) { + byline.frontMatter = frontMatter; + } + + if (data.katex) { + DMath.katexOptions = data.katex; + } } - const byline = document.querySelector('d-byline'); - if (byline && !byline.getAttribute('prerendered')) { - byline.frontMatter = frontMatter; - } - - if (data.katex) { - DMath.katexOptions = data.katex; - } - - if (data.title) { - - } }, DOMContentLoaded() { diff --git a/src/distill-components/distill-footer.js b/src/distill-components/distill-footer.js index 8cb7000..2d1cb40 100644 --- a/src/distill-components/distill-footer.js +++ b/src/distill-components/distill-footer.js @@ -38,7 +38,7 @@ const T = Template('distill-footer', ` } .container { - grid-column: margin-left / body; + grid-column: left / text; } diff --git a/src/helpers/layout.js b/src/helpers/layout.js index f2dc8be..5a1ef3d 100644 --- a/src/helpers/layout.js +++ b/src/helpers/layout.js @@ -13,14 +13,14 @@ export function body(selector) { return `${selector} { - grid-column: margin-left / body; + grid-column: left / text; } `; } export function page(selector) { return `${selector} { - grid-column: margin-left / page; + grid-column: left / page; } `; } diff --git a/src/styles/d-math.css b/src/styles/d-math.css index a51136e..6d58f89 100644 --- a/src/styles/d-math.css +++ b/src/styles/d-math.css @@ -1,10 +1,10 @@ -d-article .katex-display { +span.katex-display { text-align: left; padding: 8px 0 8px 0; margin: 20px 0 20px 24px; } -d-article .katex { +span.katex { -webkit-font-smoothing: antialiased; color: rgba(0, 0, 0, 0.8); font-size: 1.18em; diff --git a/src/styles/styles-article.css b/src/styles/styles-article.css index 3de6e8c..2248999 100644 --- a/src/styles/styles-article.css +++ b/src/styles/styles-article.css @@ -19,7 +19,7 @@ d-article { } d-article h1 { - grid-column: margin-left / page; + grid-column: left / page; padding-top: 16px; padding-bottom: 0; margin-top: 0; @@ -30,7 +30,7 @@ d-article h1 { } d-article h1+h2 { - grid-column: margin-left / page; + grid-column: left / page; border-bottom: none !important; font-size: 26px !important; font-weight: 300 !important; diff --git a/src/styles/styles-layout.css b/src/styles/styles-layout.css index 1215185..a28cb2c 100644 --- a/src/styles/styles-layout.css +++ b/src/styles/styles-layout.css @@ -14,25 +14,25 @@ d-byline, 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]; + grid-template-columns: [start] 8px [left-outset] 8px [left] 1fr [text] 0px [page] 8px [text-outset] 0px [page-outset] 8px [end]; } - +/* @media(min-width: 768px) { d-article, d-appendix, d-byline, 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]; + grid-template-columns: [start] 32px [left-outset] 32px [left] 3fr [text] 32px [text-outset] 1fr [page] 32px [page-outset] 32px [end]; } -} +}*/ -@media(min-width: 1024px) { +@media(min-width: 768px) { d-article, d-appendix, d-byline, 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]; + grid-template-columns: [start] 1fr [left-outset] 32px [left] 672px [text] 32px [text-outset] 224px [page] 32px [page-outset] 1fr [end]; } } @@ -45,20 +45,20 @@ d-article > distill-footer { .l-body, d-article > * { - grid-column: margin-left / body; + grid-column: left / text; } .l-page, d-figure { - grid-column: margin-left / page; + grid-column: left / page; } .l-body-outset { - grid-column: margin-left-outset / body-outset; + grid-column: left-outset / text-outset; } .l-page-outset { - grid-column: margin-left-outset / page-outset; + grid-column: left-outset / page-outset; } .l-screen { @@ -75,17 +75,24 @@ d-figure { /* Aside */ aside { - grid-column: margin-left / body; + grid-column: left / text; } @media(min-width: 768px) { aside { - grid-column: body-outset / page; + grid-column: text-outset / page; font-size: 14px; line-height: 1.3; } + + .side { + margin-left: 24px; + float: right; + width: 50%; + } } + /* Rows and Columns */ .row { diff --git a/src/transforms.js b/src/transforms.js index fcb2f33..92854d3 100644 --- a/src/transforms.js +++ b/src/transforms.js @@ -17,6 +17,7 @@ const extractors = [ import HTML from './transforms/html'; import Byline from './transforms/byline'; import Polyfills from './transforms/polyfills'; +import OptionalComponents from './transforms/optional-components'; import Mathematics from './transforms/mathematics'; import Meta from './transforms/meta'; import { makeStyleTag } from './styles/styles'; @@ -25,7 +26,8 @@ import Typeset from './transforms/typeset'; import Bibliography from './transforms/bibliography'; const transforms = [ - HTML, makeStyleTag, TOC, Byline, Polyfills, Mathematics, Meta, Typeset, Bibliography + HTML, makeStyleTag, Polyfills, OptionalComponents, TOC, Byline, Mathematics, + Meta, Typeset, Bibliography, ]; /* Distill Transforms */ @@ -51,6 +53,7 @@ export function render(dom, data) { // console.warn('Running transform: ', transform); transform(dom, data); } + dom.body.setAttribute('distill-prerendered', ''); // the function calling us can now use the transformed dom and filled data object } diff --git a/src/transforms/bibliography.js b/src/transforms/bibliography.js index 06037e2..a72e48b 100644 --- a/src/transforms/bibliography.js +++ b/src/transforms/bibliography.js @@ -1,4 +1,4 @@ -import { renderBibliography, templateString } from '../components/d-bibliography'; +// import { renderBibliography, templateString } from '../components/d-bibliography'; import { parseBibtex } from '../helpers/bibtex'; import fs from 'fs'; diff --git a/src/transforms/byline.js b/src/transforms/byline.js index 826aabb..ab931cb 100644 --- a/src/transforms/byline.js +++ b/src/transforms/byline.js @@ -4,6 +4,6 @@ export default function(dom, data) { const byline = dom.querySelector('d-byline'); if (byline) { byline.innerHTML = bylineTemplate(data); - byline.setAttribute('prerendered', true); + // byline.setAttribute('distill-prerendered', ''); } } diff --git a/src/transforms/optional-components.js b/src/transforms/optional-components.js new file mode 100644 index 0000000..b532379 --- /dev/null +++ b/src/transforms/optional-components.js @@ -0,0 +1,60 @@ +// no appendix -> add appendix +// title in front, no h1 -> add it +// no title in front, h1 -> read and put into frontMatter +// footnote -> footnote list +// break up bib +// if citation, no bib-list -> add citation-list + +// if authors, no byline -> add byline + +export default function(dom, data) { + const article = dom.querySelector('d-article'); + + let h1 = dom.querySelector('h1'); + if (h1) { + if (!data.title) { + data.title = h1.textContent; + } + } else { + if (data.title) { + h1 = dom.createElement('h1'); + h1.textContent = data.title; + article.insertBefore(h1, article.firstChild); + } + if (data.description) { + const h2 = dom.createElement('h2'); + h2.textContent = data.description; + article.insertBefore(h2, h1.nextSibling); + } + } + + let byline = dom.querySelector('d-byline'); + if (!byline && data.authors) { + byline = dom.createElement('d-byline'); + const skipTags = ['H1', 'H2', 'FIGURE']; + let candidate = h1; + while (skipTags.indexOf(candidate.tagName) !== -1) { + candidate = candidate.nextSibling; + } + article.insertBefore(byline, candidate); + } + + let appendix = dom.querySelector('d-appendix'); + if (!appendix) { + appendix = dom.createElement('d-appendix'); + dom.body.appendChild(appendix); + } + + let footnoteList = dom.querySelector('d-footnote-list'); + if (!footnoteList) { + footnoteList = dom.createElement('d-footnote-list'); + appendix.appendChild(footnoteList); + } + + let citationList = dom.querySelector('d-citation-list'); + if (!citationList) { + citationList = dom.createElement('d-citation-list'); + appendix.appendChild(citationList); + } + +} diff --git a/src/transforms/typeset.js b/src/transforms/typeset.js index bc763da..2f96bef 100644 --- a/src/transforms/typeset.js +++ b/src/transforms/typeset.js @@ -53,7 +53,7 @@ function punctuation(text){ // Dashes text = text.replace(/--/g, '\u2014'); - text = text.replace(/ \u2014 /g,'\u2009\u2014\u2009'); //this has thin spaces + text = text.replace(/\s*\u2014\s*/g,'\u2009\u2014\u2009'); //this has thin spaces // Elipses text = text.replace(/\.\.\./g,'…');