From 87984e2081de4e436adac552f520c02e07e371ab Mon Sep 17 00:00:00 2001 From: sharevb Date: Sun, 25 Aug 2024 22:57:07 +0200 Subject: [PATCH 1/3] feat(new tool): Markdown to HTML (#916) * feat(new tool): Markdown to HTML Fix partially #538 * feat: add print button * Update src/tools/markdown-to-html/index.ts * Update src/tools/markdown-to-html/markdown-to-html.vue --------- Co-authored-by: Corentin THOMASSET --- components.d.ts | 2 + package.json | 2 + pnpm-lock.yaml | 61 ++++++++++++++++--- src/components/TextareaCopyable.vue | 2 + src/tools/index.ts | 2 + src/tools/markdown-to-html/index.ts | 12 ++++ .../markdown-to-html/markdown-to-html.vue | 44 +++++++++++++ 7 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 src/tools/markdown-to-html/index.ts create mode 100644 src/tools/markdown-to-html/markdown-to-html.vue diff --git a/components.d.ts b/components.d.ts index 89f41f808..8e59366ab 100644 --- a/components.d.ts +++ b/components.d.ts @@ -121,6 +121,7 @@ declare module '@vue/runtime-core' { LoremIpsumGenerator: typeof import('./src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue')['default'] MacAddressGenerator: typeof import('./src/tools/mac-address-generator/mac-address-generator.vue')['default'] MacAddressLookup: typeof import('./src/tools/mac-address-lookup/mac-address-lookup.vue')['default'] + MarkdownToHtml: typeof import('./src/tools/markdown-to-html/markdown-to-html.vue')['default'] MathEvaluator: typeof import('./src/tools/math-evaluator/math-evaluator.vue')['default'] MenuBar: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar.vue')['default'] MenuBarItem: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar-item.vue')['default'] @@ -129,6 +130,7 @@ declare module '@vue/runtime-core' { MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] + NButton: typeof import('naive-ui')['NButton'] NCode: typeof import('naive-ui')['NCode'] NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] diff --git a/package.json b/package.json index 6191f702c..63e5856a5 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@tiptap/pm": "2.1.6", "@tiptap/starter-kit": "2.1.6", "@tiptap/vue-3": "2.0.3", + "@types/markdown-it": "^13.0.7", "@types/figlet": "^1.5.8", "@vicons/material": "^0.12.0", "@vicons/tabler": "^0.12.0", @@ -70,6 +71,7 @@ "jwt-decode": "^3.1.2", "libphonenumber-js": "^1.10.28", "lodash": "^4.17.21", + "markdown-it": "^14.0.0", "marked": "^10.0.0", "mathjs": "^11.9.1", "mime-types": "^2.1.35", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3044541a2..2311f3aff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ dependencies: '@types/figlet': specifier: ^1.5.8 version: 1.5.8 + '@types/markdown-it': + specifier: ^13.0.7 + version: 13.0.9 '@vicons/material': specifier: ^0.12.0 version: 0.12.0 @@ -110,6 +113,9 @@ dependencies: lodash: specifier: ^4.17.21 version: 4.17.21 + markdown-it: + specifier: ^14.0.0 + version: 14.1.0 marked: specifier: ^10.0.0 version: 10.0.0 @@ -2952,7 +2958,6 @@ packages: /@types/linkify-it@3.0.2: resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==} - dev: true /@types/lodash-es@4.17.10: resolution: {integrity: sha512-YJP+w/2khSBwbUSFdGsSqmDvmnN3cCKoPOL7Zjle6s30ZtemkkqhjVfFqGwPN7ASil5VyjE2GtyU/yqYY6mC0A==} @@ -2974,6 +2979,13 @@ packages: '@types/mdurl': 1.0.2 dev: true + /@types/markdown-it@13.0.9: + resolution: {integrity: sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw==} + dependencies: + '@types/linkify-it': 3.0.2 + '@types/mdurl': 1.0.2 + dev: false + /@types/mdast@3.0.11: resolution: {integrity: sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==} dependencies: @@ -2982,7 +2994,6 @@ packages: /@types/mdurl@1.0.2: resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} - dev: true /@types/mime-types@2.1.1: resolution: {integrity: sha512-vXOTGVSLR2jMw440moWTC7H19iUyLtP3Z1YTj7cSsubOICinjMxFeb/V57v9QdyyPGbbWolUFSSmSiRSn94tFw==} @@ -3360,7 +3371,7 @@ packages: dependencies: '@unhead/dom': 0.5.1 '@unhead/schema': 0.5.1 - '@vueuse/shared': 10.11.1(vue@3.3.4) + '@vueuse/shared': 11.0.3(vue@3.3.4) unhead: 0.5.1 vue: 3.3.4 transitivePeerDependencies: @@ -3993,19 +4004,19 @@ packages: - vue dev: false - /@vueuse/shared@10.11.1(vue@3.3.4): - resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} + /@vueuse/shared@10.3.0(vue@3.3.4): + resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} dependencies: - vue-demi: 0.14.10(vue@3.3.4) + vue-demi: 0.14.5(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue dev: false - /@vueuse/shared@10.3.0(vue@3.3.4): - resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==} + /@vueuse/shared@11.0.3(vue@3.3.4): + resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==} dependencies: - vue-demi: 0.14.5(vue@3.3.4) + vue-demi: 0.14.10(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -5016,7 +5027,6 @@ packages: /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - dev: true /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} @@ -6688,6 +6698,12 @@ packages: dependencies: uc.micro: 1.0.6 + /linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + dependencies: + uc.micro: 2.1.0 + dev: false + /local-pkg@0.4.3: resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} engines: {node: '>=14'} @@ -6825,6 +6841,18 @@ packages: mdurl: 1.0.1 uc.micro: 1.0.6 + /markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + dev: false + /marked@10.0.0: resolution: {integrity: sha512-YiGcYcWj50YrwBgNzFoYhQ1hT6GmQbFG8SksnYJX1z4BXTHSOrz1GB5/Jm2yQvMg4nN1FHP4M6r03R10KrVUiA==} engines: {node: '>= 18'} @@ -6873,6 +6901,10 @@ packages: /mdurl@1.0.1: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + /mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + dev: false + /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true @@ -7682,6 +7714,11 @@ packages: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} dev: true + /punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + dev: false + /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} @@ -8626,6 +8663,10 @@ packages: /uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + /uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + dev: false + /ufo@1.1.2: resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} diff --git a/src/components/TextareaCopyable.vue b/src/components/TextareaCopyable.vue index 8b0aae617..9585177d1 100644 --- a/src/components/TextareaCopyable.vue +++ b/src/components/TextareaCopyable.vue @@ -7,6 +7,7 @@ import sqlHljs from 'highlight.js/lib/languages/sql'; import xmlHljs from 'highlight.js/lib/languages/xml'; import yamlHljs from 'highlight.js/lib/languages/yaml'; import iniHljs from 'highlight.js/lib/languages/ini'; +import markdownHljs from 'highlight.js/lib/languages/markdown'; import { useCopy } from '@/composable/copy'; const props = withDefaults( @@ -30,6 +31,7 @@ hljs.registerLanguage('html', xmlHljs); hljs.registerLanguage('xml', xmlHljs); hljs.registerLanguage('yaml', yamlHljs); hljs.registerLanguage('toml', iniHljs); +hljs.registerLanguage('markdown', markdownHljs); const { value, language, followHeightOf, copyPlacement, copyMessage } = toRefs(props); const { height } = followHeightOf.value ? useElementSize(followHeightOf) : { height: ref(null) }; diff --git a/src/tools/index.ts b/src/tools/index.ts index b4c161ef8..c9003fe81 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -9,6 +9,7 @@ import { tool as textToUnicode } from './text-to-unicode'; import { tool as safelinkDecoder } from './safelink-decoder'; import { tool as xmlToJson } from './xml-to-json'; import { tool as jsonToXml } from './json-to-xml'; +import { tool as markdownToHtml } from './markdown-to-html'; import { tool as pdfSignatureChecker } from './pdf-signature-checker'; import { tool as numeronymGenerator } from './numeronym-generator'; import { tool as macAddressGenerator } from './mac-address-generator'; @@ -112,6 +113,7 @@ export const toolsByCategory: ToolCategory[] = [ tomlToYaml, xmlToJson, jsonToXml, + markdownToHtml, ], }, { diff --git a/src/tools/markdown-to-html/index.ts b/src/tools/markdown-to-html/index.ts new file mode 100644 index 000000000..73a6cfb33 --- /dev/null +++ b/src/tools/markdown-to-html/index.ts @@ -0,0 +1,12 @@ +import { Markdown } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Markdown to HTML', + path: '/markdown-to-html', + description: 'Convert Markdown to Html and allow to print (as PDF)', + keywords: ['markdown', 'html', 'converter', 'pdf'], + component: () => import('./markdown-to-html.vue'), + icon: Markdown, + createdAt: new Date('2024-08-25'), +}); diff --git a/src/tools/markdown-to-html/markdown-to-html.vue b/src/tools/markdown-to-html/markdown-to-html.vue new file mode 100644 index 000000000..c84d44ecf --- /dev/null +++ b/src/tools/markdown-to-html/markdown-to-html.vue @@ -0,0 +1,44 @@ + + + From 67094980c9687652c10847bf4112ae0f36a31ce9 Mon Sep 17 00:00:00 2001 From: Corentin THOMASSET Date: Fri, 13 Sep 2024 20:56:32 +0200 Subject: [PATCH 2/3] chore(readme): updated logos (#1294) --- .github/logo-dark.png | Bin 0 -> 40398 bytes .github/logo-white.png | Bin 0 -> 39632 bytes .github/logo.png | Bin 8000 -> 0 bytes README.md | 6 +++++- 4 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .github/logo-dark.png create mode 100644 .github/logo-white.png delete mode 100644 .github/logo.png diff --git a/.github/logo-dark.png b/.github/logo-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..9bee8a9cc024cb685e4159137bfa738b9f68a3a2 GIT binary patch literal 40398 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 UF8lQHKU$~!&Yff&zi{h+0p?k<*8l(j literal 0 HcmV?d00001 diff --git a/.github/logo-white.png b/.github/logo-white.png new file mode 100644 index 0000000000000000000000000000000000000000..560a135b652634440c8d1d76e5467546cee50b01 GIT binary patch literal 39632 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 AyZ`_I literal 0 HcmV?d00001 diff --git a/.github/logo.png b/.github/logo.png deleted file mode 100644 index 18bac95080859922223d82aac99703971011c5ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8000 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 Gzx^kVX6^<6 diff --git a/README.md b/README.md index a51f9c538..b9726864a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -![logo](.github/logo.png) + + + + logo + Useful tools for developer and people working in IT. [Have a look !](https://it-tools.tech). From f5c4ab19bc10ea468a453a1460b1de2d7ccab87b Mon Sep 17 00:00:00 2001 From: sharevb Date: Fri, 20 Sep 2024 20:39:40 +0200 Subject: [PATCH 3/3] feat(new tool): Regex Tester (and Cheatsheet) (#1030) * feat(new tool): Regex Tester Fix https://github.com/CorentinTh/it-tools/issues/1007, https://github.com/CorentinTh/it-tools/issues/991, https://github.com/CorentinTh/it-tools/issues/936, https://github.com/CorentinTh/it-tools/issues/761, https://github.com/CorentinTh/it-tools/issues/649 https://github.com/CorentinTh/it-tools/issues/644, https://github.com/CorentinTh/it-tools/issues/554 https://github.com/CorentinTh/it-tools/issues/308 * fix: refactor to service + add regex diagram + ui enhancements * fix: update queryParams * fix: deps * fix: svg style bug in @regexper/render @regexper/render use a stylesheet in svg that cause bugs in whole site. So add regexper in a shadow root * feat(new tool): added Regex Cheatsheet * Update src/tools/regex-memo/index.ts * Update src/tools/regex-tester/index.ts --------- Co-authored-by: Corentin THOMASSET --- components.d.ts | 15 +- package.json | 5 +- pnpm-lock.yaml | 46 +++++ src/composable/queryParams.ts | 33 ++- src/composable/validation.ts | 19 +- src/main.ts | 2 + src/tools/index.ts | 4 + src/tools/regex-memo/index.ts | 12 ++ src/tools/regex-memo/regex-memo.content.md | 121 +++++++++++ src/tools/regex-memo/regex-memo.vue | 32 +++ src/tools/regex-tester/index.ts | 12 ++ .../regex-tester/regex-tester.service.test.ts | 106 ++++++++++ .../regex-tester/regex-tester.service.ts | 61 ++++++ src/tools/regex-tester/regex-tester.vue | 193 ++++++++++++++++++ 14 files changed, 650 insertions(+), 11 deletions(-) create mode 100644 src/tools/regex-memo/index.ts create mode 100644 src/tools/regex-memo/regex-memo.content.md create mode 100644 src/tools/regex-memo/regex-memo.vue create mode 100644 src/tools/regex-tester/index.ts create mode 100644 src/tools/regex-tester/regex-tester.service.test.ts create mode 100644 src/tools/regex-tester/regex-tester.service.ts create mode 100644 src/tools/regex-tester/regex-tester.vue diff --git a/components.d.ts b/components.d.ts index 8e59366ab..3e65c3cc5 100644 --- a/components.d.ts +++ b/components.d.ts @@ -130,23 +130,19 @@ declare module '@vue/runtime-core' { MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] - NButton: typeof import('naive-ui')['NButton'] - NCode: typeof import('naive-ui')['NCode'] + NCheckbox: typeof import('naive-ui')['NCheckbox'] NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] + NDivider: typeof import('naive-ui')['NDivider'] NEllipsis: typeof import('naive-ui')['NEllipsis'] - NForm: typeof import('naive-ui')['NForm'] - NFormItem: typeof import('naive-ui')['NFormItem'] NH1: typeof import('naive-ui')['NH1'] NH3: typeof import('naive-ui')['NH3'] NIcon: typeof import('naive-ui')['NIcon'] - NInputNumber: typeof import('naive-ui')['NInputNumber'] NLayout: typeof import('naive-ui')['NLayout'] NLayoutSider: typeof import('naive-ui')['NLayoutSider'] NMenu: typeof import('naive-ui')['NMenu'] - NScrollbar: typeof import('naive-ui')['NScrollbar'] - NSlider: typeof import('naive-ui')['NSlider'] - NSwitch: typeof import('naive-ui')['NSwitch'] + NSpace: typeof import('naive-ui')['NSpace'] + NTable: typeof import('naive-ui')['NTable'] NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] @@ -156,6 +152,9 @@ declare module '@vue/runtime-core' { PhoneParserAndFormatter: typeof import('./src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue')['default'] QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default'] RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default'] + RegexMemo: typeof import('./src/tools/regex-memo/regex-memo.vue')['default'] + 'RegexMemo.content': typeof import('./src/tools/regex-memo/regex-memo.content.md')['default'] + RegexTester: typeof import('./src/tools/regex-tester/regex-tester.vue')['default'] ResultRow: typeof import('./src/tools/ipv4-range-expander/result-row.vue')['default'] RomanNumeralConverter: typeof import('./src/tools/roman-numeral-converter/roman-numeral-converter.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] diff --git a/package.json b/package.json index 63e5856a5..f5dedc0c6 100644 --- a/package.json +++ b/package.json @@ -37,12 +37,13 @@ "dependencies": { "@it-tools/bip39": "^0.0.4", "@it-tools/oggen": "^1.3.0", + "@regexper/render": "^1.0.0", "@sindresorhus/slugify": "^2.2.1", "@tiptap/pm": "2.1.6", "@tiptap/starter-kit": "2.1.6", "@tiptap/vue-3": "2.0.3", - "@types/markdown-it": "^13.0.7", "@types/figlet": "^1.5.8", + "@types/markdown-it": "^13.0.7", "@vicons/material": "^0.12.0", "@vicons/tabler": "^0.12.0", "@vueuse/core": "^10.3.0", @@ -84,6 +85,7 @@ "pinia": "^2.0.34", "plausible-tracker": "^0.3.8", "qrcode": "^1.5.1", + "randexp": "^0.5.3", "sql-formatter": "^13.0.0", "ua-parser-js": "^1.0.35", "ulid": "^2.3.0", @@ -93,6 +95,7 @@ "vue": "^3.3.4", "vue-i18n": "^9.9.1", "vue-router": "^4.1.6", + "vue-shadow-dom": "^4.2.0", "vue-tsc": "^1.8.1", "xml-formatter": "^3.3.2", "xml-js": "^1.6.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2311f3aff..e43a3217e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ dependencies: '@it-tools/oggen': specifier: ^1.3.0 version: 1.3.0 + '@regexper/render': + specifier: ^1.0.0 + version: 1.0.0 '@sindresorhus/slugify': specifier: ^2.2.1 version: 2.2.1 @@ -152,6 +155,9 @@ dependencies: qrcode: specifier: ^1.5.1 version: 1.5.1 + randexp: + specifier: ^0.5.3 + version: 0.5.3 sql-formatter: specifier: ^13.0.0 version: 13.0.0 @@ -179,6 +185,9 @@ dependencies: vue-router: specifier: ^4.1.6 version: 4.1.6(vue@3.3.4) + vue-shadow-dom: + specifier: ^4.2.0 + version: 4.2.0 vue-tsc: specifier: ^1.8.1 version: 1.8.1(typescript@5.2.2) @@ -2480,6 +2489,17 @@ packages: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} dev: false + /@regexper/parser@1.0.0: + resolution: {integrity: sha512-S8AWIGpCNdl9PNHdbhI6TpXZsPk6FDU/RTZI+6UFF4rVFqDQKjCIbZSgFu7NihoEZKq57wKFPbbT1EzrjVvPHA==} + dev: false + + /@regexper/render@1.0.0: + resolution: {integrity: sha512-xYm9RUgnhhZotTtf8UZpK1PG2CcTRXQ3JPwfTlYUZsy2J+UcTVc7BaO/MJadpMoVuT8jrIyptH4Y0HLzqhI3hQ==} + dependencies: + '@regexper/parser': 1.0.0 + '@svgdotjs/svg.js': 3.2.4 + dev: false + /@remirror/core-constants@2.0.1: resolution: {integrity: sha512-ZR4aihtnnT9lMbhh5DEbsriJRlukRXmLZe7HmM+6ufJNNUDoazc75UX26xbgQlNUqgAqMcUdGFAnPc1JwgAdLQ==} dependencies: @@ -2629,6 +2649,10 @@ packages: string.prototype.matchall: 4.0.10 dev: true + /@svgdotjs/svg.js@3.2.4: + resolution: {integrity: sha512-BjJ/7vWNowlX3Z8O4ywT58DqbNRyYlkk6Yz/D13aB7hGmfQTvGX4Tkgtm/ApYlu9M7lCQi15xUEidqMUmdMYwg==} + dev: false + /@tiptap/core@2.1.12(@tiptap/pm@2.1.6): resolution: {integrity: sha512-ZGc3xrBJA9KY8kln5AYTj8y+GDrKxi7u95xIl2eccrqTY5CQeRu6HRNM1yT4mAjuSaG9jmazyjGRlQuhyxCKxQ==} peerDependencies: @@ -4962,6 +4986,11 @@ packages: tslib: 2.5.0 dev: false + /drange@1.1.1: + resolution: {integrity: sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==} + engines: {node: '>=4'} + dev: false + /duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} dev: true @@ -7758,6 +7787,14 @@ packages: ret: 0.1.15 dev: false + /randexp@0.5.3: + resolution: {integrity: sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==} + engines: {node: '>=4'} + dependencies: + drange: 1.1.1 + ret: 0.2.2 + dev: false + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: @@ -7928,6 +7965,11 @@ packages: engines: {node: '>=0.12'} dev: false + /ret@0.2.2: + resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} + engines: {node: '>=4'} + dev: false + /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -9268,6 +9310,10 @@ packages: vue: 3.3.4 dev: false + /vue-shadow-dom@4.2.0: + resolution: {integrity: sha512-lguI064rT2HT/dxqSmXtz860KOvCq+W3nU1jMqroTmX3K1H46q22BMR4emh/Ld3ozy35XJKOaNGcr6mkJ/t/yg==} + dev: false + /vue-template-compiler@2.7.14: resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==} dependencies: diff --git a/src/composable/queryParams.ts b/src/composable/queryParams.ts index 9699abbc1..7cc8cc0dd 100644 --- a/src/composable/queryParams.ts +++ b/src/composable/queryParams.ts @@ -1,7 +1,8 @@ import { useRouteQuery } from '@vueuse/router'; import { computed } from 'vue'; +import { useStorage } from '@vueuse/core'; -export { useQueryParam }; +export { useQueryParam, useQueryParamOrStorage }; const transformers = { number: { @@ -16,6 +17,12 @@ const transformers = { fromQuery: (value: string) => value.toLowerCase() === 'true', toQuery: (value: boolean) => (value ? 'true' : 'false'), }, + object: { + fromQuery: (value: string) => { + return JSON.parse(value); + }, + toQuery: (value: object) => JSON.stringify(value), + }, }; function useQueryParam({ name, defaultValue }: { name: string; defaultValue: T }) { @@ -33,3 +40,27 @@ function useQueryParam({ name, defaultValue }: { name: string; defaultValue: }, }); } + +function useQueryParamOrStorage({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue: T }) { + const type = typeof defaultValue; + const transformer = transformers[type as keyof typeof transformers] ?? transformers.string; + + const storageRef = useStorage(storageName, defaultValue); + const proxyDefaultValue = transformer.toQuery(defaultValue as never); + const proxy = useRouteQuery(name, proxyDefaultValue); + + const r = ref(defaultValue); + + watch(r, + (value) => { + proxy.value = transformer.toQuery(value as never); + storageRef.value = value as never; + }, + { deep: true }); + + r.value = (proxy.value && proxy.value !== proxyDefaultValue + ? transformer.fromQuery(proxy.value) as unknown as T + : storageRef.value as T) as never; + + return r; +} diff --git a/src/composable/validation.ts b/src/composable/validation.ts index 472ca4b21..33a6a7b2e 100644 --- a/src/composable/validation.ts +++ b/src/composable/validation.ts @@ -3,9 +3,11 @@ import _ from 'lodash'; import { type Ref, reactive, watch } from 'vue'; type ValidatorReturnType = unknown; +type GetErrorMessageReturnType = string; export interface UseValidationRule { validator: (value: T) => ValidatorReturnType + getErrorMessage?: (value: T) => GetErrorMessageReturnType message: string } @@ -24,6 +26,15 @@ export function isFalsyOrHasThrown(cb: () => ValidatorReturnType): boolean { } } +export function getErrorMessageOrThrown(cb: () => GetErrorMessageReturnType): string { + try { + return cb() || ''; + } + catch (e: any) { + return e.toString(); + } +} + export interface ValidationAttrs { feedback: string validationStatus: string | undefined @@ -61,7 +72,13 @@ export function useValidation({ for (const rule of get(rules)) { if (isFalsyOrHasThrown(() => rule.validator(source.value))) { - state.message = rule.message; + if (rule.getErrorMessage) { + const getErrorMessage = rule.getErrorMessage; + state.message = rule.message.replace('{0}', getErrorMessageOrThrown(() => getErrorMessage(source.value))); + } + else { + state.message = rule.message; + } state.status = 'error'; } } diff --git a/src/main.ts b/src/main.ts index 36ba3b7f8..19d28bf2e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,6 +3,7 @@ import { createPinia } from 'pinia'; import { createHead } from '@vueuse/head'; import { registerSW } from 'virtual:pwa-register'; +import shadow from 'vue-shadow-dom'; import { plausible } from './plugins/plausible.plugin'; import 'virtual:uno.css'; @@ -23,5 +24,6 @@ app.use(i18nPlugin); app.use(router); app.use(naive); app.use(plausible); +app.use(shadow); app.mount('#app'); diff --git a/src/tools/index.ts b/src/tools/index.ts index c9003fe81..388cfaf49 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -9,6 +9,8 @@ import { tool as textToUnicode } from './text-to-unicode'; import { tool as safelinkDecoder } from './safelink-decoder'; import { tool as xmlToJson } from './xml-to-json'; import { tool as jsonToXml } from './json-to-xml'; +import { tool as regexTester } from './regex-tester'; +import { tool as regexMemo } from './regex-memo'; import { tool as markdownToHtml } from './markdown-to-html'; import { tool as pdfSignatureChecker } from './pdf-signature-checker'; import { tool as numeronymGenerator } from './numeronym-generator'; @@ -156,6 +158,8 @@ export const toolsByCategory: ToolCategory[] = [ xmlFormatter, yamlViewer, emailNormalizer, + regexTester, + regexMemo, ], }, { diff --git a/src/tools/regex-memo/index.ts b/src/tools/regex-memo/index.ts new file mode 100644 index 000000000..f1f56489d --- /dev/null +++ b/src/tools/regex-memo/index.ts @@ -0,0 +1,12 @@ +import { BrandJavascript } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Regex cheatsheet', + path: '/regex-memo', + description: 'Javascript Regex/Regular Expression cheatsheet', + keywords: ['regex', 'regular', 'expression', 'javascript', 'memo', 'cheatsheet'], + component: () => import('./regex-memo.vue'), + icon: BrandJavascript, + createdAt: new Date('2024-09-20'), +}); diff --git a/src/tools/regex-memo/regex-memo.content.md b/src/tools/regex-memo/regex-memo.content.md new file mode 100644 index 000000000..0f779401b --- /dev/null +++ b/src/tools/regex-memo/regex-memo.content.md @@ -0,0 +1,121 @@ +### Normal characters + +Expression | Description +:--|:-- +`.` or `[^\n\r]` | any character *excluding* a newline or carriage return +`[A-Za-z]` | alphabet +`[a-z]` | lowercase alphabet +`[A-Z]` | uppercase alphabet +`\d` or `[0-9]` | digit +`\D` or `[^0-9]` | non-digit +`_` | underscore +`\w` or `[A-Za-z0-9_]` | alphabet, digit or underscore +`\W` or `[^A-Za-z0-9_]` | inverse of `\w` +`\S` | inverse of `\s` + +### Whitespace characters + +Expression | Description +:--|:-- +` ` | space +`\t` | tab +`\n` | newline +`\r` | carriage return +`\s` | space, tab, newline or carriage return + +### Character set + +Expression | Description +:--|:-- +`[xyz]` | either `x`, `y` or `z` +`[^xyz]` | neither `x`, `y` nor `z` +`[1-3]` | either `1`, `2` or `3` +`[^1-3]` | neither `1`, `2` nor `3` + +- Think of a character set as an `OR` operation on the single characters that are enclosed between the square brackets. +- Use `^` after the opening `[` to “negate” the character set. +- Within a character set, `.` means a literal period. + +### Characters that require escaping + +#### Outside a character set + +Expression | Description +:--|:-- +`\.` | period +`\^` | caret +`\$` | dollar sign +`\|` | pipe +`\\` | back slash +`\/` | forward slash +`\(` | opening bracket +`\)` | closing bracket +`\[` | opening square bracket +`\]` | closing square bracket +`\{` | opening curly bracket +`\}` | closing curly bracket + +#### Inside a character set + +Expression | Description +:--|:-- +`\\` | back slash +`\]` | closing square bracket + +- A `^` must be escaped only if it occurs immediately after the opening `[` of the character set. +- A `-` must be escaped only if it occurs between two alphabets or two digits. + +### Quantifiers + +Expression | Description +:--|:-- +`{2}` | exactly 2 +`{2,}` | at least 2 +`{2,7}` | at least 2 but no more than 7 +`*` | 0 or more +`+` | 1 or more +`?` | exactly 0 or 1 + +- The quantifier goes *after* the expression to be quantified. + +### Boundaries + +Expression | Description +:--|:-- +`^` | start of string +`$` | end of string +`\b` | word boundary + +- How word boundary matching works: + - At the beginning of the string if the first character is `\w`. + - Between two adjacent characters within the string, if the first character is `\w` and the second character is `\W`. + - At the end of the string if the last character is `\w`. + +### Matching + +Expression | Description +:--|:-- +`foo\|bar` | match either `foo` or `bar` +`foo(?=bar)` | match `foo` if it’s before `bar` +`foo(?!bar)` | match `foo` if it’s *not* before `bar` +`(?<=bar)foo` | match `foo` if it’s after `bar` +`(? +import { useThemeVars } from 'naive-ui'; +import Memo from './regex-memo.content.md'; + +const themeVars = useThemeVars(); + + + + + diff --git a/src/tools/regex-tester/index.ts b/src/tools/regex-tester/index.ts new file mode 100644 index 000000000..9cc542f0e --- /dev/null +++ b/src/tools/regex-tester/index.ts @@ -0,0 +1,12 @@ +import { Language } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Regex Tester', + path: '/regex-tester', + description: 'Regex Tester', + keywords: ['regex', 'tester', 'sample', 'expression'], + component: () => import('./regex-tester.vue'), + icon: Language, + createdAt: new Date('2024-09-20'), +}); diff --git a/src/tools/regex-tester/regex-tester.service.test.ts b/src/tools/regex-tester/regex-tester.service.test.ts new file mode 100644 index 000000000..bd4efbbc8 --- /dev/null +++ b/src/tools/regex-tester/regex-tester.service.test.ts @@ -0,0 +1,106 @@ +import { describe, expect, it } from 'vitest'; +import { matchRegex } from './regex-tester.service'; + +const regexesData = [ + { + regex: '', + text: '', + flags: '', + result: [], + }, + { + regex: '.*', + text: '', + flags: '', + result: [], + }, + { + regex: '', + text: 'aaa', + flags: '', + result: [], + }, + { + regex: 'a', + text: 'baaa', + flags: '', + result: [ + { + captures: [], + groups: [], + index: 1, + value: 'a', + }, + ], + }, + { + regex: '(.)(?r)', + text: 'azertyr', + flags: 'g', + result: [ + { + captures: [ + { + end: 3, + name: '1', + start: 2, + value: 'e', + }, + { + end: 4, + name: '2', + start: 3, + value: 'r', + }, + ], + groups: [ + { + end: 4, + name: 'g', + start: 3, + value: 'r', + }, + ], + index: 2, + value: 'er', + }, + { + captures: [ + { + end: 6, + name: '1', + start: 5, + value: 'y', + }, + { + end: 7, + name: '2', + start: 6, + value: 'r', + }, + ], + groups: [ + { + end: 7, + name: 'g', + start: 6, + value: 'r', + }, + ], + index: 5, + value: 'yr', + }, + ], + }, +]; + +describe('regex-tester', () => { + for (const reg of regexesData) { + const { regex, text, flags, result: expected_result } = reg; + it(`Should matchRegex("${regex}","${text}","${flags}") return correct result`, async () => { + const result = matchRegex(regex, text, `${flags}d`); + + expect(result).to.deep.equal(expected_result); + }); + } +}); diff --git a/src/tools/regex-tester/regex-tester.service.ts b/src/tools/regex-tester/regex-tester.service.ts new file mode 100644 index 000000000..ec8682c5c --- /dev/null +++ b/src/tools/regex-tester/regex-tester.service.ts @@ -0,0 +1,61 @@ +interface RegExpGroupIndices { + [name: string]: [number, number] +} +interface RegExpIndices extends Array<[number, number]> { + groups: RegExpGroupIndices +} +interface RegExpExecArrayWithIndices extends RegExpExecArray { + indices: RegExpIndices +} +interface GroupCapture { + name: string + value: string + start: number + end: number +}; + +export function matchRegex(regex: string, text: string, flags: string) { + // if (regex === '' || text === '') { + // return []; + // } + + let lastIndex = -1; + const re = new RegExp(regex, flags); + const results = []; + let match = re.exec(text) as RegExpExecArrayWithIndices; + while (match !== null) { + if (re.lastIndex === lastIndex || match[0] === '') { + break; + } + const indices = match.indices; + const captures: Array = []; + Object.entries(match).forEach(([captureName, captureValue]) => { + if (captureName !== '0' && captureName.match(/\d+/)) { + captures.push({ + name: captureName, + value: captureValue, + start: indices[Number(captureName)][0], + end: indices[Number(captureName)][1], + }); + } + }); + const groups: Array = []; + Object.entries(match.groups || {}).forEach(([groupName, groupValue]) => { + groups.push({ + name: groupName, + value: groupValue, + start: indices.groups[groupName][0], + end: indices.groups[groupName][1], + }); + }); + results.push({ + index: match.index, + value: match[0], + captures, + groups, + }); + lastIndex = re.lastIndex; + match = re.exec(text) as RegExpExecArrayWithIndices; + } + return results; +} diff --git a/src/tools/regex-tester/regex-tester.vue b/src/tools/regex-tester/regex-tester.vue new file mode 100644 index 000000000..a1fa79584 --- /dev/null +++ b/src/tools/regex-tester/regex-tester.vue @@ -0,0 +1,193 @@ + + +