引言
无论是什么语言的代码,合理的注释以及手册都是交付的必要条件。 经过上一个章节,相信大家可以明白给变量命名的重要性。
现在新的问题来了:
存在语言障碍的情况下,怎么去读懂别人的代码,或者说,更明白的看懂注释。
学外语
我从不掩盖自己屎一样的外语。从多年工作来说,外语薄弱会有很多影响,但对编程的影响不是致命的。
翻译
现在机器翻译已经做到相对足够好,比如下面这家公司的产品
Microsoft 文本翻译 API 是一项基于云的机器翻译服务,支持多种语言,其支持的语言覆盖全球国内生产总值 (GDP) 95% 以上的区域。使用 Translator 可构建应用程序、网站、工具或任何需要多语言支持的解决方案。
它提供有免费的API接口,每个月可以免费用200万字。更贵的套餐也有,比如我现在用的 ` S1套餐,$40/百万 个字符的自定义翻译`
API
在使用它之前,需要先注册一个账号,具体的操作方法可以在官方网站的快速入门查找,很简单。 接下来我们需要看一下他的API
比较可惜也是情理之中的事情是,并没有PowerShell相关的范例代码。根据这个范例,以及C#大哥的参考。 下面来构造PowerShell(.net家族小弟)的查询代码
首先是两个核心函数,通过这个函数,朋友们可以学习下关于WEB请求部分,C#代码是如何翻译成PowerShell。
- 获取所有支持的语言版本
- 翻译
1
2
3
4
5
6
7
8
9
10
11
12
function GetAllTranslatorLang {
((Invoke-WebRequest https://api.cognitive.microsofttranslator.com/languages?api-version=3.0).Content | ConvertFrom-Json).translation
}
function translatorMS ($language, $texts) {
$APIuri = "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=$language" #&from=zh-Hans
$translatordata = Invoke-WebRequest $APIuri ` -Body $texts -ContentType "application/json;charset=utf-8" -Method POST -Headers $postParams
($translatordata.Content | ConvertFrom-Json).translations.text
}
- 注意用到的KEY,这个要提前申请,
1
2
$subscriptionKey = '这里是key'
$postParams = @{ "Ocp-Apim-Subscription-Key" = "$subscriptionKey" }
1
2
#然后这么使用函数就可了
translatorMS -language $lanx -texts $body
是不是很简单?通过上满几行,我们举一反三,就可以写出如下完整代码.
用法也很简单
- 把下面的代码里面的
KEY
换成自己申请的, - 然后代码存储为.ps1
- 想办法把它转换成exe
- 最后将需要翻译的ps1文件,拖动到这个文件上,默认情况下支持中英互转
- 如果你不在步骤2转换为exe,则需要使用类似如下的方法来使用
1
& '.\Bing Transit 0.1.ps1' -filename C:\x\azaa.ps1 -languages "zh-Hans"
最终结果:自动生成一个同名目录,里面有翻译好注释的ps1文件,以及所有抽出来的注释代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
param ($filename,
$languages = @("zh-Hans", "en"))
#param ($filename,$languages = @("zh-Hans", "ja", "en", "ko"))
#region function
function CreateNewFolder ($NewFolder) {
if (!(Test-Path $NewFolder)) {
mkdir $NewFolder | Out-Null
}
}
function GetAllTranslatorLang {
((Invoke-WebRequest https://api.cognitive.microsofttranslator.com/languages?api-version=3.0).Content | ConvertFrom-Json).translation
}
function translatorMS ($language, $texts) {
$APIuri = "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=$language" #&from=zh-Hans
$translatordata = Invoke-WebRequest $APIuri ` -Body $texts -ContentType "application/json;charset=utf-8" -Method POST -Headers $postParams
($translatordata.Content | ConvertFrom-Json).translations.text
}
function ConvertLanguage ($comments) {
for ($i = 0; $i -lt $comments.count; $i++) {
$x = $comments[$i].split(',')
if ($x[1] -match "region" -or $x[1] -match "\A#>" -or $x[1] -match "=" -or $x[1] -match "\$") {
$comments[$i]
}
else { $x[0] + ",#" + $translatored[$i] }
}
}
#endregion function
#$filename = "C:\x\ConvergedDeploy-V1.1.ps1"
$subscriptionKey = '这里是KEY'
$postParams = @{ "Ocp-Apim-Subscription-Key" = "$subscriptionKey" }
$gcfile = Get-Content $filename -Encoding UTF8
$info = New-Object System.Collections.ArrayList
$info2 = New-Object System.Collections.ArrayList
$fileNewname = $filename.Split('\')[-1].Substring(0, $filename.Split('\')[-1].Length - 4)
$NewFolder = ($filename.Split('\')[0 .. ($filename.Split('\').count - 2)] -join "\") + "\" + $fileNewname + "\"
CreateNewFolder $NewFolder
#创建原始文件、提取的描述文件、创建删除所有注释的文件
for ($i = 0; $i -lt $gcfile.count; $i++) {
if ($gcfile[$i].Trim() -match "\A#.*") {
$info2.Add([string]$i + "," + $gcfile[$i].Trim()) | Out-Null
}
elseif ($gcfile[$i].Trim() -eq "") { } #删除所有空行,可选
else {
$info.Add($gcfile[$i]) | Out-Null
}
}
$gcfile | Set-Content $NewFolder$fileNewname".orgin.ps1" -Force -Encoding utf8
$info | Set-Content $NewFolder$fileNewname".Production.ps1" -Force -Encoding utf8
$info2 | Set-Content $NewFolder$fileNewname".comments.txt" -Force -Encoding utf8
############翻译,根据comments写回注释
$filename = $NewFolder + $fileNewname + ".orgin.ps1"
$fileNewname = $filename.Split('\')[-1].Substring(0, $filename.Split('\')[-1].Length - 10)
$orginfile = Get-Content $filename -Encoding UTF8
#获取所有支持的语言GetAllTranslatorLang
Get-ChildItem $NewFolder *.transedcomments.* | Remove-Item
#获取原始文件的注释
$comments = Get-Content $NewFolder$fileNewname".comments.txt" -Encoding utf8
#50一组,分割一下
$commentslengthcount = [math]::ceiling($comments.count / 50)
for ($i2 = 1; $i2 -le $commentslengthcount; $i2++) {
if ($i2 -ne $commentslengthcount) {
$ctx = $comments[(0 + $i2 * 50 - 50) .. ($i2 * 50 - 1)]
}
else {
$ctx = $comments[(0 + $i2 * 50 - 50) .. ($comments.Count - 1)]
}
$body = $ctx | ForEach-Object { $_ | Select-Object @{ name = 'text'; e = { $_.split(',')[-1].replace('#', '') } } } | ConvertTo-Json
$languages | ForEach-Object {
$lanx = $_
$translatored = translatorMS -language $lanx -texts $body
$commentsnew = ConvertLanguage $ctx
#带有行号的翻译
$commentsnew | Add-Content $NewFolder$fileNewname"."$lanx".transedcomments.txt"
}
}
$languages | ForEach-Object {
$lanx = $_
$info3 = New-Object System.Collections.ArrayList
$y = 0
$commentsnew = Get-Content $NewFolder$fileNewname"."$lanx".transedcomments.txt"
for ($i = 0; $i -lt $orginfile.count + 1; $i++) {
if ($commentsnew[$y] -ne $null) {
$commentscount = $commentsnew[$y].split(',')[0]
}
else { $commentscount = "" }
if ($i -eq $commentscount) {
$info3.Add($commentsnew[$y].split(',')[1]) | Out-Null
$y++
}
else {
$info3.Add($orginfile[$i]) | Out-Null
}
}
$info3 | Set-Content $NewFolder$fileNewname"."$lanx".ps1" -Force
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
0,##处理SMB网络的路由,检查网络配置,每个网络的特征
5,#region prep
6,#$ErrorActionPreference = "Stop"
7,#####手动属性
13,#####自动属性
21,#$csvPath = "$rootpath\hfpd01new.csv"
22,#endregion prep
24,#region x
25,#Get-Help about_ActiveDirectory_Filter
26,#刷新组策略
34,# VMM添加运行方式账户
44,# 创建端口分类
46,# 根据端口分类,创建端口配置文件
50,# 创建VM主机组
53,# 创建管理和存储逻辑网络,存储为SMB网络
57,#创建地址池
0,#SMB ネットワークのルーティングの処理、ネットワーク構成の確認、各ネットワークの特性
5,#region prep
6,#$ErrorActionPreference = "Stop"
7,#手動プロパティ
13,#自動プロパティ
21,#$csvPath = "$rootpath\hfpd01new.csv"
22,#endregion prep
24,#region x
25,#ActiveDirectory_Filter に関するヘルプの取得
26,#グループ ポリシーの更新
34,# VMM 実行アカウントの追加
44,# ポート分類の作成
46,# ポートの分類に基づいてポート プロファイルを作成する
50,# VM ホスト グループの作成
53,# SMB ネットワークとして格納される管理およびストレージ論理ネットワークの作成
57,#アドレス プールの作成
未解决的问题
因为大部分场景已经满足了我自己的需求,比如判断注释里面有没有$,=这些本身有特定含义的行不去翻译。所以还剩下有问题的,都是一些 难搞的部分,比如很简单
- 无法处理<# #>包裹的注释
- 无法处理一行代码写完之后不换行,在最后写#然后注释。
如果后面有空,我会继续改进的
用翻译软件是大势所趋,无论是自用还是要走国际范,让代码走出国门,Microsoft 文本翻译 API都是您的明智之选