Skip to content

Commit 7701bc0

Browse files
committed
feat: add variable naming feature
1 parent 8ad0b9b commit 7701bc0

22 files changed

+121
-104
lines changed

README.md

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,12 @@
11

2-
# YoudaoTranslate | 有道翻译
2+
# variable-naming.alfredworkflow
33

4-
<p align="left">
5-
<img alt="GitHub stars" src="https://visitor-badge.laobi.icu/badge?page_id=wensonsmith.YoudaoTranslate"/>
6-
<img alt="GitHub stars" src="https://img.shields.io/github/stars/wensonsmith/YoudaoTranslate?style=social"/>
7-
</p>
84

9-
![screenshot_1](screenshots/screenshot_1.png)
5+
-[YoudaoTranslator](https://github.com/wensonsmith/YoudaoTranslator) 的基础上,将翻译的文本生成变量名;
6+
- 支持 `小驼峰``大驼峰``小写下划线``大写下划线` 四种变量命名规范;
7+
- 如果翻译结果不理想可以 `cmd + y` 组合键 Quick Look 网页查看其它结果;
8+
- 或者按住 `alt` 键回车,浏览器会打开 [Codelf](https://unbug.github.io/codelf/)
9+
- 配置参考 [YoudaoTranslator Uncyclo](https://github.com/wensonsmith/YoudaoTranslator/wiki)
10+
- 下载:[Releases](https://github.com/Coder-ZJQ/variable-naming.alfredworkflow/releases)
1011

11-
## ⚠️ V3 更新说明
12-
该版本使用 TS 重构,自带运行环境,不再依赖 PHP。同时支持多个平台的 API。
13-
14-
macOS Monterey 请使用 V3 版本!
15-
16-
标记为施工中 (🚧) 特性 V3 尚未支持,如果需要使用,请切换到 V2 使用。
17-
18-
## 特性
19-
- 🌟 [**无系统环境依赖**]() - 自带 [txiki](https://github.com/saghul/txiki.js) 运行环境,不再需要 PHP
20-
- 🌟 [**多平台支持**]() - 支持百度的翻译API
21-
- 🌐 [**中英文自动互翻**]() - 支持 `CamelCase` 驼峰短语翻译,长句自动换行
22-
- 🎭 [**多语言支持**](screenshots/multi.jpg) - 可以识别中文、英文、日文、韩文、法文、俄文等
23-
- 🎹 [**快捷键支持**]() - 双击 `⌥ Alt` 直接翻译选中内容
24-
- 📢 [**英文发音**](screenshots/screenshot_3.png) - `⌘ Command` + `↩︎ Enter` 本地发音,`⌥ Alt` + `↩︎ Enter` 调用有道在线语音发音
25-
- 🚧 [**有道翻译生词本**](screenshots/word-book.jpg) - 可以将陌生单词加入有道生词本
26-
- 📃 [**回车复制**]() - 在选项上 `↩︎ Enter` 回车复制翻译结果
27-
- 🚧 [**查询历史**](screenshots/translate_history.gif) - `yd *` 查询最近的翻译记录
28-
- 🔮 [**网页预览**](screenshots/screenshot_4.gif) - 翻译结果上按 `⇧ Shift` 直接预览有道网页
29-
- 🚧 [**自动更新**](screenshots/update.png) - 输入 `update` 检查更新 Workflow
30-
31-
## 🚀 开始使用
32-
33-
🌚 遇到问题不要怕,扫码加群来解答,[**点击扫码**](screenshots/wechat-group.png)
34-
35-
### 1. 下载安装
36-
37-
- [GitHub Releases 下载](https://github.com/wensonsmith/YoudaoTranslate/releases)
38-
- [又拍云下载 v3.1.0](https://img.seekbetter.me/workflows/YoudaoTranslator-3.1.zip)
39-
40-
### 2. 配置Workflow
41-
42-
[👉 请参考 wiki 进行配置](https://github.com/wensonsmith/YoudaoTranslator/wiki)
43-
## Contributors
44-
45-
<a href="https://iwenson.com" target="_blank"><img src="https://avatars1.githubusercontent.com/u/2544185?s=120&v=4" height="60"/></a>
46-
<a href="https://blog.zthxxx.me" target="_blank"><img src="https://avatars0.githubusercontent.com/u/15135943?s=120&v=4" height="60"/></a>
47-
<a href="https://www.zzaning.com/#/" target="_blank"><img src="https://avatars2.githubusercontent.com/u/12035097?s=88&u=7e419cd2eb7b9fec5ba061d8135c4875a4c32323&v=4" height="60"/></a>
48-
49-
## ~~Buy me a coffee~~ 🍼 冲奶粉!
50-
![微信支付](./screenshots/sponsor.PNG)
51-
52-
## 使用库和参考资料
53-
54-
- https://github.com/joetannenbaum/alfred-workflow
55-
- https://www.alfredapp.com/help/workflows/inputs/script-filter/json/
56-
- https://www.alfredapp.com/help/workflows/
12+
![](./screenshots/usage.gif)

assets/icon.png

100755100644
16.9 KB
Loading

assets/translate-say.png

-17.8 KB
Binary file not shown.

assets/translate.png

-4.17 KB
Binary file not shown.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
2-
"name": "youdao.translator",
3-
"version": "3.0.0",
4-
"description": "Elegant translation tool",
2+
"name": "alfred-workflow-variable-naming",
3+
"version": "0.1.0",
4+
"description": "Alfred Variable Naming Workflow",
55
"main": "index.js",
66
"scripts": {
77
"build": "rimraf dist && rollup -c rollup.config.js",
88
"test": "./runtime/quick ./dist/index.js"
99
},
10-
"author": "Wenson",
10+
"author": "jqz",
1111
"license": "MIT",
1212
"devDependencies": {
1313
"rimraf": "^3.0.2",

screenshots/config-1.jpg

-121 KB
Binary file not shown.

screenshots/config-2.jpg

-271 KB
Binary file not shown.

screenshots/multi.jpg

-578 KB
Binary file not shown.

screenshots/screenshot_1.png

-46.9 KB
Binary file not shown.

screenshots/screenshot_3.png

-112 KB
Binary file not shown.

screenshots/screenshot_4.gif

-521 KB
Binary file not shown.

screenshots/sponsor.PNG

-94.6 KB
Binary file not shown.

screenshots/translate_history.gif

-375 KB
Binary file not shown.

screenshots/update.png

-271 KB
Binary file not shown.

screenshots/usage.gif

4.29 MB
Loading

screenshots/wechat-group.png

-225 KB
Binary file not shown.

screenshots/word-book.jpg

-252 KB
Binary file not shown.

src/adapters/adapter.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { Formatter } from "./formatter";
2+
13
export interface Result {
4+
word: string;
25
title: string;
36
subtitle: string;
47
arg: string;
5-
pronounce: string;
68
quicklookurl?: string;
79
}
810

@@ -15,6 +17,8 @@ export interface Adapter {
1517

1618
isChinese: boolean;
1719

20+
formatters: Formatter[]
21+
1822
url :(word: string) => string;
1923

2024
parse: (response: any) => Result[]

src/adapters/baidu.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Adapter, Result } from "./adapter";
22
import md5 from "../libs/md5";
3+
import { Formatter, LowerCamelCase, UpperCamelCase, LowerUnderline, UpperUnderline } from './formatter';
34

45
class Baidu implements Adapter {
56
key: string;
@@ -14,6 +15,13 @@ class Baidu implements Adapter {
1415

1516
phonetic: string = "";
1617

18+
formatters: Formatter[] = [
19+
new LowerCamelCase(),
20+
new UpperCamelCase(),
21+
new LowerUnderline(),
22+
new UpperUnderline()
23+
]
24+
1725
constructor(key: string, secret: string) {
1826
this.key = key;
1927
this.secret = secret;
@@ -48,14 +56,20 @@ class Baidu implements Adapter {
4856
}
4957

5058
const { trans_result:result } = data;
51-
result.forEach(item => {
52-
const pronounce = this.isChinese ? item.dst : this.word;
53-
this.addResult(item.dst, item.src, pronounce, pronounce);
59+
result.filter(this.isAllLetter).forEach(item => {
60+
this.formatters.forEach(formatter => {
61+
const formatted = formatter.format(item.dst)
62+
this.addResult(formatted, formatter.name, formatted);
63+
})
5464
});
5565

5666
return this.results;
5767
}
5868

69+
private isAllLetter(translation: string): boolean {
70+
return /^[a-zA-Z ]+$/.test(translation)
71+
}
72+
5973
private parseError(code: number): Result[] {
6074
const messages = {
6175
54000: "缺少必填的参数",
@@ -74,9 +88,10 @@ class Baidu implements Adapter {
7488
return this.addResult("👻 翻译出错啦", message, "Ooops...");
7589
}
7690

77-
private addResult( title: string, subtitle: string, arg: string = "", pronounce: string = ""): Result[] {
91+
private addResult( title: string, subtitle: string, arg: string = ""): Result[] {
92+
// quicklook 无法打开 codelf,所以展示使用翻译页面
93+
// const quicklookurl = "https://unbug.github.io/codelf/#" + encodeURI(this.word);
7894
const quicklookurl = "https://fanyi.baidu.com/#auto/auto/" + this.word;
79-
8095
const maxLength = this.detectChinese(title) ? 27 : 60;
8196

8297
if (title.length > maxLength) {
@@ -85,7 +100,7 @@ class Baidu implements Adapter {
85100
subtitle = copy.slice(maxLength);
86101
}
87102

88-
this.results.push({ title, subtitle, arg, pronounce, quicklookurl });
103+
this.results.push({ word: this.word, title, subtitle, arg, quicklookurl });
89104
return this.results;
90105
}
91106

src/adapters/formatter.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
export interface Formatter {
2+
name: string;
3+
format: (word: string) => string;
4+
}
5+
6+
export class LowerCamelCase implements Formatter {
7+
name: string = "小驼峰"
8+
9+
format(word: string): string {
10+
return word.split(" ").map((string, index) => {
11+
if (index > 0) {
12+
return string.slice(0, 1).toUpperCase() + string.slice(1).toLowerCase()
13+
} else {
14+
return string.toLowerCase()
15+
}
16+
}).join("")
17+
}
18+
}
19+
export class UpperCamelCase implements Formatter {
20+
name: string = "大驼峰"
21+
22+
format(word: string): string {
23+
return word.split(" ").map((string, index) => {
24+
return string.slice(0, 1).toUpperCase() + string.slice(1).toLowerCase()
25+
}).join("")
26+
}
27+
}
28+
export class LowerUnderline implements Formatter {
29+
name: string = "小写下划线"
30+
31+
format(word: string): string {
32+
return word.split(" ").map((string, index) => {
33+
return string.toLowerCase()
34+
}).join("_")
35+
}
36+
}
37+
export class UpperUnderline implements Formatter {
38+
name: string = "大写下划线"
39+
40+
format(word: string): string {
41+
return word.split(" ").map((string, index) => {
42+
return string.toUpperCase()
43+
}).join("_")
44+
}
45+
}

src/adapters/youdao.ts

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Adapter, Result } from "./adapter";
22
import md5 from "../libs/md5";
3+
import { Formatter, LowerCamelCase, UpperCamelCase, LowerUnderline, UpperUnderline } from './formatter';
34

45
class Youdao implements Adapter {
56
key: string;
@@ -14,6 +15,13 @@ class Youdao implements Adapter {
1415

1516
phonetic: string = "";
1617

18+
formatters: Formatter[] = [
19+
new LowerCamelCase(),
20+
new UpperCamelCase(),
21+
new LowerUnderline(),
22+
new UpperUnderline()
23+
]
24+
1725
constructor(key: string, secret: string) {
1826
this.key = key;
1927
this.secret = secret;
@@ -47,61 +55,51 @@ class Youdao implements Adapter {
4755

4856
const { translation, basic, web } = data;
4957

50-
this.parseTranslation(translation);
51-
this.parseBasic(basic);
52-
this.parseWeb(web);
58+
if (this.isChinese) {
59+
// 因为是生成变量名(代码),普通翻译词义可能不怎么符合情况,所以将网络释义提前
60+
this.parseWeb(web);
61+
this.parseTranslation(translation);
62+
this.parseBasic(basic);
63+
}
5364

5465
return this.results;
5566
}
5667

5768
private parseTranslation(translation: object) {
58-
if (translation) {
59-
const pronounce = this.isChinese ? translation[0] : this.word;
60-
this.addResult( translation[0], this.word, translation[0], pronounce );
69+
if (translation && this.isAllLetter(translation[0])) {
70+
this.formatters.forEach(formatter => {
71+
const formatted = formatter.format(translation[0])
72+
this.addResult(formatted, formatter.name, formatted);
73+
})
6174
}
6275
}
6376

6477
private parseBasic(basic: any) {
6578
if (basic) {
66-
let pronounce;
67-
basic.explains.forEach((explain) => {
68-
pronounce = this.isChinese ? explain : this.word;
69-
this.addResult(explain, this.word, explain, pronounce);
79+
basic.explains.filter(this.isAllLetter).forEach((explain) => {
80+
this.formatters.forEach(formatter => {
81+
const formatted = formatter.format(explain)
82+
this.addResult(formatted, formatter.name, formatted);
83+
})
7084
});
71-
72-
if (basic.phonetic) {
73-
// 获取音标,同时确定要发音的单词
74-
const phonetic: string = this.parsePhonetic(basic);
75-
this.addResult( phonetic, "回车可听发音", "~" + pronounce, pronounce );
76-
}
7785
}
7886
}
7987

8088
private parseWeb(web: any) {
8189
if (web) {
8290
web.forEach((item, index) => {
83-
let pronounce = this.isChinese ? item.value[0] : item.key;
84-
this.addResult( item.value.join(", "), item.key, item.value[0], pronounce);
91+
item.value.filter(this.isAllLetter).forEach(element => {
92+
this.formatters.forEach(formatter => {
93+
const formatted = formatter.format(element)
94+
this.addResult(formatted, formatter.name, formatted);
95+
})
96+
});
8597
});
8698
}
8799
}
88100

89-
private parsePhonetic(basic: any): string {
90-
let phonetic: string = '';
91-
92-
if (this.isChinese && basic.phonetic) {
93-
phonetic = "[" + basic.phonetic + "] ";
94-
}
95-
96-
if (basic["us-phonetic"]) {
97-
phonetic += " [美: " + basic["us-phonetic"] + "] ";
98-
}
99-
100-
if (basic["uk-phonetic"]) {
101-
phonetic += " [英: " + basic["uk-phonetic"] + "]";
102-
}
103-
104-
return phonetic;
101+
private isAllLetter(translation: string): boolean {
102+
return /^[a-zA-Z ]+$/.test(translation)
105103
}
106104

107105
private parseError(code: number): Result[] {
@@ -124,9 +122,10 @@ class Youdao implements Adapter {
124122
return this.addResult("👻 翻译出错啦", message, "Ooops...");
125123
}
126124

127-
private addResult( title: string, subtitle: string, arg: string = "", pronounce: string = ""): Result[] {
125+
private addResult( title: string, subtitle: string, arg: string = ""): Result[] {
126+
// quicklook 无法打开 codelf,所以展示使用翻译页面
127+
// const quicklookurl = "https://unbug.github.io/codelf/#" + encodeURI(this.word);
128128
const quicklookurl = "https://www.youdao.com/w/" + this.word;
129-
130129
const maxLength = this.detectChinese(title) ? 27 : 60;
131130

132131
if (title.length > maxLength) {
@@ -135,7 +134,7 @@ class Youdao implements Adapter {
135134
subtitle = copy.slice(maxLength);
136135
}
137136

138-
this.results.push({ title, subtitle, arg, pronounce, quicklookurl });
137+
this.results.push({ word: this.word, title, subtitle, arg, quicklookurl });
139138
return this.results;
140139
}
141140

src/workflow/workflow.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@ class Workflow {
77

88
compose(results: Result[]): this {
99
this.results = results.map(r => {
10-
const icon = r.arg.startsWith("~") ? 'assets/translate-say.png' : 'assets/translate.png'
10+
1111
return new Item().setTitle(r.title)
1212
.setSubtitle(r.subtitle)
1313
.setArg(r.arg)
14-
.setIcon(icon)
15-
.setCmd('🔊 ' + r.pronounce, r.pronounce)
16-
.setAlt('📣 ' + r.pronounce, r.pronounce)
1714
.setCopy(r.title)
15+
.setAlt("https://unbug.github.io/codelf/#" + r.word, r.word)
1816
.setQuicklookurl(r.quicklookurl)
1917
.result();
2018
});

0 commit comments

Comments
 (0)