diff --git a/lib/markdown-to-react-loader.js b/lib/markdown-to-react-loader.js index 73503df..f34e01e 100644 --- a/lib/markdown-to-react-loader.js +++ b/lib/markdown-to-react-loader.js @@ -3,24 +3,51 @@ const marked = require('marked'); const Prism = require('prismjs'); const renderer = new marked.Renderer(); +const singleReplaceChars = { + '\(': '(', + '\)': ')', + '\{': '{', + '\}': '}', +} +const regexString = `[${Object.keys(singleReplaceChars).join('')}]`; +const regex = new RegExp(regexString, 'gm'); + +function replaceReact(string) { + return string + .replace(regex, m => singleReplaceChars[m]) + .replace(/class="/g, 'className="') +} + +const reactSafe = (fn) => { + return function () { + let original = fn.apply(renderer, [...arguments]); + let replaced = replaceReact(original); + return replaced; + } +} -renderer.code = function(code, lang) { +function processCodeBlock (code, lang) { let className, highlighter, replaced; // users can easily type in any language they want, // we don't want the app to blow up in case of bad input. try { - require(`prismjs/components/prism-${lang}`); - className = `language-${lang}`; - highlighter = Prism.languages[lang]; + if (typeof lang === 'undefined') { + className = ''; + highlighter = ''; + } else { + require(`prismjs/components/prism-${lang}`); + className = `language-${lang}`; + highlighter = Prism.languages[lang]; + } } catch (e) { - console.warn(`Could not find PrismJS language ${lang}`); + console.warn(`Could not find PrismJS language ${lang}`, e); className = ''; highlighter = ''; } try { - const wrapped = Prism.highlight(code, highlighter); + const wrapped = Prism.highlight(code, highlighter); replaced = wrapped.replace(/\n/g, '
'); } catch (e) { console.error(`Failed to highlight syntax for language ${lang}`); @@ -31,15 +58,46 @@ renderer.code = function(code, lang) { } return ` -
-      
-       ${replaced}
-      
-    
- `; -}; +
+        
+         ${replaced}
+        
+      
+ `; +} + +/** + * Block level renderer methods + * https://marked.js.org/#/USING_PRO.md#block-level-renderer-methods + */ +renderer.code = reactSafe(processCodeBlock); +renderer.blockquote = reactSafe(renderer.blockquote); +renderer.paragraph = reactSafe(renderer.paragraph); +renderer.heading = reactSafe(renderer.heading); +renderer.html = renderer.html; +renderer.hr = reactSafe(renderer.hr); +renderer.list = reactSafe(renderer.list); +renderer.listitem = reactSafe(renderer.listitem); +renderer.checkbox = reactSafe(renderer.checkbox); +renderer.paragraph = reactSafe(renderer.paragraph); +renderer.table = reactSafe(renderer.table); +renderer.tablerow = reactSafe(renderer.tablerow); +renderer.tablecell = reactSafe(renderer.tablecell); -const extraExports = extra => { +/** + * Inline level renderer methods + * https://marked.js.org/#/USING_PRO.md#inline-level-renderer-methods + */ +renderer.strong = reactSafe(renderer.strong); +renderer.em = reactSafe(renderer.em); +renderer.codespan = reactSafe(renderer.codespan); +renderer.br = reactSafe(renderer.br); +renderer.del = reactSafe(renderer.del); +renderer.link = reactSafe(renderer.link); +renderer.image = reactSafe(renderer.image); +renderer.text = reactSafe(renderer.text); + +function extraExports(extra) { let ret = ''; for (var key in extra) { ret += ` @@ -66,18 +124,11 @@ module.exports = function (source, map) { return acc; }, {}); - const replaced = html - .replace(/class="/g, 'className="') - .replace(/\(/g, '(') - .replace(/\)/g, ')') - .replace(/\{/g, '{') - .replace(/\}/g, '}'); - const processed = ` import React, { Fragment } from 'react'; ${parsed.attributes.imports ? parsed.attributes.imports : ''} ${extraExports(extra)} - const Markdown = () => (${replaced}); + const Markdown = () => (${html}); export default Markdown; `; diff --git a/test/all.test.js b/test/all.test.js index 43db09b..3caa034 100644 --- a/test/all.test.js +++ b/test/all.test.js @@ -4,7 +4,7 @@ const markdownToReact = require('../lib/markdown-to-react-loader'); const pretter = require('prettier'); -const testIO = (inFile, outFile) => { +const expectIO = (inFile, outFile) => { let input = getFileContents(inFile); let output = getFileContents(outFile); @@ -23,17 +23,33 @@ const getFileContents = file => { } test('Compiles hello, world', () => { - testIO('io/simple.md', 'io/simple.js'); + expectIO('io/simple.md', 'io/simple.js'); }); test('Compiles file with imports', () => { - testIO('io/imports.md', 'io/imports.js'); + expectIO('io/imports.md', 'io/imports.js'); }); test('Compiles file with code block', () => { - testIO('io/codeblock.md', 'io/codeblock.js'); + expectIO('io/codeblock.md', 'io/codeblock.js'); }); test('Exports extra front matter as named exports', () => { - testIO('io/data.md', 'io/data.js'); + expectIO('io/data.md', 'io/data.js'); +}); + +test('Can work with an async component', () => { + expectIO('io/javascript.md', 'io/javascript.js'); +}); + +test('Properly converts parens & curly brackets', () => { + expectIO('io/replace-chars.md', 'io/replace-chars.js'); +}); + +test('Converts tables and table cells', () => { + expectIO('io/table.md', 'io/table.js'); +}); + +test('Can render everything', () => { + expectIO('io/everything.md', 'io/everything.js'); }); diff --git a/test/io/data-function.js b/test/io/data-function.js new file mode 100644 index 0000000..c7c5114 --- /dev/null +++ b/test/io/data-function.js @@ -0,0 +1,11 @@ +import React, { Fragment } from "react"; + +const module = () => import('my-module'); +export { module }; + +const Markdown = () => ( + +

Something async

+
+); +export default Markdown; diff --git a/test/io/data-function.md b/test/io/data-function.md new file mode 100644 index 0000000..db11dee --- /dev/null +++ b/test/io/data-function.md @@ -0,0 +1,5 @@ +--- +module: () => import('my-module') +--- + +Something async diff --git a/test/io/everything.js b/test/io/everything.js new file mode 100644 index 0000000..4d6b93c --- /dev/null +++ b/test/io/everything.js @@ -0,0 +1,456 @@ +import React, { Fragment } from "react"; + +const Markdown = () => ( + +

Markdown: Syntax

+ +

+ Note: This document is itself written using Markdown; you + can{" "} + + see the source for it by adding '.text' to the URL + + . +

+
+

Overview

+

Philosophy

+

+ Markdown is intended to be as easy-to-read and easy-to-write as is + feasible. +

+

+ Readability, however, is emphasized above all else. A Markdown-formatted + document should be publishable as-is, as plain text, without looking like + it's been marked up with tags or formatting instructions. While + Markdown's syntax has been influenced by several existing text-to-HTML + filters -- including{" "} + Setext,{" "} + atx,{" "} + Textile,{" "} + reStructuredText, + Grutatext, + and EtText -- the single + biggest source of inspiration for Markdown's syntax is the format of + plain text email. +

+

Block Elements

+

Paragraphs and Line Breaks

+

+ A paragraph is simply one or more consecutive lines of text, separated by + one or more blank lines. (A blank line is any line that looks like a + blank line -- a line containing nothing but spaces or tabs is considered + blank.) Normal paragraphs should not be indented with spaces or tabs. +

+

+ The implication of the "one or more consecutive lines of text" + rule is that Markdown supports "hard-wrapped" text paragraphs. + This differs significantly from most other text-to-HTML formatters + (including Movable Type's "Convert Line Breaks" + option) which translate every line break character in a paragraph into + a <br /> tag. +

+

+ When you do want to insert a <br /> break tag + using Markdown, you end a line with two or more spaces, then type return. +

+

Headers

+

Markdown supports two styles of headers, [Setext] [1] and [atx] [2].

+

+ Optionally, you may "close" atx-style headers. This is purely + cosmetic -- you can use this if you think it looks better. The closing + hashes don't even need to match the number of hashes used to open the + header. (The number of opening hashes determines the header + level.) +

+

Blockquotes

+

+ Markdown uses email-style > characters for blockquoting. + If you're familiar with quoting passages of text in an email message, + then you know how to create a blockquote in Markdown. It looks best if you + hard wrap the text and put a > before every line: +

+
+

+ This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, + consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. + Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. +

+

+ Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id + sem consectetuer libero luctus adipiscing. +

+
+

+ Markdown allows you to be lazy and only put the > before + the first line of a hard-wrapped paragraph: +

+
+

+ This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, + consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. + Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. +

+
+
+

+ Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id + sem consectetuer libero luctus adipiscing. +

+
+

+ Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by + adding additional levels of >: +

+
+

This is the first level of quoting.

+
+

This is nested blockquote.

+
+

Back to the first level.

+
+

+ Blockquotes can contain other Markdown elements, including headers, lists, + and code blocks: +

+
+

This is a header.

+
    +
  1. This is the first list item.
  2. +
  3. This is the second list item.
  4. +
+

Here's some example code:

+ +
+        
+          return shell_exec("echo $input | $markdown_script");
+        
+      
+
+

+ Any decent text editor should make email-style quoting easy. For example, + with BBEdit, you can make a selection and choose Increase Quote Level from + the Text menu. +

+

Lists

+

+ Markdown supports ordered (numbered) and unordered + (bulleted) lists. +

+

+ Unordered lists use asterisks, pluses, and hyphens -- interchangably -- as + list markers: +

+ +

is equivalent to:

+ +

and:

+ +

Ordered lists use numbers followed by periods:

+
    +
  1. Bird
  2. +
  3. McHale
  4. +
  5. Parish
  6. +
+

+ It's important to note that the actual numbers you use to mark the + list have no effect on the HTML output Markdown produces. The HTML + Markdown produces from the above list is: +

+

If you instead wrote the list in Markdown like this:

+
    +
  1. Bird
  2. +
  3. McHale
  4. +
  5. Parish
  6. +
+

or even:

+
    +
  1. Bird
  2. +
  3. McHale
  4. +
  5. Parish
  6. +
+

+ you'd get the exact same HTML output. The point is, if you want to, + you can use ordinal numbers in your ordered Markdown lists, so that the + numbers in your source match the numbers in your published HTML. But if + you want to be lazy, you don't have to. +

+

To make lists look nice, you can wrap items with hanging indents:

+ +

But if you want to be lazy, you don't have to:

+ +

+ List items may consist of multiple paragraphs. Each subsequent paragraph + in a list item must be indented by either 4 spaces or one tab: +

+
    +
  1. +

    + This is a list item with two paragraphs. Lorem ipsum dolor sit amet, + consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. +

    +

    + Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + Donec sit amet nisl. Aliquam semper ipsum sit amet velit. +

    +
  2. +
  3. +

    Suspendisse id sem consectetuer libero luctus adipiscing.

    +
  4. +
+

+ It looks nice if you indent every line of the subsequent paragraphs, but + here again, Markdown will allow you to be lazy: +

+ +

+ To put a blockquote within a list item, the blockquote's{" "} + > + delimiters need to be indented: +

+ +

+ To put a code block within a list item, the code block needs to be + indented twice -- 8 spaces or two tabs: +

+ +

Code Blocks

+

+ Pre-formatted code blocks are used for writing about programming or markup + source code. Rather than forming normal paragraphs, the lines of a code + block are interpreted literally. Markdown wraps a code block in both{" "} + <pre> and <code> tags. +

+

+ To produce a code block in Markdown, simply indent every line of the block + by at least 4 spaces or 1 tab. +

+

This is a normal paragraph:

+ +
+      This is a code block.
+    
+

Here is an example of AppleScript:

+ +
+      
+        tell application "Foo"
+        
beep +
+ end tell +
+
+

+ A code block continues until it reaches a line that is not indented + (or the end of the article). +

+

+ Within a code block, ampersands (&) and angle + brackets (< and >) are + automatically converted into HTML entities. This makes it very easy to + include example HTML source code using Markdown -- just paste it and + indent it, and Markdown will handle the hassle of encoding the ampersands + and angle brackets. For example, this: +

+ +
+      
+        <div className="footer">
+        
&copy; 2004 Foo Corporation +
+ </div> +
+
+

+ Regular Markdown syntax is not processed within code blocks. E.g., + asterisks are just literal asterisks within a code block. This means + it's also easy to use Markdown to write about Markdown's own + syntax. +

+ +
+      
+        tell application "Foo"
+        
beep +
+ end tell +
+
+

Span Elements

+ +

+ Markdown supports two style of links: inline and{" "} + reference. +

+

In both styles, the link text is delimited by [square brackets].

+

+ To create an inline link, use a set of regular parentheses immediately + after the link text's closing square bracket. Inside the parentheses, + put the URL where you want the link to point, along with an{" "} + optional + title for the link, surrounded in quotes. For example: +

+

+ This is an example inline link. +

+

+ This link has no title attribute. +

+

Emphasis

+

+ Markdown treats asterisks (*) and underscores ( + _) as indicators of emphasis. Text wrapped with one{" "} + * or _ will be wrapped with an HTML{" "} + <em> tag; double *'s or _ + 's will be wrapped with an HTML + <strong> tag. E.g., this input: +

+

+ single asterisks +

+

+ single underscores +

+

+ double asterisks +

+

+ double underscores +

+

Code

+

+ To indicate a span of code, wrap it with backtick quotes ( + `). Unlike a pre-formatted code block, a code span + indicates code within a normal paragraph. For example: +

+

+ Use the printf() function. +

+
+); +export default Markdown; diff --git a/test/io/everything.md b/test/io/everything.md new file mode 100644 index 0000000..70dbadc --- /dev/null +++ b/test/io/everything.md @@ -0,0 +1,310 @@ +# Markdown: Syntax + +* [Overview](#overview) + * [Philosophy](#philosophy) + * [Inline HTML](#html) + * [Automatic Escaping for Special Characters](#autoescape) +* [Block Elements](#block) + * [Paragraphs and Line Breaks](#p) + * [Headers](#header) + * [Blockquotes](#blockquote) + * [Lists](#list) + * [Code Blocks](#precode) + * [Horizontal Rules](#hr) +* [Span Elements](#span) + * [Links](#link) + * [Emphasis](#em) + * [Code](#code) + * [Images](#img) +* [Miscellaneous](#misc) + * [Backslash Escapes](#backslash) + * [Automatic Links](#autolink) + + +**Note:** This document is itself written using Markdown; you +can [see the source for it by adding '.text' to the URL](/projects/markdown/syntax.text). + +---- + +## Overview + +### Philosophy + +Markdown is intended to be as easy-to-read and easy-to-write as is feasible. + +Readability, however, is emphasized above all else. A Markdown-formatted +document should be publishable as-is, as plain text, without looking +like it's been marked up with tags or formatting instructions. While +Markdown's syntax has been influenced by several existing text-to-HTML +filters -- including [Setext](http://docutils.sourceforge.net/mirror/setext.html), [atx](http://www.aaronsw.com/2002/atx/), [Textile](http://textism.com/tools/textile/), [reStructuredText](http://docutils.sourceforge.net/rst.html), +[Grutatext](http://www.triptico.com/software/grutatxt.html), and [EtText](http://ettext.taint.org/doc/) -- the single biggest source of +inspiration for Markdown's syntax is the format of plain text email. + +## Block Elements + +### Paragraphs and Line Breaks + +A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing but spaces or tabs is considered +blank.) Normal paragraphs should not be indented with spaces or tabs. + +The implication of the "one or more consecutive lines of text" rule is +that Markdown supports "hard-wrapped" text paragraphs. This differs +significantly from most other text-to-HTML formatters (including Movable +Type's "Convert Line Breaks" option) which translate every line break +character in a paragraph into a `
` tag. + +When you *do* want to insert a `
` break tag using Markdown, you +end a line with two or more spaces, then type return. + +### Headers + +Markdown supports two styles of headers, [Setext] [1] and [atx] [2]. + +Optionally, you may "close" atx-style headers. This is purely +cosmetic -- you can use this if you think it looks better. The +closing hashes don't even need to match the number of hashes +used to open the header. (The number of opening hashes +determines the header level.) + + +### Blockquotes + +Markdown uses email-style `>` characters for blockquoting. If you're +familiar with quoting passages of text in an email message, then you +know how to create a blockquote in Markdown. It looks best if you hard +wrap the text and put a `>` before every line: + +> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, +> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. +> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. +> +> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse +> id sem consectetuer libero luctus adipiscing. + +Markdown allows you to be lazy and only put the `>` before the first +line of a hard-wrapped paragraph: + +> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, +consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. +Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + +> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse +id sem consectetuer libero luctus adipiscing. + +Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by +adding additional levels of `>`: + +> This is the first level of quoting. +> +> > This is nested blockquote. +> +> Back to the first level. + +Blockquotes can contain other Markdown elements, including headers, lists, +and code blocks: + +> ## This is a header. +> +> 1. This is the first list item. +> 2. This is the second list item. +> +> Here's some example code: +> +> return shell_exec("echo $input | $markdown_script"); + +Any decent text editor should make email-style quoting easy. For +example, with BBEdit, you can make a selection and choose Increase +Quote Level from the Text menu. + + +### Lists + +Markdown supports ordered (numbered) and unordered (bulleted) lists. + +Unordered lists use asterisks, pluses, and hyphens -- interchangably +-- as list markers: + +* Red +* Green +* Blue + +is equivalent to: + ++ Red ++ Green ++ Blue + +and: + +- Red +- Green +- Blue + +Ordered lists use numbers followed by periods: + +1. Bird +2. McHale +3. Parish + +It's important to note that the actual numbers you use to mark the +list have no effect on the HTML output Markdown produces. The HTML +Markdown produces from the above list is: + +If you instead wrote the list in Markdown like this: + +1. Bird +1. McHale +1. Parish + +or even: + +3. Bird +1. McHale +8. Parish + +you'd get the exact same HTML output. The point is, if you want to, +you can use ordinal numbers in your ordered Markdown lists, so that +the numbers in your source match the numbers in your published HTML. +But if you want to be lazy, you don't have to. + +To make lists look nice, you can wrap items with hanging indents: + +* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, + viverra nec, fringilla in, laoreet vitae, risus. +* Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. + +But if you want to be lazy, you don't have to: + +* Lorem ipsum dolor sit amet, consectetuer adipiscing elit. +Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, +viverra nec, fringilla in, laoreet vitae, risus. +* Donec sit amet nisl. Aliquam semper ipsum sit amet velit. +Suspendisse id sem consectetuer libero luctus adipiscing. + +List items may consist of multiple paragraphs. Each subsequent +paragraph in a list item must be indented by either 4 spaces +or one tab: + +1. This is a list item with two paragraphs. Lorem ipsum dolor + sit amet, consectetuer adipiscing elit. Aliquam hendrerit + mi posuere lectus. + + Vestibulum enim wisi, viverra nec, fringilla in, laoreet + vitae, risus. Donec sit amet nisl. Aliquam semper ipsum + sit amet velit. + +2. Suspendisse id sem consectetuer libero luctus adipiscing. + +It looks nice if you indent every line of the subsequent +paragraphs, but here again, Markdown will allow you to be +lazy: + +* This is a list item with two paragraphs. + + This is the second paragraph in the list item. You're +only required to indent the first line. Lorem ipsum dolor +sit amet, consectetuer adipiscing elit. + +* Another item in the same list. + +To put a blockquote within a list item, the blockquote's `>` +delimiters need to be indented: + +* A list item with a blockquote: + + > This is a blockquote + > inside a list item. + +To put a code block within a list item, the code block needs +to be indented *twice* -- 8 spaces or two tabs: + +* A list item with a code block: + + + +### Code Blocks + +Pre-formatted code blocks are used for writing about programming or +markup source code. Rather than forming normal paragraphs, the lines +of a code block are interpreted literally. Markdown wraps a code block +in both `
` and `` tags.
+
+To produce a code block in Markdown, simply indent every line of the
+block by at least 4 spaces or 1 tab.
+
+This is a normal paragraph:
+
+    This is a code block.
+
+Here is an example of AppleScript:
+
+    tell application "Foo"
+        beep
+    end tell
+
+A code block continues until it reaches a line that is not indented
+(or the end of the article).
+
+Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
+are automatically converted into HTML entities. This makes it very
+easy to include example HTML source code using Markdown -- just paste
+it and indent it, and Markdown will handle the hassle of encoding the
+ampersands and angle brackets. For example, this:
+
+    
+
+Regular Markdown syntax is not processed within code blocks. E.g.,
+asterisks are just literal asterisks within a code block. This means
+it's also easy to use Markdown to write about Markdown's own syntax.
+
+```
+tell application "Foo"
+    beep
+end tell
+```
+
+## Span Elements
+
+### Links
+
+Markdown supports two style of links: *inline* and *reference*.
+
+In both styles, the link text is delimited by [square brackets].
+
+To create an inline link, use a set of regular parentheses immediately
+after the link text's closing square bracket. Inside the parentheses,
+put the URL where you want the link to point, along with an *optional*
+title for the link, surrounded in quotes. For example:
+
+This is [an example](http://example.com/) inline link.
+
+[This link](http://example.net/) has no title attribute.
+
+### Emphasis
+
+Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
+emphasis. Text wrapped with one `*` or `_` will be wrapped with an
+HTML `` tag; double `*`'s or `_`'s will be wrapped with an HTML
+`` tag. E.g., this input:
+
+*single asterisks*
+
+_single underscores_
+
+**double asterisks**
+
+__double underscores__
+
+### Code
+
+To indicate a span of code, wrap it with backtick quotes (`` ` ``).
+Unlike a pre-formatted code block, a code span indicates code within a
+normal paragraph. For example:
+
+Use the `printf()` function.
diff --git a/test/io/javascript.js b/test/io/javascript.js
new file mode 100644
index 0000000..f607ac4
--- /dev/null
+++ b/test/io/javascript.js
@@ -0,0 +1,11 @@
+import React, { Fragment } from "react";
+import AsyncComponent from "AsyncComponent";
+
+let resolve = () => import("MyComponent");
+
+const Markdown = () => (
+  
+    
+  
+);
+export default Markdown;
diff --git a/test/io/javascript.md b/test/io/javascript.md
new file mode 100644
index 0000000..008ade5
--- /dev/null
+++ b/test/io/javascript.md
@@ -0,0 +1,8 @@
+---
+imports: |
+    import AsyncComponent from 'AsyncComponent';
+
+    let resolve = () => import('MyComponent');
+---
+
+
diff --git a/test/io/replace-chars.js b/test/io/replace-chars.js
new file mode 100644
index 0000000..6d515ea
--- /dev/null
+++ b/test/io/replace-chars.js
@@ -0,0 +1,15 @@
+import React, { Fragment } from "react";
+
+const Markdown = () => (
+  
+    

Greater >

+

Less <

+

Open {

+

Closed }

+

Trademark (TM)

+

Happy :)

+

Sad :(

+

Emoji 👽

+
+); +export default Markdown; diff --git a/test/io/replace-chars.md b/test/io/replace-chars.md new file mode 100644 index 0000000..6ab8557 --- /dev/null +++ b/test/io/replace-chars.md @@ -0,0 +1,15 @@ +Greater > + +Less < + +Open { + +Closed } + +Trademark (TM) + +Happy :) + +Sad :( + +Emoji 👽 diff --git a/test/io/table.js b/test/io/table.js new file mode 100644 index 0000000..789d9cf --- /dev/null +++ b/test/io/table.js @@ -0,0 +1,41 @@ +import React, { Fragment } from "react"; + +const Markdown = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + +
column acolumn bcolumn c
+ 1 + + 2 + + 3 +
45 + code +
789
+
+); +export default Markdown; diff --git a/test/io/table.md b/test/io/table.md new file mode 100644 index 0000000..0cd5e3a --- /dev/null +++ b/test/io/table.md @@ -0,0 +1,5 @@ +| column a | column b | column c | +|----------|----------|----------| +| *1* | [2](foo) | **3** | +| 4 | 5 | `code` | +| 7 | 8 | 9 |