diff --git a/.github/workflows/publish-latest.yaml b/.github/workflows/publish-latest.yaml index 4fa583e..61a21b6 100644 --- a/.github/workflows/publish-latest.yaml +++ b/.github/workflows/publish-latest.yaml @@ -19,6 +19,8 @@ jobs: PACKAGE_NAME="eastern-arabic" elif [[ $TAG_NAME =~ ^mayan\/v.* ]]; then PACKAGE_NAME="mayan" + elif [[ $TAG_NAME =~ ^hieroglyphic\/v.* ]]; then + PACKAGE_NAME="hieroglyphic" else echo "❌ tag name: $TAG_NAME doesn't point to any publishable package" exit 1 diff --git a/.github/workflows/publish-next.yaml b/.github/workflows/publish-next.yaml index ee8ba51..074a692 100644 --- a/.github/workflows/publish-next.yaml +++ b/.github/workflows/publish-next.yaml @@ -19,6 +19,8 @@ jobs: PACKAGE_NAME="eastern-arabic" elif [[ $TAG_NAME =~ ^mayan\/v.* ]]; then PACKAGE_NAME="mayan" + elif [[ $TAG_NAME =~ ^hieroglyphic\/v.* ]]; then + PACKAGE_NAME="hieroglyphic" else echo "❌ tag name: $TAG_NAME doesn't point to any publishable package" exit 1 diff --git a/README.md b/README.md index 4137440..148b1f5 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,15 @@ This is a monorepo for the Numerals project. ## Packages -### eastern-arabic +### eastern-arabic ٠١٢٣٤٥٦٧٨٩ [README](https://github.com/amerharb/numerals/blob/main/packages/eastern-arabic/README.md) -### mayan +### mayan 𝋠 [README](https://github.com/amerharb/numerals/blob/main/packages/mayan/README.md) +### hieroglyphic 𓀀 +[README](https://github.com/amerharb/numerals/blob/main/packages/hieroglyphic/README.md) + ### numerals-client Example of a client for npm package diff --git a/package.json b/package.json index 4a90d5b..60c5731 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,11 @@ "workspaces": [ "packages/eastern-arabic", "packages/mayan", + "packages/hieroglyphic", "packages/numerals-client", "packages/numerals-web" ], - "version": "0.2.0", + "version": "0.3.0", "author": "Amer Harb", "license": "ISC", "scripts": { diff --git a/packages/hieroglyphic/CHANGELOG.md b/packages/hieroglyphic/CHANGELOG.md new file mode 100644 index 0000000..2122ed1 --- /dev/null +++ b/packages/hieroglyphic/CHANGELOG.md @@ -0,0 +1,6 @@ +# hieroglyphic Changelog + + +## [0.0.1] 2024-04-30 +### Added +- Initial project covert number into hieroglyphic numerals diff --git a/packages/hieroglyphic/LICENSE b/packages/hieroglyphic/LICENSE new file mode 100644 index 0000000..121a826 --- /dev/null +++ b/packages/hieroglyphic/LICENSE @@ -0,0 +1,12 @@ +ISC License + +Copyright 2024 Amer Harb numerals@amerharb.com + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, +provided that the above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/hieroglyphic/README.md b/packages/hieroglyphic/README.md new file mode 100644 index 0000000..f85abbe --- /dev/null +++ b/packages/hieroglyphic/README.md @@ -0,0 +1,30 @@ +# @numerals/hieroglyphic + +[![Version](https://img.shields.io/badge/version-0.0.1-blue.svg)](https://github.com/amerharb/numerals/tree/hieroglyphic/version/0.0.1) +[![License: GPLv3](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC) +![Coverage](https://raw.githubusercontent.com/amerharb/numerals/hieroglyphic/version/0.0.1/packages/hieroglyphic/badges/coverage.svg) +![Github workflow](https://github.com/amerharb/numerals/actions/workflows/lint-test.yaml/badge.svg?branch=hieroglyphic/version/0.0.1) + +**@numerals/hieroglyphic** is a package for converting number into hieroglyphic numeral. + +`2 -> 𓀀𓀀` + +## How to use +npm: +```shell +npm i @numerals/hieroglyphic +``` + +yarn: +```shell +yarn add @numerals/hieroglyphic +``` + +Type Script: +```ts +import { convert } from '@numerals/hieroglyphic'; +console.log(convert(1)); // 𓀀 +console.log(convert(2)); // 𓀀𓀀 +console.log(convert(10)); // 𓀊 +console.log(convert(1000)); // 𓀪 +``` diff --git a/packages/hieroglyphic/badges/coverage.svg b/packages/hieroglyphic/badges/coverage.svg new file mode 100644 index 0000000..a020c92 --- /dev/null +++ b/packages/hieroglyphic/badges/coverage.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/hieroglyphic/jest.config.js b/packages/hieroglyphic/jest.config.js new file mode 100644 index 0000000..777c3ce --- /dev/null +++ b/packages/hieroglyphic/jest.config.js @@ -0,0 +1,14 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + collectCoverage: true, + coverageDirectory: 'coverage', + coverageProvider: 'v8', + testMatch: [ + '**/?(*.)+(test.ts)', + ], + coverageReporters: [ + 'json-summary', + ], +}; diff --git a/packages/hieroglyphic/package.json b/packages/hieroglyphic/package.json new file mode 100644 index 0000000..d2d12ad --- /dev/null +++ b/packages/hieroglyphic/package.json @@ -0,0 +1,38 @@ +{ + "name": "@numerals/hieroglyphic", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts", + "files": [ + "dist/src/**/*.d.ts", + "dist/src/**/*.js", + "LICENSE", + "CHANGELOG.md", + "README.md" + ], + "author": "Amer Harb", + "repository": { + "type": "git", + "url": "git+https://github.com/amerharb/numerals.git" + }, + "homepage": "https://github.com/amerharb/numerals#readme", + "url": "https://github.com/amerharb/numerals/issues", + "email": "numerals@amerharb.com", + "keywords": [ + "hieroglyphic-numberals", + "hieroglyphic-numbers" + ], + "license": "ISC", + "scripts": { + "build": "rm -rf dist && tsc", + "start": "node dist/src/index.js", + "test": "jest", + "make-coverage-badge": "npx make-coverage-badge --report-path coverage/coverage-summary.json --output-path badges/coverage.svg", + "dev": "ts-node src/index.ts", + "lint": "npx eslint . --max-warnings 0", + "lint:fix": "npx eslint . --fix" + }, + "bugs": { + "url": "https://github.com/amerharb/numerals/issues" + } +} diff --git a/packages/hieroglyphic/src/index.ts b/packages/hieroglyphic/src/index.ts new file mode 100644 index 0000000..40ccf8a --- /dev/null +++ b/packages/hieroglyphic/src/index.ts @@ -0,0 +1,34 @@ +import { Hi } from './numerals' + +export function convert(source: number): string { + if (!Number.isFinite(source)) { + throw new Error('Source is not a finite number') + } + if (source < 0) { + throw new Error('Source is negative, only positive numbers are supported') + } + if (source == 0) { + throw new Error('Source is zero, only positive numbers are supported') + } + if (source % 1 !== 0) { + throw new Error('Source is not an integer, only integers are supported') + } + if (source > 10_000_000) { + throw new Error('Source is too big, only numbers up to 10 000 000 are supported') + } + + let result = '' + let reminder = source + const arr = [1000_000, 100_000, 10_000, 1000, 100, 10, 1] as const + while (reminder > 0) { + for (const n of arr) { + if (reminder - n >= 0) { + result += Hi[n] + reminder -= n + break + } + } + } + + return result +} diff --git a/packages/hieroglyphic/src/numerals.ts b/packages/hieroglyphic/src/numerals.ts new file mode 100644 index 0000000..6d806ef --- /dev/null +++ b/packages/hieroglyphic/src/numerals.ts @@ -0,0 +1,19 @@ +const numbers = [ + String.fromCodePoint(0x13000), /** #0 𓀀 U+13000 hieroglyphic numeral 1 */ + String.fromCodePoint(0x1300A), /** #1 𓀊 U+1300A hieroglyphic numeral 10 */ + String.fromCodePoint(0x1301A), /** #2 𓀚 U+1301A hieroglyphic numeral 100 */ + String.fromCodePoint(0x1302A), /** #3 𓀪 U+1302A hieroglyphic numeral 1000 */ + String.fromCodePoint(0x1303A), /** #4 𓀰 U+1303A hieroglyphic numeral 10_000 */ + String.fromCodePoint(0x1304A), /** #5 𓁀 U+1304A hieroglyphic numeral 100_000 */ + String.fromCodePoint(0x1305A), /** #6 𓁐 U+1305A hieroglyphic numeral 1000_000 */ +] as const + +export const Hi = { + 1: numbers[0], + 10: numbers[1], + 100: numbers[2], + 1000: numbers[3], + 10_000: numbers[4], + 100_000: numbers[5], + 1000_000: numbers[6], +} diff --git a/packages/hieroglyphic/test/index.test.ts b/packages/hieroglyphic/test/index.test.ts new file mode 100644 index 0000000..f1a813f --- /dev/null +++ b/packages/hieroglyphic/test/index.test.ts @@ -0,0 +1,51 @@ +import { convert } from '../src' +import { Hi } from '../src/numerals' +import { describe, expect, it } from '@jest/globals' + +describe('convert()', () => { + it('convert 1 into 𓀀', () => { + const actual = convert(1) + expect(actual).toEqual(Hi[1]) + }) + it('convert 2 into 𓀀𓀀', () => { + const actual = convert(2) + expect(actual).toEqual(Hi[1] + Hi[1]) + }) + it('convert 10 into 𓀊', () => { + const actual = convert(10) + expect(actual).toEqual(Hi[10]) + }) + it('convert 11 into 𓀊𓀀', () => { + const actual = convert(11) + expect(actual).toEqual(Hi[10] + Hi[1]) + }) + it('convert 100 into 𓀚', () => { + const actual = convert(100) + expect(actual).toEqual(Hi[100]) + }) + it('convert 101 into 𓀚𓀀', () => { + const actual = convert(101) + expect(actual).toEqual(Hi[100] + Hi[1]) + }) + it('convert 1000 into 𓀪', () => { + const actual = convert(1000) + expect(actual).toEqual(Hi[1000]) + }) + it.each([NaN, Infinity, -Infinity]) + ('throw Error for non number [%s]', (it) => { + const actual = () => convert(it) + expect(actual).toThrowError('Source is not a finite number') + }) + it('throw Error for zero', () => { + const actual = () => convert(0) + expect(actual).toThrowError('Source is zero, only positive numbers are supported') + }) + it('throw Error for negative number', () => { + const actual = () => convert(-1) + expect(actual).toThrowError('Source is negative, only positive numbers are supported') + }) + it('throw Error for float number', () => { + const actual = () => convert(1.1) + expect(actual).toThrowError('Source is not an integer, only integers are supported') + }) +}) diff --git a/packages/hieroglyphic/tsconfig.json b/packages/hieroglyphic/tsconfig.json new file mode 100644 index 0000000..9f0325b --- /dev/null +++ b/packages/hieroglyphic/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + } +} diff --git a/packages/mayan/src/U0600.pdf b/packages/mayan/src/U0600.pdf deleted file mode 100644 index f1885f2..0000000 Binary files a/packages/mayan/src/U0600.pdf and /dev/null differ diff --git a/packages/numerals-client/package.json b/packages/numerals-client/package.json index e9d9ae7..06a0022 100644 --- a/packages/numerals-client/package.json +++ b/packages/numerals-client/package.json @@ -13,6 +13,6 @@ }, "dependencies": { "@numerals/eastern-arabic": "0.0.2", - "@numerals/mayan": "0.0.1-next.2" + "@numerals/mayan": "0.0.1" } } diff --git a/packages/numerals-web/package.json b/packages/numerals-web/package.json index 7819f6a..8a177cd 100644 --- a/packages/numerals-web/package.json +++ b/packages/numerals-web/package.json @@ -15,7 +15,8 @@ "@emotion/styled": "^11.11.0", "@mui/joy": "^5.0.0-beta.11", "@numerals/eastern-arabic": "0.0.2", - "@numerals/mayan": "0.0.1-next.2", + "@numerals/hieroglyphic": "0.0.1-next.3", + "@numerals/mayan": "0.0.1", "@vercel/analytics": "^1.1.2", "@vercel/speed-insights": "^1.0.9", "next": "^14.1.0", diff --git a/packages/numerals-web/src/app/page.tsx b/packages/numerals-web/src/app/page.tsx index 3bb5e65..ee3eb7a 100644 --- a/packages/numerals-web/src/app/page.tsx +++ b/packages/numerals-web/src/app/page.tsx @@ -4,11 +4,13 @@ import { useState } from 'react' import Select from 'react-select' import { convert as convertAr } from '@numerals/eastern-arabic' import { convert as convertMa } from '@numerals/mayan' +import { convert as convertHi } from '@numerals/hieroglyphic' import Image from 'next/image' enum Numerals { - EasternArabic = 'easternArabic', - Mayan = 'mayan', + EasternArabic = 'easternArabic', + Mayan = 'mayan', + Hieroglyphic = 'hieroglyphic', } export default function Home() { @@ -19,10 +21,11 @@ export default function Home() { const options = [ { value: Numerals.EasternArabic, label: 'Eastern Arabic ٤ ٣ ٢ ١' }, { value: Numerals.Mayan, label: 'Mayan 𝋠 𝋡 𝋢 𝋣' }, + { value: Numerals.Hieroglyphic, label: 'Hieroglyphic 𓀀 𓀀𓀀 𓀀𓀀𓀀' }, ] const ToSelect = () =>