├── .eslintrc ├── .github ├── dependabot.yml └── workflows │ └── node.js.yml ├── .gitignore ├── .npmignore ├── .prettierrc ├── .storybook └── main.js ├── .travis.yml ├── LICENSE ├── README.md ├── build ├── Components │ ├── ClipBoard.d.ts │ ├── HighLighterProps.d.ts │ ├── Highlighter.d.ts │ └── utils.highlight.d.ts ├── Icons │ ├── Copy.d.ts │ ├── CopyProps.d.ts │ ├── Done.d.ts │ ├── DoneProps.d.ts │ ├── IconProps.d.ts │ └── utils │ │ └── utils.d.ts ├── index.d.ts ├── index.es.js ├── index.es.js.map ├── index.js ├── index.js.map └── tests │ └── HighLighter.spec.d.ts ├── example └── example.jsx ├── jest.config.js ├── package-lock.json ├── package.json ├── postinstallSSJ.js ├── rollup.config.js ├── src ├── Components │ ├── ClipBoard.tsx │ ├── HighLighterProps.ts │ ├── Highlighter.scss │ ├── Highlighter.tsx │ └── utils.highlight.ts ├── Icons │ ├── Copy.tsx │ ├── CopyProps.ts │ ├── Done.tsx │ ├── DoneProps.ts │ ├── IconProps.ts │ └── utils │ │ └── utils.ts ├── index.ts └── tests │ └── HighLighter.spec.tsx ├── stories └── Highlight.stories.tsx └── tsconfig.json /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "parserOptions": { 4 | "ecmaVersion": 2020, 5 | "sourceType": "module", 6 | "ecmaFeatures": { 7 | "jsx": true 8 | } 9 | }, 10 | "settings": { 11 | "react": { 12 | "version": "detect" 13 | } 14 | }, 15 | "plugins": ["jest"], 16 | "env": { 17 | "jest/globals": true 18 | }, 19 | "extends": [ 20 | "plugin:react/recommended", 21 | "plugin:@typescript-eslint/recommended", 22 | "prettier/@typescript-eslint", 23 | "plugin:prettier/recommended" 24 | ], 25 | "rules": {} 26 | } 27 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "10:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [16.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v2 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | cache: 'npm' 29 | - run: npm ci 30 | - run: npm test 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | #build 3 | storybook-static 4 | #src 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | storybook-static 3 | src 4 | .* 5 | jest.* 6 | rollup.* -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "printWidth": 80 5 | } 6 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | module.exports = { 3 | stories: ["../src/*.stories.tsx"], 4 | addons: [ 5 | "@storybook/addon-actions", 6 | "@storybook/addon-links", 7 | ], 8 | typescript: { 9 | check: false, 10 | checkOptions: {}, 11 | reactDocgen: 'react-docgen-typescript', 12 | reactDocgenTypescriptOptions: { 13 | shouldExtractLiteralValuesFromEnum: true, 14 | propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true), 15 | }, 16 | }, 17 | webpackFinal: async (config, { configType }) => { 18 | // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION' 19 | // You can change the configuration based on that. 20 | // 'PRODUCTION' is used when building the static version of storybook. 21 | 22 | // Make whatever fine-grained changes you need 23 | config.module.rules.push({ 24 | test: /\.scss$/, 25 | loaders: ['style-loader', 'css-loader'], 26 | include: path.resolve(__dirname, '../'), 27 | }); 28 | 29 | // Return the altered config 30 | return config; 31 | }, 32 | }; 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - node 5 | 6 | script: 7 | - npm run test:coveralls 8 | - pwd 9 | - ls 10 | - echo "SUCCESSSS" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Jin Jose Manuel Serrano Amaut 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

✨🖍️ React Highlight ✨🖍️

2 | React component for highlighting js and jsx code with copy to clipboard functionallity. 3 | 4 | 5 | [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/dropzone-ui/react/blob/HEAD/LICENSE) 6 | [![npm latest package](https://img.shields.io/npm/v/rc-highlight.svg?logo=npm&logoColor=fff&label=NPM+package&color=limegreen)](https://www.npmjs.com/package/rc-highlight) 7 | [![install size](https://packagephobia.com/badge?p=@unlimited-react-components/react-highlight)](https://packagephobia.com/result?p=@unlimited-react-components/react-highlight) [![Build Status](https://travis-ci.org/jinssj3/rc-highlight.svg?branch=master)](https://travis-ci.org/jinssj3/rc-highlight) 8 | [![Known Vulnerabilities](https://snyk.io/test/github/jinssj3/rc-highlight/badge.svg)](https://snyk.io/test/github/jinssj3/rc-highlight) 9 | [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/JinSSJ3/rc-highlight.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/JinSSJ3/rc-highlight/context:javascript) 10 | [![Total alerts](https://img.shields.io/lgtm/alerts/g/JinSSJ3/rc-highlight.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/JinSSJ3/rc-highlight/alerts/) 11 | ## Sample result: 12 | 13 |

14 | Sample result image 15 |

16 | 17 | ## Installation 18 | 19 | react-highlight is available as an [npm package](https://www.npmjs.com/package/@unlimited-react-components/react-highlight). 20 | 21 | ```sh 22 | // with npm 23 | npm i rc-highlight 24 | 25 | // or yran 26 | yarn add rc-highlight 27 | ``` 28 | 29 | ## Usage 30 | 31 | Here is a quick example to get you started, **it's all you need**: 32 | 33 | [![Edit Button](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/admiring-mendeleev-xgmzs?file=/package.json) 34 | 35 | ```jsx 36 | import "./styles.css"; 37 | import { Highligther } from "rc-highlight"; 38 | 39 | const App = (props) => { 40 | return {makeCode}; 41 | }; 42 | export default App; 43 | const makeCode = ` 44 | // this is a sample code 45 | const themes = { 46 | light: { ... }, 47 | dark: { ... } 48 | }; 49 | const ThemeContext = React.createContext(themes.light); 50 | function App() { 51 | return ( 52 | 53 | 54 | 55 | ); 56 | } 57 | function Toolbar(props) { ... } 58 | 59 | const ThemedButton =() => { ... } 60 | `; 61 | ``` 62 | 63 | ## Props 64 | 65 | | Name | Description | Default | 66 | | ------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------- | 67 | | `code` | The JSX code to be highlighted. | "" | 68 | | `style` | The in-line CSS object. Only affects the container | { } | 69 | | `children` | The JSX code to be highlighted in string format. | "" | 70 | | `onCopyToClipboard` | A Funtion that is triggered when copy to clipboard button is clicked. Returns the copied code as a string as first parameter. | undefined | 71 | 72 | ## License 73 | 74 | This project is licensed under the terms of the 75 | [MIT license](/LICENSE). 76 | -------------------------------------------------------------------------------- /build/Components/ClipBoard.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare const Clipboard: ({ code, onCopyToClipboard, }: { 3 | code?: string; 4 | onCopyToClipboard?: (_code: string) => void; 5 | }) => JSX.Element; 6 | export default Clipboard; 7 | -------------------------------------------------------------------------------- /build/Components/HighLighterProps.d.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | export interface HighLighterProps { 3 | /** 4 | * The JSX code to highlight 5 | */ 6 | code: string; 7 | /** 8 | * at the moment only JSX and JS is supported 9 | */ 10 | /** 11 | * style properties that affects only the container 12 | */ 13 | style?: React.CSSProperties; 14 | /** 15 | * style properties that affects only the container 16 | */ 17 | children?: string; 18 | /** 19 | * event that is triggered when copy to clipboard the code 20 | */ 21 | onCopyToClipboard?: (code: string) => void; 22 | } 23 | -------------------------------------------------------------------------------- /build/Components/Highlighter.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import "./Highlighter.scss"; 3 | import { HighLighterProps } from "./HighLighterProps"; 4 | declare const HighLighter: (props: HighLighterProps) => JSX.Element; 5 | export default HighLighter; 6 | -------------------------------------------------------------------------------- /build/Components/utils.highlight.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare type CodeLine = JSX.Element; 3 | export declare type Line = Token[]; 4 | export interface Token { 5 | token: string; 6 | category: string; 7 | level?: 1 | 2 | 3 | 0; 8 | } 9 | export declare const tokens: string[]; 10 | export declare const isClassName: (word: string) => boolean; 11 | export declare const isHighKeyWord: (word: string) => boolean; 12 | export declare const isKeyWord: (word: string) => boolean; 13 | export declare const isPunctuation: (word: string) => boolean; 14 | export declare const isArrow: (word: string) => boolean; 15 | export declare const isOpenSymbol: (word: string) => boolean; 16 | export declare const isCloseSymbol: (word: string) => boolean; 17 | /** 18 | * Makes a Token 19 | * @param token the string representation of the token 20 | * @param category the category of the token 21 | * @param isFunction wheter is a function and must take this category 22 | * @param openString wheter is part of a large splted string and must take this category 23 | * @returns a token 24 | */ 25 | export declare const makeToken: (token: string, category: string, isFunction?: boolean, openString?: boolean) => Token; 26 | /** 27 | * 28 | * @param word a word to be analized for punctuation and strings 29 | * @returns 30 | */ 31 | export declare const TOKENIZE: (currentWord: string) => Token[]; 32 | /** 33 | * 34 | * @param line 35 | * @returns 36 | */ 37 | export declare const tokenizeLine: (line: string) => Line; 38 | /** 39 | * Splits the code into lines 40 | * 41 | * For each line first splits by punctuation and strings 42 | * Also maintains whitespaces 43 | * 44 | * After that, searchs for keywords 45 | * 46 | * Tags with Classes and HTML-tags 47 | * @param code The entie code to be highlighted 48 | */ 49 | export declare const superHighlighter: (code: string) => Line[]; 50 | -------------------------------------------------------------------------------- /build/Icons/Copy.d.ts: -------------------------------------------------------------------------------- 1 | import { FC } from "react"; 2 | import { copyProps } from "./CopyProps"; 3 | declare const Copy: FC; 4 | export default Copy; 5 | -------------------------------------------------------------------------------- /build/Icons/CopyProps.d.ts: -------------------------------------------------------------------------------- 1 | import { IconProps } from "./IconProps"; 2 | export interface copyProps extends IconProps { 3 | } 4 | -------------------------------------------------------------------------------- /build/Icons/Done.d.ts: -------------------------------------------------------------------------------- 1 | import { FC } from "react"; 2 | import { DoneProps } from "./DoneProps"; 3 | declare const Done: FC; 4 | export default Done; 5 | -------------------------------------------------------------------------------- /build/Icons/DoneProps.d.ts: -------------------------------------------------------------------------------- 1 | import { IconProps } from "./IconProps"; 2 | export interface DoneProps extends IconProps { 3 | } 4 | -------------------------------------------------------------------------------- /build/Icons/IconProps.d.ts: -------------------------------------------------------------------------------- 1 | import { CSSProperties } from "react"; 2 | export interface IconProps { 3 | size?: "micro" | "small" | "semi-medium" | "medium" | "large"; 4 | color?: string; 5 | colorFill?: string; 6 | onClick?: Function; 7 | style?: CSSProperties; 8 | className?: string; 9 | } 10 | -------------------------------------------------------------------------------- /build/Icons/utils/utils.d.ts: -------------------------------------------------------------------------------- 1 | import { IconProps } from "../IconProps"; 2 | export declare const parseSize: (sizeStr: IconProps["size"]) => number; 3 | -------------------------------------------------------------------------------- /build/index.d.ts: -------------------------------------------------------------------------------- 1 | import Highlighter from "./Components/Highlighter"; 2 | import Clipboard from "./Components/ClipBoard"; 3 | export { Highlighter, Clipboard }; 4 | -------------------------------------------------------------------------------- /build/index.es.js: -------------------------------------------------------------------------------- 1 | import n,{useState as e,Fragment as t,useEffect as o}from"react"; 2 | /*! ***************************************************************************** 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. 15 | ***************************************************************************** */var r=function(){return r=Object.assign||function(n){for(var e,t=1,o=arguments.length;t","=","!=","<=",">=","===","!==",">=","/","!","+","*"],g=[">=","=>","<=","!=","===","!==",">=","!"],d=["(","{","["],f=[")","}","]"],m=function(n){return/[A-Z]/.test(n[0])},y=function(n){return u.includes(n)},k=function(n){return g.includes(n)},v=function(n){return d.includes(n)},b=function(n){return f.includes(n)},x=function(n,e,t,o){return o?{token:n,category:"string"}:t?{token:n,category:"function"}:{token:n,category:e}},w=function(n){var e,t=[],o="",r=!1,a=0;if('"'===n.charAt(0)||"'"===n.charAt(0)||"`"===n.charAt(0))return[x(n,"string")];for(;a0&&(r=!0,t[t.length-1].category="parameter",t[t.length-1].token=t[t.length-1].token.split(" ")[0]);var i=x(l,"punctuation",!1,false);t.push(i)}else if(b(l)||v(l)){var s=x(o,"",r,false);t.push(s),o="","("===l&&t[t.length-1].token.length>0&&(t[t.length-1].category="function");i=x(l,"symbol",!1,false);t.push(i)}else o+=l}var u={token:o,category:""};x(o,"",r),t.push(u);for(var p=0;p0&&(r.push(c),c=""),c+=s;for(var u=i+1;;){var h=n[u];if(h===l){c+=h,r.push(c),c="";break}c+=h,u++}i=u}else" "===s?(r.push(c),c="",r.push(" "),c=""):0===s.length||(c+=s)}r.push(c),e=r;for(i=0;i0);)u--;u>=0&&"import"===o[u].token?f.category="parameter":u>=0&&["const","function"].includes(o[u].token)?f.category="function":f.category="class-name"}"<"==f.token&&o[i+1]&&(o[i+1].category="tag"),"<"==f.token&&o[i+1]&&o[i+2]&&"/"===o[i+2].token&&o[i+3]&&(o[i+3].category="tag")}return o},E=function(r){var a=r.code,l=r.style,c=r.children,i=r.onCopyToClipboard,u=e(n.createElement(n.Fragment,null)),p=u[0],h=u[1];o((function(){c&&c.length>0?g(c):g(a||"")}),[a,c]);var g=function(e){for(var t=function(n){for(var e=n.split("\n"),t=[],o=0;o0&&c.push(n.createElement("span",{key:i,className:d?"token comment":s},u.token)),d&&"/"===u.token&&""===(null===(r=e[i-1])||void 0===r?void 0:r.token)&&"*"===(null===(a=e[i-2])||void 0===a?void 0:a.token)&&(d=!1)}return n.createElement("div",{key:t},c.map((function(n){return n})))};return n.createElement(t,null,(c||a)&&((null==a?void 0:a.length)>0||c.length>0)&&n.createElement("div",{"data-testid":"highlighter-container",style:l,className:"highlighter-container"},n.createElement(s,{code:c||a||"",onCopyToClipboard:function(n){null==i||i(n)}}),n.createElement(n.Fragment,null,p)))};export{s as Clipboard,E as Highlighter}; 16 | //# sourceMappingURL=index.es.js.map 17 | -------------------------------------------------------------------------------- /build/index.es.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.es.js","sources":["../node_modules/tslib/tslib.es6.js","../src/Icons/utils/utils.ts","../src/Icons/Done.tsx","../src/Icons/Copy.tsx","../src/Components/ClipBoard.tsx","../src/Components/utils.highlight.ts","../src/Components/Highlighter.tsx"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n","import { IconProps } from \"../IconProps\";\r\n\r\nexport const parseSize = (sizeStr: IconProps[\"size\"]): number => {\r\n switch (sizeStr) {\r\n case \"micro\":\r\n return 8;\r\n case \"small\":\r\n return 15;\r\n case \"semi-medium\":\r\n return 18;\r\n case \"medium\":\r\n return 25;\r\n case \"large\":\r\n return 28;\r\n default:\r\n return 24;\r\n }\r\n}","import React, { FC } from \"react\";\r\nimport { DoneProps } from \"./DoneProps\";\r\nimport { parseSize } from \"./utils/utils\";\r\n\r\nconst Done: FC = (props: DoneProps) => {\r\n const {\r\n size,\r\n color,\r\n colorFill = \"none\",\r\n onClick,\r\n style = {},\r\n className,\r\n } = props;\r\n const finalSize = parseSize(size);\r\n return (\r\n onClick?.()}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n //enableBackground=\"new 0 0 24 24\"\r\n height={`${finalSize}px`}\r\n viewBox=\"0 0 24 24\"\r\n width={`${finalSize}px`}\r\n fill={color ? color : \"#000000\"}\r\n className={className || \"\"}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\nexport default Done;\r\n","import React, { FC } from \"react\";\r\nimport { copyProps } from \"./CopyProps\";\r\nimport { parseSize } from \"./utils/utils\";\r\n\r\nconst Copy: FC = (props: copyProps) => {\r\n const { size, color, colorFill = \"none\", onClick, style, className } = props;\r\n const finalSize = parseSize(size);\r\n const finalStyle = style ? style : {};\r\n return (\r\n onClick?.()}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n enableBackground=\"new 0 0 24 24\"\r\n height={`${finalSize}px`}\r\n viewBox=\"0 0 24 24\"\r\n width={`${finalSize}px`}\r\n fill={color ? color : \"#000000\"}\r\n className={className || \"\"}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\nexport default Copy;\r\n","import React, { Fragment, useState } from \"react\";\r\n\r\nimport Done from \"../Icons/Done\";\r\nimport Copy from \"../Icons/Copy\";\r\n\r\nconst Clipboard = ({\r\n code = \"no code\",\r\n onCopyToClipboard = (_code: string) => {},\r\n}) => {\r\n //const { code = \"no code\" } = props;\r\n const [copied, setCopied] = useState(false);\r\n const changeIcon = () => {\r\n setCopied(true);\r\n setTimeout(() => {\r\n setCopied(false);\r\n }, 2800);\r\n };\r\n function fallbackCopyTextToClipboard(text: string) {\r\n var textArea = document.createElement(\"textarea\");\r\n textArea.value = text;\r\n\r\n // Avoid scrolling to bottom\r\n textArea.style.top = \"0\";\r\n textArea.style.left = \"0\";\r\n textArea.style.position = \"fixed\";\r\n\r\n document.body.appendChild(textArea);\r\n textArea.focus();\r\n textArea.select();\r\n\r\n try {\r\n var successful = document.execCommand(\"copy\");\r\n var msg = successful ? \"successful\" : \"unsuccessful\";\r\n if (successful) {\r\n changeIcon();\r\n onCopyToClipboard?.(code);\r\n }\r\n console.log(\"Fallback: Copying text command was \" + msg);\r\n } catch (err) {\r\n console.error(\"Fallback: Oops, unable to copy\", err);\r\n }\r\n\r\n document.body.removeChild(textArea);\r\n }\r\n function copyTextToClipboard(text: string) {\r\n if (!navigator.clipboard) {\r\n fallbackCopyTextToClipboard(text);\r\n return;\r\n }\r\n navigator.clipboard.writeText(text).then(\r\n function () {\r\n changeIcon();\r\n onCopyToClipboard?.(code);\r\n\r\n console.log(\"Async: Copying to clipboard was successful!\");\r\n },\r\n function (err) {\r\n console.error(\"Async: Could not copy text: \", err);\r\n },\r\n );\r\n }\r\n\r\n return (\r\n \r\n copyTextToClipboard(code)}\r\n className={\r\n copied ? \"floating-copy-button copied\" : \"floating-copy-button\"\r\n }\r\n >\r\n {copied ? : }\r\n \r\n \r\n );\r\n};\r\nexport default Clipboard;\r\n","\r\nexport type CodeLine = JSX.Element;\r\nexport type Line = Token[];\r\n\r\nexport interface Token {\r\n token: string;\r\n category: string;\r\n level?: 1 | 2 | 3 | 0;\r\n}\r\nconst highKeywords = [\r\n \"import\",\r\n \"from\",\r\n \"return\",\r\n \"if\",\r\n \"else\",\r\n \"switch\",\r\n \"default\",\r\n \"export\",\r\n]\r\nconst keywords = [\r\n \"class\",\r\n \"extends\",\r\n \"this\",\r\n \"super\",\r\n \"function\",\r\n \"null\",\r\n \"var\",\r\n \"let\",\r\n \"const\",\r\n \"typeof\",\r\n \"interface\",\r\n \"type\", \"false\"\r\n];\r\nexport const tokens = [\r\n \"keyword\",\r\n \"className\",\r\n \"punctuation\",\r\n \"function\",\r\n \"parameter\",\r\n \"operator\",\r\n \"number\",\r\n \"attributeName\",\r\n \"default\",\r\n];\r\nconst punctuation: string[] = [\r\n \".\",\r\n \",\",\r\n \";\",\r\n \":\",\r\n \"<\",\r\n \">\",\r\n \"=\",\r\n \"!=\",\r\n \"<=\",\r\n \">=\",\r\n \"===\",\r\n \"!==\",\r\n \">=\",\r\n \"/\",\r\n \"!\",\r\n \"+\",\r\n \"*\"\r\n];\r\nconst arrow: string[] = [\r\n \">=\",\r\n \"=>\",\r\n \"<=\",\r\n \"!=\",\r\n \"===\",\r\n \"!==\",\r\n \">=\",\r\n \"!\"\r\n]\r\nconst openSymbols: string[] = [\r\n \"(\",\r\n \"{\",\r\n \"[\",\r\n];\r\nconst closeSymbols: string[] = [\r\n \")\",\r\n \"}\",\r\n \"]\",\r\n];\r\n\r\nexport const isClassName = (word: string) => {\r\n return /[A-Z]/.test(word[0]);\r\n};\r\nexport const isHighKeyWord = (word: string) => {\r\n return highKeywords.includes(word);\r\n};\r\nexport const isKeyWord = (word: string) => {\r\n return keywords.includes(word);\r\n};\r\nexport const isPunctuation = (word: string) => {\r\n return punctuation.includes(word);\r\n};\r\nexport const isArrow = (word: string) => {\r\n return arrow.includes(word);\r\n};\r\nexport const isOpenSymbol = (word: string) => {\r\n return openSymbols.includes(word);\r\n};\r\nexport const isCloseSymbol = (word: string) => {\r\n return closeSymbols.includes(word);\r\n};\r\n/**\r\n * Makes a Token \r\n * @param token the string representation of the token\r\n * @param category the category of the token\r\n * @param isFunction wheter is a function and must take this category\r\n * @param openString wheter is part of a large splted string and must take this category\r\n * @returns a token\r\n */\r\nexport const makeToken = (\r\n token: string,\r\n category: string,\r\n isFunction?: boolean,\r\n openString?: boolean\r\n): Token => {\r\n let tokenToken: Token;\r\n\r\n if (openString) {\r\n tokenToken = { token: token, category: \"string\" };\r\n }\r\n else if (isFunction) {\r\n tokenToken = { token: token, category: \"function\" };\r\n } else {\r\n tokenToken = { token: token, category: category };\r\n\r\n }\r\n //console.log(\"make:\", tokenToken);\r\n return tokenToken;\r\n}\r\n/**\r\n * @var a flag used to check whether a large splited string is being analyzed\r\n */\r\nlet openString: boolean = false;\r\n/**\r\n * \r\n * @param word a word to be analized for punctuation and strings\r\n * @returns \r\n */\r\nexport const TOKENIZE = (\r\n currentWord: string\r\n): Token[] => {\r\n let tokenArray: Token[] = [];\r\n //identif string\r\n //for each character\r\n let acumword = \"\";\r\n let isFunction = false;\r\n let i = 0;\r\n // in the future search for the pattern\r\n // string = `${var} `\r\n // symbol symbol parameter symbol \r\n if (currentWord.charAt(0) === \"\\\"\" || currentWord.charAt(0) === \"\\'\" || currentWord.charAt(0) === \"\\`\") {\r\n let tokenPrev: Token = makeToken(currentWord, \"string\");\r\n return [tokenPrev];\r\n }\r\n for (; i < currentWord.length; i++) {\r\n //go along in chars\r\n let currentCharacter = currentWord.charAt(i);\r\n\r\n if (isPunctuation(currentCharacter)) {\r\n //PUNCTUATION\r\n\r\n let tokenPrev: Token =\r\n makeToken(acumword, \"\", false, openString);\r\n tokenArray.push(tokenPrev);\r\n acumword = \"\";\r\n\r\n if (currentCharacter === \".\" && tokenArray[tokenArray.length - 1].token.length > 0) {\r\n //I found an object and a function\r\n isFunction = true;\r\n tokenArray[tokenArray.length - 1].category = \"parameter\";\r\n tokenArray[tokenArray.length - 1].token = tokenArray[tokenArray.length - 1].token.split(\" \")[0];\r\n }\r\n\r\n // Now I add the \".\"\r\n let token: Token = //{ token: currentCharacter, category: \"punctuation\" };\r\n makeToken(currentCharacter, \"punctuation\", false, openString);\r\n tokenArray.push(token);\r\n } else if (isCloseSymbol(currentCharacter) || isOpenSymbol(currentCharacter)) {\r\n // SYMBOL\r\n let tokenPrev: Token = //{ token: acumword + \" \", category: \"\" };\r\n makeToken(acumword, \"\", isFunction, openString);\r\n tokenArray.push(tokenPrev);\r\n acumword = \"\";\r\n\r\n if (currentCharacter === \"(\" && tokenArray[tokenArray.length - 1].token.length > 0) {\r\n tokenArray[tokenArray.length - 1].category = \"function\";\r\n }\r\n\r\n let token: Token = //{ token: currentCharacter, category: \"symbol\" };\r\n makeToken(currentCharacter, \"symbol\", false, openString);\r\n tokenArray.push(token);\r\n } else {\r\n // SIMPLE WORD\r\n //continue accumulating\r\n acumword += currentCharacter;\r\n }\r\n }\r\n let tokenPrev: Token = { token: acumword, category: \"\" };\r\n makeToken(acumword, \"\", isFunction);\r\n tokenArray.push(tokenPrev);\r\n //check for functions\r\n for (let i = 0; i < tokenArray.length - 1; i++) {\r\n if (tokenArray[i].token.includes(\".\") && tokenArray[i + 1].token === \"\") {\r\n tokenArray[i + 1].category = \"function\";\r\n }\r\n }\r\n return tokenArray;\r\n}\r\n/**\r\n * \r\n * @param line \r\n * @returns \r\n */\r\nexport const tokenizeLine = (\r\n line: string\r\n): Line => {\r\n let tokenArray: Token[] = [];\r\n\r\n //separate for whitespaces\r\n let words: string[];//= line.split(\" \");\r\n // console.log(\"===>\",words);\r\n let superWords: string[] = [];\r\n let strSymbol: string = \"\";\r\n let acumWord = \"\";\r\n for (let i = 0; i < line.length; i++) {\r\n let currentChar = line[i];\r\n\r\n if (currentChar === \"\\\"\" || currentChar === \"\\'\" || currentChar === \"\\`\") {\r\n strSymbol = currentChar;\r\n if (acumWord.length > 0) {\r\n superWords.push(acumWord);\r\n //console.log(\"wors\", acumWord,currentChar);\r\n acumWord = \"\";\r\n }\r\n //better capture the entire string\r\n acumWord += currentChar;\r\n let j = i + 1;\r\n while (1) {\r\n let currentChar2 = line[j];\r\n if (currentChar2 === strSymbol) {\r\n acumWord += currentChar2;\r\n superWords.push(acumWord);\r\n // console.log(\"wors\", acumWord,currentChar);\r\n acumWord = \"\";\r\n break;\r\n } else {\r\n acumWord += currentChar2;\r\n j++;\r\n }\r\n }\r\n i = j;\r\n } else if (currentChar === \" \") {\r\n //console.log(\"ws\");\r\n superWords.push(acumWord);\r\n acumWord = \"\";\r\n //console.log(\"words\", acumWord,currentChar);\r\n superWords.push(\" \");\r\n acumWord = \"\";\r\n\r\n //i=i+2;\r\n } else if (currentChar.length === 0) {\r\n //console.log(\"empty\");\r\n //acumWord += \" \";\r\n } else {\r\n acumWord += currentChar;\r\n }\r\n\r\n }\r\n superWords.push(acumWord);\r\n words = superWords;\r\n\r\n //for each word\r\n for (let i = 0; i < words.length; i++) {\r\n // a word aftersplited by \" \"\r\n let currentWord = words[i];\r\n if (isKeyWord(currentWord)) {\r\n let tokenPrev: Token = { token: currentWord, category: \"keyword\" };\r\n // makeToken( currconsoleentWord + \" \",\"\",isFunction);\r\n tokenArray.push(tokenPrev);\r\n } else if (isHighKeyWord(currentWord)) {\r\n let tokenPrev: Token = { token: currentWord, category: \"high-keyword\" };\r\n //makeToken( currentWord + \" \",\"\",isFunction);\r\n tokenArray.push(tokenPrev);\r\n } else if (isArrow(currentWord)) {\r\n let tokenPrev: Token = { token: currentWord, category: \"punctuation\" };\r\n //makeToken( currentWord + \" \",\"\",isFunction);\r\n tokenArray.push(tokenPrev);\r\n } else {\r\n //punctuation\r\n tokenArray = [...tokenArray, ...TOKENIZE(currentWord)];\r\n }\r\n }\r\n for (let i = 0; i < tokenArray.length; i++) {\r\n if (tokenArray[i].token === \"/\") {\r\n\r\n if (tokenArray[i + 1] && tokenArray[i + 2] && tokenArray[i + 2].token === \"/\") {\r\n\r\n for (let j = i; j < tokenArray.length; j++) {\r\n tokenArray[j].category = \"comment\";\r\n }\r\n break;\r\n }\r\n }\r\n\r\n }\r\n\r\n //go along tokens array and find classes\r\n for (let i = 0; i < tokenArray.length; i++) {\r\n let token: Token = tokenArray[i];\r\n if (isClassName(token.token)) {\r\n let j = i - 1;\r\n while (1) {\r\n if (tokenArray[j].token !== \" \" && j > 0) {\r\n break;\r\n }\r\n j--;\r\n }\r\n if (j >= 0 && tokenArray[j].token === \"import\") {\r\n token.category = \"parameter\";\r\n } else if (j >= 0 && ([\"const\", \"function\"].includes(tokenArray[j].token))) {\r\n token.category = \"function\";\r\n } else {\r\n token.category = \"class-name\";\r\n }\r\n }\r\n if (\"<\" == (token.token)) {\r\n if (tokenArray[i + 1]) {\r\n tokenArray[i + 1].category = \"tag\";\r\n }\r\n }\r\n if (\"<\" == (token.token) && tokenArray[i + 1] && tokenArray[i + 2] && tokenArray[i + 2].token === \"/\") {\r\n if (tokenArray[i + 3]) {\r\n tokenArray[i + 3].category = \"tag\";\r\n }\r\n }\r\n }\r\n\r\n\r\n return tokenArray;\r\n}\r\n/**\r\n * Splits the code into lines\r\n * \r\n * For each line first splits by punctuation and strings\r\n * Also maintains whitespaces\r\n * \r\n * After that, searchs for keywords\r\n * \r\n * Tags with Classes and HTML-tags\r\n * @param code The entie code to be highlighted\r\n */\r\nexport const superHighlighter = (\r\n code: string\r\n): Line[] => {\r\n\r\n\r\n //split in lines\r\n const lines: string[] = code.split(\"\\n\");\r\n\r\n //separate by punctuation\r\n let punctuationSeparated: Line[] = [];\r\n\r\n //For each line tokenize\r\n for (let i = 0; i < lines.length; i++) {\r\n let currentLine = lines[i];\r\n let tokenArray = tokenizeLine(currentLine);\r\n\r\n punctuationSeparated.push(tokenArray);\r\n }\r\n\r\n return punctuationSeparated;\r\n}\r\n\r\n\r\n","import React, { Fragment } from \"react\";\r\nimport { useEffect } from \"react\";\r\nimport { useState } from \"react\";\r\nimport Clipboard from \"./ClipBoard\";\r\n\r\nimport \"./Highlighter.scss\";\r\nimport { HighLighterProps } from \"./HighLighterProps\";\r\nimport {\r\n Line,\r\n Token,\r\n superHighlighter,\r\n isOpenSymbol,\r\n isCloseSymbol,\r\n} from \"./utils.highlight\";\r\n\r\nconst HighLighter = (props: HighLighterProps) => {\r\n const { code, style, children ,onCopyToClipboard} = props;\r\n //const [bracketLevel, setBracketLevel] = useState(0);\r\n // const [commentBlock, setCommentBlock] = useState(false);\r\n const [codeHighlighted, setCodeHighlighted] = useState(<>);\r\n useEffect(() => {\r\n if (children && children.length > 0) {\r\n tokenize(children);\r\n } else {\r\n tokenize(code || \"\");\r\n }\r\n }, [code, children]);\r\n const tokenize = (code: string): void | React.ReactNode => {\r\n let listOfLines: Line[] = superHighlighter(code);\r\n\r\n let listOfCode: React.ReactNode[] = [];\r\n for (let i = 0; i < listOfLines.length; i++) {\r\n let tokenList: Token[] = listOfLines[i];\r\n let lineSpan: React.ReactNode = tokenizeSpan(tokenList, i);\r\n listOfCode.push(lineSpan);\r\n }\r\n\r\n setCodeHighlighted(\r\n {listOfCode.map((codeLine) => codeLine)}\r\n );\r\n\r\n //return {listOfCode.map((codeLine) => codeLine)};\r\n };\r\n //const setLevelOfSymbol = (token: Token) => {};\r\n /* findBlockComment = (tokenList: Token[], j: number) => {\r\n let token: Token = tokenList[j];\r\n if (\r\n token.token === \"/\" &&\r\n tokenList[j + 1]?.token === \"\" &&\r\n tokenList[j + 2]?.token === \"*\"\r\n ) {\r\n // setCommentBlock(true);\r\n }\r\n };*/\r\n /*const findFinalBlockComment = (tokenList: Token[], j: number) => {\r\n let token: Token = tokenList[j];\r\n if (\r\n token.token === \"/\" &&\r\n tokenList[j - 1]?.token === \"\" &&\r\n tokenList[j - 2]?.token === \"*\"\r\n ) {\r\n //setCommentBlock(false);\r\n }\r\n };*/\r\n let commentBlock: boolean = false;\r\n let levelBracket: number = 1;\r\n let openBrackets: number = 0;\r\n function reduceOpenBrackets() {\r\n if (openBrackets !== 0) {\r\n openBrackets -= 1;\r\n }\r\n }\r\n function incBrack() {\r\n if (levelBracket !== 3) {\r\n levelBracket += 1;\r\n } else {\r\n levelBracket = 1;\r\n }\r\n }\r\n function decBrack() {\r\n levelBracket -= 1;\r\n if (levelBracket === 0) {\r\n levelBracket = 3;\r\n }\r\n }\r\n function levelbefore(__levelBracket: number) {\r\n let _levelBracket = __levelBracket - 1;\r\n if (_levelBracket === 0) {\r\n _levelBracket = 3;\r\n }\r\n return _levelBracket;\r\n }\r\n const tokenizeSpan = (tokenList: Token[], key: number): React.ReactNode => {\r\n let result: React.ReactNode;\r\n //for each line I create a div\r\n //for each token create a span\r\n let listOfSpans: React.ReactNode[] = [];\r\n //let block: boolean = commentBlock;\r\n //console.log(\"found found \", block);\r\n for (let j = 0; j < tokenList.length; j++) {\r\n let spanClassName = \"token\";\r\n let token: Token = tokenList[j];\r\n /* if(!commentBlock){\r\n findBlockComment(tokenList,j);\r\n } */\r\n if (\r\n !commentBlock &&\r\n token.token === \"/\" &&\r\n //tokenList[j + 1]?.token === \"\" &&\r\n tokenList[j + 2]?.token === \"*\"\r\n ) {\r\n commentBlock = true;\r\n }\r\n\r\n ////\r\n if (isCloseSymbol(token.token)) {\r\n reduceOpenBrackets();\r\n spanClassName = `token symbol-${levelbefore(levelBracket)}`;\r\n decBrack();\r\n // console.log( \"Log:\" + token.token, \"level: \" + levelBracket, \"openBrac: \" + openBrackets, spanClassName );\r\n } else if (isOpenSymbol(token.token)) {\r\n openBrackets++;\r\n spanClassName = `token symbol-${levelBracket}`;\r\n incBrack();\r\n // console.log( \"Log:\" + token.token, \"level: \" + levelBracket, \"openBrac: \" + openBrackets, spanClassName );\r\n } else if (token.category !== \"\") {\r\n spanClassName += ` ${token.category}`;\r\n }\r\n if (token.token.length > 0) {\r\n listOfSpans.push(\r\n \r\n {token.token}\r\n \r\n );\r\n }\r\n\r\n if (\r\n commentBlock &&\r\n token.token === \"/\" &&\r\n tokenList[j - 1]?.token === \"\" &&\r\n tokenList[j - 2]?.token === \"*\"\r\n ) {\r\n commentBlock = false;\r\n }\r\n }\r\n\r\n result =
{listOfSpans.map((spanToken) => spanToken)}
;\r\n return result;\r\n };\r\n //const codeHighlighted = tokenize(code || \"\");\r\n const handleCopyToClipboard=(_code:string)=>{\r\n onCopyToClipboard?.(_code);\r\n }\r\n return (\r\n \r\n {(children || code) &&\r\n (code?.length > 0 || (children as string).length > 0) && (\r\n \r\n \r\n\r\n <>{codeHighlighted}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default HighLighter;\r\n"],"names":["__assign","Object","assign","t","s","i","n","arguments","length","p","prototype","hasOwnProperty","call","apply","this","__spreadArray","to","from","pack","ar","l","Array","slice","concat","parseSize","sizeStr","Done","props","size","color","_a","colorFill","onClick","_b","style","className","finalSize","React","cursor","xmlns","height","viewBox","width","fill","d","Copy","finalStyle","enableBackground","Clipboard","code","_c","onCopyToClipboard","_code","_d","useState","copied","setCopied","changeIcon","setTimeout","copyTextToClipboard","text","navigator","clipboard","writeText","then","console","log","err","error","textArea","document","createElement","value","top","left","position","body","appendChild","focus","select","successful","execCommand","msg","removeChild","fallbackCopyTextToClipboard","Fragment","highKeywords","keywords","punctuation","arrow","openSymbols","closeSymbols","isClassName","word","test","isHighKeyWord","includes","isArrow","isOpenSymbol","isCloseSymbol","makeToken","token","category","isFunction","openString","TOKENIZE","currentWord","tokenArray","acumword","charAt","currentCharacter","tokenPrev_2","push","split","tokenPrev_3","tokenPrev","i_1","tokenizeLine","line","words","superWords","strSymbol","acumWord","currentChar","j","currentChar2","HighLighter","children","codeHighlighted","setCodeHighlighted","useEffect","tokenize","listOfLines","lines","punctuationSeparated","currentLine","superHighlighter","listOfCode","tokenList","lineSpan","tokenizeSpan","key","map","codeLine","commentBlock","levelBracket","_levelBracket","listOfSpans","spanClassName","spanToken"],"mappings":"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"} -------------------------------------------------------------------------------- /build/index.js: -------------------------------------------------------------------------------- 1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var n=require("react");function e(n){return n&&"object"==typeof n&&"default"in n?n:{default:n}}var t=e(n),o=function(){return o=Object.assign||function(n){for(var e,t=1,o=arguments.length;t","=","!=","<=",">=","===","!==",">=","/","!","+","*"],d=[">=","=>","<=","!=","===","!==",">=","!"],f=["(","{","["],h=[")","}","]"],g=function(n){return/[A-Z]/.test(n[0])},m=function(n){return u.includes(n)},y=function(n){return d.includes(n)},k=function(n){return f.includes(n)},v=function(n){return h.includes(n)},b=function(n,e,t,o){return o?{token:n,category:"string"}:t?{token:n,category:"function"}:{token:n,category:e}},x=function(n){var e,t=[],o="",r=!1,a=0;if('"'===n.charAt(0)||"'"===n.charAt(0)||"`"===n.charAt(0))return[b(n,"string")];for(;a0&&(r=!0,t[t.length-1].category="parameter",t[t.length-1].token=t[t.length-1].token.split(" ")[0]);var i=b(l,"punctuation",!1,false);t.push(i)}else if(v(l)||k(l)){var u=b(o,"",r,false);t.push(u),o="","("===l&&t[t.length-1].token.length>0&&(t[t.length-1].category="function");i=b(l,"symbol",!1,false);t.push(i)}else o+=l}var s={token:o,category:""};b(o,"",r),t.push(s);for(var d=0;d0&&(a.push(c),c=""),c+=u;for(var p=i+1;;){var d=n[p];if(d===l){c+=d,a.push(c),c="";break}c+=d,p++}i=p}else" "===u?(a.push(c),c="",a.push(" "),c=""):0===u.length||(c+=u)}a.push(c),e=a;for(i=0;i0);)p--;p>=0&&"import"===o[p].token?k.category="parameter":p>=0&&["const","function"].includes(o[p].token)?k.category="function":k.category="class-name"}"<"==k.token&&o[i+1]&&(o[i+1].category="tag"),"<"==k.token&&o[i+1]&&o[i+2]&&"/"===o[i+2].token&&o[i+3]&&(o[i+3].category="tag")}return o};exports.Clipboard=i,exports.Highlighter=function(e){var o=e.code,r=e.style,a=e.children,l=e.onCopyToClipboard,c=n.useState(t.default.createElement(t.default.Fragment,null)),u=c[0],s=c[1];n.useEffect((function(){a&&a.length>0?p(a):p(o||"")}),[o,a]);var p=function(n){for(var e=function(n){for(var e=n.split("\n"),t=[],o=0;o0&&c.push(t.default.createElement("span",{key:i,className:d?"token comment":u},s.token)),d&&"/"===s.token&&""===(null===(r=n[i-1])||void 0===r?void 0:r.token)&&"*"===(null===(a=n[i-2])||void 0===a?void 0:a.token)&&(d=!1)}return t.default.createElement("div",{key:e},c.map((function(n){return n})))};return t.default.createElement(n.Fragment,null,(a||o)&&((null==o?void 0:o.length)>0||a.length>0)&&t.default.createElement("div",{"data-testid":"highlighter-container",style:r,className:"highlighter-container"},t.default.createElement(i,{code:a||o||"",onCopyToClipboard:function(n){null==l||l(n)}}),t.default.createElement(t.default.Fragment,null,u)))}; 16 | //# sourceMappingURL=index.js.map 17 | -------------------------------------------------------------------------------- /build/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sources":["../node_modules/tslib/tslib.es6.js","../src/Icons/utils/utils.ts","../src/Icons/Done.tsx","../src/Icons/Copy.tsx","../src/Components/ClipBoard.tsx","../src/Components/utils.highlight.ts","../src/Components/Highlighter.tsx"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n","import { IconProps } from \"../IconProps\";\r\n\r\nexport const parseSize = (sizeStr: IconProps[\"size\"]): number => {\r\n switch (sizeStr) {\r\n case \"micro\":\r\n return 8;\r\n case \"small\":\r\n return 15;\r\n case \"semi-medium\":\r\n return 18;\r\n case \"medium\":\r\n return 25;\r\n case \"large\":\r\n return 28;\r\n default:\r\n return 24;\r\n }\r\n}","import React, { FC } from \"react\";\r\nimport { DoneProps } from \"./DoneProps\";\r\nimport { parseSize } from \"./utils/utils\";\r\n\r\nconst Done: FC = (props: DoneProps) => {\r\n const {\r\n size,\r\n color,\r\n colorFill = \"none\",\r\n onClick,\r\n style = {},\r\n className,\r\n } = props;\r\n const finalSize = parseSize(size);\r\n return (\r\n onClick?.()}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n //enableBackground=\"new 0 0 24 24\"\r\n height={`${finalSize}px`}\r\n viewBox=\"0 0 24 24\"\r\n width={`${finalSize}px`}\r\n fill={color ? color : \"#000000\"}\r\n className={className || \"\"}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\nexport default Done;\r\n","import React, { FC } from \"react\";\r\nimport { copyProps } from \"./CopyProps\";\r\nimport { parseSize } from \"./utils/utils\";\r\n\r\nconst Copy: FC = (props: copyProps) => {\r\n const { size, color, colorFill = \"none\", onClick, style, className } = props;\r\n const finalSize = parseSize(size);\r\n const finalStyle = style ? style : {};\r\n return (\r\n onClick?.()}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n enableBackground=\"new 0 0 24 24\"\r\n height={`${finalSize}px`}\r\n viewBox=\"0 0 24 24\"\r\n width={`${finalSize}px`}\r\n fill={color ? color : \"#000000\"}\r\n className={className || \"\"}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\nexport default Copy;\r\n","import React, { Fragment, useState } from \"react\";\r\n\r\nimport Done from \"../Icons/Done\";\r\nimport Copy from \"../Icons/Copy\";\r\n\r\nconst Clipboard = ({\r\n code = \"no code\",\r\n onCopyToClipboard = (_code: string) => {},\r\n}) => {\r\n //const { code = \"no code\" } = props;\r\n const [copied, setCopied] = useState(false);\r\n const changeIcon = () => {\r\n setCopied(true);\r\n setTimeout(() => {\r\n setCopied(false);\r\n }, 2800);\r\n };\r\n function fallbackCopyTextToClipboard(text: string) {\r\n var textArea = document.createElement(\"textarea\");\r\n textArea.value = text;\r\n\r\n // Avoid scrolling to bottom\r\n textArea.style.top = \"0\";\r\n textArea.style.left = \"0\";\r\n textArea.style.position = \"fixed\";\r\n\r\n document.body.appendChild(textArea);\r\n textArea.focus();\r\n textArea.select();\r\n\r\n try {\r\n var successful = document.execCommand(\"copy\");\r\n var msg = successful ? \"successful\" : \"unsuccessful\";\r\n if (successful) {\r\n changeIcon();\r\n onCopyToClipboard?.(code);\r\n }\r\n console.log(\"Fallback: Copying text command was \" + msg);\r\n } catch (err) {\r\n console.error(\"Fallback: Oops, unable to copy\", err);\r\n }\r\n\r\n document.body.removeChild(textArea);\r\n }\r\n function copyTextToClipboard(text: string) {\r\n if (!navigator.clipboard) {\r\n fallbackCopyTextToClipboard(text);\r\n return;\r\n }\r\n navigator.clipboard.writeText(text).then(\r\n function () {\r\n changeIcon();\r\n onCopyToClipboard?.(code);\r\n\r\n console.log(\"Async: Copying to clipboard was successful!\");\r\n },\r\n function (err) {\r\n console.error(\"Async: Could not copy text: \", err);\r\n },\r\n );\r\n }\r\n\r\n return (\r\n \r\n copyTextToClipboard(code)}\r\n className={\r\n copied ? \"floating-copy-button copied\" : \"floating-copy-button\"\r\n }\r\n >\r\n {copied ? : }\r\n \r\n \r\n );\r\n};\r\nexport default Clipboard;\r\n","\r\nexport type CodeLine = JSX.Element;\r\nexport type Line = Token[];\r\n\r\nexport interface Token {\r\n token: string;\r\n category: string;\r\n level?: 1 | 2 | 3 | 0;\r\n}\r\nconst highKeywords = [\r\n \"import\",\r\n \"from\",\r\n \"return\",\r\n \"if\",\r\n \"else\",\r\n \"switch\",\r\n \"default\",\r\n \"export\",\r\n]\r\nconst keywords = [\r\n \"class\",\r\n \"extends\",\r\n \"this\",\r\n \"super\",\r\n \"function\",\r\n \"null\",\r\n \"var\",\r\n \"let\",\r\n \"const\",\r\n \"typeof\",\r\n \"interface\",\r\n \"type\", \"false\"\r\n];\r\nexport const tokens = [\r\n \"keyword\",\r\n \"className\",\r\n \"punctuation\",\r\n \"function\",\r\n \"parameter\",\r\n \"operator\",\r\n \"number\",\r\n \"attributeName\",\r\n \"default\",\r\n];\r\nconst punctuation: string[] = [\r\n \".\",\r\n \",\",\r\n \";\",\r\n \":\",\r\n \"<\",\r\n \">\",\r\n \"=\",\r\n \"!=\",\r\n \"<=\",\r\n \">=\",\r\n \"===\",\r\n \"!==\",\r\n \">=\",\r\n \"/\",\r\n \"!\",\r\n \"+\",\r\n \"*\"\r\n];\r\nconst arrow: string[] = [\r\n \">=\",\r\n \"=>\",\r\n \"<=\",\r\n \"!=\",\r\n \"===\",\r\n \"!==\",\r\n \">=\",\r\n \"!\"\r\n]\r\nconst openSymbols: string[] = [\r\n \"(\",\r\n \"{\",\r\n \"[\",\r\n];\r\nconst closeSymbols: string[] = [\r\n \")\",\r\n \"}\",\r\n \"]\",\r\n];\r\n\r\nexport const isClassName = (word: string) => {\r\n return /[A-Z]/.test(word[0]);\r\n};\r\nexport const isHighKeyWord = (word: string) => {\r\n return highKeywords.includes(word);\r\n};\r\nexport const isKeyWord = (word: string) => {\r\n return keywords.includes(word);\r\n};\r\nexport const isPunctuation = (word: string) => {\r\n return punctuation.includes(word);\r\n};\r\nexport const isArrow = (word: string) => {\r\n return arrow.includes(word);\r\n};\r\nexport const isOpenSymbol = (word: string) => {\r\n return openSymbols.includes(word);\r\n};\r\nexport const isCloseSymbol = (word: string) => {\r\n return closeSymbols.includes(word);\r\n};\r\n/**\r\n * Makes a Token \r\n * @param token the string representation of the token\r\n * @param category the category of the token\r\n * @param isFunction wheter is a function and must take this category\r\n * @param openString wheter is part of a large splted string and must take this category\r\n * @returns a token\r\n */\r\nexport const makeToken = (\r\n token: string,\r\n category: string,\r\n isFunction?: boolean,\r\n openString?: boolean\r\n): Token => {\r\n let tokenToken: Token;\r\n\r\n if (openString) {\r\n tokenToken = { token: token, category: \"string\" };\r\n }\r\n else if (isFunction) {\r\n tokenToken = { token: token, category: \"function\" };\r\n } else {\r\n tokenToken = { token: token, category: category };\r\n\r\n }\r\n //console.log(\"make:\", tokenToken);\r\n return tokenToken;\r\n}\r\n/**\r\n * @var a flag used to check whether a large splited string is being analyzed\r\n */\r\nlet openString: boolean = false;\r\n/**\r\n * \r\n * @param word a word to be analized for punctuation and strings\r\n * @returns \r\n */\r\nexport const TOKENIZE = (\r\n currentWord: string\r\n): Token[] => {\r\n let tokenArray: Token[] = [];\r\n //identif string\r\n //for each character\r\n let acumword = \"\";\r\n let isFunction = false;\r\n let i = 0;\r\n // in the future search for the pattern\r\n // string = `${var} `\r\n // symbol symbol parameter symbol \r\n if (currentWord.charAt(0) === \"\\\"\" || currentWord.charAt(0) === \"\\'\" || currentWord.charAt(0) === \"\\`\") {\r\n let tokenPrev: Token = makeToken(currentWord, \"string\");\r\n return [tokenPrev];\r\n }\r\n for (; i < currentWord.length; i++) {\r\n //go along in chars\r\n let currentCharacter = currentWord.charAt(i);\r\n\r\n if (isPunctuation(currentCharacter)) {\r\n //PUNCTUATION\r\n\r\n let tokenPrev: Token =\r\n makeToken(acumword, \"\", false, openString);\r\n tokenArray.push(tokenPrev);\r\n acumword = \"\";\r\n\r\n if (currentCharacter === \".\" && tokenArray[tokenArray.length - 1].token.length > 0) {\r\n //I found an object and a function\r\n isFunction = true;\r\n tokenArray[tokenArray.length - 1].category = \"parameter\";\r\n tokenArray[tokenArray.length - 1].token = tokenArray[tokenArray.length - 1].token.split(\" \")[0];\r\n }\r\n\r\n // Now I add the \".\"\r\n let token: Token = //{ token: currentCharacter, category: \"punctuation\" };\r\n makeToken(currentCharacter, \"punctuation\", false, openString);\r\n tokenArray.push(token);\r\n } else if (isCloseSymbol(currentCharacter) || isOpenSymbol(currentCharacter)) {\r\n // SYMBOL\r\n let tokenPrev: Token = //{ token: acumword + \" \", category: \"\" };\r\n makeToken(acumword, \"\", isFunction, openString);\r\n tokenArray.push(tokenPrev);\r\n acumword = \"\";\r\n\r\n if (currentCharacter === \"(\" && tokenArray[tokenArray.length - 1].token.length > 0) {\r\n tokenArray[tokenArray.length - 1].category = \"function\";\r\n }\r\n\r\n let token: Token = //{ token: currentCharacter, category: \"symbol\" };\r\n makeToken(currentCharacter, \"symbol\", false, openString);\r\n tokenArray.push(token);\r\n } else {\r\n // SIMPLE WORD\r\n //continue accumulating\r\n acumword += currentCharacter;\r\n }\r\n }\r\n let tokenPrev: Token = { token: acumword, category: \"\" };\r\n makeToken(acumword, \"\", isFunction);\r\n tokenArray.push(tokenPrev);\r\n //check for functions\r\n for (let i = 0; i < tokenArray.length - 1; i++) {\r\n if (tokenArray[i].token.includes(\".\") && tokenArray[i + 1].token === \"\") {\r\n tokenArray[i + 1].category = \"function\";\r\n }\r\n }\r\n return tokenArray;\r\n}\r\n/**\r\n * \r\n * @param line \r\n * @returns \r\n */\r\nexport const tokenizeLine = (\r\n line: string\r\n): Line => {\r\n let tokenArray: Token[] = [];\r\n\r\n //separate for whitespaces\r\n let words: string[];//= line.split(\" \");\r\n // console.log(\"===>\",words);\r\n let superWords: string[] = [];\r\n let strSymbol: string = \"\";\r\n let acumWord = \"\";\r\n for (let i = 0; i < line.length; i++) {\r\n let currentChar = line[i];\r\n\r\n if (currentChar === \"\\\"\" || currentChar === \"\\'\" || currentChar === \"\\`\") {\r\n strSymbol = currentChar;\r\n if (acumWord.length > 0) {\r\n superWords.push(acumWord);\r\n //console.log(\"wors\", acumWord,currentChar);\r\n acumWord = \"\";\r\n }\r\n //better capture the entire string\r\n acumWord += currentChar;\r\n let j = i + 1;\r\n while (1) {\r\n let currentChar2 = line[j];\r\n if (currentChar2 === strSymbol) {\r\n acumWord += currentChar2;\r\n superWords.push(acumWord);\r\n // console.log(\"wors\", acumWord,currentChar);\r\n acumWord = \"\";\r\n break;\r\n } else {\r\n acumWord += currentChar2;\r\n j++;\r\n }\r\n }\r\n i = j;\r\n } else if (currentChar === \" \") {\r\n //console.log(\"ws\");\r\n superWords.push(acumWord);\r\n acumWord = \"\";\r\n //console.log(\"words\", acumWord,currentChar);\r\n superWords.push(\" \");\r\n acumWord = \"\";\r\n\r\n //i=i+2;\r\n } else if (currentChar.length === 0) {\r\n //console.log(\"empty\");\r\n //acumWord += \" \";\r\n } else {\r\n acumWord += currentChar;\r\n }\r\n\r\n }\r\n superWords.push(acumWord);\r\n words = superWords;\r\n\r\n //for each word\r\n for (let i = 0; i < words.length; i++) {\r\n // a word aftersplited by \" \"\r\n let currentWord = words[i];\r\n if (isKeyWord(currentWord)) {\r\n let tokenPrev: Token = { token: currentWord, category: \"keyword\" };\r\n // makeToken( currconsoleentWord + \" \",\"\",isFunction);\r\n tokenArray.push(tokenPrev);\r\n } else if (isHighKeyWord(currentWord)) {\r\n let tokenPrev: Token = { token: currentWord, category: \"high-keyword\" };\r\n //makeToken( currentWord + \" \",\"\",isFunction);\r\n tokenArray.push(tokenPrev);\r\n } else if (isArrow(currentWord)) {\r\n let tokenPrev: Token = { token: currentWord, category: \"punctuation\" };\r\n //makeToken( currentWord + \" \",\"\",isFunction);\r\n tokenArray.push(tokenPrev);\r\n } else {\r\n //punctuation\r\n tokenArray = [...tokenArray, ...TOKENIZE(currentWord)];\r\n }\r\n }\r\n for (let i = 0; i < tokenArray.length; i++) {\r\n if (tokenArray[i].token === \"/\") {\r\n\r\n if (tokenArray[i + 1] && tokenArray[i + 2] && tokenArray[i + 2].token === \"/\") {\r\n\r\n for (let j = i; j < tokenArray.length; j++) {\r\n tokenArray[j].category = \"comment\";\r\n }\r\n break;\r\n }\r\n }\r\n\r\n }\r\n\r\n //go along tokens array and find classes\r\n for (let i = 0; i < tokenArray.length; i++) {\r\n let token: Token = tokenArray[i];\r\n if (isClassName(token.token)) {\r\n let j = i - 1;\r\n while (1) {\r\n if (tokenArray[j].token !== \" \" && j > 0) {\r\n break;\r\n }\r\n j--;\r\n }\r\n if (j >= 0 && tokenArray[j].token === \"import\") {\r\n token.category = \"parameter\";\r\n } else if (j >= 0 && ([\"const\", \"function\"].includes(tokenArray[j].token))) {\r\n token.category = \"function\";\r\n } else {\r\n token.category = \"class-name\";\r\n }\r\n }\r\n if (\"<\" == (token.token)) {\r\n if (tokenArray[i + 1]) {\r\n tokenArray[i + 1].category = \"tag\";\r\n }\r\n }\r\n if (\"<\" == (token.token) && tokenArray[i + 1] && tokenArray[i + 2] && tokenArray[i + 2].token === \"/\") {\r\n if (tokenArray[i + 3]) {\r\n tokenArray[i + 3].category = \"tag\";\r\n }\r\n }\r\n }\r\n\r\n\r\n return tokenArray;\r\n}\r\n/**\r\n * Splits the code into lines\r\n * \r\n * For each line first splits by punctuation and strings\r\n * Also maintains whitespaces\r\n * \r\n * After that, searchs for keywords\r\n * \r\n * Tags with Classes and HTML-tags\r\n * @param code The entie code to be highlighted\r\n */\r\nexport const superHighlighter = (\r\n code: string\r\n): Line[] => {\r\n\r\n\r\n //split in lines\r\n const lines: string[] = code.split(\"\\n\");\r\n\r\n //separate by punctuation\r\n let punctuationSeparated: Line[] = [];\r\n\r\n //For each line tokenize\r\n for (let i = 0; i < lines.length; i++) {\r\n let currentLine = lines[i];\r\n let tokenArray = tokenizeLine(currentLine);\r\n\r\n punctuationSeparated.push(tokenArray);\r\n }\r\n\r\n return punctuationSeparated;\r\n}\r\n\r\n\r\n","import React, { Fragment } from \"react\";\r\nimport { useEffect } from \"react\";\r\nimport { useState } from \"react\";\r\nimport Clipboard from \"./ClipBoard\";\r\n\r\nimport \"./Highlighter.scss\";\r\nimport { HighLighterProps } from \"./HighLighterProps\";\r\nimport {\r\n Line,\r\n Token,\r\n superHighlighter,\r\n isOpenSymbol,\r\n isCloseSymbol,\r\n} from \"./utils.highlight\";\r\n\r\nconst HighLighter = (props: HighLighterProps) => {\r\n const { code, style, children ,onCopyToClipboard} = props;\r\n //const [bracketLevel, setBracketLevel] = useState(0);\r\n // const [commentBlock, setCommentBlock] = useState(false);\r\n const [codeHighlighted, setCodeHighlighted] = useState(<>);\r\n useEffect(() => {\r\n if (children && children.length > 0) {\r\n tokenize(children);\r\n } else {\r\n tokenize(code || \"\");\r\n }\r\n }, [code, children]);\r\n const tokenize = (code: string): void | React.ReactNode => {\r\n let listOfLines: Line[] = superHighlighter(code);\r\n\r\n let listOfCode: React.ReactNode[] = [];\r\n for (let i = 0; i < listOfLines.length; i++) {\r\n let tokenList: Token[] = listOfLines[i];\r\n let lineSpan: React.ReactNode = tokenizeSpan(tokenList, i);\r\n listOfCode.push(lineSpan);\r\n }\r\n\r\n setCodeHighlighted(\r\n {listOfCode.map((codeLine) => codeLine)}\r\n );\r\n\r\n //return {listOfCode.map((codeLine) => codeLine)};\r\n };\r\n //const setLevelOfSymbol = (token: Token) => {};\r\n /* findBlockComment = (tokenList: Token[], j: number) => {\r\n let token: Token = tokenList[j];\r\n if (\r\n token.token === \"/\" &&\r\n tokenList[j + 1]?.token === \"\" &&\r\n tokenList[j + 2]?.token === \"*\"\r\n ) {\r\n // setCommentBlock(true);\r\n }\r\n };*/\r\n /*const findFinalBlockComment = (tokenList: Token[], j: number) => {\r\n let token: Token = tokenList[j];\r\n if (\r\n token.token === \"/\" &&\r\n tokenList[j - 1]?.token === \"\" &&\r\n tokenList[j - 2]?.token === \"*\"\r\n ) {\r\n //setCommentBlock(false);\r\n }\r\n };*/\r\n let commentBlock: boolean = false;\r\n let levelBracket: number = 1;\r\n let openBrackets: number = 0;\r\n function reduceOpenBrackets() {\r\n if (openBrackets !== 0) {\r\n openBrackets -= 1;\r\n }\r\n }\r\n function incBrack() {\r\n if (levelBracket !== 3) {\r\n levelBracket += 1;\r\n } else {\r\n levelBracket = 1;\r\n }\r\n }\r\n function decBrack() {\r\n levelBracket -= 1;\r\n if (levelBracket === 0) {\r\n levelBracket = 3;\r\n }\r\n }\r\n function levelbefore(__levelBracket: number) {\r\n let _levelBracket = __levelBracket - 1;\r\n if (_levelBracket === 0) {\r\n _levelBracket = 3;\r\n }\r\n return _levelBracket;\r\n }\r\n const tokenizeSpan = (tokenList: Token[], key: number): React.ReactNode => {\r\n let result: React.ReactNode;\r\n //for each line I create a div\r\n //for each token create a span\r\n let listOfSpans: React.ReactNode[] = [];\r\n //let block: boolean = commentBlock;\r\n //console.log(\"found found \", block);\r\n for (let j = 0; j < tokenList.length; j++) {\r\n let spanClassName = \"token\";\r\n let token: Token = tokenList[j];\r\n /* if(!commentBlock){\r\n findBlockComment(tokenList,j);\r\n } */\r\n if (\r\n !commentBlock &&\r\n token.token === \"/\" &&\r\n //tokenList[j + 1]?.token === \"\" &&\r\n tokenList[j + 2]?.token === \"*\"\r\n ) {\r\n commentBlock = true;\r\n }\r\n\r\n ////\r\n if (isCloseSymbol(token.token)) {\r\n reduceOpenBrackets();\r\n spanClassName = `token symbol-${levelbefore(levelBracket)}`;\r\n decBrack();\r\n // console.log( \"Log:\" + token.token, \"level: \" + levelBracket, \"openBrac: \" + openBrackets, spanClassName );\r\n } else if (isOpenSymbol(token.token)) {\r\n openBrackets++;\r\n spanClassName = `token symbol-${levelBracket}`;\r\n incBrack();\r\n // console.log( \"Log:\" + token.token, \"level: \" + levelBracket, \"openBrac: \" + openBrackets, spanClassName );\r\n } else if (token.category !== \"\") {\r\n spanClassName += ` ${token.category}`;\r\n }\r\n if (token.token.length > 0) {\r\n listOfSpans.push(\r\n \r\n {token.token}\r\n \r\n );\r\n }\r\n\r\n if (\r\n commentBlock &&\r\n token.token === \"/\" &&\r\n tokenList[j - 1]?.token === \"\" &&\r\n tokenList[j - 2]?.token === \"*\"\r\n ) {\r\n commentBlock = false;\r\n }\r\n }\r\n\r\n result =
{listOfSpans.map((spanToken) => spanToken)}
;\r\n return result;\r\n };\r\n //const codeHighlighted = tokenize(code || \"\");\r\n const handleCopyToClipboard=(_code:string)=>{\r\n onCopyToClipboard?.(_code);\r\n }\r\n return (\r\n \r\n {(children || code) &&\r\n (code?.length > 0 || (children as string).length > 0) && (\r\n \r\n \r\n\r\n <>{codeHighlighted}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default HighLighter;\r\n"],"names":["__assign","Object","assign","t","s","i","n","arguments","length","p","prototype","hasOwnProperty","call","apply","this","__spreadArray","to","from","pack","ar","l","Array","slice","concat","parseSize","sizeStr","Done","props","size","color","_a","colorFill","onClick","_b","style","className","finalSize","React","cursor","xmlns","height","viewBox","width","fill","d","Copy","finalStyle","enableBackground","Clipboard","code","_c","onCopyToClipboard","_code","_d","useState","copied","setCopied","changeIcon","setTimeout","copyTextToClipboard","text","navigator","clipboard","writeText","then","console","log","err","error","textArea","document","createElement","value","top","left","position","body","appendChild","focus","select","successful","execCommand","msg","removeChild","fallbackCopyTextToClipboard","Fragment","highKeywords","keywords","punctuation","arrow","openSymbols","closeSymbols","isClassName","word","test","isHighKeyWord","includes","isArrow","isOpenSymbol","isCloseSymbol","makeToken","token","category","isFunction","openString","TOKENIZE","currentWord","tokenArray","acumword","charAt","currentCharacter","tokenPrev_2","push","split","tokenPrev_3","tokenPrev","i_1","tokenizeLine","line","words","superWords","strSymbol","acumWord","currentChar","j","currentChar2","children","codeHighlighted","setCodeHighlighted","useEffect","tokenize","listOfLines","lines","punctuationSeparated","currentLine","superHighlighter","listOfCode","tokenList","lineSpan","tokenizeSpan","key","map","codeLine","commentBlock","levelBracket","_levelBracket","listOfSpans","spanClassName","spanToken"],"mappings":"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"} -------------------------------------------------------------------------------- /build/tests/HighLighter.spec.d.ts: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom"; 2 | -------------------------------------------------------------------------------- /example/example.jsx: -------------------------------------------------------------------------------- 1 | import { Highligther } from "@unlimited-react-components/react-highlight"; 2 | const App = (props) => { 3 | const makeCode = () => { 4 | return ` 5 | //creating themes 6 | const themes = { 7 | light: { 8 | foreground: "#000000", 9 | background: "#eeeeee" 10 | }, 11 | }; 12 | /* this is a 13 | comment */ 14 | . 15 | . 16 | . 17 | function ThemedButton() { 18 | const theme = useContext(ThemeContext); 19 | return ( 20 | 26 | ); 27 | } 28 | `; 29 | } 30 | return ( 31 | 33 | 34 | ); 35 | }; 36 | export default App; 37 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ["/src/tests"], 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest", 5 | }, 6 | preset: "ts-jest", 7 | testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$", 8 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node", "d.ts"], 9 | "moduleNameMapper": { 10 | "^.+\\.(css|less|scss)$": "identity-obj-proxy" 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rc-highlight", 3 | "version": "1.0.1", 4 | "description": "React component for highlighting js and jsx code", 5 | "main": "./build/index.js", 6 | "module": "./build/index.es.js", 7 | "types": "./build/index.d.ts", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/JinSSJ3/rc-highlight.git" 11 | }, 12 | "keywords": [ 13 | "highlight", 14 | "highlight.js", 15 | "react", 16 | "syntax", 17 | "typescript", 18 | "copy", 19 | "clipboard", 20 | "front-end" 21 | ], 22 | "author": "JinSSJ3", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/JinSSJ3/rc-highlight/issues" 26 | }, 27 | "homepage": "https://github.com/JinSSJ3/rc-highlight#readme", 28 | "dependencies": {}, 29 | "peerDependencies": { 30 | "react": "^17.0.1", 31 | "react-dom": "^17.0.1" 32 | }, 33 | "devDependencies": { 34 | "@babel/core": "^7.11.6", 35 | "@rollup/plugin-commonjs": "^19.0.0", 36 | "@rollup/plugin-node-resolve": "^13.0.6", 37 | "@storybook/addon-actions": "^6.2.9", 38 | "@storybook/addon-links": "^6.0.22", 39 | "@storybook/addons": "^6.3.12", 40 | "@storybook/preset-scss": "^1.0.3", 41 | "@storybook/react": "^6.0.22", 42 | "@testing-library/jest-dom": "^5.15.1", 43 | "@testing-library/react": "^12.1.2", 44 | "@types/jest": "^27.0.3", 45 | "@types/node": "^14.11.2", 46 | "@types/testing-library__jest-dom": "^5.14.1", 47 | "@types/testing-library__react": "^10.2.0", 48 | "@typescript-eslint/eslint-plugin": "^4.3.0", 49 | "@typescript-eslint/parser": "^4.33.0", 50 | "babel-loader": "^8.1.0", 51 | "coveralls": "^3.1.1", 52 | "css-loader": "^5.1.3", 53 | "eslint": "^7.10.0", 54 | "eslint-config-prettier": "^8.1.0", 55 | "eslint-plugin-jest": "^24.0.2", 56 | "eslint-plugin-prettier": "^3.1.4", 57 | "eslint-plugin-react": "^7.21.2", 58 | "fork-ts-checker-webpack-plugin": "^6.4.2", 59 | "identity-obj-proxy": "^3.0.0", 60 | "jest": "^26.4.2", 61 | "prettier": "^2.3.0", 62 | "rollup": "^2.41.2", 63 | "rollup-plugin-peer-deps-external": "^2.2.3", 64 | "rollup-plugin-sass": "^1.2.9", 65 | "rollup-plugin-terser": "^7.0.2", 66 | "rollup-plugin-typescript2": "^0.30.0", 67 | "sass-loader": "^12.1.0", 68 | "style-loader": "^2.0.0", 69 | "ts-jest": "^26.4.0", 70 | "ts-loader": "^9.2.1", 71 | "tslib": "^2.2.0", 72 | "typescript": "^4.0.3" 73 | }, 74 | "scripts": { 75 | "storybook": "start-storybook -p 6006", 76 | "build-storybook": "build-storybook", 77 | "build": "rollup -c", 78 | "lint": "eslint src/*.tsx --quiet --fix", 79 | "test": "jest", 80 | "test:coveralls": "jest --coverage && coveralls < coverage/lcov.info" 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /postinstallSSJ.js: -------------------------------------------------------------------------------- 1 | console.log( 2 | '\x1b[36m%s\x1b[34m%s\x1b[0m', 3 | '**************************************************************************************\n'+ 4 | '*** UNLIMITED REACT COMPONENTS ***\n'+ 5 | '*** HIGHLIGHT JSX CODE ***\n'+ 6 | '*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*//*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*\n' 7 | ); -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import commonjs from "@rollup/plugin-commonjs"; 2 | import resolve from "@rollup/plugin-node-resolve"; 3 | import peerDepsExternal from "rollup-plugin-peer-deps-external"; 4 | import typescript from "rollup-plugin-typescript2"; 5 | import sass from "rollup-plugin-sass"; 6 | import packageJson from "./package.json"; 7 | import { terser } from "rollup-plugin-terser"; 8 | 9 | export default { 10 | input: "./src/index.ts", 11 | output: [ 12 | { 13 | file: packageJson.main, 14 | format: "cjs", 15 | sourcemap: true, 16 | }, 17 | { 18 | file: packageJson.module, 19 | format: "esm", 20 | sourcemap: true, 21 | }, 22 | ], 23 | plugins: [ 24 | sass({ insert: true }), 25 | peerDepsExternal(), 26 | resolve(), 27 | commonjs(), 28 | typescript(), 29 | terser(), 30 | ], 31 | }; 32 | -------------------------------------------------------------------------------- /src/Components/ClipBoard.tsx: -------------------------------------------------------------------------------- 1 | import React, { Fragment, useState } from "react"; 2 | 3 | import Done from "../Icons/Done"; 4 | import Copy from "../Icons/Copy"; 5 | 6 | const Clipboard = ({ 7 | code = "no code", 8 | onCopyToClipboard = (_code: string) => {}, 9 | }) => { 10 | //const { code = "no code" } = props; 11 | const [copied, setCopied] = useState(false); 12 | const changeIcon = () => { 13 | setCopied(true); 14 | setTimeout(() => { 15 | setCopied(false); 16 | }, 2800); 17 | }; 18 | function fallbackCopyTextToClipboard(text: string) { 19 | var textArea = document.createElement("textarea"); 20 | textArea.value = text; 21 | 22 | // Avoid scrolling to bottom 23 | textArea.style.top = "0"; 24 | textArea.style.left = "0"; 25 | textArea.style.position = "fixed"; 26 | 27 | document.body.appendChild(textArea); 28 | textArea.focus(); 29 | textArea.select(); 30 | 31 | try { 32 | var successful = document.execCommand("copy"); 33 | var msg = successful ? "successful" : "unsuccessful"; 34 | if (successful) { 35 | changeIcon(); 36 | onCopyToClipboard?.(code); 37 | } 38 | console.log("Fallback: Copying text command was " + msg); 39 | } catch (err) { 40 | console.error("Fallback: Oops, unable to copy", err); 41 | } 42 | 43 | document.body.removeChild(textArea); 44 | } 45 | function copyTextToClipboard(text: string) { 46 | if (!navigator.clipboard) { 47 | fallbackCopyTextToClipboard(text); 48 | return; 49 | } 50 | navigator.clipboard.writeText(text).then( 51 | function () { 52 | changeIcon(); 53 | onCopyToClipboard?.(code); 54 | 55 | console.log("Async: Copying to clipboard was successful!"); 56 | }, 57 | function (err) { 58 | console.error("Async: Could not copy text: ", err); 59 | }, 60 | ); 61 | } 62 | 63 | return ( 64 | 65 |
copyTextToClipboard(code)} 67 | className={ 68 | copied ? "floating-copy-button copied" : "floating-copy-button" 69 | } 70 | > 71 | {copied ? : } 72 |
73 |
74 | ); 75 | }; 76 | export default Clipboard; 77 | -------------------------------------------------------------------------------- /src/Components/HighLighterProps.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export interface HighLighterProps { 4 | /** 5 | * The JSX code to highlight 6 | */ 7 | code: string; 8 | /** 9 | * at the moment only JSX and JS is supported 10 | */ 11 | //language?: string; 12 | /** 13 | * style properties that affects only the container 14 | */ 15 | style?: React.CSSProperties; 16 | /** 17 | * style properties that affects only the container 18 | */ 19 | children?: string; 20 | /** 21 | * event that is triggered when copy to clipboard the code 22 | */ 23 | onCopyToClipboard?:(code:string)=>void 24 | } -------------------------------------------------------------------------------- /src/Components/Highlighter.scss: -------------------------------------------------------------------------------- 1 | .highlighter-container { 2 | background: #0d1117; 3 | color: rgb(255, 255, 255); 4 | border-radius: 10px; 5 | overflow: auto; 6 | line-height: 1.15; 7 | //-moz-tab-size: 1.5em; 8 | --banner-display: none; 9 | --banner-height-normal: 0px; 10 | --banner-height-small: 0px; 11 | margin: 0; 12 | padding: 0; 13 | min-width: 200px; 14 | width: 100%; 15 | overflow: auto; 16 | position: relative; 17 | .floating-copy-button { 18 | cursor: pointer; 19 | &:hover { 20 | background-color: rgba(255, 255, 255, 0.504); 21 | border: 1px solid white; 22 | padding: 7px; 23 | } 24 | &.copied { 25 | border: 1px solid greenyellow; 26 | padding: 7px; 27 | 28 | &:hover { 29 | border: 1px solid greenyellow; 30 | 31 | background-color: rgba(53, 116, 34, 0.753); 32 | 33 | padding: 7px; 34 | } 35 | } 36 | position: absolute; 37 | padding: 8px; 38 | right: 7px; 39 | top: 7px; 40 | border-radius: 8px; 41 | background-color: rgba(255, 255, 255, 0.404); 42 | box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 43 | 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); 44 | } 45 | } 46 | .highlighter-container::after { 47 | box-sizing: inherit; 48 | } 49 | .highlighter-container::before { 50 | box-sizing: inherit; 51 | } 52 | .highlighter-jsx { 53 | min-width: 600px; 54 | width: 100%; 55 | overflow: auto; 56 | height: auto !important; 57 | margin: 1rem; 58 | font-size: 14px; 59 | line-height: 20px; 60 | white-space: pre-wrap; 61 | //word-break: break-word; 62 | } 63 | code, 64 | pre { 65 | line-height: 20px; 66 | white-space: pre-wrap; 67 | word-break: break-word; 68 | font-size: 1em; 69 | font-family: source-code-pro, Menlo, Monaco, Consolas, Courier New, monospace; 70 | } 71 | span.token { 72 | // color: rgb(57, 188, 240); 73 | color: rgb(96, 210, 255); 74 | } 75 | span.token.symbol-1 { 76 | color: rgb(207, 178, 13); 77 | } 78 | span.token.symbol-2 { 79 | color: rgb(212, 37, 212); 80 | } 81 | span.token.symbol-3 { 82 | color: rgb(51, 141, 177); 83 | } 84 | span.token.symbol-0 { 85 | color: rgb(14, 36, 83); 86 | } 87 | span.token.symbol { 88 | color: rgb(207, 178, 13); 89 | } 90 | span.token.high-keyword { 91 | color: rgb(196, 92, 196); 92 | } 93 | 94 | span.token.keyword { 95 | color: rgb(51, 91, 177); 96 | } 97 | 98 | span.token.class-name { 99 | color: rgb(94, 212, 157); 100 | } 101 | span.token.punctuation { 102 | color: rgba(255, 255, 255, 0.58); 103 | } 104 | span.token.function { 105 | color: rgb(226, 212, 135); 106 | } 107 | span.token.parameter { 108 | color: rgb(96, 210, 255); 109 | } 110 | span.token.operator { 111 | color: rgb(255, 255, 255); 112 | } 113 | span.token.number { 114 | color: rgb(80, 223, 67); 115 | } 116 | span.token.attributeName { 117 | color: rgb(36, 117, 138); 118 | } 119 | span.token.tag { 120 | color: rgb(252, 146, 158); 121 | } 122 | 123 | span.token.string { 124 | color: rgb(168, 109, 91); 125 | } 126 | 127 | span.token.comment { 128 | color: rgb(73, 128, 66); 129 | } 130 | -------------------------------------------------------------------------------- /src/Components/Highlighter.tsx: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from "react"; 2 | import { useEffect } from "react"; 3 | import { useState } from "react"; 4 | import Clipboard from "./ClipBoard"; 5 | 6 | import "./Highlighter.scss"; 7 | import { HighLighterProps } from "./HighLighterProps"; 8 | import { 9 | Line, 10 | Token, 11 | superHighlighter, 12 | isOpenSymbol, 13 | isCloseSymbol, 14 | } from "./utils.highlight"; 15 | 16 | const HighLighter = (props: HighLighterProps) => { 17 | const { code, style, children ,onCopyToClipboard} = props; 18 | //const [bracketLevel, setBracketLevel] = useState(0); 19 | // const [commentBlock, setCommentBlock] = useState(false); 20 | const [codeHighlighted, setCodeHighlighted] = useState(<>); 21 | useEffect(() => { 22 | if (children && children.length > 0) { 23 | tokenize(children); 24 | } else { 25 | tokenize(code || ""); 26 | } 27 | }, [code, children]); 28 | const tokenize = (code: string): void | React.ReactNode => { 29 | let listOfLines: Line[] = superHighlighter(code); 30 | 31 | let listOfCode: React.ReactNode[] = []; 32 | for (let i = 0; i < listOfLines.length; i++) { 33 | let tokenList: Token[] = listOfLines[i]; 34 | let lineSpan: React.ReactNode = tokenizeSpan(tokenList, i); 35 | listOfCode.push(lineSpan); 36 | } 37 | 38 | setCodeHighlighted( 39 | {listOfCode.map((codeLine) => codeLine)} 40 | ); 41 | 42 | //return {listOfCode.map((codeLine) => codeLine)}; 43 | }; 44 | //const setLevelOfSymbol = (token: Token) => {}; 45 | /* findBlockComment = (tokenList: Token[], j: number) => { 46 | let token: Token = tokenList[j]; 47 | if ( 48 | token.token === "/" && 49 | tokenList[j + 1]?.token === "" && 50 | tokenList[j + 2]?.token === "*" 51 | ) { 52 | // setCommentBlock(true); 53 | } 54 | };*/ 55 | /*const findFinalBlockComment = (tokenList: Token[], j: number) => { 56 | let token: Token = tokenList[j]; 57 | if ( 58 | token.token === "/" && 59 | tokenList[j - 1]?.token === "" && 60 | tokenList[j - 2]?.token === "*" 61 | ) { 62 | //setCommentBlock(false); 63 | } 64 | };*/ 65 | let commentBlock: boolean = false; 66 | let levelBracket: number = 1; 67 | let openBrackets: number = 0; 68 | function reduceOpenBrackets() { 69 | if (openBrackets !== 0) { 70 | openBrackets -= 1; 71 | } 72 | } 73 | function incBrack() { 74 | if (levelBracket !== 3) { 75 | levelBracket += 1; 76 | } else { 77 | levelBracket = 1; 78 | } 79 | } 80 | function decBrack() { 81 | levelBracket -= 1; 82 | if (levelBracket === 0) { 83 | levelBracket = 3; 84 | } 85 | } 86 | function levelbefore(__levelBracket: number) { 87 | let _levelBracket = __levelBracket - 1; 88 | if (_levelBracket === 0) { 89 | _levelBracket = 3; 90 | } 91 | return _levelBracket; 92 | } 93 | const tokenizeSpan = (tokenList: Token[], key: number): React.ReactNode => { 94 | let result: React.ReactNode; 95 | //for each line I create a div 96 | //for each token create a span 97 | let listOfSpans: React.ReactNode[] = []; 98 | //let block: boolean = commentBlock; 99 | //console.log("found found ", block); 100 | for (let j = 0; j < tokenList.length; j++) { 101 | let spanClassName = "token"; 102 | let token: Token = tokenList[j]; 103 | /* if(!commentBlock){ 104 | findBlockComment(tokenList,j); 105 | } */ 106 | if ( 107 | !commentBlock && 108 | token.token === "/" && 109 | //tokenList[j + 1]?.token === "" && 110 | tokenList[j + 2]?.token === "*" 111 | ) { 112 | commentBlock = true; 113 | } 114 | 115 | //// 116 | if (isCloseSymbol(token.token)) { 117 | reduceOpenBrackets(); 118 | spanClassName = `token symbol-${levelbefore(levelBracket)}`; 119 | decBrack(); 120 | // console.log( "Log:" + token.token, "level: " + levelBracket, "openBrac: " + openBrackets, spanClassName ); 121 | } else if (isOpenSymbol(token.token)) { 122 | openBrackets++; 123 | spanClassName = `token symbol-${levelBracket}`; 124 | incBrack(); 125 | // console.log( "Log:" + token.token, "level: " + levelBracket, "openBrac: " + openBrackets, spanClassName ); 126 | } else if (token.category !== "") { 127 | spanClassName += ` ${token.category}`; 128 | } 129 | if (token.token.length > 0) { 130 | listOfSpans.push( 131 | 135 | {token.token} 136 | 137 | ); 138 | } 139 | 140 | if ( 141 | commentBlock && 142 | token.token === "/" && 143 | tokenList[j - 1]?.token === "" && 144 | tokenList[j - 2]?.token === "*" 145 | ) { 146 | commentBlock = false; 147 | } 148 | } 149 | 150 | result =
{listOfSpans.map((spanToken) => spanToken)}
; 151 | return result; 152 | }; 153 | //const codeHighlighted = tokenize(code || ""); 154 | const handleCopyToClipboard=(_code:string)=>{ 155 | onCopyToClipboard?.(_code); 156 | } 157 | return ( 158 | 159 | {(children || code) && 160 | (code?.length > 0 || (children as string).length > 0) && ( 161 |
166 | 167 | 168 | <>{codeHighlighted} 169 |
170 | )} 171 |
172 | ); 173 | }; 174 | 175 | export default HighLighter; 176 | -------------------------------------------------------------------------------- /src/Components/utils.highlight.ts: -------------------------------------------------------------------------------- 1 | 2 | export type CodeLine = JSX.Element; 3 | export type Line = Token[]; 4 | 5 | export interface Token { 6 | token: string; 7 | category: string; 8 | level?: 1 | 2 | 3 | 0; 9 | } 10 | const highKeywords = [ 11 | "import", 12 | "from", 13 | "return", 14 | "if", 15 | "else", 16 | "switch", 17 | "default", 18 | "export", 19 | ] 20 | const keywords = [ 21 | "class", 22 | "extends", 23 | "this", 24 | "super", 25 | "function", 26 | "null", 27 | "var", 28 | "let", 29 | "const", 30 | "typeof", 31 | "interface", 32 | "type", "false" 33 | ]; 34 | export const tokens = [ 35 | "keyword", 36 | "className", 37 | "punctuation", 38 | "function", 39 | "parameter", 40 | "operator", 41 | "number", 42 | "attributeName", 43 | "default", 44 | ]; 45 | const punctuation: string[] = [ 46 | ".", 47 | ",", 48 | ";", 49 | ":", 50 | "<", 51 | ">", 52 | "=", 53 | "!=", 54 | "<=", 55 | ">=", 56 | "===", 57 | "!==", 58 | ">=", 59 | "/", 60 | "!", 61 | "+", 62 | "*" 63 | ]; 64 | const arrow: string[] = [ 65 | ">=", 66 | "=>", 67 | "<=", 68 | "!=", 69 | "===", 70 | "!==", 71 | ">=", 72 | "!" 73 | ] 74 | const openSymbols: string[] = [ 75 | "(", 76 | "{", 77 | "[", 78 | ]; 79 | const closeSymbols: string[] = [ 80 | ")", 81 | "}", 82 | "]", 83 | ]; 84 | 85 | export const isClassName = (word: string) => { 86 | return /[A-Z]/.test(word[0]); 87 | }; 88 | export const isHighKeyWord = (word: string) => { 89 | return highKeywords.includes(word); 90 | }; 91 | export const isKeyWord = (word: string) => { 92 | return keywords.includes(word); 93 | }; 94 | export const isPunctuation = (word: string) => { 95 | return punctuation.includes(word); 96 | }; 97 | export const isArrow = (word: string) => { 98 | return arrow.includes(word); 99 | }; 100 | export const isOpenSymbol = (word: string) => { 101 | return openSymbols.includes(word); 102 | }; 103 | export const isCloseSymbol = (word: string) => { 104 | return closeSymbols.includes(word); 105 | }; 106 | /** 107 | * Makes a Token 108 | * @param token the string representation of the token 109 | * @param category the category of the token 110 | * @param isFunction wheter is a function and must take this category 111 | * @param openString wheter is part of a large splted string and must take this category 112 | * @returns a token 113 | */ 114 | export const makeToken = ( 115 | token: string, 116 | category: string, 117 | isFunction?: boolean, 118 | openString?: boolean 119 | ): Token => { 120 | let tokenToken: Token; 121 | 122 | if (openString) { 123 | tokenToken = { token: token, category: "string" }; 124 | } 125 | else if (isFunction) { 126 | tokenToken = { token: token, category: "function" }; 127 | } else { 128 | tokenToken = { token: token, category: category }; 129 | 130 | } 131 | //console.log("make:", tokenToken); 132 | return tokenToken; 133 | } 134 | /** 135 | * @var a flag used to check whether a large splited string is being analyzed 136 | */ 137 | let openString: boolean = false; 138 | /** 139 | * 140 | * @param word a word to be analized for punctuation and strings 141 | * @returns 142 | */ 143 | export const TOKENIZE = ( 144 | currentWord: string 145 | ): Token[] => { 146 | let tokenArray: Token[] = []; 147 | //identif string 148 | //for each character 149 | let acumword = ""; 150 | let isFunction = false; 151 | let i = 0; 152 | // in the future search for the pattern 153 | // string = `${var} ` 154 | // symbol symbol parameter symbol 155 | if (currentWord.charAt(0) === "\"" || currentWord.charAt(0) === "\'" || currentWord.charAt(0) === "\`") { 156 | let tokenPrev: Token = makeToken(currentWord, "string"); 157 | return [tokenPrev]; 158 | } 159 | for (; i < currentWord.length; i++) { 160 | //go along in chars 161 | let currentCharacter = currentWord.charAt(i); 162 | 163 | if (isPunctuation(currentCharacter)) { 164 | //PUNCTUATION 165 | 166 | let tokenPrev: Token = 167 | makeToken(acumword, "", false, openString); 168 | tokenArray.push(tokenPrev); 169 | acumword = ""; 170 | 171 | if (currentCharacter === "." && tokenArray[tokenArray.length - 1].token.length > 0) { 172 | //I found an object and a function 173 | isFunction = true; 174 | tokenArray[tokenArray.length - 1].category = "parameter"; 175 | tokenArray[tokenArray.length - 1].token = tokenArray[tokenArray.length - 1].token.split(" ")[0]; 176 | } 177 | 178 | // Now I add the "." 179 | let token: Token = //{ token: currentCharacter, category: "punctuation" }; 180 | makeToken(currentCharacter, "punctuation", false, openString); 181 | tokenArray.push(token); 182 | } else if (isCloseSymbol(currentCharacter) || isOpenSymbol(currentCharacter)) { 183 | // SYMBOL 184 | let tokenPrev: Token = //{ token: acumword + " ", category: "" }; 185 | makeToken(acumword, "", isFunction, openString); 186 | tokenArray.push(tokenPrev); 187 | acumword = ""; 188 | 189 | if (currentCharacter === "(" && tokenArray[tokenArray.length - 1].token.length > 0) { 190 | tokenArray[tokenArray.length - 1].category = "function"; 191 | } 192 | 193 | let token: Token = //{ token: currentCharacter, category: "symbol" }; 194 | makeToken(currentCharacter, "symbol", false, openString); 195 | tokenArray.push(token); 196 | } else { 197 | // SIMPLE WORD 198 | //continue accumulating 199 | acumword += currentCharacter; 200 | } 201 | } 202 | let tokenPrev: Token = { token: acumword, category: "" }; 203 | makeToken(acumword, "", isFunction); 204 | tokenArray.push(tokenPrev); 205 | //check for functions 206 | for (let i = 0; i < tokenArray.length - 1; i++) { 207 | if (tokenArray[i].token.includes(".") && tokenArray[i + 1].token === "") { 208 | tokenArray[i + 1].category = "function"; 209 | } 210 | } 211 | return tokenArray; 212 | } 213 | /** 214 | * 215 | * @param line 216 | * @returns 217 | */ 218 | export const tokenizeLine = ( 219 | line: string 220 | ): Line => { 221 | let tokenArray: Token[] = []; 222 | 223 | //separate for whitespaces 224 | let words: string[];//= line.split(" "); 225 | // console.log("===>",words); 226 | let superWords: string[] = []; 227 | let strSymbol: string = ""; 228 | let acumWord = ""; 229 | for (let i = 0; i < line.length; i++) { 230 | let currentChar = line[i]; 231 | 232 | if (currentChar === "\"" || currentChar === "\'" || currentChar === "\`") { 233 | strSymbol = currentChar; 234 | if (acumWord.length > 0) { 235 | superWords.push(acumWord); 236 | //console.log("wors", acumWord,currentChar); 237 | acumWord = ""; 238 | } 239 | //better capture the entire string 240 | acumWord += currentChar; 241 | let j = i + 1; 242 | while (1) { 243 | let currentChar2 = line[j]; 244 | if (currentChar2 === strSymbol) { 245 | acumWord += currentChar2; 246 | superWords.push(acumWord); 247 | // console.log("wors", acumWord,currentChar); 248 | acumWord = ""; 249 | break; 250 | } else { 251 | acumWord += currentChar2; 252 | j++; 253 | } 254 | } 255 | i = j; 256 | } else if (currentChar === " ") { 257 | //console.log("ws"); 258 | superWords.push(acumWord); 259 | acumWord = ""; 260 | //console.log("words", acumWord,currentChar); 261 | superWords.push(" "); 262 | acumWord = ""; 263 | 264 | //i=i+2; 265 | } else if (currentChar.length === 0) { 266 | //console.log("empty"); 267 | //acumWord += " "; 268 | } else { 269 | acumWord += currentChar; 270 | } 271 | 272 | } 273 | superWords.push(acumWord); 274 | words = superWords; 275 | 276 | //for each word 277 | for (let i = 0; i < words.length; i++) { 278 | // a word aftersplited by " " 279 | let currentWord = words[i]; 280 | if (isKeyWord(currentWord)) { 281 | let tokenPrev: Token = { token: currentWord, category: "keyword" }; 282 | // makeToken( currconsoleentWord + " ","",isFunction); 283 | tokenArray.push(tokenPrev); 284 | } else if (isHighKeyWord(currentWord)) { 285 | let tokenPrev: Token = { token: currentWord, category: "high-keyword" }; 286 | //makeToken( currentWord + " ","",isFunction); 287 | tokenArray.push(tokenPrev); 288 | } else if (isArrow(currentWord)) { 289 | let tokenPrev: Token = { token: currentWord, category: "punctuation" }; 290 | //makeToken( currentWord + " ","",isFunction); 291 | tokenArray.push(tokenPrev); 292 | } else { 293 | //punctuation 294 | tokenArray = [...tokenArray, ...TOKENIZE(currentWord)]; 295 | } 296 | } 297 | for (let i = 0; i < tokenArray.length; i++) { 298 | if (tokenArray[i].token === "/") { 299 | 300 | if (tokenArray[i + 1] && tokenArray[i + 2] && tokenArray[i + 2].token === "/") { 301 | 302 | for (let j = i; j < tokenArray.length; j++) { 303 | tokenArray[j].category = "comment"; 304 | } 305 | break; 306 | } 307 | } 308 | 309 | } 310 | 311 | //go along tokens array and find classes 312 | for (let i = 0; i < tokenArray.length; i++) { 313 | let token: Token = tokenArray[i]; 314 | if (isClassName(token.token)) { 315 | let j = i - 1; 316 | while (1) { 317 | if (tokenArray[j].token !== " " && j > 0) { 318 | break; 319 | } 320 | j--; 321 | } 322 | if (j >= 0 && tokenArray[j].token === "import") { 323 | token.category = "parameter"; 324 | } else if (j >= 0 && (["const", "function"].includes(tokenArray[j].token))) { 325 | token.category = "function"; 326 | } else { 327 | token.category = "class-name"; 328 | } 329 | } 330 | if ("<" == (token.token)) { 331 | if (tokenArray[i + 1]) { 332 | tokenArray[i + 1].category = "tag"; 333 | } 334 | } 335 | if ("<" == (token.token) && tokenArray[i + 1] && tokenArray[i + 2] && tokenArray[i + 2].token === "/") { 336 | if (tokenArray[i + 3]) { 337 | tokenArray[i + 3].category = "tag"; 338 | } 339 | } 340 | } 341 | 342 | 343 | return tokenArray; 344 | } 345 | /** 346 | * Splits the code into lines 347 | * 348 | * For each line first splits by punctuation and strings 349 | * Also maintains whitespaces 350 | * 351 | * After that, searchs for keywords 352 | * 353 | * Tags with Classes and HTML-tags 354 | * @param code The entie code to be highlighted 355 | */ 356 | export const superHighlighter = ( 357 | code: string 358 | ): Line[] => { 359 | 360 | 361 | //split in lines 362 | const lines: string[] = code.split("\n"); 363 | 364 | //separate by punctuation 365 | let punctuationSeparated: Line[] = []; 366 | 367 | //For each line tokenize 368 | for (let i = 0; i < lines.length; i++) { 369 | let currentLine = lines[i]; 370 | let tokenArray = tokenizeLine(currentLine); 371 | 372 | punctuationSeparated.push(tokenArray); 373 | } 374 | 375 | return punctuationSeparated; 376 | } 377 | 378 | 379 | -------------------------------------------------------------------------------- /src/Icons/Copy.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from "react"; 2 | import { copyProps } from "./CopyProps"; 3 | import { parseSize } from "./utils/utils"; 4 | 5 | const Copy: FC = (props: copyProps) => { 6 | const { size, color, colorFill = "none", onClick, style, className } = props; 7 | const finalSize = parseSize(size); 8 | const finalStyle = style ? style : {}; 9 | return ( 10 | onClick?.()} 13 | xmlns="http://www.w3.org/2000/svg" 14 | enableBackground="new 0 0 24 24" 15 | height={`${finalSize}px`} 16 | viewBox="0 0 24 24" 17 | width={`${finalSize}px`} 18 | fill={color ? color : "#000000"} 19 | className={className || ""} 20 | > 21 | 22 | 23 | 24 | ); 25 | }; 26 | export default Copy; 27 | -------------------------------------------------------------------------------- /src/Icons/CopyProps.ts: -------------------------------------------------------------------------------- 1 | import { IconProps } from "./IconProps"; 2 | 3 | export interface copyProps extends IconProps{} -------------------------------------------------------------------------------- /src/Icons/Done.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from "react"; 2 | import { DoneProps } from "./DoneProps"; 3 | import { parseSize } from "./utils/utils"; 4 | 5 | const Done: FC = (props: DoneProps) => { 6 | const { 7 | size, 8 | color, 9 | colorFill = "none", 10 | onClick, 11 | style = {}, 12 | className, 13 | } = props; 14 | const finalSize = parseSize(size); 15 | return ( 16 | onClick?.()} 19 | xmlns="http://www.w3.org/2000/svg" 20 | //enableBackground="new 0 0 24 24" 21 | height={`${finalSize}px`} 22 | viewBox="0 0 24 24" 23 | width={`${finalSize}px`} 24 | fill={color ? color : "#000000"} 25 | className={className || ""} 26 | > 27 | 28 | 29 | 30 | ); 31 | }; 32 | export default Done; 33 | -------------------------------------------------------------------------------- /src/Icons/DoneProps.ts: -------------------------------------------------------------------------------- 1 | import { IconProps } from "./IconProps"; 2 | 3 | export interface DoneProps extends IconProps{ 4 | 5 | } -------------------------------------------------------------------------------- /src/Icons/IconProps.ts: -------------------------------------------------------------------------------- 1 | import { CSSProperties } from "react"; 2 | 3 | export interface IconProps { 4 | size?: "micro"|"small" |"semi-medium"| "medium" | "large"; 5 | color?: string; 6 | colorFill?: string; 7 | onClick?: Function; 8 | style?:CSSProperties; 9 | className?:string; 10 | } -------------------------------------------------------------------------------- /src/Icons/utils/utils.ts: -------------------------------------------------------------------------------- 1 | import { IconProps } from "../IconProps"; 2 | 3 | export const parseSize = (sizeStr: IconProps["size"]): number => { 4 | switch (sizeStr) { 5 | case "micro": 6 | return 8; 7 | case "small": 8 | return 15; 9 | case "semi-medium": 10 | return 18; 11 | case "medium": 12 | return 25; 13 | case "large": 14 | return 28; 15 | default: 16 | return 24; 17 | } 18 | } -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import Highlighter from "./Components/Highlighter"; 2 | import Clipboard from "./Components/ClipBoard"; 3 | 4 | export {Highlighter, Clipboard}; -------------------------------------------------------------------------------- /src/tests/HighLighter.spec.tsx: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom"; 2 | 3 | import React from "react"; 4 | import { render, screen } from "@testing-library/react"; 5 | import { 6 | isArrow, 7 | isClassName, 8 | isCloseSymbol, 9 | isHighKeyWord, 10 | isKeyWord, 11 | isOpenSymbol, 12 | isPunctuation, 13 | makeToken, 14 | Token, 15 | TOKENIZE, 16 | } from "../Components/utils.highlight"; 17 | import HighLighter from "../Components/Highlighter"; 18 | //import {HighLight} from "src/" 19 | const code_test1 = ` 20 | //creating themes 21 | const themes = { 22 | light: { 23 | foreground: "#000000", 24 | background: "#eeeeee" 25 | }, 26 | }; 27 | /* this is a 28 | comment */ 29 | . 30 | . 31 | . 32 | function ThemedButton() { 33 | const theme = useContext(ThemeContext); 34 | return ( 35 | 41 | ); 42 | } 43 | `; 44 | 45 | it('displays a "ThemedButton" message', () => { 46 | render(); 47 | expect(screen.getByText("ThemedButton")).toBeInTheDocument(); 48 | expect(screen.getByText("comment")).toBeInTheDocument(); 49 | expect(screen.getByText("function")).toBeInTheDocument(); 50 | expect(screen.getAllByText("themes").length).toEqual(2); 51 | expect(screen.getAllByText("background").length).toEqual(3); 52 | //expect(screen.getByText("background")).toBeInTheDocument(); 53 | expect(screen.getByText("creating")).toBeInTheDocument(); 54 | }); 55 | describe("Validate css background", () => { 56 | it("background-color must be equal to #0d1117; by default", () => { 57 | const { getByTestId } = render(); 58 | const HLcontainer = getByTestId("highlighter-container"); 59 | 60 | expect(HLcontainer).toHaveStyle(`background-color : 0d1117`); 61 | }); 62 | 63 | it("background-color must be equal to white in style object prop", () => { 64 | const { getByTestId } = render( 65 | , 66 | ); 67 | const HLcontainer = getByTestId("highlighter-container"); 68 | 69 | expect(HLcontainer).toHaveStyle(`background-color : white`); 70 | }); 71 | }); 72 | 73 | describe("Validate identification functions for tokens", () => { 74 | it("Validate isClassName function", () => { 75 | const token: string = "ThemedButton"; 76 | 77 | expect(isClassName(token)).toEqual(true); 78 | }); 79 | 80 | it("Validate isHighKeyWord function", () => { 81 | const token: string = "import"; 82 | const token2: string = "function"; 83 | 84 | expect(isHighKeyWord(token)).toEqual(true); 85 | expect(isHighKeyWord(token2)).toEqual(false); 86 | }); 87 | 88 | it("Validate isKeyWord function", () => { 89 | const token: string = "function"; 90 | const token2: string = "import"; 91 | 92 | expect(isKeyWord(token)).toEqual(true); 93 | expect(isKeyWord(token2)).toEqual(false); 94 | }); 95 | 96 | it("Validate isPunctuation function", () => { 97 | const token: string = "."; 98 | const token2: string = "= >"; 99 | 100 | expect(isPunctuation(token)).toEqual(true); 101 | expect(isPunctuation(token2)).toEqual(false); 102 | }); 103 | 104 | it("Validate isArrow function", () => { 105 | const token: string = "=>"; 106 | const token2: string = "= >"; 107 | 108 | expect(isArrow(token)).toEqual(true); 109 | expect(isArrow(token2)).toEqual(false); 110 | }); 111 | it("Validate isOpenSymbol function", () => { 112 | const token: string = "["; 113 | const token2: string = "}"; 114 | 115 | expect(isOpenSymbol(token)).toEqual(true); 116 | expect(isOpenSymbol(token2)).toEqual(false); 117 | }); 118 | it("Validate isCloseSymbol function", () => { 119 | const token: string = "}"; 120 | const token2: string = "["; 121 | 122 | expect(isCloseSymbol(token)).toEqual(true); 123 | expect(isCloseSymbol(token2)).toEqual(false); 124 | }); 125 | }); 126 | 127 | describe("Validate makeToken function", () => { 128 | it("Validate whith default values ", () => { 129 | const token: Token = makeToken("function", "keyword"); 130 | const compareToken: Token = { 131 | token: "function", 132 | category: "keyword", 133 | }; 134 | expect(token).toEqual(compareToken); 135 | }); 136 | it("Validate when isFunction is true ", () => { 137 | const token: Token = makeToken("function", "keyword", true); 138 | const compareToken: Token = { 139 | token: "function", 140 | category: "function", 141 | }; 142 | expect(token).toEqual(compareToken); 143 | }); 144 | it("Validate when openString is true ", () => { 145 | const token: Token = makeToken("function", "keyword", false, true); 146 | const compareToken: Token = { 147 | token: "function", 148 | category: "string", 149 | }; 150 | expect(token).toEqual(compareToken); 151 | }); 152 | }); 153 | 154 | describe("Validate TOKENIZE function for make token[]", () => { 155 | it("Produces an exact array of tokens", () => { 156 | const currentWord: string = "\"This is a string\""; 157 | const expectedResult: Token[] = [ 158 | { token: "\"This is a string\"", category: "string" }, 159 | ]; 160 | expect(TOKENIZE(currentWord)).toEqual(expectedResult); 161 | 162 | }); 163 | }); 164 | -------------------------------------------------------------------------------- /stories/Highlight.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Highligther} from "../src"; 3 | import App from "../example/example"; 4 | export default { 5 | title: "Highligther", 6 | component: Highligther, 7 | }; 8 | 9 | export const Default = (): React.ReactNode => ; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "declarationDir": "build", 5 | "module": "esnext", 6 | "target": "es5", 7 | "lib": ["es6", "dom", "es2016", "es2017"], 8 | "sourceMap": true, 9 | "jsx": "react", 10 | "moduleResolution": "node", 11 | "allowSyntheticDefaultImports": true, 12 | "esModuleInterop": true 13 | }, 14 | "include": ["src/**/*"], 15 | "exclude": ["node_modules", "build"], 16 | "baseUrl": "./", 17 | } 18 | --------------------------------------------------------------------------------