extend markdown support for lbry urls
This commit is contained in:
parent
d15a85eaaa
commit
723da10dad
3 changed files with 72 additions and 6 deletions
|
@ -1,8 +1,9 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import remark from 'remark';
|
import remark from 'remark';
|
||||||
import reactRenderer from 'remark-react';
|
import remarkLBRY from 'util/remark-lbry';
|
||||||
import remarkEmoji from 'remark-emoji';
|
import remarkEmoji from 'remark-emoji';
|
||||||
|
import reactRenderer from 'remark-react';
|
||||||
import ExternalLink from 'component/externalLink';
|
import ExternalLink from 'component/externalLink';
|
||||||
import defaultSchema from 'hast-util-sanitize/lib/github.json';
|
import defaultSchema from 'hast-util-sanitize/lib/github.json';
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ const SimpleLink = (props: SimpleLinkProps) => {
|
||||||
const schema = { ...defaultSchema };
|
const schema = { ...defaultSchema };
|
||||||
|
|
||||||
// Extend sanitation schema to support lbry protocol
|
// Extend sanitation schema to support lbry protocol
|
||||||
schema.protocols.href[3] = 'lbry';
|
schema.protocols.href.push('lbry');
|
||||||
|
|
||||||
const MarkdownPreview = (props: MarkdownProps) => {
|
const MarkdownPreview = (props: MarkdownProps) => {
|
||||||
const { content, promptLinks } = props;
|
const { content, promptLinks } = props;
|
||||||
|
@ -44,6 +45,7 @@ const MarkdownPreview = (props: MarkdownProps) => {
|
||||||
<div className="markdown-preview">
|
<div className="markdown-preview">
|
||||||
{
|
{
|
||||||
remark()
|
remark()
|
||||||
|
.use(remarkLBRY)
|
||||||
.use(remarkEmoji)
|
.use(remarkEmoji)
|
||||||
.use(reactRenderer, remarkOptions)
|
.use(reactRenderer, remarkOptions)
|
||||||
.processSync(content).contents
|
.processSync(content).contents
|
||||||
|
|
|
@ -20,14 +20,11 @@ class ExternalLink extends React.PureComponent<Props> {
|
||||||
|
|
||||||
createLink() {
|
createLink() {
|
||||||
const { href, title, children, openModal } = this.props;
|
const { href, title, children, openModal } = this.props;
|
||||||
|
|
||||||
// Regex for url protocol
|
// Regex for url protocol
|
||||||
const protocolRegex = new RegExp('^(https?|lbry)+:', 'i');
|
const protocolRegex = new RegExp('^(https?|lbry)+:', 'i');
|
||||||
const protocol = href ? protocolRegex.exec(href) : null;
|
const protocol = href ? protocolRegex.exec(href) : null;
|
||||||
|
|
||||||
// Return plain text if no valid url
|
// Return plain text if no valid url
|
||||||
let element = <span>{children}</span>;
|
let element = <span>{children}</span>;
|
||||||
|
|
||||||
// Return external link if protocol is http or https
|
// Return external link if protocol is http or https
|
||||||
if (protocol && (protocol[0] === 'http:' || protocol[0] === 'https:')) {
|
if (protocol && (protocol[0] === 'http:' || protocol[0] === 'https:')) {
|
||||||
element = (
|
element = (
|
||||||
|
@ -41,7 +38,6 @@ class ExternalLink extends React.PureComponent<Props> {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return local link if protocol is lbry uri
|
// Return local link if protocol is lbry uri
|
||||||
if (protocol && protocol[0] === 'lbry:' && isURIValid(href)) {
|
if (protocol && protocol[0] === 'lbry:' && isURIValid(href)) {
|
||||||
element = <Button button="link" title={title || href} label={children} navigate={href} />;
|
element = <Button button="link" title={title || href} label={children} navigate={href} />;
|
||||||
|
|
68
src/ui/util/remark-lbry.js
Normal file
68
src/ui/util/remark-lbry.js
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import { parseURI } from 'lbry-redux';
|
||||||
|
|
||||||
|
const protocol = 'lbry://';
|
||||||
|
const locateURI = (value, fromIndex) => value.indexOf(protocol, fromIndex);
|
||||||
|
const locateMention = (value, fromIndex) => value.indexOf('@', fromIndex);
|
||||||
|
|
||||||
|
// Generate a valid markdown link
|
||||||
|
const createURI = (text, uri, addProtocol = true) => ({
|
||||||
|
type: 'link',
|
||||||
|
url: (addProtocol ? protocol : '') + uri,
|
||||||
|
children: [{ type: 'text', value: text }],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Generate a markdown link from channel name
|
||||||
|
function tokenizeMention(eat, value, silent) {
|
||||||
|
const match = /^@(\w+)/.exec(value);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
const text = match[0];
|
||||||
|
const href = match[0];
|
||||||
|
return silent ? true : eat(text)(createURI(text, href));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a markdown link from lbry url
|
||||||
|
function tokenizeURI(eat, value, silent) {
|
||||||
|
const match = /^(lbry:\/\/)+([A-z0-9-_#@])+/.exec(value);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
try {
|
||||||
|
const text = match[0];
|
||||||
|
const uri = parseURI(text, true);
|
||||||
|
// Create channel link
|
||||||
|
if (uri.isChannel) {
|
||||||
|
return eat(text)(createURI(uri.claimName, uri.claimName));
|
||||||
|
}
|
||||||
|
// Create uri link
|
||||||
|
return eat(text)(createURI(text, text, false));
|
||||||
|
} catch (err) {
|
||||||
|
// Silent errors: console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure tokenizer for lbry urls
|
||||||
|
tokenizeURI.locator = locateURI;
|
||||||
|
tokenizeURI.notInLink = true;
|
||||||
|
tokenizeURI.notInBlock = true;
|
||||||
|
|
||||||
|
// Configure tokenizer for lbry channels
|
||||||
|
tokenizeMention.locator = locateMention;
|
||||||
|
tokenizeMention.notInLink = true;
|
||||||
|
tokenizeMention.notInBlock = true;
|
||||||
|
|
||||||
|
// Main module
|
||||||
|
export default function remarkLBRY() {
|
||||||
|
const Parser = this.Parser;
|
||||||
|
const tokenizers = Parser.prototype.inlineTokenizers;
|
||||||
|
const methods = Parser.prototype.inlineMethods;
|
||||||
|
|
||||||
|
// Add an inline tokenizer (defined in the following example).
|
||||||
|
tokenizers.uri = tokenizeURI;
|
||||||
|
tokenizers.mention = tokenizeMention;
|
||||||
|
|
||||||
|
// Run it just before `text`.
|
||||||
|
methods.splice(methods.indexOf('text'), 0, 'uri');
|
||||||
|
methods.splice(methods.indexOf('text'), 0, 'mention');
|
||||||
|
}
|
Loading…
Reference in a new issue