From 1b4455a535294e9198edb3c12160058e265776b0 Mon Sep 17 00:00:00 2001 From: sibiraj-s Date: Wed, 27 Oct 2021 08:55:20 +0530 Subject: [PATCH] Initial commit --- .babelrc | 5 + .eslintrc.yml | 23 + .github/workflows/tests.yml | 37 + .gitignore | 327 + .husky/pre-commit | 4 + .husky/pre-push | 4 + .lintstagedrc.yml | 2 + .prettierrc.yml | 2 + LICENSE | 21 + README.md | 45 + demo/App.css | 33 + demo/App.jsx | 25 + demo/favicon.svg | 15 + demo/index.css | 24 + demo/main.jsx | 10 + demo/markdown.css | 43 + index.html | 13 + jest.config.js | 200 + package-lock.json | 17099 ++++++++++++++++++++++++++++++++++ package.json | 64 + rollup.config.js | 29 + src/Markdown.js | 57 + src/ReactParser.js | 145 + src/ReactRenderer.js | 104 + src/helpers.js | 29 + src/index.d.ts | 20 + src/index.jsx | 7 + tests/component.spec.js | 38 + tests/markdown.spec.js | 175 + vite.config.js | 9 + 30 files changed, 18609 insertions(+) create mode 100644 .babelrc create mode 100644 .eslintrc.yml create mode 100644 .github/workflows/tests.yml create mode 100644 .gitignore create mode 100755 .husky/pre-commit create mode 100755 .husky/pre-push create mode 100644 .lintstagedrc.yml create mode 100644 .prettierrc.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 demo/App.css create mode 100644 demo/App.jsx create mode 100644 demo/favicon.svg create mode 100644 demo/index.css create mode 100644 demo/main.jsx create mode 100644 demo/markdown.css create mode 100644 index.html create mode 100644 jest.config.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 rollup.config.js create mode 100644 src/Markdown.js create mode 100644 src/ReactParser.js create mode 100644 src/ReactRenderer.js create mode 100644 src/helpers.js create mode 100644 src/index.d.ts create mode 100644 src/index.jsx create mode 100644 tests/component.spec.js create mode 100644 tests/markdown.spec.js create mode 100644 vite.config.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..a29ac99 --- /dev/null +++ b/.babelrc @@ -0,0 +1,5 @@ +{ + "presets": [ + "@babel/preset-env" + ] +} diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 0000000..f88f7b3 --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,23 @@ +root: true + +extends: + - pegasus + - plugin:react/recommended + - plugin:react-hooks/recommended + +rules: + react/react-in-jsx-scope: off + react/prop-types: off + +overrides: + - files: + - 'tests/*.js' + env: + jest: true + +settings: + react: + version: detect + +env: + browser: true diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..40ee3f2 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,37 @@ +name: Tests + +env: + NODE_VERSION: 16 + +on: + push: + branches: master + pull_request: + branches: master + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - uses: actions/setup-node@v2 + with: + node-version: ${{env.NODE_VERSION}} + cache: npm + + - run: node --version + - run: npm --version + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + env: + NODE_ENV: production + + - name: Tests + run: npm run test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a9f35f4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,327 @@ +### Bower ### +bower_components +.bower-cache +.bower-registry +.bower-tmp + +### grunt ### +# Grunt usually compiles files inside this directory +dist/ + +# Grunt usually preprocesses files such as coffeescript, compass... inside the .tmp directory +.tmp/ + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test +.env.production + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +### WebStorm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### WebStorm Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint +.idea/**/sonarlint/ + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator-enh.xml +.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +.idea/$CACHE_FILE$ + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream +.idea/codestream.xml + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### yarn ### +# https://yarnpkg.com/advanced/qa#which-files-should-be-gitignored + +.yarn/* +!.yarn/releases +!.yarn/plugins +!.yarn/sdks +!.yarn/versions + +# if you are NOT using Zero-installs, then: +# comment the following lines +!.yarn/cache + +# and uncomment the following lines +# .pnp.* diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..d37daa0 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npx --no-install lint-staged diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100755 index 0000000..d1096ab --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npm run test diff --git a/.lintstagedrc.yml b/.lintstagedrc.yml new file mode 100644 index 0000000..14d95da --- /dev/null +++ b/.lintstagedrc.yml @@ -0,0 +1,2 @@ +'*.{js,jsx}': eslint --fix --ignore-path .gitignore +'*.{html,css,md,ts}': prettier --write diff --git a/.prettierrc.yml b/.prettierrc.yml new file mode 100644 index 0000000..883b1cc --- /dev/null +++ b/.prettierrc.yml @@ -0,0 +1,2 @@ +singleQuote: true +semi: true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..802d591 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Sibiraj + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..db04039 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# marked-react + +> Render Markdown as React components using [marked](https://marked.js.org/). + +## TL;DR + +- Uses [marked](https://marked.js.org/) to parse markdown +- Renders actual react elements instead of using `dangerouslySetInnerHTML` + +## Installation + +```bash +$ npm i marked-react +``` + +If you are using `npm >=7`, peerDependencies are installed automatically. For other package managers +you might want to install `marked` manually + +```bash +$ yarn add marked marked-react +``` + +### Usage + +```js +import ReactDom from 'react-dom'; +import Markdown from 'marked-react'; + +const rootEl = document.getElementById('root'); + +ReactDom.render(# Hello world!, rootEl); +``` + +### Component Props + +- **value** - A markdown string(markdown). +- **options** - See [Options](#Options) + +### Options + +- **baseURL** [`string`] - A prefix url for any relative link. +- **openLinksInNewTab** [`boolean`] - Attribute `target=_blank` will be added to link elements +- **langPrefix** [`string`] - A string to prefix the className in a `` block. Useful for syntax highlighting. Defaults to `language-`. +- **breaks** [`boolean`] - Add `br` tag on single line breaks. Requires `gfm` to be `true` +- **gfm** [`boolean`] - Use approved [Github Flavoured Markdown](https://github.github.com/gfm/) diff --git a/demo/App.css b/demo/App.css new file mode 100644 index 0000000..b538061 --- /dev/null +++ b/demo/App.css @@ -0,0 +1,33 @@ +.Wrapper { + display: grid; + grid-template-columns: 1fr 1fr; + column-gap: 10px; + padding: 1rem; + height: 100vh; +} + +.Container { + display: flex; + flex-direction: column; +} + +textarea { + font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; + border: 1px solid black; + font-size: 12px; + height: 100%; + width: 100%; + resize: none; + padding: 5px; +} + +.Output { + border: 1px solid black; + padding: 0.5rem; + overflow-y: auto; + scroll-behavior: smooth; +} + +.Output pre { + flex-shrink: 0; +} diff --git a/demo/App.jsx b/demo/App.jsx new file mode 100644 index 0000000..5b96631 --- /dev/null +++ b/demo/App.jsx @@ -0,0 +1,25 @@ +import { useState } from 'react'; + +import Markdown from '../src'; +import readme from '../README.md?raw'; + +const App = () => { + const [markdownText, setMarkdownText] = useState(readme); + + const handleChange = (e) => { + setMarkdownText(e.target.value); + }; + + return ( +
+
+