[
  {
    "path": ".github/workflows/gh-page.yml",
    "content": "name: Deploy to GitHub pages\n\non:\n  push:\n    branches: [main]\n\njobs:\n  build-and-deploy:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n        with:\n          persist-credentials: false\n\n      - name: Use Node\n        uses: actions/setup-node@v3\n        with:\n          node-version: 16\n\n      - name: Use cached node_modules\n        uses: actions/cache@v3\n        with:\n          path: node_modules\n          key: nodeModules-${{ hashFiles('**/package-lock.json') }}\n          restore-keys: |\n            nodeModules-\n\n      - name: Install dependencies\n        run: npm ci\n        env:\n          CI: true\n\n      - name: Build storybook\n        run: npm run build-storybook\n\n      - name: Deploy to GitHub pages\n        uses: JamesIves/github-pages-deploy-action@releases/v3\n        with:\n          ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}\n          BRANCH: gh-pages\n          FOLDER: storybook-static\n          CLEAN: true\n          SINGLE_COMMIT: true\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  build:\n    strategy:\n      matrix:\n        platform: [ubuntu-latest, windows-latest, macos-latest]\n        node-version: [12, 14, 16]\n\n    name: '${{ matrix.platform }}: node.js ${{ matrix.node-version }}'\n\n    runs-on: ${{ matrix.platform }}\n\n    steps:\n      - name: Begin CI...\n        uses: actions/checkout@v3\n\n      - name: Use Node\n        uses: actions/setup-node@v3\n        with:\n          node-version: ${{ matrix.node-version }}\n\n      - name: Use cached node_modules\n        uses: actions/cache@v3\n        with:\n          path: node_modules\n          key: nodeModules-${{ hashFiles('**/package-lock.json') }}\n          restore-keys: |\n            nodeModules-\n\n      - name: Install dependencies\n        run: npm ci\n        env:\n          CI: true\n\n      - name: Lint\n        if: ${{ matrix.platform != 'windows-latest' }}\n        run: npm run lint\n        env:\n          CI: true\n\n      - name: Test\n        run: npm test -- --ci --coverage --maxWorkers=2\n        env:\n          CI: true\n\n      - name: Build\n        run: npm run build\n        env:\n          CI: true\n"
  },
  {
    "path": ".gitignore",
    "content": "*.log\n.DS_Store\nnode_modules\n.cache\ndist/\nstorybook-static/\ncoverage/\n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\nnpm run lint\n"
  },
  {
    "path": ".storybook/main.ts",
    "content": "module.exports = {\n  stories: [\"../stories/**/*\"],\n  addons: ['@storybook/addon-essentials'],\n};\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Christian Murphy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"version\": \"2.1.0\",\n  \"name\": \"react-remark\",\n  \"description\": \"Renders Markdown as React components\",\n  \"author\": \"Christian Murphy <christian.murphy.42@gmail.com>\",\n  \"license\": \"MIT\",\n  \"repository\": \"remarkjs/react-remark\",\n  \"bugs\": \"https://github.com/remarkjs/react-remark/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"main\": \"dist/index.js\",\n  \"module\": \"dist/react-remark.esm.js\",\n  \"typings\": \"dist/index.d.ts\",\n  \"sideEffects\": false,\n  \"files\": [\n    \"dist\",\n    \"src\"\n  ],\n  \"engines\": {\n    \"node\": \">=10\"\n  },\n  \"scripts\": {\n    \"start\": \"tsdx watch\",\n    \"build\": \"tsdx build\",\n    \"test\": \"tsdx test\",\n    \"lint\": \"tsdx lint\",\n    \"prepare\": \"tsdx build\",\n    \"postinstall\": \"husky install\",\n    \"prepublishOnly\": \"pinst --disable\",\n    \"postpublish\": \"pinst --enable\",\n    \"storybook\": \"start-storybook -p 6006\",\n    \"build-storybook\": \"build-storybook\"\n  },\n  \"peerDependencies\": {\n    \"react\": \">=16.8\"\n  },\n  \"dependencies\": {\n    \"rehype-react\": \"^6.0.0\",\n    \"remark-parse\": \"^9.0.0\",\n    \"remark-rehype\": \"^8.0.0\",\n    \"unified\": \"^9.0.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.0.0\",\n    \"@storybook/addon-essentials\": \"^6.0.0\",\n    \"@storybook/react\": \"^6.0.0\",\n    \"@testing-library/jest-dom\": \"^5.0.0\",\n    \"@testing-library/react\": \"^12.0.0\",\n    \"@testing-library/react-hooks\": \"^7.0.0\",\n    \"@types/react\": \"^17.0.0\",\n    \"@types/react-dom\": \"^17.0.0\",\n    \"husky\": \"^7.0.0\",\n    \"katex\": \"^0.13.0\",\n    \"pinst\": \"^2.0.0\",\n    \"react\": \"^17.0.0\",\n    \"react-dom\": \"^17.0.0\",\n    \"react-test-renderer\": \"^17.0.0\",\n    \"rehype-katex\": \"^5.0.0\",\n    \"rehype-raw\": \"^5.0.0\",\n    \"rehype-sanitize\": \"^4.0.0\",\n    \"remark-gfm\": \"^1.0.0\",\n    \"remark-math\": \"^4.0.0\",\n    \"tsdx\": \"^0.14.0\",\n    \"typescript\": \"^3.0.0\"\n  },\n  \"prettier\": {\n    \"printWidth\": 80,\n    \"semi\": true,\n    \"singleQuote\": true,\n    \"trailingComma\": \"es5\"\n  },\n  \"renovate\": {\n    \"extends\": [\n      \"config:base\",\n      \":preserveSemverRanges\"\n    ]\n  }\n}\n"
  },
  {
    "path": "readme.md",
    "content": "# react-remark\n\n[![CI](https://github.com/remarkjs/react-remark/workflows/CI/badge.svg?branch=main)](https://github.com/remarkjs/react-remark/actions?query=workflow%3ACI)\n[![Downloads](https://img.shields.io/npm/dm/react-remark.svg)](https://www.npmjs.com/package/react-remark)\n[![Size](https://img.shields.io/bundlephobia/minzip/react-remark.svg)](https://bundlephobia.com/result?p=react-remark)\n\n**react-remark** offers a [React hook](https://reactjs.org/docs/hooks-intro.html) and [React component](https://reactjs.org/docs/glossary.html#components) based way of rendering [markdown](https://commonmark.org/) into [React](https://reactjs.org) using [remark](https://github.com/remarkjs/remark)\n\n## Installation\n\n_npm_\n\n```\nnpm install --save react-remark\n```\n\n_yarn_\n\n```\nyarn add react-remark\n```\n\n## Usage\n\n### As a hook\n\n#### Render static content\n\n```tsx\nimport React, { useEffect } from 'react';\nimport { useRemark } from 'react-remark';\n\nconst ExampleComponent = () => {\n  const [reactContent, setMarkdownSource] = useRemark();\n\n  useEffect(() => {\n    setMarkdownSource('# markdown header');\n  }, []);\n\n  return reactContent;\n};\n\nexport default ExampleComponent;\n```\n\n#### Using input and events to update\n\n```tsx\nimport React from 'react';\nimport { useRemark } from 'react-remark';\n\nconst ExampleComponent = () => {\n  const [reactContent, setMarkdownSource] = useRemark();\n\n  return (\n    <>\n      <input\n        type=\"text\"\n        onChange={({ currentTarget }) => setMarkdownSource(currentTarget.value)}\n      />\n      {reactContent}\n    </>\n  );\n};\n\nexport default ExampleComponent;\n```\n\n### Server side rendering\n\n```tsx\nimport React from 'react';\nimport { useRemarkSync } from 'react-remark';\n\nconst ExampleComponent = () => {\n  const reactContent = useRemarkSync('# markdown header');\n\n  return reactContent;\n};\n\nexport default ExampleComponent;\n```\n\n:notebook: Note that some remark plugins are async, these plugins will error if used with `useRemarkSync`.\n\n[More examples of usage as hook in storybook.](https://remarkjs.github.io/react-remark/?path=/story/remark-hook)\n\n### As a component\n\n#### Render static content\n\n```tsx\nimport React, { useState } from 'react';\nimport { Remark } from 'react-remark';\n\nconst ExampleComponent = () => (\n  <Remark>{`\n# header\n\n1. ordered\n2. list\n`}</Remark>\n);\n\nexport default ExampleComponent;\n```\n\n#### Using input and events to update\n\n```tsx\nimport React, { useState } from 'react';\nimport { Remark } from 'react-remark';\n\nconst ExampleComponent = () => {\n  const [markdownSource, setMarkdownSource] = useState('');\n\n  return (\n    <>\n      <input\n        type=\"text\"\n        onChange={({ currentTarget }) => setMarkdownSource(currentTarget.value)}\n      />\n      <Remark>{markdownSource}</Remark>\n    </>\n  );\n};\n\nexport default ExampleComponent;\n```\n\n[More examples of usage as component in storybook.](https://remarkjs.github.io/react-remark/?path=/story/remark-component)\n\n## Examples\n\nA set of runnable examples are provided through storybook at <https://remarkjs.github.io/react-remark>.\nThe source for the story files can be found in [_/stories_](./stories).\n\n## Architecture\n\n```\n                                                             react-remark\n+---------------------------------------------------------------------------------------------------------------------------------------------+\n|                                                                                                                                             |\n|            +----------+        +----------------+        +---------------+       +----------------+       +--------------+                  |\n|            |          |        |                |        |               |       |                |       |              |                  |\n| -markdown->+  remark  +-mdast->+ remark plugins +-mdast->+ remark-rehype +-hast->+ rehype plugins +-hast->+ rehype-react +-react elements-> |\n|            |          |        |                |        |               |       |                |       |              |                  |\n|            +----------+        +----------------+        +---------------+       +----------------+       +--------------+                  |\n|                                                                                                                                             |\n+---------------------------------------------------------------------------------------------------------------------------------------------+\n```\n\nrelevant links: [markdown](https://commonmark.org), [remark](https://github.com/remarkjs/remark), [mdast](https://github.com/syntax-tree/mdast), [remark plugins](https://github.com/remarkjs/remark/blob/main/doc/plugins.md), [remark-rehype](https://github.com/remarkjs/remark-rehype), [hast](https://github.com/syntax-tree/hast), [rehype plugins](https://github.com/rehypejs/rehype/blob/main/doc/plugins.md), [rehype-react](https://github.com/rehypejs/rehype-react)\n\n## Options\n\n- `remarkParseOptions` (Object) - configure how Markdown is parsed, same as [`remark-parse` options](https://github.com/remarkjs/remark/tree/main/packages/remark-parse#options)\n- `remarkPlugins` (Array) - [remark plugins](https://github.com/remarkjs/remark/blob/main/doc/plugins.md) or [custom plugins](https://unifiedjs.com/learn/guide/create-a-plugin) to transform markdown content before it is translated to HTML (hast)\n- `remarkToRehypeOptions` (Object) - configure how Markdown (mdast) is translated into HTML (hast), same as [`remark-rehype` options](https://github.com/remarkjs/remark-rehype#api)\n- `rehypePlugins` (Array) - [rehype plugins](https://github.com/rehypejs/rehype/blob/main/doc/plugins.md) or [custom plugins](https://unifiedjs.com/learn/guide/create-a-plugin) to transform HTML (hast) before it is translated to React elements.\n- `rehypeReactOptions` (Object) - configure how HTML (hast) is translated into React elements, same as [`rehype-react` options](https://github.com/rehypejs/rehype-react#options)\n\n### Pass options to hook\n\n```tsx\nimport React, { Fragment } from 'react';\nimport { useRemark } from 'react-remark';\nimport remarkGemoji from 'remark-gemoji';\nimport rehypeSlug from 'rehype-slug';\nimport rehypeAutoLinkHeadings from 'rehype-autolink-headings';\n\n// ...\n\nconst [reactContent, setMarkdownSource] = useRemark({\n  remarkPlugins: [remarkGemoji],\n  remarkToRehypeOptions: { allowDangerousHtml: true },\n  rehypePlugins: [rehypeSlug, rehypeAutoLinkHeadings],\n  rehypeReactOptions: {\n    components: {\n      p: (props) => <p className=\"custom-paragraph\" {...props} />,\n    },\n  },\n});\n```\n\n### Pass options to component\n\n```tsx\nimport React, { Fragment } from 'react';\nimport { Remark } from 'react-remark';\nimport remarkGemoji from 'remark-gemoji';\nimport rehypeSlug from 'rehype-slug';\nimport rehypeAutoLinkHeadings from 'rehype-autolink-headings';\n\n// ...\n\n<Remark\n  remarkPlugins={[remarkGemoji]}\n  remarkToRehypeOptions={{ allowDangerousHtml: true }}\n  rehypePlugins={[rehypeSlug, rehypeAutoLinkHeadings]}\n  rehypeReactOptions={{\n    components: {\n      p: (props) => <p className=\"custom-paragraph\" {...props} />,\n    },\n  }}\n>\n  {markdownSource}\n</Remark>;\n```\n"
  },
  {
    "path": "src/index.ts",
    "content": "import {\n  FunctionComponent,\n  Fragment,\n  ReactElement,\n  createElement,\n  useState,\n  useEffect,\n  useCallback,\n} from 'react';\nimport unified, { PluggableList } from 'unified';\nimport remarkParse, { RemarkParseOptions } from 'remark-parse';\nimport { Options as RemarkRehypeOptions } from 'mdast-util-to-hast';\nimport remarkToRehype from 'remark-rehype';\nimport rehypeReact, { Options as RehypeReactOptions } from 'rehype-react';\n\ntype PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\nexport interface UseRemarkSyncOptions {\n  remarkParseOptions?: RemarkParseOptions;\n  remarkToRehypeOptions?: RemarkRehypeOptions;\n  rehypeReactOptions?: PartialBy<\n    RehypeReactOptions<typeof createElement>,\n    'createElement'\n  >;\n  remarkPlugins?: PluggableList;\n  rehypePlugins?: PluggableList;\n}\n\nexport const useRemarkSync = (\n  source: string,\n  {\n    remarkParseOptions,\n    remarkToRehypeOptions,\n    rehypeReactOptions,\n    remarkPlugins = [],\n    rehypePlugins = [],\n  }: UseRemarkOptions = {}\n): ReactElement =>\n  unified()\n    .use(remarkParse, remarkParseOptions)\n    .use(remarkPlugins)\n    .use(remarkToRehype, remarkToRehypeOptions)\n    .use(rehypePlugins)\n    .use(rehypeReact, {\n      createElement,\n      Fragment,\n      ...rehypeReactOptions,\n    } as RehypeReactOptions<typeof createElement>)\n    .processSync(source).result as ReactElement;\n\nexport interface UseRemarkOptions extends UseRemarkSyncOptions {\n  onError?: (err: Error) => void;\n}\n\nexport const useRemark = ({\n  remarkParseOptions,\n  remarkToRehypeOptions,\n  rehypeReactOptions,\n  remarkPlugins = [],\n  rehypePlugins = [],\n  onError = () => {},\n}: UseRemarkOptions = {}): [ReactElement | null, (source: string) => void] => {\n  const [reactContent, setReactContent] = useState<ReactElement | null>(null);\n\n  const setMarkdownSource = useCallback((source: string) => {\n    unified()\n      .use(remarkParse, remarkParseOptions)\n      .use(remarkPlugins)\n      .use(remarkToRehype, remarkToRehypeOptions)\n      .use(rehypePlugins)\n      .use(rehypeReact, {\n        createElement,\n        Fragment,\n        ...rehypeReactOptions,\n      } as RehypeReactOptions<typeof createElement>)\n      .process(source)\n      .then((vfile) => setReactContent(vfile.result as ReactElement))\n      .catch(onError);\n  }, []);\n\n  return [reactContent, setMarkdownSource];\n};\n\nexport interface RemarkProps extends UseRemarkOptions {\n  children: string;\n}\n\nexport const Remark: FunctionComponent<RemarkProps> = ({\n  children,\n  ...useRemarkOptions\n}: RemarkProps) => {\n  const [reactContent, setMarkdownSource] = useRemark(useRemarkOptions);\n\n  useEffect(() => {\n    setMarkdownSource(children);\n  }, [children, setMarkdownSource]);\n\n  return reactContent;\n};\n"
  },
  {
    "path": "stories/remark-component.stories.tsx",
    "content": "import React from 'react';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport rehypeKatex from 'rehype-katex';\nimport rehypeRaw from 'rehype-raw';\nimport rehypeSanitize from 'rehype-sanitize';\nimport 'katex/dist/katex.min.css';\n\nimport { Remark } from '../src';\n\nexport default {\n  title: 'Remark Component',\n  component: Remark,\n};\n\nexport const CommonMark = ({ content }) => <Remark>{content}</Remark>;\nCommonMark.args = {\n  content: `# header\n\n1. ordered\n2. list\n\n* unordered\n* list`,\n};\n\nexport const GithubFlavoredMarkdown = ({ content }) => (\n  <Remark remarkPlugins={[remarkGfm]}>{content}</Remark>\n);\nGithubFlavoredMarkdown.args = {\n  content: `# header\n\n| column 1 | column 2 |\n| -------- | -------- |\n| first    | row      |\n`,\n};\n\nexport const MarkdownWithMath = ({ content }) => (\n  <Remark remarkPlugins={[remarkMath]} rehypePlugins={[rehypeKatex]}>\n    {content}\n  </Remark>\n);\nMarkdownWithMath.args = {\n  content: `Lift($L$) can be determined by Lift Coefficient ($C_L$) like the following equation.\n\n$$\nL = \\\\frac{1}{2} \\\\rho v^2 S C_L\n$$`,\n};\n\nexport const MixedHTMLSanitized = ({ content }) => (\n  <Remark\n    remarkToRehypeOptions={{ allowDangerousHtml: true }}\n    rehypePlugins={[rehypeRaw, rehypeSanitize]}\n  >\n    {content}\n  </Remark>\n);\nMixedHTMLSanitized.args = {\n  content: `# header\n\n<strong>mixed</strong>\n<em>with</em>\n<kbd>html</kbd>\n`,\n};\n"
  },
  {
    "path": "stories/remark-hook-async.stories.tsx",
    "content": "import { useEffect } from 'react';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport rehypeKatex from 'rehype-katex';\nimport rehypeRaw from 'rehype-raw';\nimport rehypeSanitize from 'rehype-sanitize';\nimport 'katex/dist/katex.min.css';\n\nimport { useRemarkSync } from '../src';\n\nexport default {\n  title: 'Remark Hooks/sync and ssr with useRemarkSync',\n  component: useRemarkSync,\n};\n\nexport const CommonMark = ({ content }) => {\n  return useRemarkSync(content);\n};\nCommonMark.args = {\n  content: `# header\n\n1. ordered\n2. list\n\n* unordered\n* list`,\n};\n\nexport const GithubFlavoredMarkdown = ({ content }) => {\n  return (\n    useRemarkSync(content, {\n      remarkPlugins: [remarkGfm],\n    }) || <></>\n  );\n};\nGithubFlavoredMarkdown.args = {\n  content: `# header\n\n| column 1 | column 2 |\n| -------- | -------- |\n| first    | row      |\n`,\n};\n\nexport const MarkdownWithMath = ({ content }) => {\n  return useRemarkSync(content, {\n    remarkPlugins: [remarkMath],\n    rehypePlugins: [rehypeKatex],\n  });\n};\nMarkdownWithMath.args = {\n  content: `Lift($L$) can be determined by Lift Coefficient ($C_L$) like the following equation.\n\n$$\nL = \\\\frac{1}{2} \\\\rho v^2 S C_L\n$$`,\n};\n\nexport const MixedHTMLSanitized = ({ content }) => {\n  return useRemarkSync(content, {\n    remarkToRehypeOptions: { allowDangerousHtml: true },\n    rehypePlugins: [rehypeRaw, rehypeSanitize],\n  });\n};\nMixedHTMLSanitized.args = {\n  content: `# header\n\n<strong>mixed</strong>\n<em>with</em>\n<kbd>html</kbd>`,\n};\n"
  },
  {
    "path": "stories/remark-hook-sync.stories.tsx",
    "content": "import { useEffect } from 'react';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport rehypeKatex from 'rehype-katex';\nimport rehypeRaw from 'rehype-raw';\nimport rehypeSanitize from 'rehype-sanitize';\nimport 'katex/dist/katex.min.css';\n\nimport { useRemark } from '../src';\n\nexport default {\n  title: 'Remark Hooks/standard use with useRemark',\n  component: useRemark,\n};\n\nexport const CommonMark = ({ content }) => {\n  const [reactContent, setMarkdownSource] = useRemark();\n\n  useEffect(() => {\n    setMarkdownSource(content);\n  }, [content]);\n\n  return reactContent || <></>;\n};\nCommonMark.args = {\n  content: `# header\n\n1. ordered\n2. list\n\n* unordered\n* list`,\n};\n\nexport const GithubFlavoredMarkdown = ({ content }) => {\n  const [reactContent, setMarkdownSource] = useRemark({\n    remarkPlugins: [remarkGfm],\n  });\n\n  useEffect(() => {\n    setMarkdownSource(content);\n  }, [content]);\n\n  return reactContent || <></>;\n};\nGithubFlavoredMarkdown.args = {\n  content: `# header\n\n| column 1 | column 2 |\n| -------- | -------- |\n| first    | row      |\n`,\n};\n\nexport const MarkdownWithMath = ({ content }) => {\n  const [reactContent, setMarkdownSource] = useRemark({\n    remarkPlugins: [remarkMath],\n    rehypePlugins: [rehypeKatex],\n  });\n\n  useEffect(() => {\n    setMarkdownSource(content);\n  }, [content]);\n\n  return reactContent || <></>;\n};\nMarkdownWithMath.args = {\n  content: `Lift($L$) can be determined by Lift Coefficient ($C_L$) like the following equation.\n\n$$\nL = \\\\frac{1}{2} \\\\rho v^2 S C_L\n$$`,\n};\n\nexport const MixedHTMLSanitized = ({ content }) => {\n  const [reactContent, setMarkdownSource] = useRemark({\n    remarkToRehypeOptions: { allowDangerousHtml: true },\n    rehypePlugins: [rehypeRaw, rehypeSanitize],\n  });\n\n  useEffect(() => {\n    setMarkdownSource(content);\n  }, [content]);\n\n  return reactContent || <></>;\n};\nMixedHTMLSanitized.args = {\n  content: `# header\n\n<strong>mixed</strong>\n<em>with</em>\n<kbd>html</kbd>`,\n};\n"
  },
  {
    "path": "test/__snapshots__/remark-component.test.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Remark should render content 1`] = `\n<h1>\n  header\n</h1>\n`;\n"
  },
  {
    "path": "test/__snapshots__/remark-hook.test.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`useRemark should render content 1`] = `\n<React.Fragment>\n  <h1>\n    header\n  </h1>\n</React.Fragment>\n`;\n\nexports[`useRemark should support custom element renderer 1`] = `\n<React.Fragment>\n  <h1>\n    heading\n  </h1>\n</React.Fragment>\n`;\n\nexports[`useRemark should support gfm through remark plugins 1`] = `\n<React.Fragment>\n  <p>\n    <a\n      href=\"https://example.com\"\n    >\n      https://example.com\n    </a>\n  </p>\n</React.Fragment>\n`;\n\nexports[`useRemark should support html through rehype plugins 1`] = `\n<React.Fragment>\n  <p>\n    <span>\n      example\n    </span>\n  </p>\n</React.Fragment>\n`;\n\nexports[`useRemark should support math through remark and rehype plugins 1`] = `\n<React.Fragment>\n  <p>\n    Lift(\n    <span\n      className=\"math math-inline\"\n    >\n      <span\n        className=\"katex\"\n      >\n        <span\n          className=\"katex-mathml\"\n        >\n          <math\n            xmlns=\"http://www.w3.org/1998/Math/MathML\"\n          >\n            <semantics>\n              <mrow>\n                <mi>\n                  L\n                </mi>\n              </mrow>\n              <annotation\n                encoding=\"application/x-tex\"\n              >\n                L\n              </annotation>\n            </semantics>\n          </math>\n        </span>\n        <span\n          aria-hidden=\"true\"\n          className=\"katex-html\"\n        >\n          <span\n            className=\"base\"\n          >\n            <span\n              className=\"strut\"\n              style={\n                Object {\n                  \"height\": \"0.68333em\",\n                  \"verticalAlign\": \"0em\",\n                }\n              }\n            />\n            <span\n              className=\"mord mathnormal\"\n            >\n              L\n            </span>\n          </span>\n        </span>\n      </span>\n    </span>\n    ) can be determined by Lift Coefficient (\n    <span\n      className=\"math math-inline\"\n    >\n      <span\n        className=\"katex\"\n      >\n        <span\n          className=\"katex-mathml\"\n        >\n          <math\n            xmlns=\"http://www.w3.org/1998/Math/MathML\"\n          >\n            <semantics>\n              <mrow>\n                <msub>\n                  <mi>\n                    C\n                  </mi>\n                  <mi>\n                    L\n                  </mi>\n                </msub>\n              </mrow>\n              <annotation\n                encoding=\"application/x-tex\"\n              >\n                C_L\n              </annotation>\n            </semantics>\n          </math>\n        </span>\n        <span\n          aria-hidden=\"true\"\n          className=\"katex-html\"\n        >\n          <span\n            className=\"base\"\n          >\n            <span\n              className=\"strut\"\n              style={\n                Object {\n                  \"height\": \"0.83333em\",\n                  \"verticalAlign\": \"-0.15em\",\n                }\n              }\n            />\n            <span\n              className=\"mord\"\n            >\n              <span\n                className=\"mord mathnormal\"\n                style={\n                  Object {\n                    \"marginRight\": \"0.07153em\",\n                  }\n                }\n              >\n                C\n              </span>\n              <span\n                className=\"msupsub\"\n              >\n                <span\n                  className=\"vlist-t vlist-t2\"\n                >\n                  <span\n                    className=\"vlist-r\"\n                  >\n                    <span\n                      className=\"vlist\"\n                      style={\n                        Object {\n                          \"height\": \"0.32833099999999993em\",\n                        }\n                      }\n                    >\n                      <span\n                        style={\n                          Object {\n                            \"marginLeft\": \"-0.07153em\",\n                            \"marginRight\": \"0.05em\",\n                            \"top\": \"-2.5500000000000003em\",\n                          }\n                        }\n                      >\n                        <span\n                          className=\"pstrut\"\n                          style={\n                            Object {\n                              \"height\": \"2.7em\",\n                            }\n                          }\n                        />\n                        <span\n                          className=\"sizing reset-size6 size3 mtight\"\n                        >\n                          <span\n                            className=\"mord mathnormal mtight\"\n                          >\n                            L\n                          </span>\n                        </span>\n                      </span>\n                    </span>\n                    <span\n                      className=\"vlist-s\"\n                    >\n                      ​\n                    </span>\n                  </span>\n                  <span\n                    className=\"vlist-r\"\n                  >\n                    <span\n                      className=\"vlist\"\n                      style={\n                        Object {\n                          \"height\": \"0.15em\",\n                        }\n                      }\n                    >\n                      <span />\n                    </span>\n                  </span>\n                </span>\n              </span>\n            </span>\n          </span>\n        </span>\n      </span>\n    </span>\n    ) like the following equation.\n  </p>\n</React.Fragment>\n`;\n\nexports[`useRemarkSync should render content 1`] = `\n<React.Fragment>\n  <h1>\n    header\n  </h1>\n</React.Fragment>\n`;\n\nexports[`useRemarkSync should support custom element renderer 1`] = `\n<React.Fragment>\n  <h1>\n    heading\n  </h1>\n</React.Fragment>\n`;\n\nexports[`useRemarkSync should support gfm through remark plugins 1`] = `\n<React.Fragment>\n  <p>\n    <a\n      href=\"https://example.com\"\n    >\n      https://example.com\n    </a>\n  </p>\n</React.Fragment>\n`;\n\nexports[`useRemarkSync should support html through rehype plugins 1`] = `\n<React.Fragment>\n  <p>\n    <span>\n      example\n    </span>\n  </p>\n</React.Fragment>\n`;\n\nexports[`useRemarkSync should support math through remark and rehype plugins 1`] = `\n<React.Fragment>\n  <p>\n    Lift(\n    <span\n      className=\"math math-inline\"\n    >\n      <span\n        className=\"katex\"\n      >\n        <span\n          className=\"katex-mathml\"\n        >\n          <math\n            xmlns=\"http://www.w3.org/1998/Math/MathML\"\n          >\n            <semantics>\n              <mrow>\n                <mi>\n                  L\n                </mi>\n              </mrow>\n              <annotation\n                encoding=\"application/x-tex\"\n              >\n                L\n              </annotation>\n            </semantics>\n          </math>\n        </span>\n        <span\n          aria-hidden=\"true\"\n          className=\"katex-html\"\n        >\n          <span\n            className=\"base\"\n          >\n            <span\n              className=\"strut\"\n              style={\n                Object {\n                  \"height\": \"0.68333em\",\n                  \"verticalAlign\": \"0em\",\n                }\n              }\n            />\n            <span\n              className=\"mord mathnormal\"\n            >\n              L\n            </span>\n          </span>\n        </span>\n      </span>\n    </span>\n    ) can be determined by Lift Coefficient (\n    <span\n      className=\"math math-inline\"\n    >\n      <span\n        className=\"katex\"\n      >\n        <span\n          className=\"katex-mathml\"\n        >\n          <math\n            xmlns=\"http://www.w3.org/1998/Math/MathML\"\n          >\n            <semantics>\n              <mrow>\n                <msub>\n                  <mi>\n                    C\n                  </mi>\n                  <mi>\n                    L\n                  </mi>\n                </msub>\n              </mrow>\n              <annotation\n                encoding=\"application/x-tex\"\n              >\n                C_L\n              </annotation>\n            </semantics>\n          </math>\n        </span>\n        <span\n          aria-hidden=\"true\"\n          className=\"katex-html\"\n        >\n          <span\n            className=\"base\"\n          >\n            <span\n              className=\"strut\"\n              style={\n                Object {\n                  \"height\": \"0.83333em\",\n                  \"verticalAlign\": \"-0.15em\",\n                }\n              }\n            />\n            <span\n              className=\"mord\"\n            >\n              <span\n                className=\"mord mathnormal\"\n                style={\n                  Object {\n                    \"marginRight\": \"0.07153em\",\n                  }\n                }\n              >\n                C\n              </span>\n              <span\n                className=\"msupsub\"\n              >\n                <span\n                  className=\"vlist-t vlist-t2\"\n                >\n                  <span\n                    className=\"vlist-r\"\n                  >\n                    <span\n                      className=\"vlist\"\n                      style={\n                        Object {\n                          \"height\": \"0.32833099999999993em\",\n                        }\n                      }\n                    >\n                      <span\n                        style={\n                          Object {\n                            \"marginLeft\": \"-0.07153em\",\n                            \"marginRight\": \"0.05em\",\n                            \"top\": \"-2.5500000000000003em\",\n                          }\n                        }\n                      >\n                        <span\n                          className=\"pstrut\"\n                          style={\n                            Object {\n                              \"height\": \"2.7em\",\n                            }\n                          }\n                        />\n                        <span\n                          className=\"sizing reset-size6 size3 mtight\"\n                        >\n                          <span\n                            className=\"mord mathnormal mtight\"\n                          >\n                            L\n                          </span>\n                        </span>\n                      </span>\n                    </span>\n                    <span\n                      className=\"vlist-s\"\n                    >\n                      ​\n                    </span>\n                  </span>\n                  <span\n                    className=\"vlist-r\"\n                  >\n                    <span\n                      className=\"vlist\"\n                      style={\n                        Object {\n                          \"height\": \"0.15em\",\n                        }\n                      }\n                    >\n                      <span />\n                    </span>\n                  </span>\n                </span>\n              </span>\n            </span>\n          </span>\n        </span>\n      </span>\n    </span>\n    ) like the following equation.\n  </p>\n</React.Fragment>\n`;\n"
  },
  {
    "path": "test/remark-component.test.tsx",
    "content": "import React from 'react';\nimport { render, waitFor } from '@testing-library/react';\nimport '@testing-library/jest-dom/extend-expect';\nimport { Remark } from '../src';\n\ndescribe('Remark', () => {\n  it('should render content', async () => {\n    const { container, getByText } = render(<Remark># header</Remark>);\n    await waitFor(() => {\n      expect(getByText('header')).toBeInTheDocument();\n    });\n    expect(container.firstChild).toMatchSnapshot();\n  });\n});\n"
  },
  {
    "path": "test/remark-hook.test.ts",
    "content": "import { createElement } from 'react';\nimport type { ComponentPropsWithoutNode } from 'rehype-react';\nimport { renderHook, act } from '@testing-library/react-hooks';\nimport '@testing-library/jest-dom/extend-expect';\nimport remarkGfm from 'remark-gfm';\nimport rehypeRaw from 'rehype-raw';\nimport rehypeSanitize from 'rehype-sanitize';\nimport remarkMath from 'remark-math';\nimport rehypeKatex from 'rehype-katex';\nimport { useRemark, useRemarkSync } from '../src';\n\ndescribe('useRemark', () => {\n  it('should render content', async () => {\n    const { result, waitForNextUpdate } = renderHook(() => useRemark());\n    act(() => {\n      result.current[1]('# header');\n    });\n    await waitForNextUpdate();\n    expect(result.current[0]).toMatchSnapshot();\n  });\n\n  it('should support gfm through remark plugins', async () => {\n    const { result, waitForNextUpdate } = renderHook(() =>\n      useRemark({ remarkPlugins: [remarkGfm] })\n    );\n    act(() => {\n      result.current[1]('https://example.com');\n    });\n    await waitForNextUpdate();\n    expect(result.current[0]).toMatchSnapshot();\n  });\n\n  it('should support html through rehype plugins', async () => {\n    const { result, waitForNextUpdate } = renderHook(() =>\n      useRemark({\n        remarkToRehypeOptions: { allowDangerousHtml: true },\n        rehypePlugins: [rehypeRaw, rehypeSanitize],\n      })\n    );\n    act(() => {\n      result.current[1]('<span>example</span>');\n    });\n    await waitForNextUpdate();\n    expect(result.current[0]).toMatchSnapshot();\n  });\n\n  it('should support math through remark and rehype plugins', async () => {\n    const { result, waitForNextUpdate } = renderHook(() =>\n      useRemark({\n        remarkPlugins: [remarkMath],\n        rehypePlugins: [rehypeKatex],\n      })\n    );\n    act(() => {\n      result.current[1](\n        'Lift($L$) can be determined by Lift Coefficient ($C_L$) like the following equation.'\n      );\n    });\n    await waitForNextUpdate();\n    expect(result.current[0]).toMatchSnapshot();\n  });\n\n  it('should support custom element renderer', async () => {\n    const { result, waitForNextUpdate } = renderHook(() =>\n      useRemark({\n        rehypeReactOptions: {\n          components: {\n            h1: (props: ComponentPropsWithoutNode) =>\n              createElement('h2', props),\n          },\n        },\n      })\n    );\n    act(() => {\n      result.current[1]('# heading');\n    });\n    await waitForNextUpdate();\n    expect(result.current[0]).toMatchSnapshot();\n  });\n});\n\ndescribe('useRemarkSync', () => {\n  it('should render content', async () => {\n    const { result } = renderHook(() => useRemarkSync('# header'));\n    expect(result.current).toMatchSnapshot();\n  });\n\n  it('should support gfm through remark plugins', async () => {\n    const { result } = renderHook(() =>\n      useRemarkSync('https://example.com', { remarkPlugins: [remarkGfm] })\n    );\n    expect(result.current).toMatchSnapshot();\n  });\n\n  it('should support html through rehype plugins', async () => {\n    const { result } = renderHook(() =>\n      useRemarkSync('<span>example</span>', {\n        remarkToRehypeOptions: { allowDangerousHtml: true },\n        rehypePlugins: [rehypeRaw, rehypeSanitize],\n      })\n    );\n    expect(result.current).toMatchSnapshot();\n  });\n\n  it('should support math through remark and rehype plugins', async () => {\n    const { result } = renderHook(() =>\n      useRemarkSync(\n        'Lift($L$) can be determined by Lift Coefficient ($C_L$) like the following equation.',\n        {\n          remarkPlugins: [remarkMath],\n          rehypePlugins: [rehypeKatex],\n        }\n      )\n    );\n    expect(result.current).toMatchSnapshot();\n  });\n\n  it('should support custom element renderer', async () => {\n    const { result } = renderHook(() =>\n      useRemarkSync('# heading', {\n        rehypeReactOptions: {\n          components: {\n            h1: (props: ComponentPropsWithoutNode) =>\n              createElement('h2', props),\n          },\n        },\n      })\n    );\n    expect(result.current).toMatchSnapshot();\n  });\n});\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"include\": [\"src\", \"types\"],\n  \"compilerOptions\": {\n    \"module\": \"esnext\",\n    \"lib\": [\"dom\", \"esnext\"],\n    \"importHelpers\": true,\n    \"declaration\": true,\n    \"sourceMap\": true,\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"moduleResolution\": \"node\",\n    \"baseUrl\": \"./\",\n    \"paths\": {\n      \"@\": [\"./\"],\n      \"*\": [\"src/*\", \"node_modules/*\"]\n    },\n    \"jsx\": \"react\",\n    \"esModuleInterop\": true\n  }\n}\n"
  }
]