From 692795a9a13e41e5cc7f99bae888b9af1a05c831 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Tue, 12 Apr 2022 08:59:50 -0400 Subject: [PATCH] [Gekidou] Code syntax highlight (#6156) * Code syntax highlight * fix code syntax imports for jest * feedback review --- .../markdown/markdown_code_block/index.tsx | 85 ++-- app/components/syntax_highlight/index.tsx | 85 ++++ app/components/syntax_highlight/renderer.tsx | 144 +++++++ app/constants/screens.ts | 2 + app/screens/code/index.tsx | 41 ++ app/screens/index.tsx | 3 + app/utils/markdown/index.ts | 151 ++++--- jest.config.js | 2 +- package-lock.json | 404 ++++++++++++++++++ package.json | 2 + ...ypes+react-syntax-highlighter+13.5.2.patch | 15 + patches/react-syntax-highlighter+15.5.0.patch | 7 + 12 files changed, 820 insertions(+), 121 deletions(-) create mode 100644 app/components/syntax_highlight/index.tsx create mode 100644 app/components/syntax_highlight/renderer.tsx create mode 100644 app/screens/code/index.tsx create mode 100644 patches/@types+react-syntax-highlighter+13.5.2.patch create mode 100644 patches/react-syntax-highlighter+15.5.0.patch diff --git a/app/components/markdown/markdown_code_block/index.tsx b/app/components/markdown/markdown_code_block/index.tsx index 44b0ae36c..63e17b8ce 100644 --- a/app/components/markdown/markdown_code_block/index.tsx +++ b/app/components/markdown/markdown_code_block/index.tsx @@ -9,9 +9,11 @@ import {Keyboard, StyleSheet, Text, TextStyle, TouchableOpacity, View} from 'rea import FormattedText from '@components/formatted_text'; import SlideUpPanelItem, {ITEM_HEIGHT} from '@components/slide_up_panel_item'; +import SyntaxHighlighter from '@components/syntax_highlight'; +import {Screens} from '@constants'; import {useTheme} from '@context/theme'; import {bottomSheet, dismissBottomSheet, goToScreen} from '@screens/navigation'; -import {getDisplayNameForLanguage} from '@utils/markdown'; +import {getHighlightLanguageFromNameOrAlias, getHighlightLanguageName} from '@utils/markdown'; import {preventDoubleTap} from '@utils/tap'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; @@ -34,36 +36,10 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { borderWidth: StyleSheet.hairlineWidth, flexDirection: 'row', }, - lineNumbers: { - alignItems: 'center', - backgroundColor: changeOpacity(theme.centerChannelColor, 0.05), - borderRightColor: changeOpacity(theme.centerChannelColor, 0.15), - borderRightWidth: StyleSheet.hairlineWidth, - flexDirection: 'column', - justifyContent: 'flex-start', - paddingVertical: 4, - width: 21, - }, - lineNumbersText: { - color: changeOpacity(theme.centerChannelColor, 0.5), - fontSize: 12, - lineHeight: 18, - }, - rightColumn: { - flexDirection: 'column', - flex: 1, - paddingHorizontal: 6, - paddingVertical: 4, - }, code: { flexDirection: 'row', overflow: 'scroll', // Doesn't actually cause a scrollbar, but stops text from wrapping }, - codeText: { - color: changeOpacity(theme.centerChannelColor, 0.65), - fontSize: 12, - lineHeight: 18, - }, plusMoreLinesText: { color: changeOpacity(theme.centerChannelColor, 0.4), fontSize: 11, @@ -93,12 +69,14 @@ const MarkdownCodeBlock = ({language = '', content, textStyle}: MarkdownCodeBloc const style = getStyleSheet(theme); const handlePress = preventDoubleTap(() => { - const screen = 'Code'; + const screen = Screens.CODE; const passProps = { - content, + code: content, + language, + textStyle, }; - const languageDisplayName = getDisplayNameForLanguage(language); + const languageDisplayName = getHighlightLanguageName(language); let title: string; if (languageDisplayName) { title = intl.formatMessage( @@ -182,7 +160,7 @@ const MarkdownCodeBlock = ({language = '', content, textStyle}: MarkdownCodeBloc const renderLanguageBlock = () => { if (language) { - const languageDisplayName = getDisplayNameForLanguage(language); + const languageDisplayName = getHighlightLanguageName(language); if (languageDisplayName) { return ( @@ -199,15 +177,6 @@ const MarkdownCodeBlock = ({language = '', content, textStyle}: MarkdownCodeBloc const {content: codeContent, numberOfLines} = trimContent(content); - const getLineNumbers = () => { - let lineNumbers = '1'; - for (let i = 1; i < Math.min(numberOfLines, MAX_LINES); i++) { - const line = (i + 1).toString(); - lineNumbers += '\n' + line; - } - return lineNumbers; - }; - const renderPlusMoreLines = () => { if (numberOfLines > MAX_LINES) { return ( @@ -225,26 +194,28 @@ const MarkdownCodeBlock = ({language = '', content, textStyle}: MarkdownCodeBloc }; return ( - - - - {getLineNumbers()} - - - - - {codeContent} - + <> + + + + + + + {renderPlusMoreLines()} - {renderPlusMoreLines()} + {renderLanguageBlock()} - {renderLanguageBlock()} - - + + ); }; export default MarkdownCodeBlock; + diff --git a/app/components/syntax_highlight/index.tsx b/app/components/syntax_highlight/index.tsx new file mode 100644 index 000000000..8a2d56393 --- /dev/null +++ b/app/components/syntax_highlight/index.tsx @@ -0,0 +1,85 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {useCallback, useMemo} from 'react'; +import {StyleSheet, TextStyle, View} from 'react-native'; +import SyntaxHighlighter from 'react-syntax-highlighter'; +import {github, monokai, solarizedDark, solarizedLight} from 'react-syntax-highlighter/dist/cjs/styles/hljs'; + +import {useTheme} from '@context/theme'; + +import CodeHighlightRenderer from './renderer'; + +type Props = { + code: string; + language: string; + textStyle: TextStyle; + selectable?: boolean; +} + +const codeTheme: Record = { + github, + monokai, + 'solarized-dark': solarizedDark, + 'solarized-light': solarizedLight, +}; + +const styles = StyleSheet.create({ + preTag: { + padding: 5, + width: '100%', + }, + flex: { + flex: 1, + }, +}); + +const Highlighter = ({code, language, textStyle, selectable = false}: Props) => { + const theme = useTheme(); + const style = codeTheme[theme.codeTheme] || github; + const preTagStyle = useMemo(() => [ + styles.preTag, + selectable && styles.flex, + {backgroundColor: style.hljs.background || theme.centerChannelBg}, + ], + [theme, selectable, style]); + + const nativeRenderer = useCallback(({rows, stylesheet}) => { + const digits = rows.length.toString().length; + return ( + + ); + }, [textStyle, theme, style]); + + const preTag = useCallback((info) => ( + + {info.children} + + ), [preTagStyle]); + + return ( + + {code} + + ); +}; + +export default Highlighter; diff --git a/app/components/syntax_highlight/renderer.tsx b/app/components/syntax_highlight/renderer.tsx new file mode 100644 index 000000000..d08be58a9 --- /dev/null +++ b/app/components/syntax_highlight/renderer.tsx @@ -0,0 +1,144 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {useCallback} from 'react'; +import {FlatList, ScrollView, StyleSheet, Text} from 'react-native'; +import {createStyleObject} from 'react-syntax-highlighter/create-element'; + +import {changeOpacity} from '@utils/theme'; + +type CreateChildren = { + digits: number; + stylesheet: any; + fontFamily: string; + fontSize?: number; + selectable?: boolean; +} + +type CreateNativeElement = CreateChildren & { + node: any; + key: string; + defaultColor: string; +} + +type Props = CreateChildren & Pick & { + rows: any[]; +} + +const styles = StyleSheet.create({ + wrapped: { + flexWrap: 'nowrap', + }, +}); + +function createChildren({stylesheet, fontSize = 12, fontFamily, selectable, digits}: CreateChildren) { + let childrenCount = 0; + return (children: any[], defaultColor: string) => { + childrenCount += 1; + return children.map((child, i) => { + return createNativeElement({ + node: child, + stylesheet, + key: `code-segment-${childrenCount}-${i}`, + defaultColor, + fontSize, + fontFamily, + selectable, + digits, + }); + }); + }; +} + +function createNativeElement({node, stylesheet, key, defaultColor, fontFamily, fontSize = 12, selectable, digits}: CreateNativeElement) { + const {properties, type, tagName: TagName, value} = node; + const startingStyle = {fontFamily, fontSize, height: fontSize + 7}; + if (properties?.key?.startsWith('line-number')) { + let valueString = `${node.children[0].value}. `; + for (let i = valueString.length; i < digits + 2; i++) { + valueString += ' '; + } + + return ( + + {valueString} + + ); + } + if (type === 'text') { + return ( + + {value} + + ); + } else if (TagName) { + const childrenCreator = createChildren({stylesheet, fontSize, fontFamily, digits}); + if (properties.style?.display) { + properties.style.display = 'flex'; + } + if (properties.style?.paddingRight) { + delete properties.style.paddingRight; + } + if (properties.style?.userSelect) { + delete properties.style.userSelect; + } + const style = createStyleObject( + properties.className, + { + color: defaultColor, + ...properties.style, + ...startingStyle, + }, + stylesheet, + ); + const children = childrenCreator(node.children, style.color || defaultColor); + return ( + + {children} + + ); + } + + return null; +} + +const CodeHighlightRenderer = ({defaultColor, digits, fontFamily, fontSize, rows, selectable, stylesheet}: Props) => { + const renderItem = useCallback(({item, index}) => { + return createNativeElement({ + node: item, + stylesheet, + key: `code-segment-${index}`, + defaultColor, + fontFamily, + fontSize, + selectable, + digits, + }); + }, [defaultColor, digits, fontFamily, fontSize, stylesheet]); + + return ( + + + + ); +}; + +export default CodeHighlightRenderer; diff --git a/app/constants/screens.ts b/app/constants/screens.ts index d949bfe55..196448a86 100644 --- a/app/constants/screens.ts +++ b/app/constants/screens.ts @@ -11,6 +11,7 @@ export const CHANNEL = 'Channel'; export const CHANNEL_ADD_PEOPLE = 'ChannelAddPeople'; export const CHANNEL_DETAILS = 'ChannelDetails'; export const CHANNEL_EDIT = 'ChannelEdit'; +export const CODE = 'Code'; export const CREATE_DIRECT_MESSAGE = 'CreateDirectMessage'; export const CREATE_OR_EDIT_CHANNEL = 'CreateOrEditChannel'; export const CUSTOM_STATUS = 'CustomStatus'; @@ -51,6 +52,7 @@ export default { CHANNEL_ADD_PEOPLE, CHANNEL_EDIT, CHANNEL_DETAILS, + CODE, CREATE_DIRECT_MESSAGE, CUSTOM_STATUS_CLEAR_AFTER, CUSTOM_STATUS, diff --git a/app/screens/code/index.tsx b/app/screens/code/index.tsx new file mode 100644 index 000000000..991360a6e --- /dev/null +++ b/app/screens/code/index.tsx @@ -0,0 +1,41 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {useManagedConfig} from '@mattermost/react-native-emm'; +import React from 'react'; +import {StyleSheet, TextStyle} from 'react-native'; +import {SafeAreaView, Edge} from 'react-native-safe-area-context'; + +import SyntaxHiglight from '@components/syntax_highlight'; + +type Props = { + code: string; + language: string; + textStyle: TextStyle; +} + +const edges: Edge[] = ['left', 'right']; + +const styles = StyleSheet.create({ + flex: {flex: 1}, +}); + +const Code = ({code, language, textStyle}: Props) => { + const managedConfig = useManagedConfig(); + + return ( + + + + ); +}; + +export default Code; diff --git a/app/screens/index.tsx b/app/screens/index.tsx index ff64a4130..232556e6d 100644 --- a/app/screens/index.tsx +++ b/app/screens/index.tsx @@ -70,6 +70,9 @@ Navigation.setLazyComponentRegistrator((screenName) => { case Screens.CHANNEL: screen = withServerDatabase(require('@screens/channel').default); break; + case Screens.CODE: + screen = withServerDatabase(require('@screens/code').default); + break; case Screens.CREATE_OR_EDIT_CHANNEL: screen = withServerDatabase(require('@screens/create_or_edit_channel').default); break; diff --git a/app/utils/markdown/index.ts b/app/utils/markdown/index.ts index a57e35502..ca4295fbc 100644 --- a/app/utils/markdown/index.ts +++ b/app/utils/markdown/index.ts @@ -7,6 +7,14 @@ import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import {getViewPortWidth} from '../images'; +type LanguageObject = { + [key: string]: { + name: string; + extensions: string[]; + aliases?: Set; + }; +} + export function getCodeFont() { return Platform.OS === 'ios' ? 'Menlo' : 'monospace'; } @@ -119,71 +127,88 @@ export const getMarkdownBlockStyles = makeStyleSheetFromTheme((theme: Theme) => }; }); -const languages: Record = { - actionscript: 'ActionScript', - applescript: 'AppleScript', - bash: 'Bash', - clojure: 'Clojure', - coffeescript: 'CoffeeScript', - cpp: 'C++', - cs: 'C#', - css: 'CSS', - d: 'D', - dart: 'Dart', - delphi: 'Delphi', - diff: 'Diff', - django: 'Django', - dockerfile: 'Dockerfile', - elixir: 'Elixir', - erlang: 'Erlang', - fortran: 'Fortran', - fsharp: 'F#', - gcode: 'G-code', - go: 'Go', - groovy: 'Groovy', - handlebars: 'Handlebars', - haskell: 'Haskell', - haxe: 'Haxe', - html: 'HTML', - java: 'Java', - javascript: 'JavaScript', - js: 'JavaScript', - json: 'JSON', - julia: 'Julia', - kotlin: 'Kotlin', - latex: 'LaTeX', - less: 'Less', - lisp: 'Lisp', - lua: 'Lua', - makefile: 'Makefile', - markdown: 'Markdown', - matlab: 'Matlab', - objectivec: 'Objective-C', - ocaml: 'OCaml', - perl: 'Perl', - php: 'PHP', - powershell: 'PowerShell', - puppet: 'Puppet', - python: 'Python', - r: 'R', - ruby: 'Ruby', - rust: 'Rust', - scala: 'Scala', - scheme: 'Scheme', - scss: 'SCSS', - smalltalk: 'Smalltalk', - sql: 'SQL', - swift: 'Swift', - tex: 'TeX', - vbnet: 'VB.NET', - vbscript: 'VBScript', - verilog: 'Verilog', - xml: 'XML', - yaml: 'YAML', +const highlightedLanguages: LanguageObject = { + actionscript: {name: 'ActionScript', extensions: ['as'], aliases: new Set(['as', 'as3'])}, + applescript: {name: 'AppleScript', extensions: ['applescript', 'osascript', 'scpt']}, + bash: {name: 'Bash', extensions: ['sh'], aliases: new Set('sh')}, + clojure: {name: 'Clojure', extensions: ['clj', 'boot', 'cl2', 'cljc', 'cljs', 'cljs.hl', 'cljscm', 'cljx', 'hic']}, + coffeescript: {name: 'CoffeeScript', extensions: ['coffee', '_coffee', 'cake', 'cjsx', 'cson', 'iced'], aliases: new Set(['coffee', 'coffee-script'])}, + cpp: {name: 'C/C++', extensions: ['cpp', 'c', 'cc', 'h', 'c++', 'h++', 'hpp'], aliases: new Set(['c++', 'c'])}, + cs: {name: 'C#', extensions: ['cs', 'csharp'], aliases: new Set(['c#', 'csharp'])}, + css: {name: 'CSS', extensions: ['css']}, + d: {name: 'D', extensions: ['d', 'di'], aliases: new Set('dlang')}, + dart: {name: 'Dart', extensions: ['dart']}, + delphi: {name: 'Delphi', extensions: ['delphi', 'dpr', 'dfm', 'pas', 'pascal', 'freepascal', 'lazarus', 'lpr', 'lfm']}, + diff: {name: 'Diff', extensions: ['diff', 'patch'], aliases: new Set(['patch', 'udiff'])}, + django: {name: 'Django', extensions: ['django', 'jinja']}, + dockerfile: {name: 'Dockerfile', extensions: ['dockerfile', 'docker'], aliases: new Set('docker')}, + elixir: {name: 'Elixir', extensions: ['ex', 'exs'], aliases: new Set(['ex', 'exs'])}, + erlang: {name: 'Erlang', extensions: ['erl'], aliases: new Set('erl')}, + fortran: {name: 'Fortran', extensions: ['f90', 'f95']}, + fsharp: {name: 'F#', extensions: ['fsharp', 'fs']}, + gcode: {name: 'G-Code', extensions: ['gcode', 'nc']}, + go: {name: 'Go', extensions: ['go'], aliases: new Set('golang')}, + groovy: {name: 'Groovy', extensions: ['groovy']}, + handlebars: {name: 'Handlebars', extensions: ['handlebars', 'hbs', 'html.hbs', 'html.handlebars'], aliases: new Set(['hbs', 'mustache'])}, + haskell: {name: 'Haskell', extensions: ['hs'], aliases: new Set('hs')}, + haxe: {name: 'Haxe', extensions: ['hx']}, + java: {name: 'Java', extensions: ['java', 'jsp']}, + javascript: {name: 'JavaScript', extensions: ['js', 'jsx'], aliases: new Set(['js', 'jsx'])}, + json: {name: 'JSON', extensions: ['json']}, + julia: {name: 'Julia', extensions: ['jl'], aliases: new Set('jl')}, + kotlin: {name: 'Kotlin', extensions: ['kt', 'ktm', 'kts']}, + latex: {name: 'LaTeX', extensions: ['tex'], aliases: new Set('tex')}, + less: {name: 'Less', extensions: ['less']}, + lisp: {name: 'Lisp', extensions: ['lisp']}, + lua: {name: 'Lua', extensions: ['lua']}, + makefile: {name: 'Makefile', extensions: ['mk', 'mak'], aliases: new Set(['make', 'mf', 'gnumake', 'bsdmake'])}, + markdown: {name: 'Markdown', extensions: ['md', 'mkdown', 'mkd'], aliases: new Set(['md', 'mkd'])}, + matlab: {name: 'Matlab', extensions: ['matlab', 'm'], aliases: new Set('m')}, + objectivec: {name: 'Objective C', extensions: ['mm', 'objc', 'obj-c'], aliases: new Set(['objective_c', 'objc'])}, + ocaml: {name: 'OCaml', extensions: ['ml']}, + perl: {name: 'Perl', extensions: ['perl', 'pl'], aliases: new Set('pl')}, + pgsql: {name: 'PostgreSQL', extensions: ['pgsql', 'postgres', 'postgresql'], aliases: new Set(['postgres', 'postgresql'])}, + php: {name: 'PHP', extensions: ['php', 'php3', 'php4', 'php5', 'php6'], aliases: new Set(['php3', 'php4', 'php5'])}, + powershell: {name: 'PowerShell', extensions: ['ps', 'ps1'], aliases: new Set('posh')}, + puppet: {name: 'Puppet', extensions: ['pp'], aliases: new Set('pp')}, + python: {name: 'Python', extensions: ['py', 'gyp'], aliases: new Set('py')}, + r: {name: 'R', extensions: ['r'], aliases: new Set(['r', 's'])}, + ruby: {name: 'Ruby', extensions: ['ruby', 'rb', 'gemspec', 'podspec', 'thor', 'irb'], aliases: new Set('rb')}, + rust: {name: 'Rust', extensions: ['rs'], aliases: new Set('rs')}, + scala: {name: 'Scala', extensions: ['scala']}, + scheme: {name: 'Scheme', extensions: ['scm', 'sld']}, + scss: {name: 'SCSS', extensions: ['scss']}, + smalltalk: {name: 'Smalltalk', extensions: ['st'], aliases: new Set(['st', 'squeak'])}, + sql: {name: 'SQL', extensions: ['sql']}, + stylus: {name: 'Stylus', extensions: ['styl'], aliases: new Set('styl')}, + swift: {name: 'Swift', extensions: ['swift']}, + text: {name: 'Text', extensions: ['txt', 'log']}, + typescript: {name: 'TypeScript', extensions: ['ts', 'tsx'], aliases: new Set(['ts', 'tsx'])}, + vbnet: {name: 'VB.Net', extensions: ['vbnet', 'vb', 'bas'], aliases: new Set(['vb', 'visualbasic'])}, + vbscript: {name: 'VBScript', extensions: ['vbs']}, + verilog: {name: 'Verilog', extensions: ['v', 'veo', 'sv', 'svh']}, + vhdl: {name: 'VHDL', extensions: ['vhd', 'vhdl']}, + xml: {name: 'HTML, XML', extensions: ['xml', 'html', 'xhtml', 'rss', 'atom', 'xsl', 'plist']}, + yaml: {name: 'YAML', extensions: ['yaml'], aliases: new Set('yml')}, }; -export function getDisplayNameForLanguage(language: string) { - return languages[language.toLowerCase()] || ''; +export function getHighlightLanguageFromNameOrAlias(name: string) { + const langName: string = name.toLowerCase(); + if (highlightedLanguages[langName]) { + return langName; + } + + return Object.keys(highlightedLanguages).find((key) => { + return highlightedLanguages[key].aliases?.has(langName); + }) || ''; +} + +export function getHighlightLanguageName(language: string): string { + const name: string | undefined = getHighlightLanguageFromNameOrAlias(language); + if (!name) { + return ''; + } + return highlightedLanguages[name].name || ''; } export function escapeRegex(text: string) { diff --git a/jest.config.js b/jest.config.js index 4b034c1e2..a081ff4b8 100644 --- a/jest.config.js +++ b/jest.config.js @@ -20,6 +20,6 @@ module.exports = { '/dist/assets/images/video_player/$1@2x.png', }, transformIgnorePatterns: [ - 'node_modules/(?!(@react-native|react-native)|jail-monkey|@sentry/react-native|react-navigation|@react-native-community/cameraroll|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|sentry-expo|native-base|validator)', + 'node_modules/(?!(@react-native|react-native)|jail-monkey|@sentry/react-native|@react-native-community/cameraroll|react-clone-referenced-element|@react-native-community|react-navigation|@react-navigation/.*|validator|react-syntax-highlighter/.*)', ], }; diff --git a/package-lock.json b/package-lock.json index 9f8a4dd4b..d531aeef7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,6 +84,7 @@ "react-native-video": "5.2.0", "react-native-webview": "11.18.1", "react-native-youtube": "2.0.2", + "react-syntax-highlighter": "15.5.0", "reanimated-bottom-sheet": "1.0.0-alpha.22", "rn-placeholder": "3.0.3", "semver": "7.3.6", @@ -119,6 +120,7 @@ "@types/react-native-button": "3.0.1", "@types/react-native-share": "3.3.3", "@types/react-native-video": "5.0.13", + "@types/react-syntax-highlighter": "13.5.2", "@types/react-test-renderer": "17.0.1", "@types/semver": "7.3.9", "@types/shallow-equals": "1.0.0", @@ -5631,6 +5633,14 @@ "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.40.tgz", "integrity": "sha512-VbjwR1fhsn2h2KXAY4oy1fm7dCxaKy0D+deTb8Ilc3Eo3rc5+5eA4rfYmZaHgNJKxVyI0f6WIXzO2zLkVmQPHA==" }, + "node_modules/@types/hast": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", + "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -5785,6 +5795,15 @@ "@types/react-native": "*" } }, + "node_modules/@types/react-syntax-highlighter": { + "version": "13.5.2", + "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-13.5.2.tgz", + "integrity": "sha512-sRZoKZBGKaE7CzMvTTgz+0x/aVR58ZYUTfB7HN76vC+yQnvo1FWtzNARBt0fGqcLGEVakEzMu/CtPzssmanu8Q==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-test-renderer": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz", @@ -5829,6 +5848,11 @@ "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==", "dev": true }, + "node_modules/@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" + }, "node_modules/@types/url-parse": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/@types/url-parse/-/url-parse-1.4.8.tgz", @@ -8079,6 +8103,33 @@ "node": ">=10" } }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/charcodes": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/charcodes/-/charcodes-0.2.0.tgz", @@ -8430,6 +8481,15 @@ "node": ">= 0.8" } }, + "node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", @@ -10921,6 +10981,18 @@ "reusify": "^1.0.4" } }, + "node_modules/fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -11389,6 +11461,14 @@ "node": ">= 6" } }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -11892,6 +11972,31 @@ "minimalistic-assert": "^1.0.1" } }, + "node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -11939,6 +12044,14 @@ "node": ">= 8" } }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "engines": { + "node": "*" + } + }, "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -12342,6 +12455,28 @@ "node": ">=0.10.0" } }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -12470,6 +12605,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", @@ -12569,6 +12713,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -15531,6 +15684,19 @@ "react-native": ">=0.46" } }, + "node_modules/lowlight": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", + "dependencies": { + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -17929,6 +18095,23 @@ "safe-buffer": "^5.1.1" } }, + "node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -18278,6 +18461,14 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "node_modules/prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", + "engines": { + "node": ">=6" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -18364,6 +18555,18 @@ "signal-exit": "^3.0.2" } }, + "node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -19390,6 +19593,21 @@ "react": "^16.0.0 || ^17.0.0" } }, + "node_modules/react-syntax-highlighter": { + "version": "15.5.0", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", + "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "highlight.js": "^10.4.1", + "lowlight": "^1.17.0", + "prismjs": "^1.27.0", + "refractor": "^3.6.0" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, "node_modules/react-test-renderer": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz", @@ -19530,6 +19748,20 @@ "fbjs": "^0.8.9" } }, + "node_modules/refractor": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", + "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", + "dependencies": { + "hastscript": "^6.0.0", + "parse-entities": "^2.0.0", + "prismjs": "~1.27.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -20567,6 +20799,15 @@ "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "deprecated": "See https://github.com/lydell/source-map-url#deprecated" }, + "node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/split-on-first": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", @@ -27219,6 +27460,14 @@ "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.40.tgz", "integrity": "sha512-VbjwR1fhsn2h2KXAY4oy1fm7dCxaKy0D+deTb8Ilc3Eo3rc5+5eA4rfYmZaHgNJKxVyI0f6WIXzO2zLkVmQPHA==" }, + "@types/hast": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", + "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", + "requires": { + "@types/unist": "*" + } + }, "@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -27373,6 +27622,15 @@ "@types/react-native": "*" } }, + "@types/react-syntax-highlighter": { + "version": "13.5.2", + "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-13.5.2.tgz", + "integrity": "sha512-sRZoKZBGKaE7CzMvTTgz+0x/aVR58ZYUTfB7HN76vC+yQnvo1FWtzNARBt0fGqcLGEVakEzMu/CtPzssmanu8Q==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-test-renderer": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz", @@ -27417,6 +27675,11 @@ "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==", "dev": true }, + "@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" + }, "@types/url-parse": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/@types/url-parse/-/url-parse-1.4.8.tgz", @@ -29154,6 +29417,21 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" + }, + "character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" + }, + "character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" + }, "charcodes": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/charcodes/-/charcodes-0.2.0.tgz", @@ -29441,6 +29719,11 @@ "delayed-stream": "~1.0.0" } }, + "comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" + }, "command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", @@ -31392,6 +31675,14 @@ "reusify": "^1.0.4" } }, + "fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "requires": { + "format": "^0.2.0" + } + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -31776,6 +32067,11 @@ "mime-types": "^2.1.12" } }, + "format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=" + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -32151,6 +32447,23 @@ "minimalistic-assert": "^1.0.1" } }, + "hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" + }, + "hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "requires": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -32191,6 +32504,11 @@ } } }, + "highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -32501,6 +32819,20 @@ "kind-of": "^6.0.0" } }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, "is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -32592,6 +32924,11 @@ "has-tostringtag": "^1.0.0" } }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" + }, "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", @@ -32655,6 +32992,11 @@ "is-extglob": "^2.1.1" } }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" + }, "is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -34882,6 +35224,15 @@ "react-native-safe-modules": "^1.0.3" } }, + "lowlight": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", + "requires": { + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + } + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -36832,6 +37183,19 @@ "safe-buffer": "^5.1.1" } }, + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -37091,6 +37455,11 @@ } } }, + "prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==" + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -37165,6 +37534,14 @@ "signal-exit": "^3.0.2" } }, + "property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "requires": { + "xtend": "^4.0.0" + } + }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -37965,6 +38342,18 @@ "react-is": "^16.12.0 || ^17.0.0" } }, + "react-syntax-highlighter": { + "version": "15.5.0", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", + "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==", + "requires": { + "@babel/runtime": "^7.3.1", + "highlight.js": "^10.4.1", + "lowlight": "^1.17.0", + "prismjs": "^1.27.0", + "refractor": "^3.6.0" + } + }, "react-test-renderer": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz", @@ -38088,6 +38477,16 @@ } } }, + "refractor": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", + "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", + "requires": { + "hastscript": "^6.0.0", + "parse-entities": "^2.0.0", + "prismjs": "~1.27.0" + } + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -38924,6 +39323,11 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" }, + "space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" + }, "split-on-first": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", diff --git a/package.json b/package.json index 04754af81..6c067883f 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "react-native-video": "5.2.0", "react-native-webview": "11.18.1", "react-native-youtube": "2.0.2", + "react-syntax-highlighter": "15.5.0", "reanimated-bottom-sheet": "1.0.0-alpha.22", "rn-placeholder": "3.0.3", "semver": "7.3.6", @@ -117,6 +118,7 @@ "@types/react-native-button": "3.0.1", "@types/react-native-share": "3.3.3", "@types/react-native-video": "5.0.13", + "@types/react-syntax-highlighter": "13.5.2", "@types/react-test-renderer": "17.0.1", "@types/semver": "7.3.9", "@types/shallow-equals": "1.0.0", diff --git a/patches/@types+react-syntax-highlighter+13.5.2.patch b/patches/@types+react-syntax-highlighter+13.5.2.patch new file mode 100644 index 000000000..0122ba288 --- /dev/null +++ b/patches/@types+react-syntax-highlighter+13.5.2.patch @@ -0,0 +1,15 @@ +diff --git a/node_modules/@types/react-syntax-highlighter/index.d.ts b/node_modules/@types/react-syntax-highlighter/index.d.ts +index 6ee9af3..cf1516e 100755 +--- a/node_modules/@types/react-syntax-highlighter/index.d.ts ++++ b/node_modules/@types/react-syntax-highlighter/index.d.ts +@@ -33,6 +33,10 @@ declare module 'react-syntax-highlighter' { + export { default as Prism } from 'react-syntax-highlighter/dist/esm/prism'; + } + ++declare module 'react-syntax-highlighter/create-element' { ++ export {createStyleObject} from 'react-syntax-highlighter/create-element'; ++} ++ + // esm start + declare module 'react-syntax-highlighter/dist/esm/default-highlight' { + import * as React from 'react'; diff --git a/patches/react-syntax-highlighter+15.5.0.patch b/patches/react-syntax-highlighter+15.5.0.patch new file mode 100644 index 000000000..ecc3b8514 --- /dev/null +++ b/patches/react-syntax-highlighter+15.5.0.patch @@ -0,0 +1,7 @@ +diff --git a/node_modules/react-syntax-highlighter/create-element.js b/node_modules/react-syntax-highlighter/create-element.js +index 76d3cf2..1951d6c 100644 +--- a/node_modules/react-syntax-highlighter/create-element.js ++++ b/node_modules/react-syntax-highlighter/create-element.js +@@ -1 +1 @@ +-export { default } from './dist/esm/create-element'; ++export { default, createStyleObject } from './dist/esm/create-element';