Skip to content

Commit

Permalink
feat: 添加自定义短语库支持 #2
Browse files Browse the repository at this point in the history
  • Loading branch information
pengzhanbo committed Apr 27, 2024
1 parent 82faa2c commit 3b03ec6
Show file tree
Hide file tree
Showing 11 changed files with 156 additions and 40 deletions.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,44 @@ import { setupEnhance } from 'chinese-simple2traditional/enhance'
import { setupEnhance } from '@raise/han-convert/enhance'
```

### customS2TPhrases(phrases)

添加 自定义 简体转繁体 短语集合。

- `phrases`: `[string, string][]` , 短语集合

集合的每个元素为 `['简体短语', '繁体短语']` 的元组,表示 `简体短语` 转换为 `繁体短语`

```ts
import { customS2TPhrases, toTraditional } from 'chinese-simple2traditional'

customS2TPhrases([
['双台子区', '雙臺子區'],
// ...
])

toTraditional('双台子区', true) // 雙臺子區
```

### customT2SPhrases(phrases)

添加 自定义 繁体转简体 短语集合。

- `phrases`: `[string, string][]` , 短语集合

集合的每个元素为 `['繁体短语', '简体短语']` 的元组, 表示 `繁体短语` 转换为 `简体短语`

```ts
import { customT2SPhrases, toSimplified } from 'chinese-simple2traditional'

customT2SPhrases([
['雖覆能復', '虽覆能复']
// ...
])

