diff --git a/components.d.ts b/components.d.ts index f2c3146f..8bf87e90 100644 --- a/components.d.ts +++ b/components.d.ts @@ -120,6 +120,7 @@ declare module '@vue/runtime-core' { 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'] MathEvaluator: typeof import('./src/tools/math-evaluator/math-evaluator.vue')['default'] + MathFormatsConverter: typeof import('./src/tools/math-formats-converter/math-formats-converter.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'] MenuIconItem: typeof import('./src/components/MenuIconItem.vue')['default'] diff --git a/package.json b/package.json index 9f39ff1d..5a119188 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "dependencies": { "@it-tools/bip39": "^0.0.4", "@it-tools/oggen": "^1.3.0", + "@plurimath/plurimath": "^0.2.0", "@sindresorhus/slugify": "^2.2.1", "@tiptap/pm": "2.1.6", "@tiptap/starter-kit": "2.1.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd6c38c9..158e4c9d 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 + '@plurimath/plurimath': + specifier: ^0.2.0 + version: 0.2.0 '@sindresorhus/slugify': specifier: ^2.2.1 version: 2.2.1 @@ -2457,6 +2460,10 @@ packages: fsevents: 2.3.2 dev: true + /@plurimath/plurimath@0.2.0: + resolution: {integrity: sha512-5ca7O58sq/PHA7zZHDjDrg8pr1u9FPRNWOy8nqADKrExw9LHAwHX2FuvU3sz51liNZpwZ1KC5Nwy5U48S6Y5Xw==} + dev: false + /@polka/url@1.0.0-next.21: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} dev: true @@ -3351,7 +3358,7 @@ packages: dependencies: '@unhead/dom': 0.5.1 '@unhead/schema': 0.5.1 - '@vueuse/shared': 10.7.2(vue@3.3.4) + '@vueuse/shared': 10.9.0(vue@3.3.4) unhead: 0.5.1 vue: 3.3.4 transitivePeerDependencies: @@ -3993,10 +4000,10 @@ packages: - vue dev: false - /@vueuse/shared@10.7.2(vue@3.3.4): - resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==} + /@vueuse/shared@10.9.0(vue@3.3.4): + resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==} dependencies: - vue-demi: 0.14.6(vue@3.3.4) + vue-demi: 0.14.7(vue@3.3.4) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -9151,8 +9158,8 @@ packages: vue: 3.3.4 dev: false - /vue-demi@0.14.6(vue@3.3.4): - resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} + /vue-demi@0.14.7(vue@3.3.4): + resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} engines: {node: '>=12'} hasBin: true requiresBuild: true @@ -9442,6 +9449,7 @@ packages: /workbox-google-analytics@7.0.0: resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==} + deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained dependencies: workbox-background-sync: 7.0.0 workbox-core: 7.0.0 diff --git a/src/composable/queryParams.ts b/src/composable/queryParams.ts index 9699abbc..9e184610 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: { @@ -33,3 +34,31 @@ 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 storageDefaultValue = storageRef.value ?? defaultValue; + + const proxy = useRouteQuery(name, transformer.toQuery(storageDefaultValue as never)); + + const ref = computed({ + get() { + return transformer.fromQuery(proxy.value) as unknown as T; + }, + set(value) { + proxy.value = transformer.toQuery(value as never); + }, + }); + + watch( + ref, + (newValue) => { + storageRef.value = newValue; + }, + ); + + return ref; +} diff --git a/src/tools/index.ts b/src/tools/index.ts index aa861c93..7e6971af 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,6 +1,7 @@ import { tool as base64FileConverter } from './base64-file-converter'; import { tool as base64StringConverter } from './base64-string-converter'; import { tool as basicAuthGenerator } from './basic-auth-generator'; +import { tool as mathFormatsConverter } from './math-formats-converter'; import { tool as asciiTextDrawer } from './ascii-text-drawer'; @@ -156,7 +157,12 @@ export const toolsByCategory: ToolCategory[] = [ }, { name: 'Math', - components: [mathEvaluator, etaCalculator, percentageCalculator], + components: [ + mathEvaluator, + etaCalculator, + percentageCalculator, + mathFormatsConverter, + ], }, { name: 'Measurement', diff --git a/src/tools/math-formats-converter/index.ts b/src/tools/math-formats-converter/index.ts new file mode 100644 index 00000000..839e1b2a --- /dev/null +++ b/src/tools/math-formats-converter/index.ts @@ -0,0 +1,12 @@ +import { EqualNot } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Math Formats Converter', + path: '/math-formats-converter', + description: 'Convert mathematical expression between formats', + keywords: ['math', 'formats', 'converter', 'latex', 'mathml', 'asciimath', 'omml', 'html'], + component: () => import('./math-formats-converter.vue'), + icon: EqualNot, + createdAt: new Date('2024-05-11'), +}); diff --git a/src/tools/math-formats-converter/math-formats-converter.vue b/src/tools/math-formats-converter/math-formats-converter.vue new file mode 100644 index 00000000..489699a7 --- /dev/null +++ b/src/tools/math-formats-converter/math-formats-converter.vue @@ -0,0 +1,85 @@ + + +