Skip to content

Commit

Permalink
Add tag & props override functionality
Browse files Browse the repository at this point in the history
The caller can now specify a component to replace a given tag that
would be emitted by the converter and/or add props to that tag or
replaced tag.
  • Loading branch information
Evan Jacobs committed Mar 21, 2016
1 parent 894059d commit ca7271b
Show file tree
Hide file tree
Showing 3 changed files with 343 additions and 246 deletions.
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,40 @@ render(converter('# Hello world!'), document.body);
[remark options](https://github.com/wooorm/remark#remarkprocessvalue-options-done) can be passed as the second argument:

```js
converter('# Hello world[^2]!\n\n[^2]: A beautiful place.', {footnotes: true});
converter('* abc\n* def\n* ghi', {bullet: '*'});
```

_Footnotes are enabled by default as of `markdown-to-jsx@2.0.0`._

## Overriding tags and adding props

As of `markdown-to-jsx@2.0.0`, it's now possible to selectively override a given HTML tag's JSX representation. This is done through a new third argument to the converter: an object made of keys, each being the lowercase html tag name (p, figure, a, etc.) to be overridden.

Each override can be given a `component` that will be substituted for the tag name and/or `props` that will be applied as you would expect.

```js
converter('Hello there!', {}, {
p: {
component: MyParagraph,
props: {
className: 'foo'
},
}
});
```

The code above will replace all emitted `<p>` tags with the given component `MyParagraph`, and add the `className` specified in `props`.

Depending on the type of element, there are some props that must be preserved to ensure the markdown is converted as intended. They are:

- `a`: `title`, `href`
- `img`: `title`, `alt`, `src`
- `ol`: `start`
- `td`: `style`
- `th`: `style`

Any conflicts between passed `props` and the specific properties above will be resolved in favor of `markdown-to-jsx`'s code.

## Known Issues

- remark's handling of lists will sometimes add a child paragraph tag inside the
Expand Down
36 changes: 36 additions & 0 deletions __tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ describe('markdown-to-jsx', () => {
expect(() => converter('', true)).toThrow();
});

it('should throw if not passed an object or undefined (third arg)', () => {
expect(() => converter('', {})).not.toThrow();
expect(() => converter('', {}, {})).not.toThrow();

expect(() => converter('', {}, 1)).toThrow();
expect(() => converter('', {}, function(){})).toThrow();
expect(() => converter('', {}, [])).toThrow();
expect(() => converter('', {}, null)).toThrow();
expect(() => converter('', {}, true)).toThrow();
});

it('should handle a basic string', () => {
const element = render(converter('Hello.'));
const elementNode = ReactDOM.findDOMNode(element);
Expand Down Expand Up @@ -598,4 +609,29 @@ describe('markdown-to-jsx', () => {
expect(definitions.children[0].textContent).toBe('[abc]: Baz');
});
});

describe('overrides', () => {
it('should substitute the appropriate JSX tag if given a component', () => {
const FakeParagraph = (props) => <p className='foo'>{props.children}</p>;
const element = render(
converter('Hello.', {}, {p: {component: FakeParagraph}})
);

const elementNode = ReactDOM.findDOMNode(element);

expect(elementNode.children.length).toBe(1);
expect(elementNode.children[0].className).toBe('foo');
});

it('should add props to the appropriate JSX tag if supplied', () => {
const element = render(
converter('Hello.', {}, {p: {props: {className: 'abc'}}})
);

const elementNode = ReactDOM.findDOMNode(element);

expect(elementNode.children.length).toBe(1);
expect(elementNode.children[0].className).toBe('abc');
});
});
});

0 comments on commit ca7271b

Please sign in to comment.