Skip to content

Instantly share code, notes, and snippets.

@emisjerry
Created August 10, 2024 01:45
Show Gist options
  • Save emisjerry/5e460bd0ea47e5a58871ed4fa6077fad to your computer and use it in GitHub Desktop.
Save emisjerry/5e460bd0ea47e5a58871ed4fa6077fad to your computer and use it in GitHub Desktop.
AutoHotkey v2 script. Generating .md file for Obsidian-Yanki plugin.
#Requires AutoHotkey v2.0
#SingleInstance Force
/*
1. 分號(;)或井號(#)開頭表示是註解行。
2. 斜線(/)開頭表示輸出資料夾
3. 單字
一行一個單字,自動到Yahoo!奇摩網站取回解釋、音標與詞類
park
4. 克漏字
一行一句,含有 {{c1:: 時是克漏字句子
I love {{c1::summer}} {{c2::vacation}}. 我喜歡暑假
*/
Global _EXPL_ := 1 ; 解釋
Global _NOTION_ := 2 ; 詞類
Global _PRONOUNCE_ := 3 ; 發音音標
; 輸入文字檔有3種格式
; 1=英文單字
; 2=片語 [Tab] 中文解釋
; 3=克漏字
Global _ACTION_WORD_ := 1
Global _ACTION_PHRASE_ := 2
Global _ACTION_CLOZE_ := 3
Global sInputFile := "j:\AHK2\English-7A.txt" ; 輸入的設定檔, 檔案編碼:UTF-8
;;Global sOutputFolder := "j:\JERRY\MOC\060-Anki\English-7\English-7-1-words\"
Global sSeparator := A_Tab ; 輸入檔的分隔字元
Global action_word
; 要產生的模板
; {1}=單字 {2}=詞類+中文解釋 {3}=音標 {4}=空白未用
action_word := "
(
---
tags:
- english
- english-word
- english-7A
---
# {1}
---
---
{2}
{3}
{4}
)" ; action_word
;f1::
oInputBox := InputBox("輸入設定檔名:", "輸入檔名", "w300 h100", sInputFile)
if (oInputBox.Result = "Cancel") {
Return
}
sInputFile := oInputBox.Value
if !FileExist(sInputFile) {
MsgBox(sInputFile . "必須先建立。", "Error!", 0)
Return
}
_iCount := 0
FileEncoding "UTF-8"
_sTags := ""
_sOutputFolder := ""
_aEnglishWords := []
_aOutputFolders := []
_iWordCount := 0
; 為了顯示進度條,將要處理的單字加入陣列,並找出單字數目
Loop read, sInputFile
{
iLineNumber := A_Index
Loop parse, A_LoopReadLine, "`n"
{
;MsgBox line #%A_Index%=%_sLine%.
_sLine := A_LoopField
_sFirstChar := SubStr(_sLine, 1, 1)
if (_sFirstChar == ";" or _sFirstChar == "#") { ;; 第一個字元分號或井號是註解行
continue
}
if (_sFirstChar == "/") { ;; 第一個字元 / 指定輸出資料夾
_sOutputFolder := SubStr(_sLine, 2, 255)
_sLastChar := SubStr(_sOutputFolder, StrLen(_sOutputFolder) - 1, 1)
if (_sLastChar != "\") {
_sOutputFolder := _sOutputFolder . "\"
}
if (!FileExist(_sOutputFolder)) {
DirCreate(_sOutputFolder)
}
continue
}
_iWordCount++
_aEnglishWords.Push(_sLine)
_aOutputFolders.Push(_sOutputFolder)
}
}
_fProgressInc := Float(100 / _iWordCount) ; 進度條每次要增加的數字
MyGui := Gui()
oText := MyGui.Add("Text", "w200", "產生總數: " . "0 / " . _iWordCount)
MyGui.Add("Progress", "w200 h20 cBlue vMyProgress", 0)
MyGui.Show()
_iCount := 0
Loop _iWordCount
{
_sEnglishWord := _aEnglishWords[A_Index]
_sOutputFolder := _aOutputFolders[A_Index]
_iCount++
oText.Value := "產生總數: " . _iCount . " / " . _iWordCount
MyGui["MyProgress"].Value := _iCount * _fProgressInc
output(_ACTION_WORD_, _sOutputFolder, _sEnglishWord, "", "")
}
MyGui.Destroy
MsgBox("處理數: " . _iCount, "Result", 0)
ExitApp(0)
Return
;; 寫出單字 sNotion: 詞性
output(iActionKind, sOutputFolder, sEnglish, sChinese, sNotion) {
;MsgBox("Text " . sEnglish . "=" . sChinese, "Title", 0)
local _sOutput, _aTokens, _sChineseGet, _sNotion
if (iActionKind == _ACTION_WORD_) { ; 單字
action := action_word
try {
_aTokens := translate(sEnglish) ; 取翻譯、音標與詞類
_sChineseGet := _aTokens[_EXPL_]
_sNotion := _aTokens[_NOTION_] ; 詞類
;; \r與\t會造成寫入失敗,必須先行轉換
_sChineseGet := StrReplace(_sChineseGet, "`r", " ")
_sChineseGet := _sNotion . " " . StrReplace(_sChineseGet, "`t", " ")
_sEnghishGet := " " . _aTokens[_PRONOUNCE_]
_sEnghishGet := StrReplace(_sEnghishGet, "`r", " ")
_sOutputFilename := sEnglish . ".md"
if (FileExist(sOutputFolder . _sOutputFilename)) {
FileDelete(sOutputFolder . _sOutputFilename)
}
_sOutput := Format(action, sEnglish, _sChineseGet, _sEnghishGet, "")
FileAppend(_sOutput, sOutputFolder . _sOutputFilename)
return 1
} catch (Error as err) {
MsgBox(sEnglish . " " . err.Message, "Error!", 0)
return 0
}
}
}
;; 傳入要搜尋的文字,傳回查詢到的結果
;; 再將結果以Markdown格式輸出到檔案
translate(sSearch) {
;msgbox sSearch=%sSearch%
url := "https://tw.dictionary.search.yahoo.com/search?p=" . sSearch . "&fr=sfp&iscqry="
httpClient := ComObject("WinHttp.WinHttpRequest.5.1")
httpClient.Open("POST", url, false)
httpClient.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
httpClient.Send()
httpClient.WaitForResponse()
Result := httpClient.ResponseText
html := ComObject("HTMLFile")
html.write(Result)
elements := html.getElementsByTagName("div")
_sPronounce := "" ; 發音
_sNotion := "" ; 詞類
_sDictionaryExplanation := "" ; 解釋
_isFirstNotion := true
_isFirstExplain := true
;MsgBox("length=" . elements.Length, "Length", 0)
Loop elements.length
{
ele := elements(A_Index - 1) ; zero based collection. 不能用 []
_sClassName := ele.className
if (InStr(_sClassName, "pos_button") > 0) and (_isFirstNotion) { ; 詞類
_sNotion := ele.innerHTML
_sNotion := StrReplace(_sNotion, "[", "\[") ; n.[C]改成 n.\[C]
_isFirstNotion := false
} else if (InStr(_sClassName, "compList d-ib") > 0) { ; 音標
_sPronounce := ele.innerText
_iPos := InStr(_sPronounce, "DJ[")
_sPronounce := SubStr(_sPronounce, 1, _iPos - 1)
_sPronounce := StrReplace(_sPronounce, "[", "\[") ; KK[改成 KK\[
;Msgbox("pronounce=" _sPronounce, "pronounce", 0)
} else if (InStr(_sClassName, "dictionaryExplanation") > 0 and _isFirstExplain) {
_sDictionaryExplanation .= ele.innerHTML . "`r"
_sDictionaryExplanation := StrReplace(_sDictionaryExplanation, "[", "\[")
_isFirstExplain := false
}
}
;;MsgBox("expl=" . _sDictionaryExplanation . ", notion=" . _sNotion . ", pron=" . _sPronounce, "title",0)
_aTokens := []
_aTokens.Push(_sDictionaryExplanation, _sNotion, _sPronounce)
return _aTokens
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment