Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
coverage
node_modules

.env
.idea/
.vscode/
*.code-*
Expand Down
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
-include .env

.DEFAULT_GOAL := help
.PHONY: help
.EXPORT_ALL_VARIABLES:
Expand All @@ -14,6 +16,17 @@ example/public/img/emojis: node_modules/@readme/emojis
mkdir -p example/public/img/emojis
cp node_modules/@readme/emojis/src/img/*.png example/public/img/emojis/

mdx:
npm run build && \
cp -R dist/* ${README_PATH}/node_modules/@readme/mdx/dist && \
cd ${README_PATH} && \
npm run build --workspace=@readme/react && \
npm run build --workspace=@readme/bundles && \
npm run ui:build && \
echo "${NODE_ENV}" > public/data/build-env && \
npx ts-node ./bin/print-webpack-config.ts > ./build-time-webpack-config.json && \
npm run ui

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hee hee

ifeq ($(USE_LEGACY), true)
dockerfile = -f Dockerfile.legacy
endif
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions __tests__/compilers/images.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,10 @@ describe('image compiler', () => {

expect(mdx(mdast(txt))).toMatch(txt);
});

it('correctly serializes an Image component back to MDX', () => {
const doc = '<Image src="/path/to/image.png" width="200px" alt="alt text" />';

expect(mdx(mdast(doc))).toMatch(doc);
});
});
28 changes: 14 additions & 14 deletions __tests__/components/Image.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ describe('Image', () => {
/>
);

expect(screen.getByRole('figure')).toMatchInlineSnapshot(`
<figure>
expect(screen.getByRole('button')).toMatchInlineSnapshot(`
<span
aria-label=""
class="img lightbox closed"
role="button"
tabindex="0"
>
<span
aria-label=""
class="img lightbox closed"
role="button"
tabindex="0"
class="lightbox-inner"
>
<span
class="lightbox-inner"
>
<figure>
<img
alt=""
class="img img-align-center "
Expand All @@ -50,12 +50,12 @@ describe('Image', () => {
title=""
width="auto"
/>
</span>
<figcaption>
A pizza bro
</figcaption>
</figure>
</span>
<figcaption>
A pizza bro
</figcaption>
</figure>
</span>
`);
});
});
2 changes: 1 addition & 1 deletion __tests__/components/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ exports[`Components > Embed 2`] = `"<iframe height="550" src="https://consent-ma

exports[`Components > Embed 3`] = `"<div class="embed embed_hasImg"><a class="embed-link" href="https://www.nytimes.com/2020/05/03/us/politics/george-w-bush-coronavirus-unity.html" rel="noopener noreferrer" target="_blank"><img alt="George W. Bush Calls for End to Pandemic Partisanship" class="embed-img" loading="lazy" src="https://static01.nyt.com/images/2020/05/02/world/02dc-virus-bush-2/merlin_171999921_e857a690-fb9b-462d-a20c-28c8161107c9-facebookJumbo.jpg"><div class="embed-body"><img alt="nytimes.com" height="14" src="https://www.nytimes.com/vi-assets/static-assets/favicon-4bf96cb6a1093748bf5b3c429accb9b4.ico" width="14"><small class="embed-provider">nytimes.com</small><div class="embed-title">George W. Bush Calls for End to Pandemic Partisanship</div></div></a></div>"`;

exports[`Components > Embed 4`] = `"<p><a href="https://www.nytimes.com/2020/05/03/us/politics/george-w-bush-coronavirus-unity.html" title="@embed">rdmd</a></p>"`;
exports[`Components > Embed 4`] = `"<div class="embed "><a class="embed-link" href="https://www.nytimes.com/2020/05/03/us/politics/george-w-bush-coronavirus-unity.html" rel="noopener noreferrer" target="_blank"><div class="embed-body"><small class="embed-provider">nytimes.com</small><div class="embed-title">rdmd</div></div></a></div>"`;

exports[`Components > Image 1`] = `"<p><span aria-label="Bro eats pizza and makes an OK gesture." class="img lightbox closed" role="button" tabindex="0"><span class="lightbox-inner"><img src="https://files.readme.io/6f52e22-man-eating-pizza-and-making-an-ok-gesture.jpg" width="auto" height="auto" title="Pizza Face" class="img img-align- " alt="Bro eats pizza and makes an OK gesture." loading="eager"></span></span></p>"`;
2 changes: 1 addition & 1 deletion __tests__/html-block-parser.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { mdast } from '../index';

describe.skip('Parse html block', () => {
describe('Parse html block', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

it('parses an html block', () => {
const text = `
<div>Some block html</div>
Expand Down
12 changes: 2 additions & 10 deletions __tests__/transformers/readme-components.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe('Readme Components Transformer', () => {
{ md: '<Callout />', type: 'rdme-callout' },
{ md: '<Code />', type: 'code' },
{ md: '<CodeTabs />', type: 'code-tabs' },
{ md: '<Image />', type: 'image' },
{ md: '<Image />', type: 'image-block' },
{ md: '<Table />', type: 'table' },
{ md: '<TutorialTile />', type: 'tutorial-tile' },
];
Expand Down Expand Up @@ -50,7 +50,7 @@ Second
},
image: {
md: `![](http://placekitten.com/600/200)`,
mdx: `<Image url="http://placekitten.com/600/200" />`,
mdx: `<Image src="http://placekitten.com/600/200" />`,
},
table: {
md: `
Expand All @@ -76,14 +76,6 @@ Second
let mdTree = mdast(md);
const mdxTree = mdast(mdx);

if (type === 'image') {
// @todo something about these dang paragraphs!
mdTree = {
type: 'root',
children: mdTree.children[0].children,
};
}

expect(mdxTree).toStrictEqualExceptPosition(mdTree);
});

Expand Down
36 changes: 27 additions & 9 deletions components/Embed/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,42 @@ interface EmbedProps {
lazy?: boolean;
url: string;
title: string;
provider?: string;
providerName?: string;
providerUrl?: string;
html?: string;
iframe?: boolean;
image?: string;
favicon?: string;
typeOfEmbed?: string;
}

const Embed = ({ lazy = true, url, provider, title, html, iframe, image, favicon, ...attrs }: EmbedProps) => {
const Embed = ({
lazy = true,
url,
html,
providerName,
providerUrl,
title,
iframe,
image,
favicon,
...attrs
}: EmbedProps) => {
if (typeof iframe !== 'boolean') iframe = iframe === 'true';
if (html === 'false') html = undefined;

if (iframe) {
return <iframe {...attrs} src={url} style={{ border: 'none', display: 'flex', margin: 'auto' }} />;
}

if (!provider)
provider = new URL(url).hostname
if (!providerUrl && url)
providerUrl = new URL(url).hostname
.split(/(?:www)?\./)
.filter(i => i)
.join('.');

if (!providerName) providerName = providerUrl;

const classes = ['embed', image ? 'embed_hasImg' : ''];

return (
Expand All @@ -40,13 +58,13 @@ const Embed = ({ lazy = true, url, provider, title, html, iframe, image, favicon
) : (
<a className="embed-link" href={url} rel="noopener noreferrer" target="_blank">
{!image || <img alt={title} className="embed-img" loading={lazy ? 'lazy' : undefined} src={image} />}
{title ? (
{title && title !== '@embed' ? (
<div className="embed-body">
{!favicon || <Favicon alt={provider} src={favicon} />}
{provider && (
{!favicon || <Favicon alt={providerName} src={favicon} />}
{providerUrl && (
<small className="embed-provider">
{provider.search(/^@{1}/) < 0 ? (
provider
{providerUrl.search(/^@{1}/) < 0 ? (
providerName
) : (
<code style={{ fontFamily: 'var(--md-code-font, monospace)' }}>{url}</code>
)}
Expand Down
66 changes: 34 additions & 32 deletions components/Image/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ const Image = (Props: ImageProps) => {

if (caption) {
return (
<figure>
<span
aria-label={alt}
className={`img lightbox ${lightbox ? 'open' : 'closed'}`}
onClick={toggle}
onKeyDown={handleKeyDown}
role={'button'}
tabIndex={0}
>
<span className="lightbox-inner">
<span
aria-label={alt}
className={`img lightbox ${lightbox ? 'open' : 'closed'}`}
onClick={toggle}
onKeyDown={handleKeyDown}
role={'button'}
tabIndex={0}
>
<span className="lightbox-inner">
<figure>
<img
src={src}
width={width}
Expand All @@ -76,34 +76,36 @@ const Image = (Props: ImageProps) => {
alt={alt}
loading={lazy ? 'lazy' : 'eager'}
/>
</span>
<figcaption>{caption}</figcaption>
</figure>
</span>
<figcaption>{caption}</figcaption>
</figure>
</span>
);
}

return (
<span
aria-label={alt}
className={`img lightbox ${lightbox ? 'open' : 'closed'}`}
onClick={toggle}
onKeyDown={handleKeyDown}
role={'button'}
tabIndex={0}
>
<span className="lightbox-inner">
<img
src={src}
width={width}
height={height}
title={title}
className={`img img-align-${align} ${border ? 'border' : ''}`}
alt={alt}
loading={lazy ? 'lazy' : 'eager'}
/>
<p>
<span
aria-label={alt}
className={`img lightbox ${lightbox ? 'open' : 'closed'}`}
onClick={toggle}
onKeyDown={handleKeyDown}
role={'button'}
tabIndex={0}
>
<span className="lightbox-inner">
<img
src={src}
width={width}
height={height}
title={title}
className={`img img-align-${align} ${border ? 'border' : ''}`}
alt={alt}
loading={lazy ? 'lazy' : 'eager'}
/>
</span>
</span>
</span>
</p>
);
};

Expand Down
4 changes: 2 additions & 2 deletions enums.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export enum NodeTypes {
callout = 'rdme-callout',
codeTabs = 'code-tabs',
embed = 'embed',
embedBlock = 'embed-block',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a regular embed block still?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh, no. i changed the structure enough that the serializing/deserializing was getting to be spaghetti with the current/old embed block, so i just moved it all wholesale to a new block/block type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it also allows me more freedom to dial in the new image and embed blocks, haha

emoji = 'gemoji',
glossary = 'readme-glossary-item',
htmlBlock = 'html-block',
i = 'i',
image = 'image',
imageBlock = 'image-block',
reusableContent = 'reusable-content',
tutorialTile = 'tutorial-tile',
variable = 'readme-variable',
Expand Down
2 changes: 0 additions & 2 deletions lib/run.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ const makeUseMDXComponents = (more: ReturnType<UseMdxComponents> = {}): UseMdxCo
...Components,
Variable,
code: Components.Code,
'code-tabs': Components.CodeTabs,
'html-block': Components.HTMLBlock,
embed: Components.Embed,
img: Components.Image,
table: Components.Table,
Expand Down
19 changes: 9 additions & 10 deletions processor/compile/embed.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import type { Embed } from "types";
import { formatHProps, getHProps } from "../utils";
import type { EmbedBlock } from "types";

const embed = (node: Embed) => {
const { image, favicon, iframe, title, url } = node.data?.hProperties || {};
const complexEmbed: boolean = Boolean(image) || Boolean(favicon) || iframe;
const embed = (node: EmbedBlock) => {
const attributes = formatHProps<EmbedBlock['data']['hProperties']>(node)
const props = getHProps<EmbedBlock['data']['hProperties']>(node);

if (complexEmbed) {
const attributes = Object.keys(node.data?.hProperties).map(key => `${key}="${node.data?.hProperties[key]}"`).join(' ')
// TODO: make this a util
return `<Embed ${attributes} />`;
}
if (node.title !== '@embed') {
return `<Embed ${attributes} />`
};

return `[${title}](${url} "@embed")'`;
return `[${node.label || ''}](${props.url} "${node.title}")`
}

export default embed;
27 changes: 15 additions & 12 deletions processor/compile/image.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import type { Image } from 'mdast';
import type { ImageBlock } from 'types';
import { formatHProps, getHPropKeys, getHProps } from '../utils';

const image = (node: Image) => {
const { align, className, width } = node.data?.hProperties || {};
const complexImage: boolean = Boolean(width) || Boolean(className) || Boolean(align);
const image = (node: ImageBlock) => {
const attributes = formatHProps<ImageBlock['data']['hProperties']>(node);
const hProps = getHProps<ImageBlock['data']['hProperties']>(node);
const hPropKeys = getHPropKeys<string[]>(node);

const ImageBlock = `<Image ${attributes} />`;
const MDImage = `![${node.alt ?? ''}](${hProps.src ? hProps.src : node.url}${node.title ? ` "${node.title}")` : ')'}`;

if (complexImage) {
const attributes = Object.keys(node.data?.hProperties)
.map(key => `${key}="${node.data?.hProperties[key]}"`)
.join(' ');
return `<Image ${attributes} />`;
if (Boolean(attributes)) {
if (hPropKeys.includes('src') && (hPropKeys.includes('width') || hPropKeys.includes('border') || hPropKeys.includes('align'))) {
return ImageBlock;
}
}

return `![${node.alt}](${node.url}${node.title ? ` "${node.title}")` : ')'}`;
};
return MDImage;
}

export default image;
4 changes: 2 additions & 2 deletions processor/compile/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ function compilers() {
[NodeTypes.callout]: callout,
[NodeTypes.emoji]: gemoji,
[NodeTypes.codeTabs]: codeTabs,
[NodeTypes.embed]: embed,
[NodeTypes.embedBlock]: embed,
[NodeTypes.htmlBlock]: htmlBlock,
[NodeTypes.image]: image,
[NodeTypes.imageBlock]: image,
[NodeTypes.variable]: compatibility,
[NodeTypes.glossary]: compatibility,
[NodeTypes.reusableContent]: compatibility,
Expand Down
Loading