Run Prettier

This commit is contained in:
Frank Li 2017-07-10 16:38:35 -07:00
parent a7b5148e06
commit fbae29b0ff
29 changed files with 1311 additions and 987 deletions

View file

@ -64,17 +64,18 @@ const siteConfig = {
"rgba(46, 133, 85, 0.03)" /* primaryColor in rgba form, with 0.03 alpha */ "rgba(46, 133, 85, 0.03)" /* primaryColor in rgba form, with 0.03 alpha */
}, },
tagline: "My Tagline", tagline: "My Tagline",
recruitingLink: "https://crowdin.com/project/test-site" /* translation site "help translate" link */, recruitingLink:
"https://crowdin.com/project/test-site" /* translation site "help translate" link */,
/* remove this section to disable search bar */ /* remove this section to disable search bar */
algolia: { algolia: {
apiKey: "0f9f28b9ab9efae89810921a351753b5", /* use your search-only api key */ apiKey:
"0f9f28b9ab9efae89810921a351753b5" /* use your search-only api key */,
indexName: "github" indexName: "github"
}, }
/* remove this to disable google analytics tracking */ /* remove this to disable google analytics tracking */
/* gaTrackingId: "" */ /* gaTrackingId: "" */
}; };
/* DO NOT EDIT BELOW THIS LINE */ /* DO NOT EDIT BELOW THIS LINE */
const fs = require("fs"); const fs = require("fs");

View file

@ -10,6 +10,6 @@
*/ */
const CWD = process.cwd(); const CWD = process.cwd();
const fs = require('fs-extra'); const fs = require("fs-extra");
fs.copySync(__dirname + '/../examples/', CWD, {overwrite: false}); fs.copySync(__dirname + "/../examples/", CWD, { overwrite: false });

View file