toSimplified('雖覆能復', true) // 虽覆能复
```

## LICENSE

[MIT](./LICENSE)
2 changes: 1 addition & 1 deletion jsr.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@raise/han-convert",
"version": "2.1.0",
"version": "2.2.0",
"exports": {
".": "./src/index.ts",
"./enhance": "./src/enhance.ts"
Expand Down
5 changes: 1 addition & 4 deletions playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ <h1>繁简体转换</h1>
<p class="langs">
<span>简体</span>
<button type="button" id="toggle">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
<path fill="currentColor" d="M16.5 17.5h-9a5.5 5.5 0 1 1 0-11h9a5.5 5.5 0 1 1 0 11" opacity="0.5" />
<circle cx="7.5" cy="12" r="2.5" fill="currentColor" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16"><path fill="currentColor" d="M8.6 3.5L12.1 7H0v2h12.1l-3.5 3.5l1.4 1.4L16 8l-6-5.9z"/></svg>
</button>
<span>繁体</span>
</p>
Expand Down
6 changes: 3 additions & 3 deletions playground/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ function convert() {
const result = type === 's2t' ? toTraditional(text, isEnhance) : toSimplified(text, isEnhance)
const time = performance.now() - begin

output.innerHTML = result.replace(/\n/g, '<br>')
output.innerHTML = result.replace(/\n$/, '<br><br>').replace(/\n/g, '<br>')

input.style.setProperty('height', `${input.scrollHeight}px`)
input.style.setProperty('height', `${output.offsetHeight}px`)

meta.textContent = `共 ${text.length} 字,耗时 ${time.toFixed(2)}ms`
meta.textContent = `共 ${text.replace(/\n/g, '').length} 字,耗时 ${time.toFixed(4)}ms`
}
23 changes: 14 additions & 9 deletions playground/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -58,27 +58,31 @@ header {
border: none;
outline: 0;
background-color: transparent;
font-size: 48px;
line-height: 48px;
height: 48px;
font-size: 24px;
line-height: 24px;
height: 24px;
color: #333;
cursor: pointer;
}

.langs #toggle svg circle {
.langs #toggle svg {
transition: all 0.3s ease;
transform: rotate(0);
}

.langs.reverse #toggle svg circle {
cx: 16.5;
.langs.reverse #toggle svg {
transform: rotate(180deg);
}

.box {
position: relative;
width: 100%;
display: flex;
justify-content: flex-start;
align-items: flex-start;
border: 2px solid #e6eeff;
border-radius: 8px;
padding: 20px 0;
overflow: hidden;
background: linear-gradient(0deg, #f4f7ff, #f4f7ff),
linear-gradient(94.84deg, #fff 3.78%, #fcfdff 9.75%, #e6eeff 102.09%),
Expand All @@ -102,17 +106,18 @@ header {
min-height: 300px;
border: none;
background-color: transparent;
padding: 20px;
padding: 0 20px;
outline: 0;
font-size: 20px;
line-height: 32px;
resize: vertical;
resize: none;
}

#output {
flex: 1;
align-self: flex-start;
min-height: 300px;
padding: 20px;
padding: 0 20px;
font-size: 20px;
line-height: 32px;
}
Expand Down
19 changes: 2 additions & 17 deletions src/enhance.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import simplifiedPhrases from './data/simplified-phrases'
import traditionalPhrases from './data/traditional-phrases'
import { type PhrasesMap, simplifiedPhrasesMap, traditionalPhrasesMap } from './cache'
import { transformPhrases } from './phrases'
import { simplifiedPhrasesMap, traditionalPhrasesMap } from './cache'

/**
* 注入 短语库,增强 繁简体 转换 的准确性
Expand All @@ -9,19 +10,3 @@ export function setupEnhance() {
transformPhrases(simplifiedPhrases, simplifiedPhrasesMap)
transformPhrases(traditionalPhrases, traditionalPhrasesMap)
}

function transformPhrases(data: readonly [string, string], map: PhrasesMap) {
const sources = data[0].split(' ')
const targets = data[1].split(' ')

for (const [index, source] of sources.entries()) {
const key = source[0]
const target = targets[index]

let value = map.get(key)
!value && map.set(key, (value = [[], []]))

value[0].push(source)
value[1].push(target === '_' ? source : target)
}
}
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export * from './convert'

export {
customS2TPhrases,
customT2SPhrases,
} from './phrases'
51 changes: 51 additions & 0 deletions src/phrases.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { PhrasesMap } from './cache'
import { simplifiedPhrasesMap, traditionalPhrasesMap } from './cache'

export type PhrasesConfig = (readonly [string, string])[]

/**
* 添加 自定义 简体转繁体 短语集合
* @param config - 短语集合 [['简体短语', '繁体短语'], ...]
*
* @example
* ```ts
* customS2TPhrases([
* ['友谊万岁', '友誼萬歲'],
* ['王后', '王后'],
* ])
* ```
*/
export function customS2TPhrases(config: PhrasesConfig): void {
config.forEach(([source, target]) => addPhrases(simplifiedPhrasesMap, source, target))
}

/**
* 添加 自定义 繁体转简体 短语集合
* @param config - 短语集合 [['繁体短语', '简体短语'], ...]
*
* @example
* ```ts
* customT2SPhrases([
* ['酒逢知己千鍾少', '酒逢知己千锺少'],
* ['雖覆能復', '虽覆能复'],
* ])
* ```
*/
export function customT2SPhrases(config: PhrasesConfig): void {
config.forEach(([source, target]) => addPhrases(traditionalPhrasesMap, source, target))
}

function addPhrases(map: PhrasesMap, source: string, target: string): void {
const key = source[0]
let tuple = map.get(key)
!tuple && map.set(key, (tuple = [[], []]))

tuple[0].push(source)
tuple[1].push(target === '_' ? source : target)
}

export function transformPhrases(data: readonly [string, string], map: PhrasesMap): void {
const sources = data[0].split(' ')
const targets = data[1].split(' ')
sources.forEach((source, index) => addPhrases(map, source, targets[index]))
}
12 changes: 6 additions & 6 deletions test/converter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { it } from 'vitest'
import { toSimplified, toTraditional } from '../src/index'

it('simpleToTradition', ({ expect }) => {
const s = '主人何为言少钱,径须酤取对君酌。'
const res = '主人何爲言少錢,徑須酤取對君酌。'
expect(toTraditional(s)).toBe(res)
expect(toTraditional('主人何为言少钱,径须酤取对君酌。')).toBe('主人何爲言少錢,徑須酤取對君酌。')

// #2
expect(toTraditional('坚强')).toBe('堅強')
expect(toTraditional('堅強')).toBe('堅強')
})

it('traditionToSimple', ({ expect }) => {
const res = '主人何为言少钱,径须酤取对君酌。'
const s = '主人何爲言少錢,徑須酤取對君酌。'
expect(toSimplified(s)).toBe(res)
expect(toSimplified('主人何爲言少錢,徑須酤取對君酌。')).toBe('主人何为言少钱,径须酤取对君酌。')
})
28 changes: 28 additions & 0 deletions test/customPhrases.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { beforeEach, it } from 'vitest'
import { toSimplified, toTraditional, customS2TPhrases, customT2SPhrases } from '../src/index'
import { simplifiedPhrasesMap, traditionalPhrasesMap } from '../src/cache'
import { afterEach } from 'node:test'

beforeEach(() => {
customS2TPhrases([
['双台子区', '雙臺子區'],
])
customT2SPhrases([
['雖覆能復', '虽覆能复']
])
})

afterEach(() => {
simplifiedPhrasesMap.clear()
traditionalPhrasesMap.clear()
})

it('custom simplified to traditional phrases', ({ expect }) => {
expect(toTraditional('双台子区')).toBe('雙台子區')
expect(toTraditional('双台子区', true)).toBe('雙臺子區')
})

it('custom traditional to simplified phrases', ({ expect }) => {
expect(toSimplified('雖覆能復')).toBe('虽复能复')
expect(toSimplified('雖覆能復', true)).toBe('虽覆能复')
})
7 changes: 7 additions & 0 deletions test/enhance.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { beforeEach, it } from 'vitest'
import { toSimplified, toTraditional } from '../src/index'
import { setupEnhance } from '../src/enhance'
import { simplifiedPhrasesMap, traditionalPhrasesMap } from '../src/cache'
import { afterEach } from 'node:test'

beforeEach(() => {
setupEnhance()
})

afterEach(() => {
simplifiedPhrasesMap.clear()
traditionalPhrasesMap.clear()
})

it('enhance converter', ({ expect }) => {
const s = '主人何为言少钱,径须酤取对君酌。'
const res = '主人何爲言少錢,徑須酤取對君酌。'
Expand Down

0 comments on commit 3b03ec6

Please sign in to comment.