Skip to content

Commit

Permalink
Merge branch 'next'
Browse files Browse the repository at this point in the history
  • Loading branch information
kellyjosephprice committed Aug 29, 2024
2 parents 16d1cc6 + 6e3a7ac commit e18612d
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 51 deletions.
53 changes: 18 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<img align="right" width="26%" src="https://owlbertsio-resized.s3.amazonaws.com/Reading.psd.full.png">

ReadMe's flavored Markdown parser and MDX rendering engine. <img align=center src=https://github.com/readmeio/markdown/workflows/CI/badge.svg alt="RDMD CI Status">
ReadMe's MDX rendering engine and custom component collection. <img align=center src=https://github.com/readmeio/markdown/workflows/CI/badge.svg alt="RDMD CI Status">

```
npm install --save @readme/markdown
Expand All @@ -21,25 +21,21 @@ export default ({ body }) => <div className="markdown-body">{run(compile(body))}

#### `compile`

Compiles mdx to js. A wrapper around [`mdx.compile`](https://mdxjs.com/packages/mdx/#compilefile-options)

You usually only need this when calling `run` as well. It's been left as a seperate step as a potential caching opportunity.
Compiles MDX to JS. Essentially a wrapper around [`mdx.compile`](https://mdxjs.com/packages/mdx/#compilefile-options). You usually only need this when calling `run` as well. It's been left as a seperate step as a potential caching opportunity.

###### Parameters

- `string` (`string`) -- An mdx document
- `opts` ([`CompileOpts`](#compileopts), optional) -- configuration
- `string` (`string`) -- an MDX document
- `opts` ([`CompileOpts`](#compileopts), optional) -- a configuration object

###### Returns

compiled code (`string`)

#### `run`

Run compiled code. A wrapper around [`mdx.run`](https://mdxjs.com/packages/mdx/#runcode-options)

> [!CAUTION]
> This `eval`'s JavaScript.
> **This will `eval` the compiled MDX**! Essentially a wrapper around [`mdx.run`](https://mdxjs.com/packages/mdx/#runcode-options).
###### Parameters

Expand All @@ -64,17 +60,11 @@ Parses mdx to an hast.

#### `plain`

Parses mdx to a plain string.

> [!WARNING]
> This **does** not `eval` the doc.
Parses mdx to a plain string. (This **does** not `eval` the doc.)

#### `tags`

Returns a list of tag names from the doc.

> [!WARNING]
> This **does** not `eval` the doc.
Returns a list of tag names from the doc. (This **does** not `eval` the doc.)

#### `utils`

Expand All @@ -86,35 +76,33 @@ Extends [`CompileOptions`](https://mdxjs.com/packages/mdx/#compileoptions)

###### Additional Properties

- `lazyImages` (`boolean`, optional) -- Load images lazily.
- `safeMode` (`boolean`, optional) -- Extract script tags from `HTMLBlock`s
- `components` (`Record<string, string>`, optional) -- An object of tag names to mdx.
- `copyButtons` (`Boolean`, optional) — Automatically insert a button to copy a block of text to the clipboard. Currently used on `<code>` elements.
- `lazyImages` (`boolean`, optional) -- load images lazily
- `safeMode` (`boolean`, optional) -- extract script tags from `HTMLBlock`s
- `components` (`Record<string, string>`, optional) -- an object of tag names to mdx.
- `copyButtons` (`Boolean`, optional) — add a copy button to code blocks

### `RunOpts`

Extends [`RunOptions`](https://mdxjs.com/packages/mdx/#runoptions)

###### Additional Properties

- `components` (`Record<string, MDXModule>`, optional) -- An object of tag names to executed components.
- `imports` (`Record<string, unknown>`, optional) -- An object of modules to import.
- `components` (`Record<string, MDXModule>`, optional) -- a set of custom MDX components
- `imports` (`Record<string, unknown>`, optional) -- an set of modules to import globally
- `terms` (`GlossaryTerm[]`, optional)
- `variables` (`Variables`, optional) -- An object containing [user variables}(https://github.com/readmeio/variable).
- `variables` (`Variables`, optional) -- an object containing [user variables](https://github.com/readmeio/variable)

### `RMDXModule`

###### Properties

- `default` (`() => MDXContent`) -- The mdx douments default export
- `toc` (`HastHeading[]`) -- A list of headings in the document
- `Toc` (`() => MDCContent`) -- A table of contents component
- `default` (`() => MDXContent`) -- the MDX douments default export
- `toc` (`HastHeading[]`) -- a list of headings in the document
- `Toc` (`() => MDCContent`) -- a table of contents component

## Flavored Syntax

~~Our old editor rendered "Magic Block" components from a custom, JSON-based syntax. To provide seamless backwards-compatibility, our new processor ships with built in support for parsing this old format, and transpiles it straight in to our new, flavored Markdown.~~

We've also sprinkled a bit of our own syntactic sugar on top to let you supercharge your docs. [**Learn more about ReadMe's flavored syntax!**](https://docs.readme.com/rdmd/docs/syntax-extensions)
We've also sprinkled a bit of our own custom components in to help you supercharge your docs. [**Learn more about ReadMe's new MDX engine!**](https://docs.readme.com/rdmd/page/mdx-engine)

## Local Development

Expand All @@ -131,8 +119,3 @@ If you make changes to the docs or how the markdown is rendered, you may need to
```
make updateSnapshot
```

## Credits

- **License**: MIT
- **Authors**: [Dom Harrington](https://github.com/domharrington/), [Rafe Goldberg](https://github.com/rafegoldberg)
2 changes: 1 addition & 1 deletion __tests__/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ exports[`export multiple Markdown renderers > renders plain markdown as React 1`
exports[`heading 1`] = `"<h2 class=\\"heading heading-2 header-scroll\\" align=\\"\\"><div class=\\"heading-anchor anchor waypoint\\" id=\\"example-header\\"></div><div class=\\"heading-text\\"><div id=\\"section-example-header\\" class=\\"heading-anchor_backwardsCompatibility\\"></div>Example Header</div><a aria-label=\\"Skip link to Example Header\\" class=\\"heading-anchor-icon fa fa-anchor\\" href=\\"#example-header\\"></a></h2>"`;
exports[`image 1`] = `"<span aria-label="Image" class="img lightbox closed" role="button" tabindex="0"><span class="lightbox-inner"><img src="http://example.com/image.png" width="auto" height="auto" title="" class="img img-align-center" alt="Image" loading="lazy"></span></span>"`;
exports[`image 1`] = `"<span aria-label="Image" class="img lightbox closed" role="button" tabindex="0"><span class="lightbox-inner"><img src="http://example.com/image.png" width="auto" height="auto" title="" class="img " alt="Image" loading="lazy"></span></span>"`;
exports[`list items 1`] = `
"<ul>
Expand Down
6 changes: 6 additions & 0 deletions __tests__/compilers/images.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@ describe('image compiler', () => {

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

it('correctly serializes an Image component with expression attributes back to MDX', () => {
const doc = '<Image src="/path/to/image.png" border={false} />';

expect(mdx(mdast(doc))).toMatch(doc);
});
});
4 changes: 2 additions & 2 deletions __tests__/components/Image.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('Image', () => {
expect(screen.getByRole('img')).toMatchInlineSnapshot(`
<img
alt=""
class="img img-align-center"
class="img img-align-center "
height="auto"
loading="lazy"
src="https://files.readme.io/b8674d6-pizzabro.jpg"
Expand Down Expand Up @@ -42,7 +42,7 @@ describe('Image', () => {
>
<img
alt=""
class="img img-align-center"
class="img img-align-center "
height="auto"
loading="lazy"
src="https://files.readme.io/b8674d6-pizzabro.jpg"
Expand Down
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 @@ -10,4 +10,4 @@ exports[`Components > Embed 3`] = `"<div class="embed embed_hasImg"><a class="em
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`] = `"<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-center" alt="Bro eats pizza and makes an OK gesture." loading="lazy"></span></span>"`;
exports[`Components > Image 1`] = `"<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 " alt="Bro eats pizza and makes an OK gesture." loading="lazy"></span></span>"`;
6 changes: 3 additions & 3 deletions components/Image/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface ImageProps {

const Image = (Props: ImageProps) => {
const {
align = 'center',
align = '',
alt = '',
border = false,
caption,
Expand Down Expand Up @@ -75,7 +75,7 @@ const Image = (Props: ImageProps) => {
width={width}
height={height}
title={title}
className={`img img-align-center${border ? ' border' : ''}`}
className={`img img-align-center ${border ? 'border' : ''}`}
alt={alt}
loading={lazy ? 'lazy' : 'eager'}
/>
Expand All @@ -101,7 +101,7 @@ const Image = (Props: ImageProps) => {
width={width}
height={height}
title={title}
className={`img img-align-${align}${border ? ' border' : ''}`}
className={`img ${align ? `img-align-${align}` : ''} ${border ? 'border' : ''}`}
alt={alt}
loading={lazy ? 'lazy' : 'eager'}
/>
Expand Down
4 changes: 1 addition & 3 deletions components/Image/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,8 @@
&[alt~='align-left'] {
@extend %img-align-left;
}

&[width='80%'],
&[align='middle'], // hack to fix Firefox; see: https://stackoverflow.com/a/45901819/1341949
&[align='center'],
&[align='middle'],
&[alt~='align-center'] {
@extend %img-align-center;
}
Expand Down
43 changes: 37 additions & 6 deletions processor/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Node } from 'mdast';
import { MdxJsxFlowElement, MdxJsxTextElement, MdxFlowExpression } from 'mdast-util-mdx';
import { MdxJsxAttribute } from 'mdast-util-mdx-jsx';
import type { Node } from 'mdast';
import type { MdxJsxFlowElement, MdxJsxTextElement, MdxFlowExpression } from 'mdast-util-mdx';
import type {
MdxJsxAttribute,
MdxJsxAttributeValueExpression,
MdxJsxAttributeValueExpressionData,
} from 'mdast-util-mdx-jsx';
import mdast from '../lib/mdast';

/**
* Formats the hProperties of a node as a string, so they can be compiled back into JSX/MDX.
Expand Down Expand Up @@ -145,13 +150,39 @@ export const reformatHTML = (html: string, indent: number = 2): string => {

export const toAttributes = (object: Record<string, any>, keys: string[] = []): MdxJsxAttribute[] => {
let attributes: MdxJsxAttribute[] = [];
Object.entries(object).forEach(([name, value]) => {
if (keys.length > 0 && !keys.includes(name)) return;
Object.entries(object).forEach(([name, v]) => {
if ((keys.length > 0 && !keys.includes(name)) || typeof v === 'undefined') return;

let value: MdxJsxAttributeValueExpression | string;

if (typeof v === 'string') {
value = v;
} else {
/* values can be null, undefined, string, or a expression, eg:
*
* ```
* <Image src="..." border={false} size={width - 20} />
* ```
*
* Parsing the expression seems to only be done by the library
* `mdast-util-mdx-jsx`, and so the most straight forward way to parse
* the expression and get the appropriate AST is with our `mdast`
* function.
*/
const proxy = mdast(`{${v}}`);
const data = proxy.children[0].data as MdxJsxAttributeValueExpressionData;

value = {
type: 'mdxJsxAttributeValueExpression',
value: v.toString(),
data,
};
}

attributes.push({
type: 'mdxJsxAttribute',
name,
value: value as string,
value,
});
});

Expand Down

0 comments on commit e18612d

Please sign in to comment.