@ -7,44 +7,53 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const BlogPost = require('./BlogPost.js'); const BlogPost = require("./BlogPost.js");
const BlogSidebar = require('./BlogSidebar.js'); const BlogSidebar = require("./BlogSidebar.js");
const Container = require('./Container.js'); const Container = require("./Container.js");
const MetadataBlog = require('./MetadataBlog.js'); const MetadataBlog = require("./MetadataBlog.js");
const React = require('react'); const React = require("react");
const Site = require('./Site.js'); const Site = require("./Site.js");
const BlogPageLayout = React.createClass({ const BlogPageLayout = React.createClass({
getPageURL(page) { getPageURL(page) {
let url = this.props.config.baseUrl + 'blog/'; let url = this.props.config.baseUrl + "blog/";
if (page > 0) { if (page > 0) {
url += 'page' + (page + 1) + '/'; url += "page" + (page + 1) + "/";
} }
return url + '#content'; return url + "#content";
}, },
render() { render() {
const perPage = this.props.metadata.perPage; const perPage = this.props.metadata.perPage;
const page = this.props.metadata.page; const page = this.props.metadata.page;
return ( return (
<Site section="blog" title="Blog" language="en" config={this.props.config} > <Site
section="blog"
title="Blog"
language="en"
config={this.props.config}
>
<div className="docMainWrapper wrapper"> <div className="docMainWrapper wrapper">
<BlogSidebar language={this.props.language} config={this.props.config} /> <BlogSidebar
language={this.props.language}
config={this.props.config}
/>
<Container className="mainContainer documentContainer postContainer blogContainer"> <Container className="mainContainer documentContainer postContainer blogContainer">
<div className="posts"> <div className="posts">
{MetadataBlog {MetadataBlog.slice(
.slice(page * perPage, (page + 1) * perPage) page * perPage,
.map(post => { (page + 1) * perPage
return ( ).map(post => {
<BlogPost return (
post={post} <BlogPost
content={post.content} post={post}
truncate={true} content={post.content}
key={post.path + post.title} truncate={true}
config={this.props.config} key={post.path + post.title}
/> config={this.props.config}
); />
})} );
})}
<div className="docs-prevnext"> <div className="docs-prevnext">
{page > 0 && {page > 0 &&
<a className="docs-prev" href={this.getPageURL(page - 1)}> <a className="docs-prev" href={this.getPageURL(page - 1)}>
@ -60,7 +69,7 @@ const BlogPageLayout = React.createClass({
</div> </div>
</Site> </Site>
); );
}, }
}); });
module.exports = BlogPageLayout; module.exports = BlogPageLayout;

View file

@ -7,26 +7,35 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const Marked = require('./Marked.js'); const Marked = require("./Marked.js");
const React = require('react'); const React = require("react");
class BlogPost extends React.Component { class BlogPost extends React.Component {
renderContent() { renderContent() {
let content = this.props.content; let content = this.props.content;
if (this.props.truncate) { if (this.props.truncate) {
content = content.split('<!--truncate-->')[0]; content = content.split("<!--truncate-->")[0];
return ( return (
<article className="post-content"> <article className="post-content">
<Marked>{content}</Marked> <Marked>
{content}
</Marked>
<div className="read-more"> <div className="read-more">
<a className="button" href={this.props.config.baseUrl + 'blog/' + this.props.post.path}> <a
className="button"
href={this.props.config.baseUrl + "blog/" + this.props.post.path}
>
Read More Read More
</a> </a>
</div> </div>
</article> </article>
); );
} }
return <Marked>{content}</Marked>; return (
<Marked>
{content}
</Marked>
);
} }
renderAuthorPhoto() { renderAuthorPhoto() {
@ -37,9 +46,9 @@ class BlogPost extends React.Component {
<a href={post.authorURL} target="_blank"> <a href={post.authorURL} target="_blank">
<img <img
src={ src={
'https://graph.facebook.com/' + "https://graph.facebook.com/" +
post.authorFBID + post.authorFBID +
'/picture/?height=200&width=200' "/picture/?height=200&width=200"
} }
/> />
</a> </a>
@ -54,7 +63,9 @@ class BlogPost extends React.Component {
const post = this.props.post; const post = this.props.post;
return ( return (
<h1> <h1>
<a href={this.props.config.baseUrl + 'blog/' + post.path}>{post.title}</a> <a href={this.props.config.baseUrl + "blog/" + post.path}>
{post.title}
</a>
</h1> </h1>
); );
} }
@ -65,18 +76,18 @@ class BlogPost extends React.Component {
// Because JavaScript sucks at date handling :( // Because JavaScript sucks at date handling :(
const year = match[1]; const year = match[1];
const month = [ const month = [
'January', "January",
'February', "February",
'March', "March",
'April', "April",
'May', "May",
'June', "June",
'July', "July",
'August', "August",
'September', "September",
'October', "October",
'November', "November",
'December', "December"
][parseInt(match[2], 10) - 1]; ][parseInt(match[2], 10) - 1];
const day = parseInt(match[3], 10); const day = parseInt(match[3], 10);
@ -84,7 +95,9 @@ class BlogPost extends React.Component {
<header className="postHeader"> <header className="postHeader">
{this.renderAuthorPhoto()} {this.renderAuthorPhoto()}
<p className="post-authorName"> <p className="post-authorName">
<a href={post.authorURL} target="_blank">{post.author}</a> <a href={post.authorURL} target="_blank">
{post.author}
</a>
</p> </p>
{this.renderTitle()} {this.renderTitle()}
<p className="post-meta"> <p className="post-meta">

View file

@ -7,11 +7,11 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const BlogPost = require('./BlogPost.js'); const BlogPost = require("./BlogPost.js");
const BlogSidebar = require('./BlogSidebar.js'); const BlogSidebar = require("./BlogSidebar.js");
const Container = require('./Container.js'); const Container = require("./Container.js");
const Site = require('./Site.js'); const Site = require("./Site.js");
class BlogPostLayout extends React.Component { class BlogPostLayout extends React.Component {
render() { render() {
@ -19,20 +19,24 @@ class BlogPostLayout extends React.Component {
<Site <Site
className="sideNavVisible" className="sideNavVisible"
section="blog" section="blog"
url={'blog/' + this.props.metadata.path} url={"blog/" + this.props.metadata.path}
title={this.props.metadata.title} title={this.props.metadata.title}
language={'en'} language={"en"}
description={this.props.children.trim().split('\n')[0]} description={this.props.children.trim().split("\n")[0]}
config={this.props.config} config={this.props.config}
> >
<div className="docMainWrapper wrapper"> <div className="docMainWrapper wrapper">
<BlogSidebar language={'en'} current={this.props.metadata} config={this.props.config}/> <BlogSidebar
language={"en"}
current={this.props.metadata}
config={this.props.config}
/>
<Container className="mainContainer documentContainer postContainer blogContainer"> <Container className="mainContainer documentContainer postContainer blogContainer">
<div className="lonePost"> <div className="lonePost">
<BlogPost <BlogPost
post={this.props.metadata} post={this.props.metadata}
content={this.props.children} content={this.props.children}
language={'en'} language={"en"}
config={this.props.config} config={this.props.config}
/> />
</div> </div>

View file

@ -7,22 +7,24 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const Container = require('./Container.js'); const Container = require("./Container.js");
const SideNav = require('./nav/SideNav.js'); const SideNav = require("./nav/SideNav.js");
const MetadataBlog = require('./MetadataBlog.js'); const MetadataBlog = require("./MetadataBlog.js");
class BlogSidebar extends React.Component { class BlogSidebar extends React.Component {
render() { render() {
const contents = [{ const contents = [
name: 'Recent Posts', {
links: MetadataBlog, name: "Recent Posts",
}]; links: MetadataBlog
}
];
const title = this.props.current && this.props.current.title; const title = this.props.current && this.props.current.title;
const current = { const current = {
id: title || '', id: title || "",
category: 'Recent Posts', category: "Recent Posts"
}; };
return ( return (
<Container className="docsNavContainer" id="docsNav" wrapper={false}> <Container className="docsNavContainer" id="docsNav" wrapper={false}>

View file

@ -7,12 +7,12 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const Marked = require('./Marked.js'); const Marked = require("./Marked.js");
const Container = require('./Container.js'); const Container = require("./Container.js");
const GridBlock = require('./GridBlock.js'); const GridBlock = require("./GridBlock.js");
module.exports = { module.exports = {
Marked: Marked, Marked: Marked,
Container: Container, Container: Container,
GridBlock: GridBlock GridBlock: GridBlock
} };

View file

@ -7,26 +7,29 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const classNames = require('classnames'); const classNames = require("classnames");
class Container extends React.Component { class Container extends React.Component {
render() { render() {
const containerClasses = classNames('container', this.props.className, { const containerClasses = classNames("container", this.props.className, {
'darkBackground': this.props.background === 'dark', darkBackground: this.props.background === "dark",
'highlightBackground': this.props.background === 'highlight', highlightBackground: this.props.background === "highlight",
'lightBackground': this.props.background === 'light', lightBackground: this.props.background === "light",
'paddingAll': this.props.padding.indexOf('all') >= 0, paddingAll: this.props.padding.indexOf("all") >= 0,
'paddingBottom': this.props.padding.indexOf('bottom') >= 0, paddingBottom: this.props.padding.indexOf("bottom") >= 0,
'paddingLeft': this.props.padding.indexOf('left') >= 0, paddingLeft: this.props.padding.indexOf("left") >= 0,
'paddingRight': this.props.padding.indexOf('right') >= 0, paddingRight: this.props.padding.indexOf("right") >= 0,
'paddingTop': this.props.padding.indexOf('top') >= 0, paddingTop: this.props.padding.indexOf("top") >= 0
}); });
let wrappedChildren; let wrappedChildren;
if (this.props.wrapper) { if (this.props.wrapper) {
wrappedChildren = wrappedChildren = (
<div className="wrapper">{this.props.children}</div>; <div className="wrapper">
{this.props.children}
</div>
);
} else { } else {
wrappedChildren = this.props.children; wrappedChildren = this.props.children;
} }
@ -39,9 +42,9 @@ class Container extends React.Component {
} }
Container.defaultProps = { Container.defaultProps = {
background: 'transparent', background: "transparent",
padding: [], padding: [],
wrapper: true, wrapper: true
}; };
module.exports = Container; module.exports = Container;

View file

@ -7,8 +7,8 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const Marked = require('./Marked.js'); const Marked = require("./Marked.js");
class Doc extends React.Component { class Doc extends React.Component {
render() { render() {
@ -17,9 +17,9 @@ class Doc extends React.Component {
className="edit-page-link button" className="edit-page-link button"
href={ href={
this.props.config.editUrl + this.props.config.editUrl +
this.props.language + this.props.language +
'/' + "/" +
this.props.source this.props.source
} }
target="_blank" target="_blank"
> >
@ -30,10 +30,14 @@ class Doc extends React.Component {
<div className="post"> <div className="post">
<header className="postHeader"> <header className="postHeader">
{editLink} {editLink}
<h1>{this.props.title}</h1> <h1>
{this.props.title}
</h1>
</header> </header>
<article> <article>
<Marked>{this.props.content}</Marked> <Marked>
{this.props.content}
</Marked>
</article> </article>
</div> </div>
); );

View file

@ -7,11 +7,11 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const Container = require('./Container.js'); const Container = require("./Container.js");
const Doc = require('./Doc.js'); const Doc = require("./Doc.js");
const DocsSidebar = require('./DocsSidebar.js'); const DocsSidebar = require("./DocsSidebar.js");
const Site = require('./Site.js'); const Site = require("./Site.js");
class DocsLayout extends React.Component { class DocsLayout extends React.Component {
render() { render() {
@ -24,11 +24,13 @@ class DocsLayout extends React.Component {
className="sideNavVisible" className="sideNavVisible"
section="docs" section="docs"
title={ title={
i18n ? this.props.config[this.props.metadata.language]['localized-strings'][ i18n
this.props.metadata.localized_id ? this.props.config[this.props.metadata.language][
] || this.props.metadata.title : this.props.metadata.title "localized-strings"
][this.props.metadata.localized_id] || this.props.metadata.title
: this.props.metadata.title
} }
description={content.trim().split('\n')[0]} description={content.trim().split("\n")[0]}
language={metadata.language} language={metadata.language}
> >
<div className="docMainWrapper wrapper"> <div className="docMainWrapper wrapper">
@ -39,9 +41,12 @@ class DocsLayout extends React.Component {
config={this.props.config} config={this.props.config}
source={metadata.source} source={metadata.source}
title={ title={
i18n ? this.props.config[this.props.metadata.language]['localized-strings'][ i18n
this.props.metadata.localized_id ? this.props.config[this.props.metadata.language][
] || this.props.metadata.title : this.props.metadata.title "localized-strings"
][this.props.metadata.localized_id] ||
this.props.metadata.title
: this.props.metadata.title
} }
language={metadata.language} language={metadata.language}
/> />
@ -49,27 +54,25 @@ class DocsLayout extends React.Component {
{metadata.previous_id && {metadata.previous_id &&
<a <a
className="docs-prev button" className="docs-prev button"
href={metadata.previous_id + '.html#content'} href={metadata.previous_id + ".html#content"}
> >
{" "}
{' '} {i18n
{ ? this.props.config[this.props.metadata.language][
i18n ? this.props.config[this.props.metadata.language][ "localized-strings"
'localized-strings' ]["previous"] || "Previous"
]['previous'] || 'Previous' : 'Previous' : "Previous"}
}
</a>} </a>}
{metadata.next_id && {metadata.next_id &&
<a <a
className="docs-next button" className="docs-next button"
href={metadata.next_id + '.html#content'} href={metadata.next_id + ".html#content"}
> >
{ {i18n
i18n ? this.props.config[this.props.metadata.language][ ? this.props.config[this.props.metadata.language][
'localized-strings' "localized-strings"
]['next'] || 'Next' : 'Next' ]["next"] || "Next"
} : "Next"}{" "}
{' '}
</a>} </a>}
</div> </div>

View file

@ -7,16 +7,16 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const Metadata = require('./metadata.js'); const Metadata = require("./metadata.js");
const React = require('react'); const React = require("react");
const Container = require('./Container.js'); const Container = require("./Container.js");
const SideNav = require('./nav/SideNav.js'); const SideNav = require("./nav/SideNav.js");
const siteConfig = require(process.cwd() + '/siteConfig.js'); const siteConfig = require(process.cwd() + "/siteConfig.js");
class DocsSidebar extends React.Component { class DocsSidebar extends React.Component {
render() { render() {
let layout = this.props.metadata.layout; let layout = this.props.metadata.layout;
let docsCategories = require('./' + layout + 'Categories.js'); let docsCategories = require("./" + layout + "Categories.js");
return ( return (
<Container className="docsNavContainer" id="docsNav" wrapper={false}> <Container className="docsNavContainer" id="docsNav" wrapper={false}>
<SideNav <SideNav
@ -34,7 +34,7 @@ class DocsSidebar extends React.Component {
DocsSidebar.propTypes = { DocsSidebar.propTypes = {
layout: React.PropTypes.string, layout: React.PropTypes.string,
root: React.PropTypes.string, root: React.PropTypes.string,
title: React.PropTypes.string, title: React.PropTypes.string
}; };
DocsSidebar.defaultProps = siteConfig.docsSidebarDefaults; DocsSidebar.defaultProps = siteConfig.docsSidebarDefaults;

View file

@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const githubButton = ( const githubButton = (
<a <a
@ -17,7 +17,8 @@ const githubButton = (
data-count-href="/deltice/test-site/stargazers" data-count-href="/deltice/test-site/stargazers"
data-count-api="/repos/deltice/test-site#stargazers_count" data-count-api="/repos/deltice/test-site#stargazers_count"
data-count-aria-label="# stargazers on GitHub" data-count-aria-label="# stargazers on GitHub"
aria-label="Star this project on GitHub"> aria-label="Star this project on GitHub"
>
Star Star
</a> </a>
); );
@ -40,21 +41,30 @@ class Footer extends React.Component {
<h5>Docs</h5> <h5>Docs</h5>
<a <a
href={ href={
this.props.config.baseUrl + 'docs/' + this.props.language + '/doc1.html' this.props.config.baseUrl +
"docs/" +
this.props.language +
"/doc1.html"
} }
> >
Getting Started (or other categories) Getting Started (or other categories)
</a> </a>
<a <a
href={ href={
this.props.config.baseUrl + 'docs/' + this.props.language + '/doc2.html' this.props.config.baseUrl +
"docs/" +
this.props.language +
"/doc2.html"
} }
> >
Guides (or other categories) Guides (or other categories)
</a> </a>
<a <a
href={ href={
this.props.config.baseUrl + 'docs/' + this.props.language + '/doc3.html' this.props.config.baseUrl +
"docs/" +
this.props.language +
"/doc3.html"
} }
> >
API Reference (or other categories) API Reference (or other categories)
@ -62,7 +72,11 @@ class Footer extends React.Component {
</div> </div>
<div> <div>
<h5>Community</h5> <h5>Community</h5>
<a href={this.props.config.baseUrl + this.props.language + '/users.html'}> <a
href={
this.props.config.baseUrl + this.props.language + "/users.html"
}
>
User Showcase User Showcase
</a> </a>
<a <a
@ -71,12 +85,10 @@ class Footer extends React.Component {
> >
Stack Overflow Stack Overflow
</a> </a>
<a <a href="https://discordapp.com/">Project Chat</a>
href="https://discordapp.com/" <a href="https://twitter.com/" target="_blank">
> Twitter
Project Chat
</a> </a>
<a href="https://twitter.com/" target="_blank">Twitter</a>
</div> </div>
<div> <div>
<h5>More</h5> <h5>More</h5>
@ -106,6 +118,4 @@ class Footer extends React.Component {
} }
} }
module.exports = Footer; module.exports = Footer;

View file

@ -7,31 +7,32 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const classNames = require('classnames'); const classNames = require("classnames");
const Marked = require('./Marked.js'); const Marked = require("./Marked.js");
class GridBlock extends React.Component { class GridBlock extends React.Component {
renderBlock(block) { renderBlock(block) {
const blockClasses = classNames('blockElement', this.props.className, { const blockClasses = classNames("blockElement", this.props.className, {
'alignCenter': this.props.align === 'center', alignCenter: this.props.align === "center",
'alignRight': this.props.align === 'right', alignRight: this.props.align === "right",
'fourByGridBlock': this.props.layout === 'fourColumn', fourByGridBlock: this.props.layout === "fourColumn",
'imageAlignBottom': (block.image && block.imageAlign === 'bottom'), imageAlignBottom: block.image && block.imageAlign === "bottom",
'imageAlignSide': (block.image && (block.imageAlign === 'left' || imageAlignSide:
block.imageAlign === 'right')), block.image &&
'imageAlignTop': (block.image && block.imageAlign === 'top'), (block.imageAlign === "left" || block.imageAlign === "right"),
'threeByGridBlock': this.props.layout === 'threeColumn', imageAlignTop: block.image && block.imageAlign === "top",
'twoByGridBlock': this.props.layout === 'twoColumn', threeByGridBlock: this.props.layout === "threeColumn",
twoByGridBlock: this.props.layout === "twoColumn"
}); });
const topLeftImage = (block.imageAlign === 'top' || const topLeftImage =
block.imageAlign === 'left') && (block.imageAlign === "top" || block.imageAlign === "left") &&
this.renderBlockImage(block.image); this.renderBlockImage(block.image);
const bottomRightImage = (block.imageAlign === 'bottom' || const bottomRightImage =
block.imageAlign === 'right') && (block.imageAlign === "bottom" || block.imageAlign === "right") &&
this.renderBlockImage(block.image); this.renderBlockImage(block.image);
return ( return (
@ -39,7 +40,9 @@ class GridBlock extends React.Component {
{topLeftImage} {topLeftImage}
<div className="blockContent"> <div className="blockContent">
{this.renderBlockTitle(block.title)} {this.renderBlockTitle(block.title)}
<Marked>{block.content}</Marked> <Marked>
{block.content}
</Marked>
</div> </div>
{bottomRightImage} {bottomRightImage}
</div> </div>
@ -49,7 +52,9 @@ class GridBlock extends React.Component {
renderBlockImage(image) { renderBlockImage(image) {
if (image) { if (image) {
return ( return (
<div className="blockImage"><img src={image} /></div> <div className="blockImage">
<img src={image} />
</div>
); );
} else { } else {
return null; return null;
@ -58,7 +63,11 @@ class GridBlock extends React.Component {
renderBlockTitle(title) { renderBlockTitle(title) {
if (title) { if (title) {
return <h2>{title}</h2>; return (
<h2>
{title}
</h2>
);
} else { } else {
return null; return null;
} }
@ -74,10 +83,10 @@ class GridBlock extends React.Component {
} }
GridBlock.defaultProps = { GridBlock.defaultProps = {
align: 'left', align: "left",
contents: [], contents: [],
imagealign: 'top', imagealign: "top",
layout: 'twoColumn', layout: "twoColumn"
}; };
module.exports = GridBlock; module.exports = GridBlock;

View file

@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
class Head extends React.Component { class Head extends React.Component {
render() { render() {
@ -29,19 +29,29 @@ class Head extends React.Component {
<head> <head>
<meta charSet="utf-8" /> <meta charSet="utf-8" />
<meta httpEquiv="X-UA-Compatible" content="IE=edge, chrome=1" /> <meta httpEquiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<title>{this.props.title}</title> <title>
{this.props.title}
</title>
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<meta property="og:title" content={this.props.title} /> <meta property="og:title" content={this.props.title} />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:url" content={this.props.url} /> <meta property="og:url" content={this.props.url} />
<meta property="og:description" content={this.props.description} /> <meta property="og:description" content={this.props.description} />
<link rel="shortcut icon" href={this.props.config.baseUrl + this.props.config.favicon} /> <link
rel="shortcut icon"
href={this.props.config.baseUrl + this.props.config.favicon}
/>
{this.props.config.algolia && {this.props.config.algolia &&
<link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css" /> <link
} rel="stylesheet"
<link rel="stylesheet" href={this.props.config.baseUrl + "css/main.css"} /> href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"
<script async defer src="https://buttons.github.io/buttons.js"></script> />}
<link
rel="stylesheet"
href={this.props.config.baseUrl + "css/main.css"}
/>
<script async defer src="https://buttons.github.io/buttons.js" />
</head> </head>
); );
} }

View file

@ -7,22 +7,24 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const toSlug = require('./toSlug.js'); const toSlug = require("./toSlug.js");
const Header = React.createClass({ const Header = React.createClass({
render() { render() {
const slug = toSlug(this.props.toSlug || this.props.children); const slug = toSlug(this.props.toSlug || this.props.children);
const Heading = 'h' + this.props.level; const Heading = "h" + this.props.level;
return ( return (
<Heading {...this.props}> <Heading {...this.props}>
<a className="anchor" name={slug}></a> <a className="anchor" name={slug} />
{this.props.children} {this.props.children}{" "}
{' '}<a className="hash-link" href={'#' + slug}>#</a> <a className="hash-link" href={"#" + slug}>
#
</a>
</Heading> </Heading>
); );
}, }
}); });
module.exports = Header; module.exports = Header;

View file

@ -7,9 +7,9 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const Prism = require('./Prism.js'); const Prism = require("./Prism.js");
const Header = require('./Header.js'); const Header = require("./Header.js");
/** /**
* Block-Level Grammar * Block-Level Grammar
@ -29,23 +29,36 @@ const block = {
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
table: noop, table: noop,
paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/, paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
text: /^[^\n]+/, text: /^[^\n]+/
}; };
block.bullet = /(?:[*+-]|\d+\.)/; block.bullet = /(?:[*+-]|\d+\.)/;
block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/; block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
block.item = replace(block.item, 'gm')(/bull/g, block.bullet)(); block.item = replace(block.item, "gm")(/bull/g, block.bullet)();
block.list = replace(block.list)(/bull/g, block.bullet)('hr', /\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)(); block.list = replace(block.list)(/bull/g, block.bullet)(
"hr",
/\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/
)();
block._tag = '(?!(?:' block._tag =
+ 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' "(?!(?:" +
+ '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' "a|em|strong|small|s|cite|q|dfn|abbr|data|time|code" +
+ '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b'; "|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo" +
"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b";
block.html = replace(block.html)('comment', /<!--[\s\S]*?-->/)('closed', /<(tag)[\s\S]+?<\/\1>/)('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g, block._tag)(); block.html = replace(block.html)("comment", /<!--[\s\S]*?-->/)(
"closed",
/<(tag)[\s\S]+?<\/\1>/
)("closing", /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g, block._tag)();
block.paragraph = replace(block.paragraph)('hr', block.hr)('heading', block.heading)('lheading', block.lheading)('blockquote', block.blockquote)('tag', '<' + block._tag)('def', block.def)(); block.paragraph = replace(block.paragraph)("hr", block.hr)(
"heading",
block.heading
)("lheading", block.lheading)("blockquote", block.blockquote)(
"tag",
"<" + block._tag
)("def", block.def)();
/** /**
* Normal Block Grammar * Normal Block Grammar
@ -59,10 +72,13 @@ block.normal = merge({}, block);
block.gfm = merge({}, block.normal, { block.gfm = merge({}, block.normal, {
fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/, fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
paragraph: /^/, paragraph: /^/
}); });
block.gfm.paragraph = replace(block.paragraph)('(?!', '(?!' + block.gfm.fences.source.replace('\\1', '\\2') + '|')(); block.gfm.paragraph = replace(block.paragraph)(
"(?!",
"(?!" + block.gfm.fences.source.replace("\\1", "\\2") + "|"
)();
/** /**
* GFM + Tables Block Grammar * GFM + Tables Block Grammar
@ -70,7 +86,7 @@ block.gfm.paragraph = replace(block.paragraph)('(?!', '(?!' + block.gfm.fences.s
block.tables = merge({}, block.gfm, { block.tables = merge({}, block.gfm, {
nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/, nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/, table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
}); });
/** /**
@ -113,10 +129,10 @@ Lexer.lex = function(src, options) {
Lexer.prototype.lex = function(src) { Lexer.prototype.lex = function(src) {
src = src src = src
.replace(/\r\n|\r/g, '\n') .replace(/\r\n|\r/g, "\n")
.replace(/\t/g, ' ') .replace(/\t/g, " ")
.replace(/\u00a0/g, ' ') .replace(/\u00a0/g, " ")
.replace(/\u2424/g, '\n'); .replace(/\u2424/g, "\n");
return this.token(src, true); return this.token(src, true);
}; };
@ -126,7 +142,7 @@ Lexer.prototype.lex = function(src) {
*/ */
Lexer.prototype.token = function(_src, top) { Lexer.prototype.token = function(_src, top) {
let src = _src.replace(/^ +$/gm, ''); let src = _src.replace(/^ +$/gm, "");
let next; let next;
let loose; let loose;
let cap; let cap;
@ -139,46 +155,44 @@ Lexer.prototype.token = function(_src, top) {
while (src) { while (src) {
// newline // newline
if (cap = this.rules.newline.exec(src)) { if ((cap = this.rules.newline.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
if (cap[0].length > 1) { if (cap[0].length > 1) {
this.tokens.push({ this.tokens.push({
type: 'space', type: "space"
}); });
} }
} }
// code // code
if (cap = this.rules.code.exec(src)) { if ((cap = this.rules.code.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
cap = cap[0].replace(/^ {4}/gm, ''); cap = cap[0].replace(/^ {4}/gm, "");
this.tokens.push({ this.tokens.push({
type: 'code', type: "code",
text: !this.options.pedantic text: !this.options.pedantic ? cap.replace(/\n+$/, "") : cap
? cap.replace(/\n+$/, '')
: cap,
}); });
continue; continue;
} }
// fences (gfm) // fences (gfm)
if (cap = this.rules.fences.exec(src)) { if ((cap = this.rules.fences.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'code', type: "code",
lang: cap[2], lang: cap[2],
text: cap[3], text: cap[3]
}); });
continue; continue;
} }
// heading // heading
if (cap = this.rules.heading.exec(src)) { if ((cap = this.rules.heading.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'heading', type: "heading",
depth: cap[1].length, depth: cap[1].length,
text: cap[2], text: cap[2]
}); });
continue; continue;
} }
@ -188,19 +202,19 @@ Lexer.prototype.token = function(_src, top) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
item = { item = {
type: 'table', type: "table",
header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), header: cap[1].replace(/^ *| *\| *$/g, "").split(/ *\| */),
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */),
cells: cap[3].replace(/\n$/, '').split('\n'), cells: cap[3].replace(/\n$/, "").split("\n")
}; };
for (i = 0; i < item.align.length; i++) { for (i = 0; i < item.align.length; i++) {
if (/^ *-+: *$/.test(item.align[i])) { if (/^ *-+: *$/.test(item.align[i])) {
item.align[i] = 'right'; item.align[i] = "right";
} else if (/^ *:-+: *$/.test(item.align[i])) { } else if (/^ *:-+: *$/.test(item.align[i])) {
item.align[i] = 'center'; item.align[i] = "center";
} else if (/^ *:-+ *$/.test(item.align[i])) { } else if (/^ *:-+ *$/.test(item.align[i])) {
item.align[i] = 'left'; item.align[i] = "left";
} else { } else {
item.align[i] = null; item.align[i] = null;
} }
@ -216,34 +230,34 @@ Lexer.prototype.token = function(_src, top) {
} }
// lheading // lheading
if (cap = this.rules.lheading.exec(src)) { if ((cap = this.rules.lheading.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'heading', type: "heading",
depth: cap[2] === '=' ? 1 : 2, depth: cap[2] === "=" ? 1 : 2,
text: cap[1], text: cap[1]
}); });
continue; continue;
} }
// hr // hr
if (cap = this.rules.hr.exec(src)) { if ((cap = this.rules.hr.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'hr', type: "hr"
}); });
continue; continue;
} }
// blockquote // blockquote
if (cap = this.rules.blockquote.exec(src)) { if ((cap = this.rules.blockquote.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'blockquote_start', type: "blockquote_start"
}); });
cap = cap[0].replace(/^ *> ?/gm, ''); cap = cap[0].replace(/^ *> ?/gm, "");
// Pass `top` to keep the current // Pass `top` to keep the current
// "toplevel" state. This is exactly // "toplevel" state. This is exactly
@ -251,20 +265,20 @@ Lexer.prototype.token = function(_src, top) {
this.token(cap, top); this.token(cap, top);
this.tokens.push({ this.tokens.push({
type: 'blockquote_end', type: "blockquote_end"
}); });
continue; continue;
} }
// list // list
if (cap = this.rules.list.exec(src)) { if ((cap = this.rules.list.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
bull = cap[2]; bull = cap[2];
this.tokens.push({ this.tokens.push({
type: 'list_start', type: "list_start",
ordered: bull.length > 1, ordered: bull.length > 1
}); });
// Get each top-level item. // Get each top-level item.
@ -280,15 +294,16 @@ Lexer.prototype.token = function(_src, top) {
// Remove the list item's bullet // Remove the list item's bullet
// so it is seen as the next token. // so it is seen as the next token.
space = item.length; space = item.length;
item = item.replace(/^ *([*+-]|\d+\.) +/, ''); item = item.replace(/^ *([*+-]|\d+\.) +/, "");
// Outdent whatever the // Outdent whatever the
// list item contains. Hacky. // list item contains. Hacky.
if (~item.indexOf('\n ')) { // eslint-disable-line if (~item.indexOf("\n ")) {
// eslint-disable-line
space -= item.length; space -= item.length;
item = !this.options.pedantic item = !this.options.pedantic
? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') ? item.replace(new RegExp("^ {1," + space + "}", "gm"), "")
: item.replace(/^ {1,4}/gm, ''); : item.replace(/^ {1,4}/gm, "");
} }
// Determine whether the next list item belongs here. // Determine whether the next list item belongs here.
@ -296,7 +311,7 @@ Lexer.prototype.token = function(_src, top) {
if (this.options.smartLists && i !== l - 1) { if (this.options.smartLists && i !== l - 1) {
b = block.bullet.exec(cap[i + 1])[0]; b = block.bullet.exec(cap[i + 1])[0];
if (bull !== b && !(bull.length > 1 && b.length > 1)) { if (bull !== b && !(bull.length > 1 && b.length > 1)) {
src = cap.slice(i + 1).join('\n') + src; src = cap.slice(i + 1).join("\n") + src;
i = l - 1; i = l - 1;
} }
} }
@ -306,40 +321,38 @@ Lexer.prototype.token = function(_src, top) {
// for discount behavior. // for discount behavior.
loose = next || /\n\n(?!\s*$)/.test(item); loose = next || /\n\n(?!\s*$)/.test(item);
if (i !== l - 1) { if (i !== l - 1) {
next = item[item.length - 1] === '\n'; next = item[item.length - 1] === "\n";
if (!loose) {loose = next;} if (!loose) {
loose = next;
}
} }
this.tokens.push({ this.tokens.push({
type: loose type: loose ? "loose_item_start" : "list_item_start"
? 'loose_item_start'
: 'list_item_start',
}); });
// Recurse. // Recurse.
this.token(item, false); this.token(item, false);
this.tokens.push({ this.tokens.push({
type: 'list_item_end', type: "list_item_end"
}); });
} }
this.tokens.push({ this.tokens.push({
type: 'list_end', type: "list_end"
}); });
continue; continue;
} }
// html // html
if (cap = this.rules.html.exec(src)) { if ((cap = this.rules.html.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: this.options.sanitize type: this.options.sanitize ? "paragraph" : "html",
? 'paragraph' pre: cap[1] === "pre" || cap[1] === "script",
: 'html', text: cap[0]
pre: cap[1] === 'pre' || cap[1] === 'script',
text: cap[0],
}); });
continue; continue;
} }
@ -349,7 +362,7 @@ Lexer.prototype.token = function(_src, top) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.links[cap[1].toLowerCase()] = { this.tokens.links[cap[1].toLowerCase()] = {
href: cap[2], href: cap[2],
title: cap[3], title: cap[3]
}; };
continue; continue;
} }
@ -359,19 +372,19 @@ Lexer.prototype.token = function(_src, top) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
item = { item = {
type: 'table', type: "table",
header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), header: cap[1].replace(/^ *| *\| *$/g, "").split(/ *\| */),
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */),
cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n'), cells: cap[3].replace(/(?: *\| *)?\n$/, "").split("\n")
}; };
for (i = 0; i < item.align.length; i++) { for (i = 0; i < item.align.length; i++) {
if (/^ *-+: *$/.test(item.align[i])) { if (/^ *-+: *$/.test(item.align[i])) {
item.align[i] = 'right'; item.align[i] = "right";
} else if (/^ *:-+: *$/.test(item.align[i])) { } else if (/^ *:-+: *$/.test(item.align[i])) {
item.align[i] = 'center'; item.align[i] = "center";
} else if (/^ *:-+ *$/.test(item.align[i])) { } else if (/^ *:-+ *$/.test(item.align[i])) {
item.align[i] = 'left'; item.align[i] = "left";
} else { } else {
item.align[i] = null; item.align[i] = null;
} }
@ -379,7 +392,7 @@ Lexer.prototype.token = function(_src, top) {
for (i = 0; i < item.cells.length; i++) { for (i = 0; i < item.cells.length; i++) {
item.cells[i] = item.cells[i] item.cells[i] = item.cells[i]
.replace(/^ *\| *| *\| *$/g, '') .replace(/^ *\| *| *\| *$/g, "")
.split(/ *\| */); .split(/ *\| */);
} }
@ -392,28 +405,25 @@ Lexer.prototype.token = function(_src, top) {
if (top && (cap = this.rules.paragraph.exec(src))) { if (top && (cap = this.rules.paragraph.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'paragraph', type: "paragraph",
text: cap[1][cap[1].length - 1] === '\n' text: cap[1][cap[1].length - 1] === "\n" ? cap[1].slice(0, -1) : cap[1]
? cap[1].slice(0, -1)
: cap[1],
}); });
continue; continue;
} }
// text // text
if (cap = this.rules.text.exec(src)) { if ((cap = this.rules.text.exec(src))) {
// Top-level should never reach here. // Top-level should never reach here.
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
this.tokens.push({ this.tokens.push({
type: 'text', type: "text",
text: cap[0], text: cap[0]
}); });
continue; continue;
} }
if (src) { if (src) {
throw new throw new Error("Infinite loop on byte: " + src.charCodeAt(0));
Error('Infinite loop on byte: ' + src.charCodeAt(0));
} }
} }
@ -437,15 +447,18 @@ const inline = {
code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/, code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
br: /^ {2,}\n(?!\s*$)/, br: /^ {2,}\n(?!\s*$)/,
del: noop, del: noop,
text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/, text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
}; };
inline._inside = /(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/; inline._inside = /(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/;
inline._href = /\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/; inline._href = /\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
inline.link = replace(inline.link)('inside', inline._inside)('href', inline._href)(); inline.link = replace(inline.link)("inside", inline._inside)(
"href",
inline._href
)();
inline.reflink = replace(inline.reflink)('inside', inline._inside)(); inline.reflink = replace(inline.reflink)("inside", inline._inside)();
/** /**
* Normal Inline Grammar * Normal Inline Grammar
@ -459,7 +472,7 @@ inline.normal = merge({}, inline);
inline.pedantic = merge({}, inline.normal, { inline.pedantic = merge({}, inline.normal, {
strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/, em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
}); });
/** /**
@ -467,10 +480,10 @@ inline.pedantic = merge({}, inline.normal, {
*/ */
inline.gfm = merge({}, inline.normal, { inline.gfm = merge({}, inline.normal, {
escape: replace(inline.escape)('])', '~|])')(), escape: replace(inline.escape)("])", "~|])")(),
url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
del: /^~~(?=\S)([\s\S]*?\S)~~/, del: /^~~(?=\S)([\s\S]*?\S)~~/,
text: replace(inline.text)(']|', '~]|')('|', '|https?://|')(), text: replace(inline.text)("]|", "~]|")("|", "|https?://|")()
}); });
/** /**
@ -478,8 +491,8 @@ inline.gfm = merge({}, inline.normal, {
*/ */
inline.breaks = merge({}, inline.gfm, { inline.breaks = merge({}, inline.gfm, {
br: replace(inline.br)('{2,}', '*')(), br: replace(inline.br)("{2,}", "*")(),
text: replace(inline.gfm.text)('{2,}', '*')(), text: replace(inline.gfm.text)("{2,}", "*")()
}); });
/** /**
@ -492,8 +505,7 @@ function InlineLexer(links, options) {
this.rules = inline.normal; this.rules = inline.normal;
if (!this.links) { if (!this.links) {
throw new throw new Error("Tokens array requires a `links` property.");
Error('Tokens array requires a `links` property.');
} }
if (this.options.gfm) { if (this.options.gfm) {
@ -535,39 +547,37 @@ InlineLexer.prototype.output = function(src) {
while (src) { while (src) {
// escape // escape
if (cap = this.rules.escape.exec(src)) { if ((cap = this.rules.escape.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(cap[1]); out.push(cap[1]);
continue; continue;
} }
// autolink // autolink
if (cap = this.rules.autolink.exec(src)) { if ((cap = this.rules.autolink.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
if (cap[2] === '@') { if (cap[2] === "@") {
text = cap[1][6] === ':' text = cap[1][6] === ":" ? cap[1].substring(7) : cap[1];
? cap[1].substring(7) href = "mailto:" + text;
: cap[1];
href = 'mailto:' + text;
} else { } else {
text = cap[1]; text = cap[1];
href = text; href = text;
} }
out.push(React.DOM.a({href: this.sanitizeUrl(href)}, text)); out.push(React.DOM.a({ href: this.sanitizeUrl(href) }, text));
continue; continue;
} }
// url (gfm) // url (gfm)
if (cap = this.rules.url.exec(src)) { if ((cap = this.rules.url.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
text = cap[1]; text = cap[1];
href = text; href = text;
out.push(React.DOM.a({href: this.sanitizeUrl(href)}, text)); out.push(React.DOM.a({ href: this.sanitizeUrl(href) }, text));
continue; continue;
} }
// tag // tag
if (cap = this.rules.tag.exec(src)) { if ((cap = this.rules.tag.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
// TODO(alpert): Don't escape if sanitize is false // TODO(alpert): Don't escape if sanitize is false
out.push(cap[0]); out.push(cap[0]);
@ -575,20 +585,24 @@ InlineLexer.prototype.output = function(src) {
} }
// link // link
if (cap = this.rules.link.exec(src)) { if ((cap = this.rules.link.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(this.outputLink(cap, { out.push(
href: cap[2], this.outputLink(cap, {
title: cap[3], href: cap[2],
})); title: cap[3]
})
);
continue; continue;
} }
// reflink, nolink // reflink, nolink
if ((cap = this.rules.reflink.exec(src)) if (
|| (cap = this.rules.nolink.exec(src))) { (cap = this.rules.reflink.exec(src)) ||
(cap = this.rules.nolink.exec(src))
) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
link = (cap[2] || cap[1]).replace(/\s+/g, ' '); link = (cap[2] || cap[1]).replace(/\s+/g, " ");
link = this.links[link.toLowerCase()]; link = this.links[link.toLowerCase()];
if (!link || !link.href) { if (!link || !link.href) {
out.push.apply(out, this.output(cap[0][0])); out.push.apply(out, this.output(cap[0][0]));
@ -600,50 +614,49 @@ InlineLexer.prototype.output = function(src) {
} }
// strong // strong
if (cap = this.rules.strong.exec(src)) { if ((cap = this.rules.strong.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(React.DOM.strong(null, this.output(cap[2] || cap[1]))); out.push(React.DOM.strong(null, this.output(cap[2] || cap[1])));
continue; continue;
} }
// em // em
if (cap = this.rules.em.exec(src)) { if ((cap = this.rules.em.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(React.DOM.em(null, this.output(cap[2] || cap[1]))); out.push(React.DOM.em(null, this.output(cap[2] || cap[1])));
continue; continue;
} }
// code // code
if (cap = this.rules.code.exec(src)) { if ((cap = this.rules.code.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(React.DOM.code(null, cap[2])); out.push(React.DOM.code(null, cap[2]));
continue; continue;
} }
// br // br
if (cap = this.rules.br.exec(src)) { if ((cap = this.rules.br.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(React.DOM.br(null, null)); out.push(React.DOM.br(null, null));
continue; continue;
} }
// del (gfm) // del (gfm)
if (cap = this.rules.del.exec(src)) { if ((cap = this.rules.del.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(React.DOM.del(null, this.output(cap[1]))); out.push(React.DOM.del(null, this.output(cap[1])));
continue; continue;
} }
// text // text
if (cap = this.rules.text.exec(src)) { if ((cap = this.rules.text.exec(src))) {
src = src.substring(cap[0].length); src = src.substring(cap[0].length);
out.push(this.smartypants(cap[0])); out.push(this.smartypants(cap[0]));
continue; continue;
} }
if (src) { if (src) {
throw new throw new Error("Infinite loop on byte: " + src.charCodeAt(0));
Error('Infinite loop on byte: ' + src.charCodeAt(0));
} }
} }
@ -658,13 +671,14 @@ InlineLexer.prototype.sanitizeUrl = function(url) {
if (this.options.sanitize) { if (this.options.sanitize) {
try { try {
const prot = decodeURIComponent(url) const prot = decodeURIComponent(url)
.replace(/[^A-Za-z0-9:]/g, '') .replace(/[^A-Za-z0-9:]/g, "")
.toLowerCase(); .toLowerCase();
if (prot.indexOf('javascript:') === 0) { // eslint-disable-line if (prot.indexOf("javascript:") === 0) {
return '#'; // eslint-disable-line
return "#";
} }
} catch (e) { } catch (e) {
return '#'; return "#";
} }
} }
return url; return url;
@ -675,22 +689,27 @@ InlineLexer.prototype.sanitizeUrl = function(url) {
*/ */
InlineLexer.prototype.outputLink = function(cap, link) { InlineLexer.prototype.outputLink = function(cap, link) {
if (cap[0][0] !== '!') { if (cap[0][0] !== "!") {
const shouldOpenInNewWindow = const shouldOpenInNewWindow =
link.href.charAt(0) !== '/' link.href.charAt(0) !== "/" && link.href.charAt(0) !== "#";
&& link.href.charAt(0) !== '#';
return React.DOM.a({ return React.DOM.a(
href: this.sanitizeUrl(link.href), {
title: link.title, href: this.sanitizeUrl(link.href),
target: shouldOpenInNewWindow ? '_blank' : '', title: link.title,
}, this.output(cap[1])); target: shouldOpenInNewWindow ? "_blank" : ""
},
this.output(cap[1])
);
} else { } else {
return React.DOM.img({ return React.DOM.img(
src: this.sanitizeUrl(link.href), {
alt: cap[1], src: this.sanitizeUrl(link.href),
title: link.title, alt: cap[1],
}, null); title: link.title
},
null
);
} }
}; };
@ -699,12 +718,14 @@ InlineLexer.prototype.outputLink = function(cap, link) {
*/ */
InlineLexer.prototype.smartypants = function(text) { InlineLexer.prototype.smartypants = function(text) {
if (!this.options.smartypants) {return text;} if (!this.options.smartypants) {
return text;
}
return text return text
.replace(/--/g, '\u2014') .replace(/--/g, "\u2014")
.replace(/'([^']*)'/g, '\u2018$1\u2019') .replace(/'([^']*)'/g, "\u2018$1\u2019")
.replace(/"([^"]*)"/g, '\u201C$1\u201D') .replace(/"([^"]*)"/g, "\u201C$1\u201D")
.replace(/\.{3}/g, '\u2026'); .replace(/\.{3}/g, "\u2026");
}; };
/** /**
@ -747,7 +768,7 @@ Parser.prototype.parse = function(src) {
*/ */
Parser.prototype.next = function() { Parser.prototype.next = function() {
return this.token = this.tokens.pop(); return (this.token = this.tokens.pop());
}; };
/** /**
@ -765,8 +786,8 @@ Parser.prototype.peek = function() {
Parser.prototype.parseText = function() { Parser.prototype.parseText = function() {
let body = this.token.text; let body = this.token.text;
while (this.peek().type === 'text') { while (this.peek().type === "text") {
body += '\n' + this.next().text; body += "\n" + this.next().text;
} }
return this.inline.output(body); return this.inline.output(body);
@ -776,25 +797,30 @@ Parser.prototype.parseText = function() {
* Parse Current Token * Parse Current Token
*/ */
Parser.prototype.tok = function() { // eslint-disable-line Parser.prototype.tok = function() {
// eslint-disable-line
switch (this.token.type) { switch (this.token.type) {
case 'space': { case "space": {
return []; return [];
} }
case 'hr': { case "hr": {
return React.DOM.hr(null, null); return React.DOM.hr(null, null);
} }
case 'heading': { case "heading": {
return ( return (
<Header level={this.token.depth} toSlug={this.token.text}> <Header level={this.token.depth} toSlug={this.token.text}>
{this.inline.output(this.token.text)} {this.inline.output(this.token.text)}
</Header> </Header>
); );
} }
case 'code': { case "code": {
return <Prism>{this.token.text}</Prism>; return (
<Prism>
{this.token.text}
</Prism>
);
} }
case 'table': { case "table": {
const table = []; const table = [];
const body = []; const body = [];
let row = []; let row = [];
@ -806,12 +832,14 @@ Parser.prototype.tok = function() { // eslint-disable-line
// header // header
for (i = 0; i < this.token.header.length; i++) { for (i = 0; i < this.token.header.length; i++) {
heading = this.inline.output(this.token.header[i]); heading = this.inline.output(this.token.header[i]);
row.push(React.DOM.th( row.push(
this.token.align[i] React.DOM.th(
? {style: {textAlign: this.token.align[i]}} this.token.align[i]
: null, ? { style: { textAlign: this.token.align[i] } }
heading : null,
)); heading
)
);
} }
table.push(React.DOM.thead(null, React.DOM.tr(null, row))); table.push(React.DOM.thead(null, React.DOM.tr(null, row)));
@ -820,12 +848,14 @@ Parser.prototype.tok = function() { // eslint-disable-line
row = []; row = [];
cells = this.token.cells[i]; cells = this.token.cells[i];
for (j = 0; j < cells.length; j++) { for (j = 0; j < cells.length; j++) {
row.push(React.DOM.td( row.push(
this.token.align[j] React.DOM.td(
? {style: {textAlign: this.token.align[j]}} this.token.align[j]
: null, ? { style: { textAlign: this.token.align[j] } }
this.inline.output(cells[j]) : null,
)); this.inline.output(cells[j])
)
);
} }
body.push(React.DOM.tr(null, row)); body.push(React.DOM.tr(null, row));
} }
@ -833,58 +863,59 @@ Parser.prototype.tok = function() { // eslint-disable-line
return React.DOM.table(null, table); return React.DOM.table(null, table);
} }
case 'blockquote_start': { case "blockquote_start": {
const body = []; const body = [];
while (this.next().type !== 'blockquote_end') { while (this.next().type !== "blockquote_end") {
body.push(this.tok()); body.push(this.tok());
} }
return React.DOM.blockquote(null, body); return React.DOM.blockquote(null, body);
} }
case 'list_start': { case "list_start": {
const type = this.token.ordered ? 'ol' : 'ul'; const type = this.token.ordered ? "ol" : "ul";
const body = []; const body = [];
while (this.next().type !== 'list_end') { while (this.next().type !== "list_end") {
body.push(this.tok()); body.push(this.tok());
} }
return React.DOM[type](null, body); return React.DOM[type](null, body);
} }
case 'list_item_start': { case "list_item_start": {
const body = []; const body = [];
while (this.next().type !== 'list_item_end') { while (this.next().type !== "list_item_end") {
body.push(this.token.type === 'text' body.push(this.token.type === "text" ? this.parseText() : this.tok());
? this.parseText()
: this.tok());
} }
return React.DOM.li(null, body); return React.DOM.li(null, body);
} }
case 'loose_item_start': { case "loose_item_start": {
const body = []; const body = [];
while (this.next().type !== 'list_item_end') { while (this.next().type !== "list_item_end") {
body.push(this.tok()); body.push(this.tok());
} }
return React.DOM.li(null, body); return React.DOM.li(null, body);
} }
case 'html': { case "html": {
return React.DOM.div({ return React.DOM.div({
dangerouslySetInnerHTML: { dangerouslySetInnerHTML: {
__html: this.token.text, __html: this.token.text
}, }
}); });
} }
case 'paragraph': { case "paragraph": {
return this.options.paragraphFn return this.options.paragraphFn
? this.options.paragraphFn.call(null, this.inline.output(this.token.text)) ? this.options.paragraphFn.call(
null,
this.inline.output(this.token.text)
)
: React.DOM.p(null, this.inline.output(this.token.text)); : React.DOM.p(null, this.inline.output(this.token.text));
} }
case 'text': { case "text": {
return this.options.paragraphFn return this.options.paragraphFn
? this.options.paragraphFn.call(null, this.parseText()) ? this.options.paragraphFn.call(null, this.parseText())
: React.DOM.p(null, this.parseText()); : React.DOM.p(null, this.parseText());
@ -898,11 +929,13 @@ Parser.prototype.tok = function() { // eslint-disable-line
function replace(regex, opt) { function replace(regex, opt) {
regex = regex.source; regex = regex.source;
opt = opt || ''; opt = opt || "";
return function self(name, val) { return function self(name, val) {
if (!name) {return new RegExp(regex, opt);} if (!name) {
return new RegExp(regex, opt);
}
val = val.source || val; val = val.source || val;
val = val.replace(/(^|[^\[])\^/g, '$1'); val = val.replace(/(^|[^\[])\^/g, "$1");
regex = regex.replace(name, val); regex = regex.replace(name, val);
return self; return self;
}; };
@ -933,13 +966,15 @@ function merge(obj) {
*/ */
function marked(src, opt, callback) { function marked(src, opt, callback) {
if (callback || typeof opt === 'function') { if (callback || typeof opt === "function") {
if (!callback) { if (!callback) {
callback = opt; callback = opt;
opt = null; opt = null;
} }
if (opt) {opt = merge({}, marked.defaults, opt);} if (opt) {
opt = merge({}, marked.defaults, opt);
}
const highlight = opt.highlight; const highlight = opt.highlight;
let tokens; let tokens;
@ -969,20 +1004,20 @@ function marked(src, opt, callback) {
opt.highlight = highlight; opt.highlight = highlight;
return err return err ? callback(err) : callback(null, out);
? callback(err)
: callback(null, out);
}; };
if (!highlight || highlight.length < 3) { if (!highlight || highlight.length < 3) {
return done(true); return done(true);
} }
if (!pending) {return done();} if (!pending) {
return done();
}
for (; i < tokens.length; i++) { for (; i < tokens.length; i++) {
(function(token) { (function(token) {
if (token.type !== 'code') { if (token.type !== "code") {
return --pending || done(); return --pending || done();
} }
return highlight(token.text, token.lang, (err, code) => { return highlight(token.text, token.lang, (err, code) => {
@ -1000,13 +1035,17 @@ function marked(src, opt, callback) {
return undefined; return undefined;
} }
try { try {
if (opt) {opt = merge({}, marked.defaults, opt);} if (opt) {
opt = merge({}, marked.defaults, opt);
}
return Parser.parse(Lexer.lex(src, opt), opt); return Parser.parse(Lexer.lex(src, opt), opt);
} catch (e) { } catch (e) {
e.message += '\nPlease report this to https://github.com/chjj/marked.'; e.message += "\nPlease report this to https://github.com/chjj/marked.";
if ((opt || marked.defaults).silent) { if ((opt || marked.defaults).silent) {
return [React.DOM.p(null, 'An error occurred:'), return [
React.DOM.pre(null, e.message)]; React.DOM.p(null, "An error occurred:"),
React.DOM.pre(null, e.message)
];
} }
throw e; throw e;
} }
@ -1016,8 +1055,7 @@ function marked(src, opt, callback) {
* Options * Options
*/ */
marked.options = marked.options = marked.setOptions = function(opt) {
marked.setOptions = function(opt) {
merge(marked.defaults, opt); merge(marked.defaults, opt);
return marked; return marked;
}; };
@ -1031,9 +1069,9 @@ marked.defaults = {
smartLists: false, smartLists: false,
silent: false, silent: false,
highlight: null, highlight: null,
langPrefix: 'lang-', langPrefix: "lang-",
smartypants: false, smartypants: false,
paragraphFn: null, paragraphFn: null
}; };
/** /**
@ -1053,7 +1091,11 @@ marked.parse = marked;
class Marked extends React.Component { class Marked extends React.Component {
render() { render() {
return <div>{marked(this.props.children, this.props)}</div>; return (
<div>
{marked(this.props.children, this.props)}
</div>
);
} }
} }

View file

@ -7,8 +7,8 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const unindent = require('./unindent.js'); const unindent = require("./unindent.js");
/* http://prismjs.com/download.html?themes=prism&languages=markup+clike+javascript+jsx */ /* http://prismjs.com/download.html?themes=prism&languages=markup+clike+javascript+jsx */
/** /**
@ -20,15 +20,22 @@ const unindent = require('./unindent.js');
// Private helper vars // Private helper vars
const lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; const lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i;
const _ = Prism = { const _ = (Prism = {
util: { util: {
encode(tokens) { encode(tokens) {
if (tokens instanceof Token) { if (tokens instanceof Token) {
return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); return new Token(
} else if (_.util.type(tokens) === 'Array') { tokens.type,
_.util.encode(tokens.content),
tokens.alias
);
} else if (_.util.type(tokens) === "Array") {
return tokens.map(_.util.encode); return tokens.map(_.util.encode);
} else { } else {
return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' '); return tokens
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/\u00a0/g, " ");
} }
}, },
@ -41,7 +48,7 @@ const _ = Prism = {
const type = _.util.type(o); const type = _.util.type(o);
switch (type) { switch (type) {
case 'Object': case "Object":
var clone = {}; var clone = {};
for (const key in o) { for (const key in o) {
@ -52,13 +59,18 @@ const _ = Prism = {
return clone; return clone;
case 'Array': case "Array":
// Check for existence for IE8 // Check for existence for IE8
return o.map && o.map(v => { return _.util.clone(v); }); return (
o.map &&
o.map(v => {
return _.util.clone(v);
})
);
} }
return o; return o;
}, }
}, },
languages: { languages: {
@ -100,13 +112,9 @@ const _ = Prism = {
const ret = {}; const ret = {};
for (const token in grammar) { for (const token in grammar) {
if (grammar.hasOwnProperty(token)) { if (grammar.hasOwnProperty(token)) {
if (token == before) { if (token == before) {
for (var newToken in insert) { for (var newToken in insert) {
if (insert.hasOwnProperty(newToken)) { if (insert.hasOwnProperty(newToken)) {
ret[newToken] = insert[newToken]; ret[newToken] = insert[newToken];
} }
@ -124,7 +132,7 @@ const _ = Prism = {
} }
}); });
return root[inside] = ret; return (root[inside] = ret);
}, },
// Traverse a language definition with Depth First Search // Traverse a language definition with Depth First Search
@ -133,45 +141,55 @@ const _ = Prism = {
if (o.hasOwnProperty(i)) { if (o.hasOwnProperty(i)) {
callback.call(o, i, o[i], type || i); callback.call(o, i, o[i], type || i);
if (_.util.type(o[i]) === 'Object') { if (_.util.type(o[i]) === "Object") {
_.languages.DFS(o[i], callback); _.languages.DFS(o[i], callback);
} else if (_.util.type(o[i]) === 'Array') { } else if (_.util.type(o[i]) === "Array") {
_.languages.DFS(o[i], callback, i); _.languages.DFS(o[i], callback, i);
} }
} }
} }
}, }
}, },
highlightAll(async, callback) { highlightAll(async, callback) {
const elements = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'); const elements = document.querySelectorAll(
'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
);
for (let i = 0, element; element = elements[i++];) { for (let i = 0, element; (element = elements[i++]); ) {
_.highlightElement(element, async === true, callback); _.highlightElement(element, async === true, callback);
} }
}, },
highlightElement(element, async, callback) { highlightElement(element, async, callback) {
// Find language // Find language
let language, grammar, parent = element; let language,
grammar,
parent = element;
while (parent && !lang.test(parent.className)) { while (parent && !lang.test(parent.className)) {
parent = parent.parentNode; parent = parent.parentNode;
} }
if (parent) { if (parent) {
language = (parent.className.match(lang) || [, ''])[1]; language = (parent.className.match(lang) || [, ""])[1];
grammar = _.languages[language]; grammar = _.languages[language];
} }
// Set language on the element, if not present // Set language on the element, if not present
element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; element.className =
element.className.replace(lang, "").replace(/\s+/g, " ") +
" language-" +
language;
// Set language on the parent, for styling // Set language on the parent, for styling
parent = element.parentNode; parent = element.parentNode;
if (/pre/i.test(parent.nodeName)) { if (/pre/i.test(parent.nodeName)) {
parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; parent.className =
parent.className.replace(lang, "").replace(/\s+/g, " ") +
" language-" +
language;
} }
if (!grammar) { if (!grammar) {
@ -184,16 +202,16 @@ const _ = Prism = {
return; return;
} }
code = code.replace(/^(?:\r?\n|\r)/, ''); code = code.replace(/^(?:\r?\n|\r)/, "");
const env = { const env = {
element, element,
language, language,
grammar, grammar,
code, code
}; };
_.hooks.run('before-highlight', env); _.hooks.run("before-highlight", env);
if (async && _self.Worker) { if (async && _self.Worker) {
const worker = new Worker(_.filename); const worker = new Worker(_.filename);
@ -201,28 +219,30 @@ const _ = Prism = {
worker.onmessage = function(evt) { worker.onmessage = function(evt) {
env.highlightedCode = Token.stringify(JSON.parse(evt.data), language); env.highlightedCode = Token.stringify(JSON.parse(evt.data), language);
_.hooks.run('before-insert', env); _.hooks.run("before-insert", env);
env.element.innerHTML = env.highlightedCode; env.element.innerHTML = env.highlightedCode;
callback && callback.call(env.element); callback && callback.call(env.element);
_.hooks.run('after-highlight', env); _.hooks.run("after-highlight", env);
}; };
worker.postMessage(JSON.stringify({ worker.postMessage(
language: env.language, JSON.stringify({
code: env.code, language: env.language,
})); code: env.code
} else { })
);
} else {
env.highlightedCode = _.highlight(env.code, env.grammar, env.language); env.highlightedCode = _.highlight(env.code, env.grammar, env.language);
_.hooks.run('before-insert', env); _.hooks.run("before-insert", env);
env.element.innerHTML = env.highlightedCode; env.element.innerHTML = env.highlightedCode;
callback && callback.call(element); callback && callback.call(element);
_.hooks.run('after-highlight', env); _.hooks.run("after-highlight", env);
} }
}, },
@ -252,7 +272,7 @@ const _ = Prism = {
} }
let patterns = grammar[token]; let patterns = grammar[token];
patterns = (_.util.type(patterns) === 'Array') ? patterns : [patterns]; patterns = _.util.type(patterns) === "Array" ? patterns : [patterns];
for (let j = 0; j < patterns.length; ++j) { for (let j = 0; j < patterns.length; ++j) {
let pattern = patterns[j], let pattern = patterns[j],
@ -263,7 +283,8 @@ const _ = Prism = {
pattern = pattern.pattern || pattern; pattern = pattern.pattern || pattern;
for (let i = 0; i < strarr.length; i++) { // Don't cache length as it changes during the loop for (let i = 0; i < strarr.length; i++) {
// Don't cache length as it changes during the loop
const str = strarr[i]; const str = strarr[i];
@ -298,7 +319,11 @@ const _ = Prism = {
args.push(before); args.push(before);
} }
const wrapped = new Token(token, inside ? _.tokenize(match, inside) : match, alias); const wrapped = new Token(
token,
inside ? _.tokenize(match, inside) : match,
alias
);
args.push(wrapped); args.push(wrapped);
@ -333,25 +358,25 @@ const _ = Prism = {
return; return;
} }
for (let i = 0, callback; callback = callbacks[i++];) { for (let i = 0, callback; (callback = callbacks[i++]); ) {
callback(env); callback(env);
} }
}, }
}, }
}; });
const Token = _.Token = function(type, content, alias) { const Token = (_.Token = function(type, content, alias) {
this.type = type; this.type = type;
this.content = content; this.content = content;
this.alias = alias; this.alias = alias;
}; });
Token.reactify = function(o, language, parent, key) { Token.reactify = function(o, language, parent, key) {
if (typeof o == 'string') { if (typeof o == "string") {
return o; return o;
} }
if (_.util.type(o) === 'Array') { if (_.util.type(o) === "Array") {
return o.map((element, i) => { return o.map((element, i) => {
return Token.reactify(element, language, o, i); return Token.reactify(element, language, o, i);
}); });
@ -360,183 +385,186 @@ Token.reactify = function(o, language, parent, key) {
const env = { const env = {
type: o.type, type: o.type,
content: Token.reactify(o.content, language, parent), content: Token.reactify(o.content, language, parent),
tag: 'span', tag: "span",
classes: ['token', o.type], classes: ["token", o.type],
attributes: {key}, attributes: { key },
language, language,
parent, parent
}; };
if (env.type == 'comment') { if (env.type == "comment") {
env.attributes.spellCheck = true; env.attributes.spellCheck = true;
} }
if (o.alias) { if (o.alias) {
const aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; const aliases = _.util.type(o.alias) === "Array" ? o.alias : [o.alias];
Array.prototype.push.apply(env.classes, aliases); Array.prototype.push.apply(env.classes, aliases);
} }
_.hooks.run('wrap', env); _.hooks.run("wrap", env);
env.attributes.className = env.classes.join(' '); env.attributes.className = env.classes.join(" ");
return React.DOM[env.tag](env.attributes, env.content); return React.DOM[env.tag](env.attributes, env.content);
}; };
Prism.languages.markup = { Prism.languages.markup = {
'comment': /<!--[\w\W]*?-->/, comment: /<!--[\w\W]*?-->/,
'prolog': /<\?[\w\W]+?\?>/, prolog: /<\?[\w\W]+?\?>/,
'doctype': /<!DOCTYPE[\w\W]+?>/, doctype: /<!DOCTYPE[\w\W]+?>/,
'cdata': /<!\[CDATA\[[\w\W]*?]]>/i, cdata: /<!\[CDATA\[[\w\W]*?]]>/i,
'tag': { tag: {
pattern: /<\/?[^\s>\/]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i, pattern: /<\/?[^\s>\/]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,
inside: { inside: {
'tag': { tag: {
pattern: /^<\/?[^\s>\/]+/i, pattern: /^<\/?[^\s>\/]+/i,
inside: { inside: {
'punctuation': /^<\/?/, punctuation: /^<\/?/,
'namespace': /^[^\s>\/:]+:/, namespace: /^[^\s>\/:]+:/
}, }
}, },
'attr-value': { "attr-value": {
pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i, pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,
inside: { inside: {
'punctuation': /[=>"']/, punctuation: /[=>"']/
}, }
}, },
'punctuation': /\/?>/, punctuation: /\/?>/,
'attr-name': { "attr-name": {
pattern: /[^\s>\/]+/, pattern: /[^\s>\/]+/,
inside: { inside: {
'namespace': /^[^\s>\/:]+:/, namespace: /^[^\s>\/:]+:/
}, }
}, }
}
},
}, },
'entity': /&#?[\da-z]{1,8};/i, entity: /&#?[\da-z]{1,8};/i
}; };
// Plugin to make entity title show the real entity, idea by Roman Komarov // Plugin to make entity title show the real entity, idea by Roman Komarov
Prism.hooks.add('wrap', env => { Prism.hooks.add("wrap", env => {
if (env.type === "entity") {
if (env.type === 'entity') { env.attributes["title"] = env.content.replace(/&amp;/, "&");
env.attributes['title'] = env.content.replace(/&amp;/, '&');
} }
}); });
Prism.languages.clike = { Prism.languages.clike = {
'comment': [ comment: [
{ {
pattern: /(^|[^\\])\/\*[\w\W]*?\*\//, pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
lookbehind: true, lookbehind: true
}, },
{ {
pattern: /(^|[^\\:])\/\/.*/, pattern: /(^|[^\\:])\/\/.*/,
lookbehind: true, lookbehind: true
}, }
], ],
'string': /("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, string: /("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
'class-name': { "class-name": {
pattern: /((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, pattern: /((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,
lookbehind: true, lookbehind: true,
inside: { inside: {
punctuation: /(\.|\\)/, punctuation: /(\.|\\)/
}, }
}, },
'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, keyword: /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
'boolean': /\b(true|false)\b/, boolean: /\b(true|false)\b/,
'function': /[a-z0-9_]+(?=\()/i, function: /[a-z0-9_]+(?=\()/i,
'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/, number: /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,
'operator': /[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/, operator: /[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,
'punctuation': /[{}[\];(),.:]/, punctuation: /[{}[\];(),.:]/
}; };
Prism.languages.javascript = Prism.languages.extend('clike', { Prism.languages.javascript = Prism.languages.extend("clike", {
'keyword': /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/, keyword: /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,
'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, number: /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,
'function': /(?!\d)[a-z0-9_$]+(?=\()/i, function: /(?!\d)[a-z0-9_$]+(?=\()/i
}); });
Prism.languages.insertBefore('javascript', 'keyword', { Prism.languages.insertBefore("javascript", "keyword", {
'regex': { regex: {
pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,
lookbehind: true, lookbehind: true
}, }
}); });
Prism.languages.insertBefore('javascript', 'class-name', { Prism.languages.insertBefore("javascript", "class-name", {
'template-string': { "template-string": {
pattern: /`(?:\\`|\\?[^`])*`/, pattern: /`(?:\\`|\\?[^`])*`/,
inside: { inside: {
'interpolation': { interpolation: {
pattern: /\$\{[^}]+\}/, pattern: /\$\{[^}]+\}/,
inside: { inside: {
'interpolation-punctuation': { "interpolation-punctuation": {
pattern: /^\$\{|\}$/, pattern: /^\$\{|\}$/,
alias: 'punctuation', alias: "punctuation"
}, },
rest: Prism.languages.javascript, rest: Prism.languages.javascript
}, }
}, },
'string': /[\s\S]+/, string: /[\s\S]+/
}, }
}, }
}); });
if (Prism.languages.markup) { if (Prism.languages.markup) {
Prism.languages.insertBefore('markup', 'tag', { Prism.languages.insertBefore("markup", "tag", {
'script': { script: {
pattern: /<script[\w\W]*?>[\w\W]*?<\/script>/i, pattern: /<script[\w\W]*?>[\w\W]*?<\/script>/i,
inside: { inside: {
'tag': { tag: {
pattern: /<script[\w\W]*?>|<\/script>/i, pattern: /<script[\w\W]*?>|<\/script>/i,
inside: Prism.languages.markup.tag.inside, inside: Prism.languages.markup.tag.inside
}, },
rest: Prism.languages.javascript, rest: Prism.languages.javascript
}, },
alias: 'language-javascript', alias: "language-javascript"
}, }
}); });
} }
(function(Prism) { (function(Prism) {
const javascript = Prism.util.clone(Prism.languages.javascript); const javascript = Prism.util.clone(Prism.languages.javascript);
Prism.languages.jsx = Prism.languages.extend('markup', javascript); Prism.languages.jsx = Prism.languages.extend("markup", javascript);
Prism.languages.jsx.tag.pattern = /<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+|(\{[\w\W]*?\})))?\s*)*\/?>/i; Prism.languages.jsx.tag.pattern = /<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+|(\{[\w\W]*?\})))?\s*)*\/?>/i;
Prism.languages.jsx.tag.inside['attr-value'].pattern = /=[^\{](?:('|")[\w\W]*?(\1)|[^\s>]+)/i; Prism.languages.jsx.tag.inside[
"attr-value"
].pattern = /=[^\{](?:('|")[\w\W]*?(\1)|[^\s>]+)/i;
Prism.languages.insertBefore('inside', 'attr-value', { Prism.languages.insertBefore(
'script': { "inside",
pattern: /=(\{[\w\W]*?\})/i, "attr-value",
inside: { {
'function' : Prism.languages.javascript.function, script: {
'punctuation': /[={}[\];(),.:]/, pattern: /=(\{[\w\W]*?\})/i,
'keyword': Prism.languages.javascript.keyword, inside: {
}, function: Prism.languages.javascript.function,
'alias': 'language-javascript', punctuation: /[={}[\];(),.:]/,
keyword: Prism.languages.javascript.keyword
},
alias: "language-javascript"
}
}, },
}, Prism.languages.jsx.tag); Prism.languages.jsx.tag
);
}(Prism)); })(Prism);
const PrismComponent = React.createClass({ const PrismComponent = React.createClass({
statics: { statics: {
_, _
}, },
getDefaultProps() { getDefaultProps() {
return { return {
language: 'javascript', language: "javascript"
}; };
}, },
render() { render() {
const lines = []; const lines = [];
if (this.props.line) { if (this.props.line) {
this.props.line.split(',').forEach(range => { this.props.line.split(",").forEach(range => {
const parts = range.split('-'); const parts = range.split("-");
if (parts.length === 1) { if (parts.length === 1) {
lines.push(parts[0].trim()); lines.push(parts[0].trim());
} else { } else {
@ -550,20 +578,20 @@ const PrismComponent = React.createClass({
} }
const grammar = _.languages[this.props.language]; const grammar = _.languages[this.props.language];
return ( return (
<pre className={'prism language-' + this.props.language}> <pre className={"prism language-" + this.props.language}>
{Token.reactify(_.tokenize(this.props.children, grammar))} {Token.reactify(_.tokenize(this.props.children, grammar))}
{lines.map((line, ii) => { {lines.map((line, ii) => {
return ( return (
<div <div
className="line-highlight" className="line-highlight"
key={ii} key={ii}
style={{height: 20, top: 20 * (line - 1)}} style={{ height: 20, top: 20 * (line - 1) }}
/> />
); );
})} })}
</pre> </pre>
); );
}, }
}); });
module.exports = PrismComponent; module.exports = PrismComponent;

View file

@ -7,10 +7,10 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const HeaderNav = require('./nav/HeaderNav.js'); const HeaderNav = require("./nav/HeaderNav.js");
const Head = require('./Head.js'); const Head = require("./Head.js");
const Footer = require(process.cwd() + '/core/Footer.js'); const Footer = require(process.cwd() + "/core/Footer.js");
class Site extends React.Component { class Site extends React.Component {
/* /*
@ -48,18 +48,26 @@ class Site extends React.Component {
*/ */
render() { render() {
const tagline = this.props.config[this.props.language] ? this.props.config[this.props.language]["localized-strings"].tagline : this.props.config.tagline; const tagline = this.props.config[this.props.language]
? this.props.config[this.props.language]["localized-strings"].tagline
: this.props.config.tagline;
const title = this.props.title const title = this.props.title
? this.props.title + ' · ' + this.props.config.title ? this.props.title + " · " + this.props.config.title
: this.props.config.title + ' · ' + tagline; : this.props.config.title + " · " + tagline;
const description = const description = this.props.description || tagline;
this.props.description || tagline;
const url = const url =
this.props.config.url + this.props.config.baseUrl + (this.props.url || 'index.html'); this.props.config.url +
this.props.config.baseUrl +
(this.props.url || "index.html");
return ( return (
<html> <html>
<Head config={this.props.config} description={description} title={title} url={url} /> <Head
config={this.props.config}
description={description}
title={title}
url={url}
/>
<body className={this.props.className}> <body className={this.props.className}>
<HeaderNav <HeaderNav
config={this.props.config} config={this.props.config}
@ -76,36 +84,41 @@ class Site extends React.Component {
<script <script
type="text/javascript" type="text/javascript"
src="//cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js" src="//cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"
/> />}
}
{this.props.config.gaTrackingId && {this.props.config.gaTrackingId &&
<script <script
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: ` __html:
`
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', '` + this.props.config.gaTrackingId + `', 'auto'); ga('create', '` +
this.props.config.gaTrackingId +
`', 'auto');
ga('send', 'pageview'); ga('send', 'pageview');
`, `
}} }}
/> />}
}
{this.props.config.algolia && {this.props.config.algolia &&
<script <script
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: ` __html:
`
var search = docsearch({ var search = docsearch({
apiKey: '` + this.props.config.algolia.apiKey + `', apiKey: '` +
indexName: '` + this.props.config.algolia.indexName + `', this.props.config.algolia.apiKey +
`',
indexName: '` +
this.props.config.algolia.indexName +
`',
inputSelector: '#search_input_react' inputSelector: '#search_input_react'
}); });
`, `
}} }}
/> />}
}
</body> </body>
</html> </html>
); );

View file

@ -7,16 +7,16 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const siteConfig = require(process.cwd() + '/siteConfig.js'); const siteConfig = require(process.cwd() + "/siteConfig.js");
class LanguageDropDown extends React.Component { class LanguageDropDown extends React.Component {
render() { render() {
const enabledLanguages = []; const enabledLanguages = [];
let currentLanguage = 'English'; let currentLanguage = "English";
siteConfig['languages'].map(lang => { siteConfig["languages"].map(lang => {
if (lang.tag == this.props.language) { if (lang.tag == this.props.language) {
currentLanguage = lang.name; currentLanguage = lang.name;
} }
@ -48,7 +48,7 @@ class LanguageDropDown extends React.Component {
<a id="languages-menu" href="#"> <a id="languages-menu" href="#">
<img <img
className="languages-icon" className="languages-icon"
src={this.props.baseUrl + 'img/language.svg'} src={this.props.baseUrl + "img/language.svg"}
/> />
{currentLanguage} {currentLanguage}
</a> </a>
@ -70,7 +70,7 @@ class LanguageDropDown extends React.Component {
languagesDropDown.className = "hide"; languagesDropDown.className = "hide";
} }
}); });
`, `
}} }}
/> />
</span> </span>
@ -82,21 +82,24 @@ class HeaderNav extends React.Component {
constructor() { constructor() {
super(); super();
this.state = { this.state = {
slideoutActive: false, slideoutActive: false
}; };
} }
makeLinks(link) { makeLinks(link) {
const linkWithLang = link.href.replace( const linkWithLang = link.href.replace(
/\/LANGUAGE\//, /\/LANGUAGE\//,
'\/' + this.props.language + '\/' "/" + this.props.language + "/"
); );
return ( return (
<li key={link.section}> <li key={link.section}>
<a <a
href={linkWithLang} href={linkWithLang}
className={link.section === this.props.section ? 'active' : ''}> className={link.section === this.props.section ? "active" : ""}
{siteConfig[this.props.language] ? siteConfig[this.props.language]['localized-strings'][link.text] : link.text} >
{siteConfig[this.props.language]
? siteConfig[this.props.language]["localized-strings"][link.text]
: link.text}
</a> </a>
</li> </li>
); );
@ -109,7 +112,9 @@ class HeaderNav extends React.Component {
<header> <header>
<a href={this.props.baseUrl}> <a href={this.props.baseUrl}>
<img src={this.props.baseUrl + siteConfig.headerIcon} /> <img src={this.props.baseUrl + siteConfig.headerIcon} />
<h2>{this.props.title}</h2> <h2>
{this.props.title}
</h2>
</a> </a>
{this.renderResponsiveNav()} {this.renderResponsiveNav()}
</header> </header>
@ -130,9 +135,12 @@ class HeaderNav extends React.Component {
/> />
{this.props.config.algolia && {this.props.config.algolia &&
<li className="navSearchWrapper reactNavSearchWrapper"> <li className="navSearchWrapper reactNavSearchWrapper">
<input id="search_input_react" type="text" placeholder="Search" /> <input
</li> id="search_input_react"
} type="text"
placeholder="Search"
/>
</li>}
{this.props.config.headerLinksExternal.map(this.makeLinks, this)} {this.props.config.headerLinksExternal.map(this.makeLinks, this)}
</ul> </ul>
</nav> </nav>

View file

@ -7,10 +7,10 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const React = require('react'); const React = require("react");
const classNames = require('classnames'); const classNames = require("classnames");
const siteConfig = require(process.cwd() + '/siteConfig.js'); const siteConfig = require(process.cwd() + "/siteConfig.js");
class SideNav extends React.Component { class SideNav extends React.Component {
render() { render() {
@ -19,10 +19,14 @@ class SideNav extends React.Component {
<div className="toggleNav"> <div className="toggleNav">
<section className="navWrapper wrapper"> <section className="navWrapper wrapper">
<div className="navBreadcrumb wrapper"> <div className="navBreadcrumb wrapper">
<div className="navToggle" id="navToggler"><i /></div> <div className="navToggle" id="navToggler">
<i />
</div>
<h2> <h2>
<i></i> <i></i>
<span>{this.props.current.category}</span> <span>
{this.props.current.category}
</span>
</h2> </h2>
</div> </div>
<div className="navGroups"> <div className="navGroups">
@ -38,7 +42,7 @@ class SideNav extends React.Component {
toggler.onclick = function() { toggler.onclick = function() {
nav.classList.toggle('docsSliderActive'); nav.classList.toggle('docsSliderActive');
}; };
`, `
}} }}
/> />
</nav> </nav>
@ -47,7 +51,9 @@ class SideNav extends React.Component {
renderCategory(category) { renderCategory(category) {
return ( return (
<div className="navGroup navGroupActive" key={category.name}> <div className="navGroup navGroupActive" key={category.name}>
<h3>{this.getLocalizedCategoryString(category.name)}</h3> <h3>
{this.getLocalizedCategoryString(category.name)}
</h3>
<ul> <ul>
{category.links.map(this.renderItemLink, this)} {category.links.map(this.renderItemLink, this)}
</ul> </ul>
@ -55,16 +61,17 @@ class SideNav extends React.Component {
); );
} }
getLocalizedCategoryString(category) { getLocalizedCategoryString(category) {
let categoryString = let categoryString = siteConfig[this.props.language]
siteConfig[this.props.language] ? ? siteConfig[this.props.language]["localized-strings"][category] ||
siteConfig[this.props.language]['localized-strings'][category] || category category
: category; : category;
return categoryString; return categoryString;
} }
getLocalizedString(metadata) { getLocalizedString(metadata) {
let localizedString = let localizedString = siteConfig[this.props.language]
siteConfig[this.props.language] ? ? siteConfig[this.props.language]["localized-strings"][
siteConfig[this.props.language]['localized-strings'][metadata.localized_id] || metadata.title metadata.localized_id
] || metadata.title
: metadata.title; : metadata.title;
return localizedString; return localizedString;
@ -74,19 +81,19 @@ class SideNav extends React.Component {
if (metadata.permalink.match(/^https?:/)) { if (metadata.permalink.match(/^https?:/)) {
return metadata.permalink; return metadata.permalink;
} }
return siteConfig.baseUrl + metadata.permalink + '#content'; return siteConfig.baseUrl + metadata.permalink + "#content";
} }
if (metadata.path) { if (metadata.path) {
return siteConfig.baseUrl + 'blog/' + metadata.path; return siteConfig.baseUrl + "blog/" + metadata.path;
} }
return null; return null;
} }
renderItemLink(link) { renderItemLink(link) {
const itemClasses = classNames('navListItem', { const itemClasses = classNames("navListItem", {
navListItemActive: link.id === this.props.current.id, navListItemActive: link.id === this.props.current.id
}); });
const linkClasses = classNames('navItem', { const linkClasses = classNames("navItem", {
navItemActive: link.id === this.props.current.id, navItemActive: link.id === this.props.current.id
}); });
return ( return (
<li className={itemClasses} key={link.id}> <li className={itemClasses} key={link.id}>
@ -98,6 +105,6 @@ class SideNav extends React.Component {
} }
} }
SideNav.defaultProps = { SideNav.defaultProps = {
contents: [], contents: []
}; };
module.exports = SideNav; module.exports = SideNav;

View file

@ -9,39 +9,34 @@
module.exports = string => { module.exports = string => {
// var accents = "àáäâèéëêìíïîòóöôùúüûñç"; // var accents = "àáäâèéëêìíïîòóöôùúüûñç";
const accents = '\u00e0\u00e1\u00e4\u00e2\u00e8' const accents =
+ '\u00e9\u00eb\u00ea\u00ec\u00ed\u00ef' "\u00e0\u00e1\u00e4\u00e2\u00e8" +
+ '\u00ee\u00f2\u00f3\u00f6\u00f4\u00f9' "\u00e9\u00eb\u00ea\u00ec\u00ed\u00ef" +
+ '\u00fa\u00fc\u00fb\u00f1\u00e7'; "\u00ee\u00f2\u00f3\u00f6\u00f4\u00f9" +
"\u00fa\u00fc\u00fb\u00f1\u00e7";
const without = 'aaaaeeeeiiiioooouuuunc'; const without = "aaaaeeeeiiiioooouuuunc";
let slug = string let slug = string
.toString() .toString()
// Handle uppercase characters // Handle uppercase characters
.toLowerCase() .toLowerCase()
// Handle accentuated characters // Handle accentuated characters
.replace( .replace(new RegExp("[" + accents + "]", "g"), c => {
new RegExp('[' + accents + ']', 'g'), return without.charAt(accents.indexOf(c));
c => { return without.charAt(accents.indexOf(c)); }) })
// Replace `.`, `(` and `?` with blank string like Github does // Replace `.`, `(` and `?` with blank string like Github does
.replace(/\.|\(|\?/g, '') .replace(/\.|\(|\?/g, "")
// Dash special characters // Dash special characters
.replace(/[^a-z0-9]/g, '-') .replace(/[^a-z0-9]/g, "-")
// Compress multiple dash // Compress multiple dash
.replace(/-+/g, '-') .replace(/-+/g, "-")
// Trim dashes // Trim dashes
.replace(/^-|-$/g, ''); .replace(/^-|-$/g, "");
// Add trailing `-` if string contains ` ...` in the end like Github does // Add trailing `-` if string contains ` ...` in the end like Github does
if (/\s[.]{1,}/.test(string)) { if (/\s[.]{1,}/.test(string)) {
slug += '-'; slug += "-";
} }
return slug; return slug;

View file

@ -9,8 +9,8 @@
// Remove the indentation introduced by JSX // Remove the indentation introduced by JSX
function unindent(code) { function unindent(code) {
const lines = code.split('\n'); const lines = code.split("\n");
if (lines[0] === '') { if (lines[0] === "") {
lines.shift(); lines.shift();
} }
if (lines.length <= 1) { if (lines.length <= 1) {
@ -19,9 +19,9 @@ function unindent(code) {
const indent = lines[0].match(/^\s*/)[0]; const indent = lines[0].match(/^\s*/)[0];
for (let i = 0; i < lines.length; ++i) { for (let i = 0; i < lines.length; ++i) {
lines[i] = lines[i].replace(new RegExp('^' + indent), ''); lines[i] = lines[i].replace(new RegExp("^" + indent), "");
} }
return lines.join('\n'); return lines.join("\n");
} }
module.exports = unindent; module.exports = unindent;

View file

@ -9,7 +9,7 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const shell = require('shelljs'); const shell = require("shelljs");
const GIT_USER = process.env.GIT_USER; const GIT_USER = process.env.GIT_USER;
const CIRCLE_BRANCH = process.env.CIRCLE_BRANCH; const CIRCLE_BRANCH = process.env.CIRCLE_BRANCH;
@ -18,54 +18,64 @@ const CIRCLE_PROJECT_REPONAME = process.env.CIRCLE_PROJECT_REPONAME;
const CI_PULL_REQUEST = process.env.CI_PULL_REQUEST; const CI_PULL_REQUEST = process.env.CI_PULL_REQUEST;
const remoteBranch = `https://${GIT_USER}@github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}.git`; const remoteBranch = `https://${GIT_USER}@github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}.git`;
if (!shell.which("git")) {
if (!shell.which('git')) { shell.echo("Sorry, this script requires git");
shell.echo('Sorry, this script requires git');
shell.exit(1); shell.exit(1);
} }
if (CI_PULL_REQUEST || CIRCLE_BRANCH !== `master`) { if (CI_PULL_REQUEST || CIRCLE_BRANCH !== `master`) {
shell.echo('Skipping deploy'); shell.echo("Skipping deploy");
shell.exit(0); shell.exit(0);
} }
if (shell.exec('docusaurus-build').code) { if (shell.exec("docusaurus-build").code) {
shell.echo('Error: generating html failed'); shell.echo("Error: generating html failed");
shell.exit(1); shell.exit(1);
} }
shell.cd(__dirname); shell.cd(__dirname);
shell.cd('..'); shell.cd("..");
shell.cd('build'); shell.cd("build");
if (shell.exec(`git clone ${remoteBranch} ${CIRCLE_PROJECT_REPONAME}-gh-pages`).code !== 0) { if (
shell.echo('Error: git clone failed'); shell.exec(`git clone ${remoteBranch} ${CIRCLE_PROJECT_REPONAME}-gh-pages`)
.code !== 0
) {
shell.echo("Error: git clone failed");
shell.exit(1); shell.exit(1);
} }
shell.cd(`${CIRCLE_PROJECT_REPONAME}-gh-pages`); shell.cd(`${CIRCLE_PROJECT_REPONAME}-gh-pages`);
if (shell.exec('git checkout origin/gh-pages').code + if (
shell.exec('git checkout -b gh-pages').code + shell.exec("git checkout origin/gh-pages").code +
shell.exec('git branch --set-upstream-to=origin/gh-pages').code !== 0 shell.exec("git checkout -b gh-pages").code +
) { shell.exec("git branch --set-upstream-to=origin/gh-pages").code !==
shell.echo('Error: Git checkout gh-pages failed'); 0
) {
shell.echo("Error: Git checkout gh-pages failed");
shell.exit(1); shell.exit(1);
} }
shell.exec('rm -rf *'); shell.exec("rm -rf *");
shell.cd('../..'); shell.cd("../..");
shell.cp('-R', `build/${CIRCLE_PROJECT_REPONAME}/*`, `build/${CIRCLE_PROJECT_REPONAME}-gh-pages/`); shell.cp(
"-R",
`build/${CIRCLE_PROJECT_REPONAME}/*`,
`build/${CIRCLE_PROJECT_REPONAME}-gh-pages/`
);
shell.cd(`build/${CIRCLE_PROJECT_REPONAME}-gh-pages`); shell.cd(`build/${CIRCLE_PROJECT_REPONAME}-gh-pages`);
shell.exec('git add --all'); shell.exec("git add --all");
shell.exec('git commit -m "update website [ci skip]"'); shell.exec('git commit -m "update website [ci skip]"');
if (shell.exec('git push origin gh-pages').code !== 0) { if (shell.exec("git push origin gh-pages").code !== 0) {
shell.echo('Error: Git push failed'); shell.echo("Error: Git push failed");
shell.exit(1); shell.exit(1);
} else { } else {
shell.echo(`Website is live at: https://${CIRCLE_PROJECT_USERNAME}.github.io/${CIRCLE_PROJECT_REPONAME}/`); shell.echo(
`Website is live at: https://${CIRCLE_PROJECT_USERNAME}.github.io/${CIRCLE_PROJECT_REPONAME}/`
);
shell.exit(0); shell.exit(0);
} }

View file

@ -7,40 +7,42 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
function execute() { function execute() {
const translation = require('./translation.js'); const translation = require("./translation.js");
translation(); translation();
const CWD = process.cwd(); const CWD = process.cwd();
const fs = require('fs-extra'); const fs = require("fs-extra");
const readMetadata = require('./readMetadata.js'); const readMetadata = require("./readMetadata.js");
const renderToStaticMarkup = require('react-dom/server').renderToStaticMarkup; const renderToStaticMarkup = require("react-dom/server").renderToStaticMarkup;
const path = require('path'); const path = require("path");
const toSlug = require('../core/toSlug.js'); const toSlug = require("../core/toSlug.js");
const React = require('react'); const React = require("react");
const mkdirp = require('mkdirp'); const mkdirp = require("mkdirp");
const glob = require('glob'); const glob = require("glob");
const Site = require('../core/Site.js'); const Site = require("../core/Site.js");
const siteConfig = require(CWD + '/siteConfig.js'); const siteConfig = require(CWD + "/siteConfig.js");
const translate = require('./translate.js'); const translate = require("./translate.js");
let languages; let languages;
if (fs.existsSync(CWD + '/languages.js')) { if (fs.existsSync(CWD + "/languages.js")) {
languages = require(CWD + '/languages.js'); languages = require(CWD + "/languages.js");
} else { } else {
languages = [{ languages = [
enabled: true, {
name: 'English', enabled: true,
tag: 'en', name: "English",
}]; tag: "en"
}
];
} }
function writeFileAndCreateFolder(file, content) { function writeFileAndCreateFolder(file, content) {
mkdirp.sync(file.replace(new RegExp('/[^/]*$'), '')); mkdirp.sync(file.replace(new RegExp("/[^/]*$"), ""));
fs.writeFileSync(file, content); fs.writeFileSync(file, content);
} }
const TABLE_OF_CONTENTS_TOKEN = '<AUTOGENERATED_TABLE_OF_CONTENTS>'; const TABLE_OF_CONTENTS_TOKEN = "<AUTOGENERATED_TABLE_OF_CONTENTS>";
const insertTableOfContents = rawContent => { const insertTableOfContents = rawContent => {
const regexp = /\n###\s+(`.*`.*)\n/g; const regexp = /\n###\s+(`.*`.*)\n/g;
@ -52,12 +54,12 @@
const tableOfContents = headers const tableOfContents = headers
.map(header => ` - [${header}](#${toSlug(header)})`) .map(header => ` - [${header}](#${toSlug(header)})`)
.join('\n'); .join("\n");
return rawContent.replace(TABLE_OF_CONTENTS_TOKEN, tableOfContents); return rawContent.replace(TABLE_OF_CONTENTS_TOKEN, tableOfContents);
}; };
console.log('generate.js triggered...'); console.log("generate.js triggered...");
const regexSubFolder = /docs\/(.*)\/.*/; const regexSubFolder = /docs\/(.*)\/.*/;
@ -67,14 +69,15 @@
}); });
readMetadata.generateDocsMetadata(); readMetadata.generateDocsMetadata();
const Metadata = require('../core/metadata.js'); const Metadata = require("../core/metadata.js");
let mdToHtml = {}; let mdToHtml = {};
for (let i = 0; i < Metadata.length; i++) { for (let i = 0; i < Metadata.length; i++) {
const metadata = Metadata[i]; const metadata = Metadata[i];
mdToHtml['/docs/' + metadata.language + '/' + metadata.source] = '/' + siteConfig.projectName + '/' + metadata.permalink; mdToHtml["/docs/" + metadata.language + "/" + metadata.source] =
"/" + siteConfig.projectName + "/" + metadata.permalink;
} }
const readCategories = require('./readCategories.js'); const readCategories = require("./readCategories.js");
let layouts = {}; let layouts = {};
for (let i = 0; i < Metadata.length; i++) { for (let i = 0; i < Metadata.length; i++) {
let layout = Metadata[i].layout; let layout = Metadata[i].layout;
@ -84,15 +87,15 @@
} }
} }
const DocsLayout = require('../core/DocsLayout.js'); const DocsLayout = require("../core/DocsLayout.js");
fs.removeSync(__dirname + '/../../build'); fs.removeSync(__dirname + "/../../build");
// create html files for all docs // create html files for all docs
let files = glob.sync(CWD + '/../docs/**'); let files = glob.sync(CWD + "/../docs/**");
files.forEach(file => { files.forEach(file => {
// console.log(file); // console.log(file);
let language = 'en'; let language = "en";
const match = regexSubFolder.exec(file); const match = regexSubFolder.exec(file);
if (match) { if (match) {
language = match[1]; language = match[1];
@ -104,7 +107,7 @@
const extension = path.extname(file); const extension = path.extname(file);
if (extension === '.md' || extension === '.markdown') { if (extension === ".md" || extension === ".markdown") {
const result = readMetadata.processMetadata(file); const result = readMetadata.processMetadata(file);
const metadata = result.metadata; const metadata = result.metadata;
@ -117,170 +120,265 @@
/* replace any links to markdown files to their website html links */ /* replace any links to markdown files to their website html links */
Object.keys(mdToHtml).forEach(function(key, index) { Object.keys(mdToHtml).forEach(function(key, index) {
rawContent = rawContent.replace(new RegExp(key,'g'), mdToHtml[key]); rawContent = rawContent.replace(new RegExp(key, "g"), mdToHtml[key]);
}); });
const docComp = <DocsLayout metadata={metadata} language={language} config={siteConfig}>{rawContent}</DocsLayout>; const docComp = (
<DocsLayout metadata={metadata} language={language} config={siteConfig}>
{rawContent}
</DocsLayout>
);
const str = renderToStaticMarkup(docComp); const str = renderToStaticMarkup(docComp);
let targetFile = __dirname + '/../../build' + '/' + siteConfig.projectName + '/' + metadata.permalink; let targetFile =
__dirname +
"/../../build" +
"/" +
siteConfig.projectName +
"/" +
metadata.permalink;
// console.log(targetFile); // console.log(targetFile);
writeFileAndCreateFolder(targetFile, str); writeFileAndCreateFolder(targetFile, str);
} }
}); });
// create html files for all blog posts // create html files for all blog posts
if (fs.existsSync(__dirname + '../core/MetadataBlog.js')) { if (fs.existsSync(__dirname + "../core/MetadataBlog.js")) {
fs.removeSync(__dirname + '../core/MetadataBlog.js'); fs.removeSync(__dirname + "../core/MetadataBlog.js");
} }
readMetadata.generateBlogMetadata(); readMetadata.generateBlogMetadata();
const MetadataBlog = require('../core/MetadataBlog.js'); const MetadataBlog = require("../core/MetadataBlog.js");
const BlogPostLayout = require('../core/BlogPostLayout.js'); const BlogPostLayout = require("../core/BlogPostLayout.js");
files = glob.sync(CWD + '/../blog/**/*.*'); files = glob.sync(CWD + "/../blog/**/*.*");
files.sort().reverse().forEach(file => { files.sort().reverse().forEach(file => {
/* convert filename ot use slashes */ /* convert filename ot use slashes */
const filePath = path const filePath = path
.basename(file) .basename(file)
.replace('-', '/') .replace("-", "/")
.replace('-', '/') .replace("-", "/")
.replace('-', '/') .replace("-", "/")
.replace(/\./g, '-') .replace(/\./g, "-")
.replace(/\-md$/, '.html'); .replace(/\-md$/, ".html");
const result = readMetadata.extractMetadata(fs.readFileSync(file, {encoding: 'utf8'})); const result = readMetadata.extractMetadata(
fs.readFileSync(file, { encoding: "utf8" })
);
const rawContent = result.rawContent; const rawContent = result.rawContent;
const metadata = Object.assign( const metadata = Object.assign(
{path: filePath, content: rawContent}, { path: filePath, content: rawContent },
result.metadata result.metadata
); );
metadata.id = metadata.title; metadata.id = metadata.title;
let language = 'en'; let language = "en";
const blogPostComp = <BlogPostLayout metadata={metadata} language={language} config={siteConfig}>{rawContent}</BlogPostLayout>; const blogPostComp = (
<BlogPostLayout
metadata={metadata}
language={language}
config={siteConfig}
>
{rawContent}
</BlogPostLayout>
);
const str = renderToStaticMarkup(blogPostComp); const str = renderToStaticMarkup(blogPostComp);
let targetFile = __dirname + '/../../build' + '/' + siteConfig.projectName + '/' + 'blog/' + filePath; let targetFile =
__dirname +
"/../../build" +
"/" +
siteConfig.projectName +
"/" +
"blog/" +
filePath;
writeFileAndCreateFolder(targetFile, str); writeFileAndCreateFolder(targetFile, str);
}); });
// create html files for all blog pages // create html files for all blog pages
const BlogPageLayout = require('../core/BlogPageLayout.js'); const BlogPageLayout = require("../core/BlogPageLayout.js");
const perPage = 10; const perPage = 10;
for ( for (let page = 0; page < Math.ceil(MetadataBlog.length / perPage); page++) {
let page = 0; let language = "en";
page < Math.ceil(MetadataBlog.length / perPage); const metadata = { page: page, perPage: perPage };
page++ const blogPageComp = (
) { <BlogPageLayout
let language = 'en'; metadata={metadata}
const metadata = {page: page, perPage: perPage}; language={language}
const blogPageComp = <BlogPageLayout metadata={metadata} language={language} config={siteConfig}></BlogPageLayout> config={siteConfig}
/>
);
const str = renderToStaticMarkup(blogPageComp); const str = renderToStaticMarkup(blogPageComp);
let targetFile = __dirname + '/../../build' + '/' + siteConfig.projectName + '/' + 'blog' + (page > 0 ? '/page' + (page + 1) : '') + '/index.html'; let targetFile =
__dirname +
"/../../build" +
"/" +
siteConfig.projectName +
"/" +
"blog" +
(page > 0 ? "/page" + (page + 1) : "") +
"/index.html";
writeFileAndCreateFolder(targetFile, str); writeFileAndCreateFolder(targetFile, str);
} }
/* copy all static files from docusaurus */ /* copy all static files from docusaurus */
files = glob.sync(__dirname + '/../static/**'); files = glob.sync(__dirname + "/../static/**");
files.forEach(file => { files.forEach(file => {
let targetFile = file.replace('/lib/static/', '/build' + '/' + siteConfig.projectName + '/'); let targetFile = file.replace(
"/lib/static/",
"/build" + "/" + siteConfig.projectName + "/"
);
if (file.match(/\.css$/)) { if (file.match(/\.css$/)) {
let cssContent = fs.readFileSync(file); let cssContent = fs.readFileSync(file);
cssContent = cssContent.toString().replace(new RegExp('{primaryColor}', 'g'), siteConfig.colors.primaryColor); cssContent = cssContent
cssContent = cssContent.replace(new RegExp('{secondaryColor}', 'g'), siteConfig.colors.secondaryColor); .toString()
cssContent = cssContent.replace(new RegExp('{prismColor}', 'g'), siteConfig.colors.prismColor); .replace(
new RegExp("{primaryColor}", "g"),
siteConfig.colors.primaryColor
);
cssContent = cssContent.replace(
new RegExp("{secondaryColor}", "g"),
siteConfig.colors.secondaryColor
);
cssContent = cssContent.replace(
new RegExp("{prismColor}", "g"),
siteConfig.colors.prismColor
);
mkdirp.sync(targetFile.replace(new RegExp('/[^/]*$'), '')); mkdirp.sync(targetFile.replace(new RegExp("/[^/]*$"), ""));
fs.writeFileSync(targetFile, cssContent); fs.writeFileSync(targetFile, cssContent);
} } else if (!fs.lstatSync(file).isDirectory()) {
else if (!fs.lstatSync(file).isDirectory()) { mkdirp.sync(targetFile.replace(new RegExp("/[^/]*$"), ""));
mkdirp.sync(targetFile.replace(new RegExp('/[^/]*$'), ''));
fs.copySync(file, targetFile); fs.copySync(file, targetFile);
} }
}); });
/* copy all static files from user */ /* copy all static files from user */
files = glob.sync(CWD + '/static/**'); files = glob.sync(CWD + "/static/**");
files.forEach(file => { files.forEach(file => {
if (file.match(/\.css$/)) { if (file.match(/\.css$/)) {
const mainCss = __dirname + '/../../build' + '/' + siteConfig.projectName + '/' + 'css/main.css'; const mainCss =
__dirname +
"/../../build" +
"/" +
siteConfig.projectName +
"/" +
"css/main.css";
let cssContent = fs.readFileSync(file); let cssContent = fs.readFileSync(file);
cssContent = fs.readFileSync(mainCss) + '\n' + cssContent; cssContent = fs.readFileSync(mainCss) + "\n" + cssContent;
cssContent = cssContent.toString().replace(new RegExp('{primaryColor}', 'g'), siteConfig.colors.primaryColor); cssContent = cssContent
cssContent = cssContent.replace(new RegExp('{secondaryColor}', 'g'), siteConfig.colors.secondaryColor); .toString()
cssContent = cssContent.replace(new RegExp('{prismColor}', 'g'), siteConfig.colors.prismColor); .replace(
new RegExp("{primaryColor}", "g"),
siteConfig.colors.primaryColor
);
cssContent = cssContent.replace(
new RegExp("{secondaryColor}", "g"),
siteConfig.colors.secondaryColor
);
cssContent = cssContent.replace(
new RegExp("{prismColor}", "g"),
siteConfig.colors.prismColor
);
fs.writeFileSync(mainCss, cssContent); fs.writeFileSync(mainCss, cssContent);
} } else if (!fs.lstatSync(file).isDirectory()) {
else if (!fs.lstatSync(file).isDirectory()) { let parts = file.split("static");
let parts = file.split('static'); let targetFile =
let targetFile = __dirname + '/../../build' + '/' + siteConfig.projectName + '/' + parts[1]; __dirname +
mkdirp.sync(targetFile.replace(new RegExp('/[^/]*$'), '')); "/../../build" +
"/" +
siteConfig.projectName +
"/" +
parts[1];
mkdirp.sync(targetFile.replace(new RegExp("/[^/]*$"), ""));
fs.copySync(file, targetFile); fs.copySync(file, targetFile);
} }
}); });
/* compile/copy pages from user */ /* compile/copy pages from user */
files = glob.sync(CWD + '/pages/**'); files = glob.sync(CWD + "/pages/**");
files.forEach(file => { files.forEach(file => {
if (file.match(/\.js$/)) { if (file.match(/\.js$/)) {
/* make temp file for sake of require paths */ /* make temp file for sake of require paths */
const parts = file.split('pages'); const parts = file.split("pages");
let tempFile = __dirname + '/../pages' + parts[1]; let tempFile = __dirname + "/../pages" + parts[1];
tempFile = tempFile.replace(path.basename(file), 'temp' + path.basename(file)); tempFile = tempFile.replace(
mkdirp.sync(tempFile.replace(new RegExp('/[^/]*$'), '')); path.basename(file),
"temp" + path.basename(file)
);
mkdirp.sync(tempFile.replace(new RegExp("/[^/]*$"), ""));
fs.copySync(file, tempFile); fs.copySync(file, tempFile);
const ReactComp = require(tempFile); const ReactComp = require(tempFile);
let targetFile = __dirname + '/../../build/' + siteConfig.projectName + '/' + parts[1]; let targetFile =
targetFile = targetFile.replace(/\.js$/, '.html'); __dirname + "/../../build/" + siteConfig.projectName + "/" + parts[1];
targetFile = targetFile.replace(/\.js$/, ".html");
const regexLang = /\/pages\/(.*)\//; const regexLang = /\/pages\/(.*)\//;
const match = regexLang.exec(file); const match = regexLang.exec(file);
const langParts = match[1].split('/'); const langParts = match[1].split("/");
if (langParts.indexOf('en') !== -1) { if (langParts.indexOf("en") !== -1) {
/* copy and compile a page for each enabled language from the English file */ /* copy and compile a page for each enabled language from the English file */
for (let i = 0; i < enabledLanguages.length; i++) { for (let i = 0; i < enabledLanguages.length; i++) {
let language = enabledLanguages[i]; let language = enabledLanguages[i];
/* skip conversion from english file if a file exists for this language */ /* skip conversion from english file if a file exists for this language */
if (language !== 'en' && fs.existsSync(file.replace('/en/', '/' + language + '/'))) { if (
language !== "en" &&
fs.existsSync(file.replace("/en/", "/" + language + "/"))
) {
continue; continue;
} }
translate.setLanguage(language); translate.setLanguage(language);
const str = renderToStaticMarkup(<Site language={language} config={siteConfig}><ReactComp language={language}/></Site>); const str = renderToStaticMarkup(
writeFileAndCreateFolder(targetFile.replace('/en/', '/' + language + '/'), str); <Site language={language} config={siteConfig}>
<ReactComp language={language} />
</Site>
);
writeFileAndCreateFolder(
targetFile.replace("/en/", "/" + language + "/"),
str
);
} }
} else {
} /* allow for rendering of other files not in pages/en folder */
/* allow for rendering of other files not in pages/en folder */ let language = "en";
else {
let language = 'en';
for (let i = 0; i < langParts.length; i++) { for (let i = 0; i < langParts.length; i++) {
if (enabledLanguages.indexOf(langParts[i]) !== -1) { if (enabledLanguages.indexOf(langParts[i]) !== -1) {
language = langParts[i]; language = langParts[i];
} }
} }
translate.setLanguage(language); translate.setLanguage(language);
const str = renderToStaticMarkup(<Site language={language} config={siteConfig}><ReactComp language={language}/></Site>); const str = renderToStaticMarkup(
<Site language={language} config={siteConfig}>
<ReactComp language={language} />
</Site>
);
writeFileAndCreateFolder(targetFile, str); writeFileAndCreateFolder(targetFile, str);
} }
fs.removeSync(tempFile); fs.removeSync(tempFile);
} } else if (!fs.lstatSync(file).isDirectory()) {
else if (!fs.lstatSync(file).isDirectory()) { let parts = file.split("pages");
let parts = file.split('pages'); let targetFile =
let targetFile = __dirname + '/../../build' + '/' + siteConfig.projectName + '/' + parts[1]; __dirname +
mkdirp.sync(targetFile.replace(new RegExp('/[^/]*$'), '')); "/../../build" +
"/" +
siteConfig.projectName +
"/" +
parts[1];
mkdirp.sync(targetFile.replace(new RegExp("/[^/]*$"), ""));
fs.copySync(file, targetFile); fs.copySync(file, targetFile);
} }
}); });
/* copy html files in 'en' to base level as well */ /* copy html files in 'en' to base level as well */
files = glob.sync(__dirname + '/../../build' + '/' + siteConfig.projectName + '/' +'en/**'); files = glob.sync(
__dirname + "/../../build" + "/" + siteConfig.projectName + "/" + "en/**"
);
files.forEach(file => { files.forEach(file => {
let targetFile = file.replace('en/', ''); let targetFile = file.replace("en/", "");
if (file.match(/\.html$/)) { if (file.match(/\.html$/)) {
fs.copySync(file, targetFile); fs.copySync(file, targetFile);
} }

View file

@ -7,22 +7,23 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const CWD = process.cwd(); const CWD = process.cwd();
const Metadata = require('../core/metadata.js'); const Metadata = require("../core/metadata.js");
const fs = require('fs'); const fs = require("fs");
let languages; let languages;
if (fs.existsSync(CWD + '/languages.js')) { if (fs.existsSync(CWD + "/languages.js")) {
languages = require(CWD + '/languages.js'); languages = require(CWD + "/languages.js");
} else { } else {
languages = [{ languages = [
enabled: true, {
name: 'English', enabled: true,
tag: 'en', name: "English",
}]; tag: "en"
}
];
} }
function readCategories(layout) { function readCategories(layout) {
const enabledLanguages = []; const enabledLanguages = [];
languages.filter(lang => lang.enabled).map(lang => { languages.filter(lang => lang.enabled).map(lang => {
enabledLanguages.push(lang.tag); enabledLanguages.push(lang.tag);
@ -34,8 +35,7 @@ function readCategories(layout) {
const language = enabledLanguages[k]; const language = enabledLanguages[k];
const metadatas = Metadata.filter(metadata => { const metadatas = Metadata.filter(metadata => {
return metadata.layout === layout && return metadata.layout === layout && metadata.language === language;
metadata.language === language;
}); });
// Build a hashmap of article_id -> metadata // Build a hashmap of article_id -> metadata
@ -52,7 +52,7 @@ function readCategories(layout) {
if (metadata.next) { if (metadata.next) {
if (!articles[metadata.next]) { if (!articles[metadata.next]) {
throw new Error( throw new Error(
'`next: ' + metadata.next + '` in ' + metadata.id + " doesn't exist" "`next: " + metadata.next + "` in " + metadata.id + " doesn't exist"
); );
} }
previous[articles[metadata.next].id] = metadata.id; previous[articles[metadata.next].id] = metadata.id;
@ -79,7 +79,7 @@ function readCategories(layout) {
currentCategory && categories.push(currentCategory); currentCategory && categories.push(currentCategory);
currentCategory = { currentCategory = {
name: metadata.category, name: metadata.category,
links: [], links: []
}; };
} }
currentCategory.links.push(metadata); currentCategory.links.push(metadata);
@ -91,15 +91,14 @@ function readCategories(layout) {
} }
fs.writeFileSync( fs.writeFileSync(
__dirname + '/../core/' + layout + 'Categories.js', __dirname + "/../core/" + layout + "Categories.js",
'/**\n' + "/**\n" +
' * @generated\n' + " * @generated\n" +
' */\n' + " */\n" +
'module.exports = ' + "module.exports = " +
JSON.stringify(allCategories, null, 2) + JSON.stringify(allCategories, null, 2) +
';' ";"
); );
} }
module.exports = readCategories; module.exports = readCategories;

View file

@ -7,34 +7,36 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
const CWD = process.cwd(); const CWD = process.cwd();
const path = require('path'); const path = require("path");
const fs = require('fs'); const fs = require("fs");
const os = require('os'); const os = require("os");
let languages; let languages;
if (fs.existsSync(CWD + '/languages.js')) { if (fs.existsSync(CWD + "/languages.js")) {
languages = require(CWD + '/languages.js'); languages = require(CWD + "/languages.js");
} else { } else {
languages = [{ languages = [
enabled: true, {
name: 'English', enabled: true,
tag: 'en', name: "English",
}]; tag: "en"
}
];
} }
const glob = require('glob'); const glob = require("glob");
function splitHeader(content) { function splitHeader(content) {
const lines = content.split(os.EOL); const lines = content.split(os.EOL);
let i = 1; let i = 1;
for (; i < lines.length - 1; ++i) { for (; i < lines.length - 1; ++i) {
if (lines[i] === '---') { if (lines[i] === "---") {
break; break;
} }
} }
return { return {
header: lines.slice(1, i + 1).join('\n'), header: lines.slice(1, i + 1).join("\n"),
content: lines.slice(i + 1).join('\n'), content: lines.slice(i + 1).join("\n")
}; };
} }
@ -42,26 +44,26 @@ function splitHeader(content) {
function extractMetadata(content) { function extractMetadata(content) {
const metadata = {}; const metadata = {};
const both = splitHeader(content); const both = splitHeader(content);
const lines = both.header.split('\n'); const lines = both.header.split("\n");
for (let i = 0; i < lines.length - 1; ++i) { for (let i = 0; i < lines.length - 1; ++i) {
const keyvalue = lines[i].split(':'); const keyvalue = lines[i].split(":");
const key = keyvalue[0].trim(); const key = keyvalue[0].trim();
let value = keyvalue.slice(1).join(':').trim(); let value = keyvalue.slice(1).join(":").trim();
// Handle the case where you have "Community #10" // Handle the case where you have "Community #10"
try { try {
value = JSON.parse(value); value = JSON.parse(value);
} catch (e) {} } catch (e) {}
metadata[key] = value; metadata[key] = value;
} }
return {metadata, rawContent: both.content}; return { metadata, rawContent: both.content };
} }
function processMetadata(file) { function processMetadata(file) {
const result = extractMetadata(fs.readFileSync(file, 'utf8')); const result = extractMetadata(fs.readFileSync(file, "utf8"));
const regexSubFolder = /docs\/(.*)\/.*/; const regexSubFolder = /docs\/(.*)\/.*/;
let language = 'en'; let language = "en";
const match = regexSubFolder.exec(file); const match = regexSubFolder.exec(file);
if (match) { if (match) {
language = match[1]; language = match[1];
@ -74,26 +76,25 @@ function processMetadata(file) {
// in permalink replace /en/ language with localized folder // in permalink replace /en/ language with localized folder
metadata.permalink = metadata.permalink.replace( metadata.permalink = metadata.permalink.replace(
/\/en\//g, /\/en\//g,
'/' + language + '/' "/" + language + "/"
); );
// change ids previous, next // change ids previous, next
metadata.localized_id = metadata.id; metadata.localized_id = metadata.id;
metadata.id = language + '-' + metadata.id; metadata.id = language + "-" + metadata.id;
if (metadata.previous) { if (metadata.previous) {
metadata.previous_id = metadata.previous; metadata.previous_id = metadata.previous;
metadata.previous = language + '-' + metadata.previous; metadata.previous = language + "-" + metadata.previous;
} }
if (metadata.next) { if (metadata.next) {
metadata.next_id = metadata.next; metadata.next_id = metadata.next;
metadata.next = language + '-' + metadata.next; metadata.next = language + "-" + metadata.next;
} }
metadata.language = language; metadata.language = language;
return {metadata, rawContent: rawContent}; return { metadata, rawContent: rawContent };
} }
function generateDocsMetadata() { function generateDocsMetadata() {
const regexSubFolder = /docs\/(.*)\/.*/; const regexSubFolder = /docs\/(.*)\/.*/;
const enabledLanguages = []; const enabledLanguages = [];
@ -103,9 +104,9 @@ function generateDocsMetadata() {
const metadatas = []; const metadatas = [];
const files = glob.sync(CWD + '/../docs/**'); const files = glob.sync(CWD + "/../docs/**");
files.forEach(file => { files.forEach(file => {
let language = 'en'; let language = "en";
const match = regexSubFolder.exec(file); const match = regexSubFolder.exec(file);
if (match) { if (match) {
language = match[1]; language = match[1];
@ -117,29 +118,28 @@ function generateDocsMetadata() {
const extension = path.extname(file); const extension = path.extname(file);
if (extension === '.md' || extension === '.markdown') { if (extension === ".md" || extension === ".markdown") {
const res = processMetadata(file); const res = processMetadata(file);
const metadata = res.metadata; const metadata = res.metadata;
metadatas.push(metadata); metadatas.push(metadata);
} }
}); });
fs.writeFileSync( fs.writeFileSync(
__dirname + '/../core/metadata.js', __dirname + "/../core/metadata.js",
'/**\n' + "/**\n" +
' * @generated\n' + " * @generated\n" +
' */\n' + " */\n" +
'module.exports = ' + "module.exports = " +
JSON.stringify(metadatas, null, 2) + JSON.stringify(metadatas, null, 2) +
';' ";"
); );
} }
function generateBlogMetadata() { function generateBlogMetadata() {
const metadatas = []; const metadatas = [];
let files = glob.sync(CWD + '/../blog/**/*.*'); let files = glob.sync(CWD + "/../blog/**/*.*");
files.sort().reverse().forEach(file => { files.sort().reverse().forEach(file => {
// Transform // Transform
// 2015-08-13-blog-post-name-0.5.md // 2015-08-13-blog-post-name-0.5.md
@ -147,17 +147,17 @@ function generateBlogMetadata() {
// 2015/08/13/blog-post-name-0-5.html // 2015/08/13/blog-post-name-0-5.html
const filePath = path const filePath = path
.basename(file) .basename(file)
.replace('-', '/') .replace("-", "/")
.replace('-', '/') .replace("-", "/")
.replace('-', '/') .replace("-", "/")
// react-middleware is broken with files that contains multiple . // react-middleware is broken with files that contains multiple .
// like react-0.14.js // like react-0.14.js
.replace(/\./g, '-') .replace(/\./g, "-")
.replace(/\-md$/, '.html'); .replace(/\-md$/, ".html");
const result = extractMetadata(fs.readFileSync(file, {encoding: 'utf8'})); const result = extractMetadata(fs.readFileSync(file, { encoding: "utf8" }));
const rawContent = result.rawContent; const rawContent = result.rawContent;
const metadata = Object.assign( const metadata = Object.assign(
{path: filePath, content: rawContent}, { path: filePath, content: rawContent },
result.metadata result.metadata
); );
metadata.id = metadata.title; metadata.id = metadata.title;
@ -165,13 +165,13 @@ function generateBlogMetadata() {
}); });
fs.writeFileSync( fs.writeFileSync(
__dirname + '/../core/MetadataBlog.js', __dirname + "/../core/MetadataBlog.js",
'/**\n' + "/**\n" +
' * @generated\n' + " * @generated\n" +
' */\n' + " */\n" +
'module.exports = ' + "module.exports = " +
JSON.stringify(metadatas, null, 2) + JSON.stringify(metadatas, null, 2) +
';' ";"
); );
} }

View file

@ -7,22 +7,22 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
function execute () { function execute() {
const translation = require('./translation.js'); const translation = require("./translation.js");
translation(); translation();
const CWD = process.cwd(); const CWD = process.cwd();
const express = require('express'); const express = require("express");
const React = require('react'); const React = require("react");
const request = require('request'); const request = require("request");
const renderToStaticMarkup = require('react-dom/server').renderToStaticMarkup; const renderToStaticMarkup = require("react-dom/server").renderToStaticMarkup;
const fs = require('fs-extra'); const fs = require("fs-extra");
const os = require('os'); const os = require("os");
const path = require('path'); const path = require("path");
const readMetadata = require('./readMetadata.js'); const readMetadata = require("./readMetadata.js");
const toSlug = require('../core/toSlug.js'); const toSlug = require("../core/toSlug.js");
const mkdirp = require('mkdirp'); const mkdirp = require("mkdirp");
const glob = require('glob'); const glob = require("glob");
let siteConfig = require(CWD + '/siteConfig.js'); let siteConfig = require(CWD + "/siteConfig.js");
/** /**
* Removes a module from the cache * Removes a module from the cache
@ -30,17 +30,17 @@
function purgeCache(moduleName) { function purgeCache(moduleName) {
// Traverse the cache looking for the files // Traverse the cache looking for the files
// loaded by the specified module name // loaded by the specified module name
searchCache(moduleName, function (mod) { searchCache(moduleName, function(mod) {
delete require.cache[mod.id]; delete require.cache[mod.id];
}); });
// Remove cached paths to the module. // Remove cached paths to the module.
Object.keys(module.constructor._pathCache).forEach(function(cacheKey) { Object.keys(module.constructor._pathCache).forEach(function(cacheKey) {
if (cacheKey.indexOf(moduleName)>0) { if (cacheKey.indexOf(moduleName) > 0) {
delete module.constructor._pathCache[cacheKey]; delete module.constructor._pathCache[cacheKey];
} }
}); });
}; }
/** /**
* Traverses the cache to search for all the cached * Traverses the cache to search for all the cached
@ -52,21 +52,21 @@
// Check if the module has been resolved and found within // Check if the module has been resolved and found within
// the cache // the cache
if (mod && ((mod = require.cache[mod]) !== undefined)) { if (mod && (mod = require.cache[mod]) !== undefined) {
// Recursively go over the results // Recursively go over the results
(function traverse(mod) { (function traverse(mod) {
// Go over each of the module's children and // Go over each of the module's children and
// traverse them // traverse them
mod.children.forEach(function (child) { mod.children.forEach(function(child) {
traverse(child); traverse(child);
}); });
// Call the specified callback providing the // Call the specified callback providing the
// found cached module // found cached module
callback(mod); callback(mod);
}(mod)); })(mod);
} }
}; }
/****************************************************************************/ /****************************************************************************/
@ -75,10 +75,10 @@
function reloadMetadataCategories() { function reloadMetadataCategories() {
readMetadata.generateDocsMetadata(); readMetadata.generateDocsMetadata();
purgeCache('../core/metadata.js'); purgeCache("../core/metadata.js");
Metadata = require('../core/metadata.js'); Metadata = require("../core/metadata.js");
purgeCache('./readCategories.js'); purgeCache("./readCategories.js");
readCategories = require('./readCategories.js'); readCategories = require("./readCategories.js");
let layouts = {}; let layouts = {};
for (let i = 0; i < Metadata.length; i++) { for (let i = 0; i < Metadata.length; i++) {
@ -92,7 +92,7 @@
/****************************************************************************/ /****************************************************************************/
const TABLE_OF_CONTENTS_TOKEN = '<AUTOGENERATED_TABLE_OF_CONTENTS>'; const TABLE_OF_CONTENTS_TOKEN = "<AUTOGENERATED_TABLE_OF_CONTENTS>";
const insertTableOfContents = rawContent => { const insertTableOfContents = rawContent => {
const regexp = /\n###\s+(`.*`.*)\n/g; const regexp = /\n###\s+(`.*`.*)\n/g;
@ -104,80 +104,84 @@
const tableOfContents = headers const tableOfContents = headers
.map(header => ` - [${header}](#${toSlug(header)})`) .map(header => ` - [${header}](#${toSlug(header)})`)
.join('\n'); .join("\n");
return rawContent.replace(TABLE_OF_CONTENTS_TOKEN, tableOfContents); return rawContent.replace(TABLE_OF_CONTENTS_TOKEN, tableOfContents);
}; };
/****************************************************************************/ /****************************************************************************/
console.log('server.js triggered...'); console.log("server.js triggered...");
const port = 3000; const port = 3000;
reloadMetadataCategories(); reloadMetadataCategories();
/* handle all requests for document pages */ /* handle all requests for document pages */
const app = express() const app = express().get(/docs\/[\s\S]*html$/, (req, res) => {
.get(/docs\/[\s\S]*html$/, (req, res) => { purgeCache(CWD + "/siteConfig.js");
purgeCache(CWD + '/siteConfig.js'); siteConfig = require(CWD + "/siteConfig.js");
siteConfig = require(CWD + '/siteConfig.js');
console.log(req.path); console.log(req.path);
reloadMetadataCategories(); reloadMetadataCategories();
let links = {}; let links = {};
for (let i = 0; i < Metadata.length; i++) { for (let i = 0; i < Metadata.length; i++) {
const metadata = Metadata[i]; const metadata = Metadata[i];
links[metadata.permalink] = 'docs/' + metadata.language + '/' + metadata.source; links[metadata.permalink] =
} "docs/" + metadata.language + "/" + metadata.source;
let mdToHtml = {}; }
for (let i = 0; i < Metadata.length; i++) { let mdToHtml = {};
const metadata = Metadata[i]; for (let i = 0; i < Metadata.length; i++) {
mdToHtml['/docs/' + metadata.language + '/' + metadata.source] = siteConfig.baseUrl + metadata.permalink; const metadata = Metadata[i];
} mdToHtml["/docs/" + metadata.language + "/" + metadata.source] =
siteConfig.baseUrl + metadata.permalink;
}
let file = links[req.path.toString().replace(siteConfig.baseUrl, '')]; let file = links[req.path.toString().replace(siteConfig.baseUrl, "")];
file = CWD + '/../' + file; file = CWD + "/../" + file;
console.log(file); console.log(file);
const result = readMetadata.processMetadata(file); const result = readMetadata.processMetadata(file);
const metadata = result.metadata; const metadata = result.metadata;
const language = metadata.language; const language = metadata.language;
let rawContent = result.rawContent; let rawContent = result.rawContent;
/* generate table of contents if appropriate */ /* generate table of contents if appropriate */
if (rawContent && rawContent.indexOf(TABLE_OF_CONTENTS_TOKEN) !== -1) { if (rawContent && rawContent.indexOf(TABLE_OF_CONTENTS_TOKEN) !== -1) {
rawContent = insertTableOfContents(rawContent); rawContent = insertTableOfContents(rawContent);
} }
/* replace any links to markdown files to their website html links */ /* replace any links to markdown files to their website html links */
Object.keys(mdToHtml).forEach(function(key, index) { Object.keys(mdToHtml).forEach(function(key, index) {
rawContent = rawContent.replace(new RegExp(key,'g'), mdToHtml[key]); rawContent = rawContent.replace(new RegExp(key, "g"), mdToHtml[key]);
});
purgeCache('../core/DocsLayout.js');
const DocsLayout = require('../core/DocsLayout.js');
const docComp = <DocsLayout metadata={metadata} language={language} config={siteConfig}>{rawContent}</DocsLayout>;
res.send(renderToStaticMarkup(docComp));
}); });
purgeCache("../core/DocsLayout.js");
const DocsLayout = require("../core/DocsLayout.js");
const docComp = (
<DocsLayout metadata={metadata} language={language} config={siteConfig}>
{rawContent}
</DocsLayout>
);
res.send(renderToStaticMarkup(docComp));
});
/* handle all requests for blog pages and posts */ /* handle all requests for blog pages and posts */
app.get(/blog\/[\s\S]*html$/, (req, res) => { app.get(/blog\/[\s\S]*html$/, (req, res) => {
purgeCache(CWD + '/siteConfig.js'); purgeCache(CWD + "/siteConfig.js");
siteConfig = require(CWD + '/siteConfig.js'); siteConfig = require(CWD + "/siteConfig.js");
if (fs.existsSync(__dirname + "../core/MetadataBlog.js")) {
if (fs.existsSync(__dirname + '../core/MetadataBlog.js')) { purgeCache("../core/MetadataBlog.js");
purgeCache('../core/MetadataBlog.js'); fs.removeSync(__dirname + "../core/MetadataBlog.js");
fs.removeSync(__dirname + '../core/MetadataBlog.js')
} }
readMetadata.generateBlogMetadata(); readMetadata.generateBlogMetadata();
MetadataBlog = require('../core/MetadataBlog.js'); MetadataBlog = require("../core/MetadataBlog.js");
/* generate all of the blog pages */ /* generate all of the blog pages */
purgeCache('../core/BlogPageLayout.js'); purgeCache("../core/BlogPageLayout.js");
const BlogPageLayout = require('../core/BlogPageLayout.js'); const BlogPageLayout = require("../core/BlogPageLayout.js");
const blogPages = {}; const blogPages = {};
/* make blog pages with 10 posts per page */ /* make blog pages with 10 posts per page */
const perPage = 10; const perPage = 10;
@ -186,158 +190,208 @@
page < Math.ceil(MetadataBlog.length / perPage); page < Math.ceil(MetadataBlog.length / perPage);
page++ page++
) { ) {
let language = 'en'; let language = "en";
const metadata = {page: page, perPage: perPage}; const metadata = { page: page, perPage: perPage };
const blogPageComp = <BlogPageLayout metadata={metadata} language={language} config={siteConfig} />; const blogPageComp = (
<BlogPageLayout
metadata={metadata}
language={language}
config={siteConfig}
/>
);
const str = renderToStaticMarkup(blogPageComp); const str = renderToStaticMarkup(blogPageComp);
let path = (page > 0 ? 'page' + (page + 1) : '') + '/index.html'; let path = (page > 0 ? "page" + (page + 1) : "") + "/index.html";
blogPages[path] = str; blogPages[path] = str;
} }
let parts = req.path.toString().split('blog/'); let parts = req.path.toString().split("blog/");
// send corresponding blog page if appropriate // send corresponding blog page if appropriate
if (parts[1] === 'index.html') { if (parts[1] === "index.html") {
res.send(blogPages['/index.html']); res.send(blogPages["/index.html"]);
} } else if (parts[1].endsWith("/index.html")) {
else if (parts[1].endsWith('/index.html')) {
res.send(blogPages[parts[1]]); res.send(blogPages[parts[1]]);
} } else if (parts[1].match(/page([0-9]+)/)) {
else if (parts[1].match(/page([0-9]+)/)) { if (parts[1].endsWith("/")) {
if (parts[1].endsWith('/')) { res.send(blogPages[parts[1] + "index.html"]);
res.send(blogPages[parts[1] + 'index.html']);
} else { } else {
res.send(blogPages[parts[1] + '/index.html']); res.send(blogPages[parts[1] + "/index.html"]);
} }
} } else {
// else send corresponding blog post // else send corresponding blog post
else {
let file = parts[1]; let file = parts[1];
file = file.replace(/\.html$/, '.md'); file = file.replace(/\.html$/, ".md");
file = file.replace(new RegExp('/', 'g'), '-'); file = file.replace(new RegExp("/", "g"), "-");
file = CWD + '/../blog/' + file; file = CWD + "/../blog/" + file;
const result = readMetadata.extractMetadata(fs.readFileSync(file, {encoding: 'utf8'})); const result = readMetadata.extractMetadata(
fs.readFileSync(file, { encoding: "utf8" })
);
const rawContent = result.rawContent; const rawContent = result.rawContent;
const metadata = Object.assign( const metadata = Object.assign(
{path: req.path.toString().split('blog/')[1], content: rawContent}, { path: req.path.toString().split("blog/")[1], content: rawContent },
result.metadata result.metadata
); );
metadata.id = metadata.title; metadata.id = metadata.title;
let language = 'en'; let language = "en";
purgeCache('../core/BlogPostLayout.js') purgeCache("../core/BlogPostLayout.js");
const BlogPostLayout = require('../core/BlogPostLayout.js'); const BlogPostLayout = require("../core/BlogPostLayout.js");
const blogPostComp = <BlogPostLayout metadata={metadata} language={language} config={siteConfig}>{rawContent}</BlogPostLayout>; const blogPostComp = (
<BlogPostLayout
metadata={metadata}
language={language}
config={siteConfig}
>
{rawContent}
</BlogPostLayout>
);
res.send(renderToStaticMarkup(blogPostComp)); res.send(renderToStaticMarkup(blogPostComp));
} }
}); });
/* handle all other main pages */ /* handle all other main pages */
app.get('*.html', (req, res) => { app.get("*.html", (req, res) => {
purgeCache(CWD + '/siteConfig.js'); purgeCache(CWD + "/siteConfig.js");
siteConfig = require(CWD + '/siteConfig.js'); siteConfig = require(CWD + "/siteConfig.js");
console.log(req.path); console.log(req.path);
/* look for user provided html file first */ /* look for user provided html file first */
let htmlFile = req.path.toString().replace(siteConfig.baseUrl, ''); let htmlFile = req.path.toString().replace(siteConfig.baseUrl, "");
htmlFile = CWD + '/pages/' + htmlFile; htmlFile = CWD + "/pages/" + htmlFile;
if (fs.existsSync(htmlFile) || if (
fs.existsSync(htmlFile=htmlFile.replace(path.basename(htmlFile), 'en/' + path.basename(htmlFile)))) { fs.existsSync(htmlFile) ||
res.send(fs.readFileSync(htmlFile, {encoding: 'utf8'})); fs.existsSync(
(htmlFile = htmlFile.replace(
path.basename(htmlFile),
"en/" + path.basename(htmlFile)
))
)
) {
res.send(fs.readFileSync(htmlFile, { encoding: "utf8" }));
return; return;
} }
/* look for user provided react file either in specified path or in path for english files */ /* look for user provided react file either in specified path or in path for english files */
let file = req.path.toString().replace(/\.html$/, '.js'); let file = req.path.toString().replace(/\.html$/, ".js");
file = file.replace(siteConfig.baseUrl, ''); file = file.replace(siteConfig.baseUrl, "");
let userFile = CWD + '/pages/' + file; let userFile = CWD + "/pages/" + file;
let language = 'en'; let language = "en";
const regexLang = /(.*)\/.*\.html$/; const regexLang = /(.*)\/.*\.html$/;
const match = regexLang.exec(req.path); const match = regexLang.exec(req.path);
const parts = match[1].split('/'); const parts = match[1].split("/");
const enabledLangTags = []; const enabledLangTags = [];
for (let i = 0; i < siteConfig['languages'].length; i++) { for (let i = 0; i < siteConfig["languages"].length; i++) {
enabledLangTags.push(siteConfig['languages'][i].tag); enabledLangTags.push(siteConfig["languages"][i].tag);
} }
for (let i = 0; i < parts.length; i++) { for (let i = 0; i < parts.length; i++) {
if (enabledLangTags.indexOf(parts[i]) !== -1) { if (enabledLangTags.indexOf(parts[i]) !== -1) {
language = parts[i]; language = parts[i];
} }
} }
if (fs.existsSync(userFile) || if (
fs.existsSync(userFile=userFile.replace(path.basename(userFile), 'en/' + path.basename(userFile)))) { fs.existsSync(userFile) ||
fs.existsSync(
(userFile = userFile.replace(
path.basename(userFile),
"en/" + path.basename(userFile)
))
)
) {
/* copy into docusaurus so require paths work */ /* copy into docusaurus so require paths work */
let parts = userFile.split('pages/'); let parts = userFile.split("pages/");
let tempFile = __dirname + '/../pages/' + parts[1]; let tempFile = __dirname + "/../pages/" + parts[1];
tempFile = tempFile.replace(path.basename(file), 'temp' + path.basename(file)); tempFile = tempFile.replace(
mkdirp.sync(tempFile.replace(new RegExp('/[^/]*$'), '')); path.basename(file),
"temp" + path.basename(file)
);
mkdirp.sync(tempFile.replace(new RegExp("/[^/]*$"), ""));
fs.copySync(userFile, tempFile); fs.copySync(userFile, tempFile);
/* render into a string */ /* render into a string */
purgeCache(tempFile); purgeCache(tempFile);
const ReactComp = require(tempFile); const ReactComp = require(tempFile);
purgeCache('../core/Site.js'); purgeCache("../core/Site.js");
const Site = require('../core/Site.js'); const Site = require("../core/Site.js");
const str = renderToStaticMarkup(<Site language={language} config={siteConfig}><ReactComp language={language}/></Site>); const str = renderToStaticMarkup(
<Site language={language} config={siteConfig}>
<ReactComp language={language} />
</Site>
);
fs.removeSync(tempFile); fs.removeSync(tempFile);
res.send(str); res.send(str);
} } else {
else {
console.log(req.path); console.log(req.path);
res.send('No file found'); res.send("No file found");
} }
}); });
/* generate the main.css file by concatenating user provided css to the end */ /* generate the main.css file by concatenating user provided css to the end */
app.get(/main\.css$/, (req,res) => { app.get(/main\.css$/, (req, res) => {
const mainCssPath = __dirname +'/../static/' + req.path.toString().replace(siteConfig.baseUrl, '/'); const mainCssPath =
let cssContent = fs.readFileSync(mainCssPath, {encoding: 'utf8'}); __dirname +
"/../static/" +
req.path.toString().replace(siteConfig.baseUrl, "/");
let cssContent = fs.readFileSync(mainCssPath, { encoding: "utf8" });
let files = glob.sync(CWD + '/static/**/*.css') let files = glob.sync(CWD + "/static/**/*.css");
files.forEach(file => { files.forEach(file => {
cssContent = cssContent + '\n' + fs.readFileSync(file, {encoding: 'utf8'}); cssContent =
cssContent + "\n" + fs.readFileSync(file, { encoding: "utf8" });
}); });
cssContent = cssContent.toString().replace(new RegExp('{primaryColor}', 'g'), siteConfig.colors.primaryColor); cssContent = cssContent
cssContent = cssContent.replace(new RegExp('{secondaryColor}', 'g'), siteConfig.colors.secondaryColor); .toString()
cssContent = cssContent.replace(new RegExp('{prismColor}', 'g'), siteConfig.colors.prismColor); .replace(
new RegExp("{primaryColor}", "g"),
siteConfig.colors.primaryColor
);
cssContent = cssContent.replace(
new RegExp("{secondaryColor}", "g"),
siteConfig.colors.secondaryColor
);
cssContent = cssContent.replace(
new RegExp("{prismColor}", "g"),
siteConfig.colors.prismColor
);
res.send(cssContent); res.send(cssContent);
}); });
/* serve static content first from user folder then from docusaurus */ /* serve static content first from user folder then from docusaurus */
app.use(siteConfig.baseUrl, express.static(CWD + '/static')); app.use(siteConfig.baseUrl, express.static(CWD + "/static"));
app.use(siteConfig.baseUrl, express.static(__dirname + '/../static')); app.use(siteConfig.baseUrl, express.static(__dirname + "/../static"));
app.get(/\/[^\.]*\/?$/, (req, res) => { app.get(/\/[^\.]*\/?$/, (req, res) => {
if (req.path.toString().endsWith('/')) { if (req.path.toString().endsWith("/")) {
request.get('http://localhost:3000' + req.path + 'index.html', (err, response, body) => { request.get(
if (!err) { "http://localhost:3000" + req.path + "index.html",
res.send(body); (err, response, body) => {
if (!err) {
res.send(body);
}
} }
}); );
} else { } else {
request.get('http://localhost:3000' + req.path + '/index.html', (err, response, body) => { request.get(
if (!err) { "http://localhost:3000" + req.path + "/index.html",
res.send(body); (err, response, body) => {
if (!err) {
res.send(body);
}
} }
}); );
} }
}); });
app.listen(port); app.listen(port);
console.log('listening on port: ' + port); console.log("listening on port: " + port);
} }
module.exports = execute; module.exports = execute;

View file

@ -8,43 +8,43 @@
*/ */
const CWD = process.cwd(); const CWD = process.cwd();
const fs = require('fs-extra'); const fs = require("fs-extra");
const glob = require('glob'); const glob = require("glob");
const path = require('path'); const path = require("path");
const mkdirp = require('mkdirp'); const mkdirp = require("mkdirp");
console.log('translation.js triggered...'); console.log("translation.js triggered...");
function writeFileAndCreateFolder(file, content) { function writeFileAndCreateFolder(file, content) {
mkdirp.sync(file.replace(new RegExp('/[^/]*$'), '')); mkdirp.sync(file.replace(new RegExp("/[^/]*$"), ""));
fs.writeFileSync(file, content); fs.writeFileSync(file, content);
} }
function execute() { function execute() {
if (fs.existsSync(CWD + '/languages.js')) { if (fs.existsSync(CWD + "/languages.js")) {
injectContent(); injectContent();
} else { } else {
console.log('No languages besides English enabled'); console.log("No languages besides English enabled");
} }
} }
function injectContent() { function injectContent() {
const I18N_JSON_DIR = CWD + '/i18n/'; const I18N_JSON_DIR = CWD + "/i18n/";
const files = glob.sync(I18N_JSON_DIR + '**'); const files = glob.sync(I18N_JSON_DIR + "**");
const languages = []; const languages = [];
const langRegex = /\/i18n\/(.*)\.json$/; const langRegex = /\/i18n\/(.*)\.json$/;
files.forEach(file => { files.forEach(file => {
const extension = path.extname(file); const extension = path.extname(file);
if (extension == '.json') { if (extension == ".json") {
const match = langRegex.exec(file); const match = langRegex.exec(file);
const language = match[1]; const language = match[1];
languages.push(language); languages.push(language);
} }
}); });
let injectedContent = ''; let injectedContent = "";
languages.forEach(language => { languages.forEach(language => {
injectedContent += injectedContent +=
"\nsiteConfig['" + "\nsiteConfig['" +
@ -54,18 +54,18 @@ function injectContent() {
".json');"; ".json');";
}); });
let siteConfigFile = fs.readFileSync(CWD + '/siteConfig.js', 'utf8'); let siteConfigFile = fs.readFileSync(CWD + "/siteConfig.js", "utf8");
const injectStart = '/* INJECT LOCALIZED FILES BEGIN */'; const injectStart = "/* INJECT LOCALIZED FILES BEGIN */";
const injectEnd = '/* INJECT LOCALIZED FILES END */'; const injectEnd = "/* INJECT LOCALIZED FILES END */";
siteConfigFile = siteConfigFile =
siteConfigFile.slice( siteConfigFile.slice(
0, 0,
siteConfigFile.indexOf(injectStart) + injectStart.length siteConfigFile.indexOf(injectStart) + injectStart.length
) + ) +
injectedContent + injectedContent +
'\n' + "\n" +
siteConfigFile.slice(siteConfigFile.indexOf(injectEnd)); siteConfigFile.slice(siteConfigFile.indexOf(injectEnd));
fs.writeFileSync(CWD + '/siteConfig.js', siteConfigFile); fs.writeFileSync(CWD + "/siteConfig.js", siteConfigFile);
} }
module.exports = execute; module.exports = execute;

View file

@ -9,10 +9,10 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
require('babel-register') ({ require("babel-register")({
ignore: false, ignore: false,
"presets": ["react"] presets: ["react"]
}); });
const server = require('./server/server.js'); const server = require("./server/server.js");
server(); server();