diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 00000000..e5b6d8d6 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 00000000..d2c51ae1 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [ + "landing" + ] +} \ No newline at end of file diff --git a/.changeset/lucky-rules-fetch.md b/.changeset/lucky-rules-fetch.md new file mode 100644 index 00000000..7543915b --- /dev/null +++ b/.changeset/lucky-rules-fetch.md @@ -0,0 +1,5 @@ +--- +"braillify": major +--- + +Deploy diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..fa54435a --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: owjs3901 +patreon: JeongMinOh +open_collective: braillify +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] \ No newline at end of file diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml new file mode 100644 index 00000000..705699b9 --- /dev/null +++ b/.github/workflows/publish-pypi.yml @@ -0,0 +1,60 @@ +name: Publish Package to pypi + +on: + release: + types: [published] +permissions: write-all + +jobs: + publish-pypi: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: 3.13 + - name: Install uv + uses: astral-sh/setup-uv@v5 + - name: Install maturin + run: uv pip install maturin --system + - uses: actions-rust-lang/setup-rust-toolchain@v1 + - name: Cargo tarpaulin + run: cargo install cargo-tarpaulin + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + run_install: false + + - uses: jetli/wasm-pack-action@v0.4.0 + with: + version: 'latest' + - name: Install Node.js + uses: actions/setup-node@v4 + with: + registry-url: "https://registry.npmjs.org" + node-version: 22 + cache: 'pnpm' + - run: pnpm i + - name: Setup + run: | + pnpm build + pnpm lint + pnpm test + + - name: Publish to pypi + run: | + cd packages/python + uv publish + env: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + + - name: Publish to cargo + run: | + cd libs/braillify + cargo publish + diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..f9de914c --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,75 @@ +name: Publish Package to npm + +on: + push: + branches: + - main + pull_request: + branches: + - main +permissions: write-all + +jobs: + publish: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: 3.13 + - name: Install uv + uses: astral-sh/setup-uv@v5 + - name: Install maturin + run: uv pip install maturin --system + - uses: actions-rust-lang/setup-rust-toolchain@v1 + - name: Cargo tarpaulin + run: cargo install cargo-tarpaulin + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + run_install: false + + - uses: jetli/wasm-pack-action@v0.4.0 + with: + version: 'latest' + - name: Install Node.js + uses: actions/setup-node@v4 + with: + registry-url: "https://registry.npmjs.org" + node-version: 22 + cache: 'pnpm' + - run: pnpm i + - run: | + pnpm build + pnpm lint + pnpm test + - name: Build Landing + run: pnpm -F landing build + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./apps/landing/out + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + - uses: actions/deploy-pages@v4 + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + - name: Upload to codecov.io + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + - name: Create Release Pull Request or Publish to npm + id: changesets + uses: changesets/action@v1 + with: + publish: pnpm changeset publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + if: github.ref == 'refs/heads/main' + diff --git a/.gitignore b/.gitignore index 3e4aa7a1..c9808acd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ target/ .vscode/ .idea/ +node_modules +.df +test_status.json +.venv +__pycache__ +.pytest_cache +coverage +cobertura.xml \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 18175b72..ca22f03f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,50 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + [[package]] name = "braillify" -version = "0.1.0" +version = "1.0.0" dependencies = [ "csv", "phf", + "serde_json", +] + +[[package]] +name = "bumpalo" +version = "3.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" + +[[package]] +name = "cc" +version = "1.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", ] [[package]] @@ -31,18 +69,87 @@ dependencies = [ "memchr", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indoc" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" + [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minicov" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b" +dependencies = [ + "cc", + "walkdir", +] + +[[package]] +name = "node" +version = "0.1.0" +dependencies = [ + "braillify", + "console_error_panic_hook", + "wasm-bindgen", + "wasm-bindgen-test", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + [[package]] name = "phf" version = "0.11.3" @@ -85,6 +192,12 @@ dependencies = [ "siphasher", ] +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + [[package]] name = "proc-macro2" version = "1.0.95" @@ -94,6 +207,77 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pyo3" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872" +dependencies = [ + "cfg-if", + "indoc", + "libc", + "memoffset", + "once_cell", + "portable-atomic", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "unindent", +] + +[[package]] +name = "pyo3-build-config" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb" +dependencies = [ + "once_cell", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-macros" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028" +dependencies = [ + "heck", + "proc-macro2", + "pyo3-build-config", + "quote", + "syn", +] + +[[package]] +name = "python" +version = "1.0.0" +dependencies = [ + "braillify", + "pyo3", +] + [[package]] name = "quote" version = "1.0.40" @@ -118,12 +302,27 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + [[package]] name = "ryu" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "serde" version = "1.0.219" @@ -144,6 +343,24 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "siphasher" version = "1.0.1" @@ -161,8 +378,217 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unindent" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66c8d5e33ca3b6d9fa3b4676d774c5778031d27a578c2b007f905acf816152c3" +dependencies = [ + "js-sys", + "minicov", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index f7defc3b..c792cf1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["libs/*"] +members = ["libs/*", "packages/*"] [workspace.package] version = "0.1.0" diff --git a/__tests__/index.test.ts b/__tests__/index.test.ts new file mode 100644 index 00000000..99015b4d --- /dev/null +++ b/__tests__/index.test.ts @@ -0,0 +1,8 @@ +import { translateToUnicode } from '../packages/node/pkg' + +describe('index', () => { + it('should translate to unicode', () => { + const result = translateToUnicode('안녕하세요.') + expect(result).toBe('⠣⠒⠉⠻⠚⠠⠝⠬⠲') + }) +}) diff --git a/apps/landing/.gitignore b/apps/landing/.gitignore new file mode 100644 index 00000000..ebe99d6c --- /dev/null +++ b/apps/landing/.gitignore @@ -0,0 +1,42 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +.df +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/apps/landing/README.md b/apps/landing/README.md new file mode 100644 index 00000000..e215bc4c --- /dev/null +++ b/apps/landing/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/apps/landing/devup.json b/apps/landing/devup.json new file mode 100644 index 00000000..4e6e7f27 --- /dev/null +++ b/apps/landing/devup.json @@ -0,0 +1,385 @@ +{ + "theme": { + "colors": { + "light": { + "primary": "#2B2B2B", + "secondary": "#EAD5FF", + "link": "#006BFF", + "text": "#2B2B2B", + "background": "#EFEEEB", + "containerBackground": "#FFFFFF", + "border": "#E0E0E0", + "success": "#16887F", + "warning": "#FF9800", + "error": "#EA1C5D", + "info": "#2196F3", + "base": "#FFFFFF", + "negativeBase": "#000000", + "title": "#1A1A1A", + "caption": "#787878", + "menuHover": "#D8D8D8", + "menuActive": "#CCCCCC" + }, + "dark": { + "primary": "#EBEBEB", + "secondary": "#EAD5FF", + "link": "#006BFF", + "text": "#EBEBEB", + "background": "#000000", + "containerBackground": "#202020", + "border": "#333333", + "success": "#3F8580", + "warning": "#FF9800", + "error": "#EA1C5D", + "info": "#2196F3", + "base": "#000000", + "negativeBase": "#FFFFFF", + "title": "#FAFAFA", + "caption": "#787878", + "menuHover": "#191919", + "menuActive": "#292929" + } + }, + "typography": { + "mainText": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "22px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "32px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + } + ], + "buttonLg": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "17px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "24px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + } + ], + "braillie": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "16px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "20px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + } + ], + "title": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "24px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "36px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + } + ], + "bodyLg": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "15px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "18px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + } + ], + "featureCount": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "14px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "18px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + } + ], + "featureTitle": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "18px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "24px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + } + ], + "body": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "14px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "16px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + } + ], + "button": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "15px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "20px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + } + ], + "footer": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 400, + "fontSize": "12px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 400, + "fontSize": "14px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + } + ], + "gnbMenu": { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "18px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + }, + "docsMenu": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "14px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "15px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + } + ], + "docsTitle": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "24px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "32px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + } + ], + "gnbMenuBold": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "15px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "18px", + "lineHeight": "normal", + "letterSpacing": "-0.06em" + } + ], + "docsCaption": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "13px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "14px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + } + ], + "docsMenuBold": [ + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "14px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + }, + null, + null, + null, + { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "15px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + } + ], + "docsCaptionBold": { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 700, + "fontSize": "14px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + }, + "docsSmall": { + "fontFamily": "Spoqa Han Sans Neo", + "fontStyle": "normal", + "fontWeight": 500, + "fontSize": "12px", + "lineHeight": 1.8, + "letterSpacing": "-0.06em" + } + } + } +} \ No newline at end of file diff --git a/apps/landing/eslint.config.mjs b/apps/landing/eslint.config.mjs new file mode 100644 index 00000000..97ff2ace --- /dev/null +++ b/apps/landing/eslint.config.mjs @@ -0,0 +1,3 @@ +import { configs } from 'eslint-plugin-devup' + +export default configs.recommended \ No newline at end of file diff --git a/apps/landing/next.config.ts b/apps/landing/next.config.ts new file mode 100644 index 00000000..eaa8c618 --- /dev/null +++ b/apps/landing/next.config.ts @@ -0,0 +1,28 @@ +import { DevupUI } from '@devup-ui/next-plugin' +import createMDX from '@next/mdx' + +const withMDX = createMDX({}) + +export default withMDX( + DevupUI( + { + webpack(config, { isServer, dev }) { + // Use the client static directory in the server bundle and prod mode + // Fixes `Error occurred prerendering page "/"` + config.output.webassemblyModuleFilename = + isServer && !dev + ? '../static/wasm/[modulehash].wasm' + : 'static/wasm/[modulehash].wasm' + + // Since Webpack 5 doesn't enable WebAssembly by default, we should do it manually + config.experiments = { ...config.experiments, asyncWebAssembly: true } + + return config + }, + + pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'], + output: 'export', + }, + {}, + ), +) diff --git a/apps/landing/package.json b/apps/landing/package.json new file mode 100644 index 00000000..74454ba5 --- /dev/null +++ b/apps/landing/package.json @@ -0,0 +1,31 @@ +{ + "name": "landing", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@devup-ui/react": "^1.0.2", + "@mdx-js/loader": "^3.1.0", + "@mdx-js/react": "^3.1.0", + "@next/mdx": "^15.3.3", + "@types/mdx": "^2.0.13", + "braillify": "workspace:*", + "next": "15.3.3", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "react-syntax-highlighter": "15.6.1" + }, + "devDependencies": { + "@devup-ui/next-plugin": "^1.0.2", + "@types/node": "^24", + "@types/react": "^19", + "@types/react-dom": "^19", + "typescript": "^5", + "@types/react-syntax-highlighter": "^15.5.13" + } +} \ No newline at end of file diff --git "a/apps/landing/public/2024 \352\260\234\354\240\225 \355\225\234\352\265\255 \354\240\220\354\236\220 \352\267\234\354\240\225.pdf" "b/apps/landing/public/2024 \352\260\234\354\240\225 \355\225\234\352\265\255 \354\240\220\354\236\220 \352\267\234\354\240\225.pdf" new file mode 100644 index 00000000..2c507116 Binary files /dev/null and "b/apps/landing/public/2024 \352\260\234\354\240\225 \355\225\234\352\265\255 \354\240\220\354\236\220 \352\267\234\354\240\225.pdf" differ diff --git a/apps/landing/public/favicon.svg b/apps/landing/public/favicon.svg new file mode 100644 index 00000000..955f911d --- /dev/null +++ b/apps/landing/public/favicon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/landing/public/file.svg b/apps/landing/public/file.svg new file mode 100644 index 00000000..004145cd --- /dev/null +++ b/apps/landing/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/landing/public/globe.svg b/apps/landing/public/globe.svg new file mode 100644 index 00000000..567f17b0 --- /dev/null +++ b/apps/landing/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/landing/public/images/close.svg b/apps/landing/public/images/close.svg new file mode 100644 index 00000000..13389e2b --- /dev/null +++ b/apps/landing/public/images/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/landing/public/images/color-theme-dark.svg b/apps/landing/public/images/color-theme-dark.svg new file mode 100644 index 00000000..3f113dd9 --- /dev/null +++ b/apps/landing/public/images/color-theme-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/landing/public/images/color-theme.svg b/apps/landing/public/images/color-theme.svg new file mode 100644 index 00000000..5b5cdd2f --- /dev/null +++ b/apps/landing/public/images/color-theme.svg @@ -0,0 +1,12 @@ + + + diff --git a/apps/landing/public/images/discord.svg b/apps/landing/public/images/discord.svg new file mode 100644 index 00000000..4f30e7ff --- /dev/null +++ b/apps/landing/public/images/discord.svg @@ -0,0 +1,12 @@ + + + diff --git a/apps/landing/public/images/docs/menu-arrow.svg b/apps/landing/public/images/docs/menu-arrow.svg new file mode 100644 index 00000000..7229ff71 --- /dev/null +++ b/apps/landing/public/images/docs/menu-arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/landing/public/images/github.svg b/apps/landing/public/images/github.svg new file mode 100644 index 00000000..eaa3ea39 --- /dev/null +++ b/apps/landing/public/images/github.svg @@ -0,0 +1,12 @@ + + + diff --git a/apps/landing/public/images/home/background-braille.svg b/apps/landing/public/images/home/background-braille.svg new file mode 100644 index 00000000..244d9ac1 --- /dev/null +++ b/apps/landing/public/images/home/background-braille.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/landing/public/images/home/button-arrow.svg b/apps/landing/public/images/home/button-arrow.svg new file mode 100644 index 00000000..f173b789 --- /dev/null +++ b/apps/landing/public/images/home/button-arrow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/apps/landing/public/images/home/hero.svg b/apps/landing/public/images/home/hero.svg new file mode 100644 index 00000000..938917f5 --- /dev/null +++ b/apps/landing/public/images/home/hero.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/landing/public/images/home/texture.png b/apps/landing/public/images/home/texture.png new file mode 100644 index 00000000..c986c52b Binary files /dev/null and b/apps/landing/public/images/home/texture.png differ diff --git a/apps/landing/public/images/home/translate-arrow-circle.svg b/apps/landing/public/images/home/translate-arrow-circle.svg new file mode 100644 index 00000000..c48ddce9 --- /dev/null +++ b/apps/landing/public/images/home/translate-arrow-circle.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/apps/landing/public/images/home/translate-arrow.svg b/apps/landing/public/images/home/translate-arrow.svg new file mode 100644 index 00000000..257ebdc9 --- /dev/null +++ b/apps/landing/public/images/home/translate-arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/landing/public/images/kakao.svg b/apps/landing/public/images/kakao.svg new file mode 100644 index 00000000..6b310317 --- /dev/null +++ b/apps/landing/public/images/kakao.svg @@ -0,0 +1,14 @@ + + + diff --git a/apps/landing/public/images/team/image-01.jpg b/apps/landing/public/images/team/image-01.jpg new file mode 100644 index 00000000..63109659 Binary files /dev/null and b/apps/landing/public/images/team/image-01.jpg differ diff --git a/apps/landing/public/images/team/image-02.jpg b/apps/landing/public/images/team/image-02.jpg new file mode 100644 index 00000000..4fb46d22 Binary files /dev/null and b/apps/landing/public/images/team/image-02.jpg differ diff --git a/apps/landing/public/images/team/image-03.jpg b/apps/landing/public/images/team/image-03.jpg new file mode 100644 index 00000000..507bb73f Binary files /dev/null and b/apps/landing/public/images/team/image-03.jpg differ diff --git a/apps/landing/public/images/team/image-04.jpg b/apps/landing/public/images/team/image-04.jpg new file mode 100644 index 00000000..507bb73f Binary files /dev/null and b/apps/landing/public/images/team/image-04.jpg differ diff --git a/apps/landing/public/images/team/profile-01.jpg b/apps/landing/public/images/team/profile-01.jpg new file mode 100644 index 00000000..e8e7026c Binary files /dev/null and b/apps/landing/public/images/team/profile-01.jpg differ diff --git a/apps/landing/public/images/team/profile-02.jpg b/apps/landing/public/images/team/profile-02.jpg new file mode 100644 index 00000000..de33136a Binary files /dev/null and b/apps/landing/public/images/team/profile-02.jpg differ diff --git a/apps/landing/public/images/team/profile-03.jpg b/apps/landing/public/images/team/profile-03.jpg new file mode 100644 index 00000000..01d7790f Binary files /dev/null and b/apps/landing/public/images/team/profile-03.jpg differ diff --git a/apps/landing/public/next.svg b/apps/landing/public/next.svg new file mode 100644 index 00000000..5174b28c --- /dev/null +++ b/apps/landing/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/landing/public/og-image.png b/apps/landing/public/og-image.png new file mode 100644 index 00000000..c803a3bc Binary files /dev/null and b/apps/landing/public/og-image.png differ diff --git a/apps/landing/public/vercel.svg b/apps/landing/public/vercel.svg new file mode 100644 index 00000000..77053960 --- /dev/null +++ b/apps/landing/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/landing/public/window.svg b/apps/landing/public/window.svg new file mode 100644 index 00000000..b2b2a44f --- /dev/null +++ b/apps/landing/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/landing/src/app/Trans.tsx b/apps/landing/src/app/Trans.tsx new file mode 100644 index 00000000..238bf39e --- /dev/null +++ b/apps/landing/src/app/Trans.tsx @@ -0,0 +1,89 @@ +'use client' +import { Flex, Image, Input } from '@devup-ui/react' +import { useEffect, useState } from 'react' + +export function Trans() { + const [input, setInput] = useState('') + const [translateToUnicode, setTranslateToUnicode] = useState< + (input: string) => string + >(() => () => '') + useEffect(() => { + import('braillify').then((mod) => { + setTranslateToUnicode(() => mod.translateToUnicode) + }) + }, [input]) + return ( + + + setInput(e.target.value)} + p={['16px', null, null, '40px']} + placeholder={ + 'braillify는 한글 점역을 빠르고 안정적으로 처리하는 Rust 기반 라이브러리입니다.\nNode.js, WebAssembly, Python 등 다양한 환경에서 사용할 수 있어요.\n점역하고 싶은 문장이나 단어를 여기에 입력해 직접 확인해보세요!' + } + resize="none" + selectors={{ + '&::placeholder': { + color: '$text', + typography: 'braille', + opacity: 0.5, + }, + }} + typography="braillie" + value={input} + w="100%" + /> + + + + + + + + + + ) +} diff --git a/apps/landing/src/app/docs/LeftMenu.tsx b/apps/landing/src/app/docs/LeftMenu.tsx new file mode 100644 index 00000000..066f8745 --- /dev/null +++ b/apps/landing/src/app/docs/LeftMenu.tsx @@ -0,0 +1,13 @@ +import { VStack } from '@devup-ui/react' + +import { MenuItem } from './MenuItem' + +export function LeftMenu() { + return ( + + 개요 + 설치 + API + + ) +} diff --git a/apps/landing/src/app/docs/MenuItem.tsx b/apps/landing/src/app/docs/MenuItem.tsx new file mode 100644 index 00000000..6ed17950 --- /dev/null +++ b/apps/landing/src/app/docs/MenuItem.tsx @@ -0,0 +1,72 @@ +'use client' +import { Box, css, Flex, Text } from '@devup-ui/react' +import Link from 'next/link' +import { usePathname } from 'next/navigation' + +import { OpenMenuItem } from './OpenMenuItem' + +const URL_PREFIX = '' + +export interface MenuItemProps { + children?: React.ReactNode + to?: string + subMenu?: { + children?: React.ReactNode + to?: string + }[] +} + +export function MenuItem(props: MenuItemProps) { + const { children, to, subMenu } = props + const path = usePathname() + const selected = to + ? path.startsWith(to) || path.startsWith(URL_PREFIX + to) + : !!subMenu?.some((item) => + item.to + ? path.startsWith(URL_PREFIX + item.to) || path.startsWith(item.to) + : false, + ) + + if (subMenu) return + const inner = ( + + {selected && } + + {children} + + + ) + return to ? ( + + {inner} + + ) : ( + inner + ) +} diff --git a/apps/landing/src/app/docs/OpenMenuItem.tsx b/apps/landing/src/app/docs/OpenMenuItem.tsx new file mode 100644 index 00000000..54877fcd --- /dev/null +++ b/apps/landing/src/app/docs/OpenMenuItem.tsx @@ -0,0 +1,107 @@ +'use client' +import { Box, css, Flex, Image, Text, VStack } from '@devup-ui/react' +import Link from 'next/link' +import { usePathname } from 'next/navigation' +import { Fragment, useReducer } from 'react' + +import { MenuItemProps } from './MenuItem' + +const URL_PREFIX = '' + +export function OpenMenuItem({ + children, + subMenu, +}: Omit & + Required>) { + const path = usePathname() + const selected = subMenu.some((item) => + item.to + ? path.startsWith(URL_PREFIX + item.to) || path.startsWith(item.to) + : false, + ) + const [open, handleOpen] = useReducer((state) => !state, selected) + return ( + <> + + {selected && } + + {children} + + {subMenu && ( + + )} + + {open && ( + + + + {subMenu.map(({ children, to }, idx) => { + const selected = to + ? path.startsWith(to) || path.startsWith(URL_PREFIX + to) + : false + const inner = ( + + {selected && ( + + )} + + {children} + + + ) + + return to ? ( + + {inner} + + ) : ( + {inner} + ) + })} + + + )} + + ) +} diff --git a/apps/landing/src/app/docs/RightIndex.tsx b/apps/landing/src/app/docs/RightIndex.tsx new file mode 100644 index 00000000..dcacf73e --- /dev/null +++ b/apps/landing/src/app/docs/RightIndex.tsx @@ -0,0 +1,130 @@ +'use client' +import { Box, css, Flex, Text, VStack } from '@devup-ui/react' +import Link from 'next/link' +import { usePathname } from 'next/navigation' +import { useEffect, useState } from 'react' + +function IndexMenu({ + children, + selected, + sub, + onClick, +}: { + children: React.ReactNode + selected?: boolean + sub?: boolean + onClick?: () => void +}) { + return ( + + {selected && } + + {children} + + + ) +} + +export function RightIndex() { + const pathname = usePathname() + const editUrl = `https://github.com/dev-five-git/braillify/tree/main/apps/landing/src/app/docs${pathname.split('docs')[1]}/page.mdx` + const [menus, setMenus] = useState< + { + text: string + sub?: boolean + onClick?: () => void + }[] + >([]) + useEffect(() => { + const elements = document.querySelectorAll( + '.markdown-body h1, .markdown-body h2', + ) + const menus = [] + for (let i = 0; i < elements.length; i++) { + const element = elements[i] + const text = element.textContent! + menus.push({ + text, + sub: element.tagName === 'H2', + onClick: () => { + element.scrollIntoView({ behavior: 'smooth' }) + }, + }) + } + setMenus(menus) + }, [pathname]) + + return ( + + + + + 내용 + + + {menus.map((menu) => ( + + {menu.text} + + ))} + + + + + + 이 페이지 편집하기 + + + + + + + + + ) +} diff --git a/apps/landing/src/app/docs/api/page.mdx b/apps/landing/src/app/docs/api/page.mdx new file mode 100644 index 00000000..8336a8eb --- /dev/null +++ b/apps/landing/src/app/docs/api/page.mdx @@ -0,0 +1,86 @@ +export const metadata = { + title: 'API', +} + +# API + +Braillify 는 nodejs(wams for web) 와 python 그리고 rust를 지원합니다. + +모든 함수는 표현 방식만 다를 뿐 사용법과 함수명은 같습니다. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Node.js 함수Python 함수설명
encodeencode문자열을 바이너리로 변환합니다.
translateToUnicodetranslate_to_unicode문자열을 유니코드 점자로 변환합니다.
translateToBrailleFonttranslate_to_braille_font문자열을 점자 폰트로 변환합니다.
diff --git a/apps/landing/src/app/docs/features/page.mdx b/apps/landing/src/app/docs/features/page.mdx new file mode 100644 index 00000000..f3527ff0 --- /dev/null +++ b/apps/landing/src/app/docs/features/page.mdx @@ -0,0 +1,5 @@ +export const metadata = { + title: 'Features', +} + +# Features \ No newline at end of file diff --git a/apps/landing/src/app/docs/installation/page.mdx b/apps/landing/src/app/docs/installation/page.mdx new file mode 100644 index 00000000..07556436 --- /dev/null +++ b/apps/landing/src/app/docs/installation/page.mdx @@ -0,0 +1,23 @@ +export const metadata = { + title: '설치', +} + +# 설치 + +Braillify 는 nodejs(wams for web) 와 python 환경을 지원합니다. + +표준 저장소에 배포되었기 때문에 모든 패키지 매니저로 다운받을 수 있습니다. + +
+## Python +
+```bash +pip install braillify # python +``` + +
+## Nodejs +
+```bash +npm install braillify # nodejs +``` \ No newline at end of file diff --git a/apps/landing/src/app/docs/layout.tsx b/apps/landing/src/app/docs/layout.tsx new file mode 100644 index 00000000..d6c9e15b --- /dev/null +++ b/apps/landing/src/app/docs/layout.tsx @@ -0,0 +1,28 @@ +import { Box, Flex } from '@devup-ui/react' + +import { LeftMenu } from './LeftMenu' +import { RightIndex } from './RightIndex' + +export default function DocsLayout({ + children, +}: Readonly<{ + children: React.ReactNode +}>) { + return ( + + + + + + + + {children} + + + + + + + + ) +} diff --git a/apps/landing/src/app/docs/overview/page.mdx b/apps/landing/src/app/docs/overview/page.mdx new file mode 100644 index 00000000..422e8d63 --- /dev/null +++ b/apps/landing/src/app/docs/overview/page.mdx @@ -0,0 +1,34 @@ +export const metadata = { + title: '개요', +} + +# 개요 +
+ +Braillify 는 완전 오픈소스 한글 점역 라이브러리입니다. +
+ +기존에도 한글 점역 라이브러리가 존재했으나 2024 개정 한국 점자 규정을 준수하지 않거나, 오픈소스가 아니었습니다. + +
+하지만 Braillify 가 Apache License 2.0 라이센스를 기반으로 완전 오픈소스 점자 라이브러리를 공개합니다. + +
+원하는 한글을 점역해보세요. + +
+Rust 기반으로 네이티브 성능을 구현했고, nodejs, python 등 가장 대중적인 언어들을 지원합니다. + +
+# 테스트 케이스 추가 +
+ +[github issue](https://github.com/dev-five-git/braillify/issues) 에서 테스트 케이스 추가를 건의해주세요. +
+ +지속적인 테스트 케이스 추가로 옛한글, 수학, 컴퓨터 점자까지 한글 점자 완전 정복을 위하여 함께 노력합시다. + +
+# 기여하기 +
+모든 오픈소스 기여는 환영입니다. \ No newline at end of file diff --git a/apps/landing/src/app/docs/theme/page.mdx b/apps/landing/src/app/docs/theme/page.mdx new file mode 100644 index 00000000..e67cab39 --- /dev/null +++ b/apps/landing/src/app/docs/theme/page.mdx @@ -0,0 +1,5 @@ +export const metadata = { + title: 'Theme', +} + +# Theme \ No newline at end of file diff --git a/apps/landing/src/app/globals.css b/apps/landing/src/app/globals.css new file mode 100644 index 00000000..f2a4a3ff --- /dev/null +++ b/apps/landing/src/app/globals.css @@ -0,0 +1,15 @@ +@import url(//spoqa.github.io/spoqa-han-sans/css/SpoqaHanSansNeo.css); + + +html, +body { + max-width: 100vw; + overflow-x: hidden; +} + + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} \ No newline at end of file diff --git a/apps/landing/src/app/layout.tsx b/apps/landing/src/app/layout.tsx new file mode 100644 index 00000000..db239924 --- /dev/null +++ b/apps/landing/src/app/layout.tsx @@ -0,0 +1,53 @@ +import './globals.css' + +import { Box, css, ThemeScript } from '@devup-ui/react' +import type { Metadata } from 'next' + +import Footer from '@/components/Footer' +import Header from '@/components/Header' + +export const metadata: Metadata = { + title: 'Braillify', + description: 'Braillify', +} + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode +}>) { + return ( + + + + + + + + + + +
+ {children} + +