convert markdown logic to re-usable component
This commit is contained in:
parent
2831790f61
commit
f88bbc6d72
5 changed files with 114 additions and 107 deletions
|
@ -1,6 +1,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
import markdown from "../markdown";
|
||||||
|
|
||||||
// E X P O R T
|
// E X P O R T
|
||||||
|
|
||||||
|
@ -20,23 +20,7 @@ module.exports = exports = () => `
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div class="ecosystem__module__details">
|
<div class="ecosystem__module__details">
|
||||||
<p><em>This section assumes "blockchain" already means something to you. If you're totally new, the key problem solved by blockhain is the ability for distributed, disparate entities to all agree on a rivalrous state of affairs. For a more comprehensive introduction to blockchain, try starting [here]</em></p>
|
${markdown("./documents/partials/lbrycrd.md")}
|
||||||
|
|
||||||
<p>LBRY uses a public, proof-of-work blockchain that is very similar to Bitcoin. The blockchain is the foundation of the protocol stack.</p>
|
|
||||||
|
|
||||||
<p>The most salient feature of the LBRY blockchain is the association of a string of characters (a "name") with a structured set of metadata. This name can be accessed as a LBRY URL, e.g. <a class="__plain" href="/playground?url=hellolbry"><code>lbry://hellolbry</code></a></p>
|
|
||||||
|
|
||||||
<p>The LBRY blockchain stores names and metadata in a Merkle tree. This allows LBRY URLs to be trustfully resolved even without a full copy of the blockchain.</p>
|
|
||||||
|
|
||||||
<p>The metadata contains information about the content, such as the title, creator, price (if any), and a unique signature allowing the actual content to be fetched from the data network, the next level in the LBRY stack.</p>
|
|
||||||
|
|
||||||
<h3>Additional Resources</h3>
|
|
||||||
<ul>
|
|
||||||
<li>See the <a href="/whitepaper" title="Whitepaper">Whitepaper</a> for a more comprehensive introduction to the LBRY blockchain.</li>
|
|
||||||
<li>See the <a href="/resources" title="">Resources</a> for documentation about the LBRY blockchain, including its API.</li>
|
|
||||||
<li>See [[Naming]] for learning more about LBRY URLs and how they work.</li>
|
|
||||||
<li>See [[Identities]] for learning how the LBRY blockchain handles publisher identities.</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
82
app/components/markdown.js
Normal file
82
app/components/markdown.js
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import decamelize from "decamelize";
|
||||||
|
import exists from "fs-exists-sync";
|
||||||
|
import fs from "graceful-fs";
|
||||||
|
import fm from "front-matter";
|
||||||
|
import html from "choo/html";
|
||||||
|
import path from "path";
|
||||||
|
import raw from "choo/html/raw";
|
||||||
|
import { require as local } from "app-root-path";
|
||||||
|
|
||||||
|
const numberRegex = /^[0-9]/g;
|
||||||
|
const md = require("markdown-it")({
|
||||||
|
html: true,
|
||||||
|
typographer: true
|
||||||
|
}).use(local("app/modules/markdown-it-sup"))
|
||||||
|
.use(require("markdown-it-anchor"), {
|
||||||
|
slugify: stringToSlugify => {
|
||||||
|
let finalString = stringToSlugify
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/\s\/\s/g, "-")
|
||||||
|
.replace(/\s/g, "-")
|
||||||
|
.replace(/%/g, "")
|
||||||
|
.replace(/\(/g, "")
|
||||||
|
.replace(/\)/g, "")
|
||||||
|
.replace(/,/g, "");
|
||||||
|
|
||||||
|
if (finalString.match(numberRegex)) finalString = `_${finalString}`;
|
||||||
|
return finalString;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default path => {
|
||||||
|
|
||||||
|
const markdownFile = fs.readFileSync(path, "utf-8");
|
||||||
|
const markdownFileDetails = fm(markdownFile);
|
||||||
|
const renderedMarkdown = md.render(markdownFileDetails.body);
|
||||||
|
const updatedMarkdown = wikiFinder(partialFinder(renderedMarkdown));
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="page__markup">${raw(updatedMarkdown)}</div>
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
|
||||||
|
function partialFinder(markdownBody) {
|
||||||
|
const regexToFindPartials = /<\w+ ?\/>/g;
|
||||||
|
const partials = markdownBody.match(regexToFindPartials);
|
||||||
|
|
||||||
|
if (!partials) return markdownBody;
|
||||||
|
|
||||||
|
for (const partial of partials) {
|
||||||
|
const filename = decamelize(partial, "-").replace("<", "")
|
||||||
|
.replace("/>", "")
|
||||||
|
.trim();
|
||||||
|
const fileExistsTest = exists(`./app/components/${filename}.js`); // `local` results in error if used here and file !exist
|
||||||
|
|
||||||
|
if (!fileExistsTest)
|
||||||
|
markdownBody = markdownBody.replace(partial, "");
|
||||||
|
|
||||||
|
else {
|
||||||
|
const partialFunction = require(path.join(__dirname, "..", `./components/${filename}.js`));
|
||||||
|
|
||||||
|
if (filename === "glossary-toc") markdownBody = markdownBody.replace(partial, partialFunction);
|
||||||
|
else markdownBody = markdownBody.replace(partial, `</div>${partialFunction.default()}<div class="page__markup">`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return markdownBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wikiFinder(markdownBody) {
|
||||||
|
return markdownBody.replace(/\[\[([\w\s/-]+)\]\]/g, (match, p1) => {
|
||||||
|
const label = p1.trim();
|
||||||
|
const url = encodeURI("/glossary#" + label.replace(/\s+/g, "-"));
|
||||||
|
|
||||||
|
return label ?
|
||||||
|
`<a href="${url}" class="link--glossary">${label}</a>` :
|
||||||
|
match.input;
|
||||||
|
});
|
||||||
|
}
|
|
@ -184,7 +184,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a:not(.__button-black):not(.button):not(.header-anchor):not(.newsletter-standalone__submit):not(.__plain) {
|
a:not(.__button-black):not(.button) {
|
||||||
@include underline($teal, $white);
|
@include underline($teal, $white);
|
||||||
color: $teal;
|
color: $teal;
|
||||||
|
|
||||||
|
|
|
@ -1,60 +1,24 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// P A C K A G E S
|
|
||||||
|
|
||||||
import decamelize from "decamelize";
|
|
||||||
import exists from "fs-exists-sync";
|
|
||||||
import fm from "front-matter";
|
|
||||||
import fs from "graceful-fs";
|
import fs from "graceful-fs";
|
||||||
import html from "choo/html";
|
import html from "choo/html";
|
||||||
import path from "path";
|
import fm from "front-matter";
|
||||||
import { require as local } from "app-root-path";
|
import { require as local } from "app-root-path";
|
||||||
|
import markdown from "../components/markdown";
|
||||||
import raw from "choo/html/raw";
|
import raw from "choo/html/raw";
|
||||||
|
|
||||||
// V A R I A B L E S
|
|
||||||
|
|
||||||
const numberRegex = /^[0-9]/g;
|
|
||||||
const redirect404 = local("app/modules/redirect-404");
|
const redirect404 = local("app/modules/redirect-404");
|
||||||
|
|
||||||
const md = require("markdown-it")({
|
|
||||||
html: true,
|
|
||||||
typographer: true
|
|
||||||
}).use(local("app/modules/markdown-it-sup"))
|
|
||||||
.use(require("markdown-it-anchor"), {
|
|
||||||
slugify: stringToSlugify => {
|
|
||||||
let finalString = stringToSlugify
|
|
||||||
.toLowerCase()
|
|
||||||
.replace(/\s\/\s/g, "-")
|
|
||||||
.replace(/\s/g, "-")
|
|
||||||
.replace(/%/g, "")
|
|
||||||
.replace(/\(/g, "")
|
|
||||||
.replace(/\)/g, "")
|
|
||||||
.replace(/,/g, "");
|
|
||||||
|
|
||||||
if (finalString.match(numberRegex)) finalString = `_${finalString}`;
|
|
||||||
return finalString;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// E X P O R T
|
|
||||||
|
|
||||||
module.exports = exports = (state, emit) => { // eslint-disable-line
|
module.exports = exports = (state, emit) => { // eslint-disable-line
|
||||||
let path;
|
const partialPath = state.route === "resources/*" ? `resources/${state.params.wildcard}` : state.params.wildcard;
|
||||||
|
const path = `./documents/${partialPath}.md`;
|
||||||
|
|
||||||
if (state.route === "resources/*") path = `resources/${state.params.wildcard}`;
|
if (!fs.existsSync(path)) {
|
||||||
else path = state.params.wildcard;
|
|
||||||
|
|
||||||
if (!fs.existsSync(`./documents/${path}.md`))
|
|
||||||
return redirect404(state);
|
return redirect404(state);
|
||||||
|
}
|
||||||
|
|
||||||
const markdownFile = fs.readFileSync(`./documents/${path}.md`, "utf-8");
|
const markdownFile = fs.readFileSync(path, "utf-8");
|
||||||
const markdownFileDetails = fm(markdownFile);
|
const markdownFileDetails = fm(markdownFile);
|
||||||
const renderedMarkdown = md.render(markdownFileDetails.body);
|
|
||||||
const updatedMarkdown = wikiFinder(partialFinder(renderedMarkdown));
|
|
||||||
|
|
||||||
if (markdownFileDetails.attributes.meta) {
|
if (markdownFileDetails.attributes.meta) {
|
||||||
const customMetadata = {};
|
const customMetadata = {};
|
||||||
|
@ -66,14 +30,16 @@ module.exports = exports = (state, emit) => { // eslint-disable-line
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// below seems evil
|
||||||
state.lbry = customMetadata;
|
state.lbry = customMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// below should be refactored into components
|
||||||
let pageScript = "";
|
let pageScript = "";
|
||||||
|
|
||||||
if (path === "glossary") pageScript = "<script>" + fs.readFileSync("./app/components/client/glossary-scripts.js", "utf-8") + "</script>";
|
if (partialPath === "glossary") pageScript = "<script>" + fs.readFileSync("./app/components/client/glossary-scripts.js", "utf-8") + "</script>";
|
||||||
if (path === "overview") pageScript = "<script>" + fs.readFileSync("./app/components/client/ecosystem-scripts.js", "utf-8") + "</script>";
|
if (partialPath === "overview") pageScript = "<script>" + fs.readFileSync("./app/components/client/ecosystem-scripts.js", "utf-8") + "</script>";
|
||||||
if (path === "playground") pageScript = "<script>" + fs.readFileSync("./app/components/client/playground-scripts.js", "utf-8") + "</script>";
|
if (partialPath === "playground") pageScript = "<script>" + fs.readFileSync("./app/components/client/playground-scripts.js", "utf-8") + "</script>";
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<article class="page" itemtype="http://schema.org/BlogPosting">
|
<article class="page" itemtype="http://schema.org/BlogPosting">
|
||||||
|
@ -87,51 +53,10 @@ module.exports = exports = (state, emit) => { // eslint-disable-line
|
||||||
|
|
||||||
<section class="page__content" itemprop="articleBody">
|
<section class="page__content" itemprop="articleBody">
|
||||||
<div class="inner-wrap">
|
<div class="inner-wrap">
|
||||||
<div class="page__markup">${raw(updatedMarkdown)}</div>
|
${markdown(path)}
|
||||||
${raw(pageScript)}
|
${raw(pageScript)}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</article>
|
</article>
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// H E L P E R S
|
|
||||||
|
|
||||||
function partialFinder(markdownBody) {
|
|
||||||
const regexToFindPartials = /<\w+ ?\/>/g;
|
|
||||||
const partials = markdownBody.match(regexToFindPartials);
|
|
||||||
|
|
||||||
if (!partials) return markdownBody;
|
|
||||||
|
|
||||||
for (const partial of partials) {
|
|
||||||
const filename = decamelize(partial, "-").replace("<", "")
|
|
||||||
.replace("/>", "")
|
|
||||||
.trim();
|
|
||||||
const fileExistsTest = exists(`./app/components/${filename}.js`); // `local` results in error if used here and file !exist
|
|
||||||
|
|
||||||
if (!fileExistsTest)
|
|
||||||
markdownBody = markdownBody.replace(partial, "");
|
|
||||||
|
|
||||||
else {
|
|
||||||
const partialFunction = require(path.join(__dirname, "..", `./components/${filename}.js`));
|
|
||||||
|
|
||||||
if (filename === "glossary-toc") markdownBody = markdownBody.replace(partial, partialFunction);
|
|
||||||
else markdownBody = markdownBody.replace(partial, `</div>${partialFunction.default()}<div class="page__markup">`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return markdownBody;
|
|
||||||
}
|
|
||||||
|
|
||||||
function wikiFinder(markdownBody) {
|
|
||||||
return markdownBody.replace(/\[\[([\w\s/-]+)\]\]/g, (match, p1) => {
|
|
||||||
const label = p1.trim();
|
|
||||||
const url = encodeURI("/glossary#" + label.replace(/\s+/g, "-"));
|
|
||||||
|
|
||||||
return label ?
|
|
||||||
`<a href="${url}" class="link--glossary">${label}</a>` :
|
|
||||||
match.input;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
16
documents/partials/lbrycrd.md
Normal file
16
documents/partials/lbrycrd.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
_This section assumes "blockchain" already means something to you. If you're totally new, the key problem solved by blockhain is the ability for distributed, disparate entities to all agree on a rivalrous state of affairs. For a more comprehensive introduction to blockchain, try starting [here](https://lopp.net/bitcoin.html)_
|
||||||
|
|
||||||
|
LBRY uses a public, proof-of-work blockchain that is very similar to Bitcoin. The blockchain is the foundation of the protocol stack.
|
||||||
|
|
||||||
|
The most salient feature of the LBRY blockchain is the association of a normalized string of characters (a "name") with a structured set of metadata. This coupling is called a [[claim]]. The content referenced by a claim can be accessed as a LBRY URL, e.g. [lbry://hellolbry](/playground?url=hellolbry).
|
||||||
|
|
||||||
|
The LBRY blockchain stores names and metadata in a parallel [[Merkle tree]], separate from the tree used to store transaction data. This allows LBRY URLs to be trustfully resolved even without a full copy of the blockchain.
|
||||||
|
|
||||||
|
The metadata contains information about the content, such as the title, creator, price (if any), and a unique signature allowing the actual content to be fetched from the data network, the next level in the LBRY stack.
|
||||||
|
|
||||||
|
### Additional Resources
|
||||||
|
|
||||||
|
* See the [Whitepaper](/whitepaper "Whitepaper") for a more comprehensive introduction to the LBRY blockchain.
|
||||||
|
* See the [Resources](/resources) for documentation about the LBRY blockchain, including its API.
|
||||||
|
* See [[Naming]] for learning more about LBRY URLs and how they work.
|
||||||
|
* See [[Identities]] for learning how the LBRY blockchain handles publisher identities.
|
Loading…
Reference in a new issue