diff --git a/__tests__/renderer-spec.tsx b/__tests__/renderer-spec.tsx index 3a6fb20..325b810 100644 --- a/__tests__/renderer-spec.tsx +++ b/__tests__/renderer-spec.tsx @@ -176,18 +176,34 @@ test('should render blockquote with mixed text', () => { ).toBe('> This is _hello_ **world**'); }); -test('should render code tag with text', () => { +test('should render inline code tag with text', () => { expect( (render( - const a = 1; +

Code is const a = 1;

+ ) as string).trim() + ).toBe('Code is `const a = 1;`'); +}); + +test('should render inline code tag without text', () => { + expect( + (render( +

Code is

+ ) as string).trim() + ).toBe('Code is ``'); +}); + +test('should render pre.code tag with text', () => { + expect( + (render( +
const a = 1;
) as string).trim() ).toBe('```js\nconst a = 1;\n```'); }); -test('should render code tag without text', () => { +test('should render pre.code tag without text', () => { expect( (render( - +
) as string).trim() ).toBe('```js\n\n```'); }); diff --git a/src/tagHandler.ts b/src/tagHandler.ts index 2f9ffd5..ce0e9c4 100644 --- a/src/tagHandler.ts +++ b/src/tagHandler.ts @@ -4,6 +4,7 @@ import { emphasis, heading, image, + inlineCode, link, list, listItem, @@ -11,18 +12,23 @@ import { strong, } from 'mdast-builder'; import { - HTMLAttributes, AnchorHTMLAttributes, + Children as ReactChildren, + HTMLAttributes, ImgHTMLAttributes, } from 'react'; // tslint:disable-next-line: no-implicit-dependencies import { Node as MDASTNode, Parent as MDASTParent } from 'unist'; -import { IReactElementSubset } from './helpers'; +import { + IReactElementSubset, + ReactElementSubsetWithPrimitive, +} from './helpers'; export default function handleTag( node: IReactElementSubset, - parentASTNode: MDASTParent + parentASTNode: MDASTParent, + extraProps = {} ) { const { type: tagType } = node; @@ -112,7 +118,10 @@ export default function handleTag( // START - Handle code case 'code': { - const props = node.props as HTMLAttributes; + // tslint:disable-next-line: no-object-literal-type-assertion + const props = { ...node.props, ...extraProps } as HTMLAttributes & { + inline?: boolean; + }; let lang = ''; if (props.lang !== undefined) { @@ -127,11 +136,38 @@ export default function handleTag( } } - childASTNode = code(lang, value); + let isInline = true; + if (props.inline !== undefined) { + isInline = !!props.inline; + } + + if (isInline) { + childASTNode = inlineCode(value); + } else { + childASTNode = code(lang, value); + } break; } // END - Handle code + // START - Handle pre.code + case 'pre': { + const childrenArray = ReactChildren.toArray(node.props.children); + if (childrenArray.length === 1) { + let onlyChild = childrenArray[0] as ReactElementSubsetWithPrimitive; + if ( + onlyChild instanceof Object && + (onlyChild as IReactElementSubset).type === 'code' + ) { + onlyChild = onlyChild as IReactElementSubset; + + handleTag(onlyChild, parentASTNode, { inline: false }); + } + } + break; + } + // END - Handle blockquote + default: newParentASTNode = parentASTNode; break;