https://github.com/imgarylai/use-wg
將中文字轉換為威妥瑪拼音的 TypeScript 函式庫。
https://github.com/imgarylai/use-wg
chinese mandarin typescript
Last synced: 2 months ago
JSON representation
將中文字轉換為威妥瑪拼音的 TypeScript 函式庫。
- Host: GitHub
- URL: https://github.com/imgarylai/use-wg
- Owner: imgarylai
- License: mit
- Created: 2026-01-23T22:35:06.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-04-30T02:43:10.000Z (2 months ago)
- Last Synced: 2026-04-30T04:24:02.903Z (2 months ago)
- Topics: chinese, mandarin, typescript
- Language: TypeScript
- Homepage: https://imgarylai.github.io/use-wg/
- Size: 200 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.en.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# use-wg
A TypeScript library for converting Chinese characters to Wade-Giles romanization.
[](https://github.com/imgarylai/use-wg/actions/workflows/test.yml)
[](https://opensource.org/licenses/MIT)
[繁體中文](README.md)
## Features
- Chinese characters (Traditional & Simplified) → Wade-Giles romanization
- Configurable tone format (superscript, number, none)
- Mixed Chinese/English text handling
- URL-safe output mode
- Context-aware polyphone handling
- TypeScript support with full type definitions
- Command-line interface (CLI)
## Installation
```bash
npm install use-wg
```
## CLI
Use directly via `npx`:
```bash
# Basic usage
npx use-wg "台灣" # Output: t'ai²-wan¹
# URL-safe mode
npx use-wg "台灣" --url-safe # Output: tai-wan
# Tone formats
npx use-wg "高雄" --tone number # Output: kao1-hsiung2
npx use-wg "高雄" --tone none # Output: kao-hsiung
# From stdin
echo "台灣" | npx use-wg
# JSON output (with segments)
npx use-wg "台灣" --json
# Pinyin mode
npx use-wg --pinyin "zhong1" # Output: chung¹
```
### CLI Options
| Option | Short | Description | Default |
| ------------------- | ----- | -------------------------------------- | ----------- |
| `--url-safe` | `-u` | Produce URL-safe output | false |
| `--tone ` | `-t` | Tone format: superscript, number, none | superscript |
| `--separator ` | `-s` | Separator between syllables | - |
| `--capitalize` | `-c` | Capitalize first letter | false |
| `--json` | `-j` | Output JSON format | false |
| `--pinyin` | `-p` | Pinyin to Wade-Giles mode | false |
## Library Usage
### Basic Conversion
```typescript
import { toWadeGiles } from "use-wg";
// Basic conversion
toWadeGiles("台灣").text; // "t'ai²-wan¹"
toWadeGiles("台北").text; // "t'ai²-pei³"
toWadeGiles("高雄").text; // "kao¹-hsiung²"
```
### Tone Formats
```typescript
// Superscript tones (default)
toWadeGiles("高雄", { toneFormat: "superscript" }).text; // "kao¹-hsiung²"
// Number tones
toWadeGiles("高雄", { toneFormat: "number" }).text; // "kao1-hsiung2"
// No tones
toWadeGiles("高雄", { toneFormat: "none" }).text; // "kao-hsiung"
```
### URL-Safe Mode
Produces ASCII-only output suitable for URLs, filenames, and identifiers:
```typescript
toWadeGiles("台灣", { urlSafe: true }).text; // "tai-wan"
toWadeGiles("氣功", { urlSafe: true }).text; // "chi-kung"
```
URL-safe mode automatically:
- Removes tone markers
- Converts `ü` → `u`
- Removes apostrophes (`'`)
- Outputs lowercase
- Converts spaces to hyphens (`-`)
### Mixed Chinese/English Text
The converter intelligently handles mixed text:
```typescript
toWadeGiles("Hello 世界!").text; // "Hello shih⁴-chieh⁴!"
toWadeGiles("iPhone 手機 Pro").text; // "iPhone shou³-chi¹ Pro"
toWadeGiles("2024年").text; // "2024nien²"
```
### Options
```typescript
toWadeGiles("台北", {
toneFormat: "superscript", // 'superscript' | 'number' | 'none'
separator: "-", // Separator between syllables
preserveNonChinese: true, // Keep non-Chinese characters
capitalize: false, // Capitalize first letter
polyphoneMode: "auto", // 'auto' | 'all'
urlSafe: false, // ASCII-only output
});
```
### Direct Pinyin Conversion
```typescript
import { pinyinToWadeGiles } from "use-wg";
pinyinToWadeGiles("zhong1"); // "chung¹"
pinyinToWadeGiles("guo2"); // "kuo²"
pinyinToWadeGiles("qi4"); // "ch'i⁴"
```
### Utility Functions
```typescript
import { containsChinese } from "use-wg";
containsChinese("Hello 世界"); // true
containsChinese("Hello World"); // false
```
### Segments Information
Access detailed conversion information:
```typescript
const result = toWadeGiles("台北");
console.log(result.text); // "t'ai²-pei³"
console.log(result.segments);
// [
// { original: "台", pinyin: "tai2", wadeGiles: "t'ai", tone: 2 },
// { original: "北", pinyin: "bei3", wadeGiles: "pei", tone: 3 }
// ]
```
## Wade-Giles Mapping
Key conversion patterns:
| Pinyin | Wade-Giles | Example |
| ------- | ---------- | -------------- |
| b → p | ba → pa | 八 bā → pa¹ |
| p → p' | pa → p'a | 怕 pà → p'a⁴ |
| d → t | da → ta | 大 dà → ta⁴ |
| t → t' | ta → t'a | 他 tā → t'a¹ |
| g → k | ga → ka | 高 gāo → kao¹ |
| k → k' | ka → k'a | 看 kàn → k'an⁴ |
| j → ch | ji → chi | 雞 jī → chi¹ |
| q → ch' | qi → ch'i | 氣 qì → ch'i⁴ |
| x → hs | xi → hsi | 西 xī → hsi¹ |
| zh → ch | zhi → chih | 知 zhī → chih¹ |
| z → ts | zi → tzu | 子 zǐ → tzu³ |
| c → ts' | ci → tz'u | 次 cì → tz'u⁴ |
| r → j | ri → jih | 日 rì → jih⁴ |
| si → ss | si → ssu | 四 sì → ssu⁴ |
## API Reference
### `toWadeGiles(text, options?)`
Convert Chinese text to Wade-Giles romanization.
**Parameters:**
- `text` (string) - Chinese text to convert
- `options` (WadeGilesOptions) - Optional configuration
**Returns:** `WadeGilesResult`
### `pinyinToWadeGiles(pinyin, options?)`
Convert a pinyin syllable to Wade-Giles.
**Parameters:**
- `pinyin` (string) - Pinyin syllable with optional tone number
- `options` ({ toneFormat?: ToneFormat }) - Optional tone format
**Returns:** `string`
### `containsChinese(text)`
Check if a string contains Chinese characters.
**Parameters:**
- `text` (string) - Text to check
**Returns:** `boolean`
## Types
```typescript
type ToneFormat = "superscript" | "number" | "none";
interface WadeGilesOptions {
toneFormat?: ToneFormat; // Default: 'superscript'
separator?: string; // Default: '-'
preserveNonChinese?: boolean; // Default: true
capitalize?: boolean; // Default: false
polyphoneMode?: "auto" | "all"; // Default: 'auto'
urlSafe?: boolean; // Default: false
}
interface WadeGilesResult {
text: string;
segments: WadeGilesSegment[];
}
interface WadeGilesSegment {
original: string;
pinyin: string;
wadeGiles: string;
tone?: number;
alternatives?: string[];
}
```
## Performance
Run benchmark: `npm run benchmark`
| Test | Input | Avg (ms) | Ops/sec |
| ---------------- | --------------------------------- | -------- | ------- |
| Short (2 chars) | `台灣` | 0.0037 | 273,321 |
| Medium (8 chars) | `這是一個測試句子` | 0.0108 | 92,664 |
| Long (11 chars) | `台北市信義區忠孝東路四段` | 0.0150 | 66,465 |
| Mixed text | `Hello 世界! This is a test 測試` | 0.0063 | 159,867 |
| With numbers | `2024年台灣之旅` | 0.0064 | 157,288 |
| URL-safe short | `台灣` | 0.0031 | 318,489 |
| URL-safe mixed | `My 台灣 Trip 2024年` | 0.0057 | 176,106 |
**Average: ~180,000 ops/sec**
## Requirements
- Node.js >= 22
- npm >= 10.0.0
## Development
```bash
# Install dependencies
npm install
# Run tests
npm test
# Build
npm run build
# Type check
npm run type-check
```
## License
MIT License - see the [LICENSE](LICENSE) file for details.
## Author
Gary Lai - [@imgarylai](https://github.com/imgarylai)