SSブログ

Safariで表示された英文を自動で翻訳する [AppleScript辞書はつくれるか?]

Safariで開いているページの、選択した部分を自動で翻訳して表示するスクリプトを作ってみた。

 

image220128a.jpg

use AppleScript version "2.7"

use scripting additions

use framework "Foundation"

use framework "AppKit"

use framework "WebKit"

 

global theWindow, mainView

global closeFlg

global currentAppName

 

global windowTitle

global textView1, webView1, progressIndicator1

 

on run

    my performSelectorOnMainThread:"mainMakeObject:" withObject:(missing value) waitUntilDone:true

    log "End"

end run

 

on mainMakeObject:inputObj

    set currentAppName to name of (current application)

    set closeFlg to false

    set windowTitle to "Google翻訳"

    set aRect to {0, 0, 640, 450}

    set theWindow to my makeNewWindow(windowTitle, aRect, true)

    my makeObject()

    theWindow's setAlphaValue:1.0

    repeat

        if closeFlg then

            my closeWin:theWindow

            exit repeat

        end if

        delay 0.2

    end repeat

end mainMakeObject:

 

on makeNewWindow(aTitle, aRect, moveCenter)

    set {windowX, windowY, windowW, windowH} to aRect

    set theRect to current application's NSMakeRect(windowX, windowY, windowW, windowH)

    set aScreen to current application's class "NSScreen"'s mainScreen()

    set aStyle to (current application's NSWindowStyleMaskTitled as integer)

    set aStyle to aStyle + (current application's NSWindowStyleMaskClosable as integer)

    set aStyle to aStyle + (current application's NSWindowStyleMaskMiniaturizable as integer)

    set aStyle to aStyle + (current application's NSWindowStyleMaskResizable as integer)

    set aBacking to current application's NSBackingStoreBuffered

    set aWindow to current application's class "NSWindow"'s alloc()'s initWithContentRect:theRect styleMask:aStyle backing:aBacking defer:false screen:aScreen

    tell aWindow

        setAlphaValue_(0.0)

        setDelegate_(me)

        setTitle_(aTitle)

        setMinSize_(current application's NSMakeSize(360, 250))

        setMaxSize_(current application's NSMakeSize(10000, 10000))

        setBackgroundColor_(current application's class "NSColor"'s colorWithCalibratedRed:0.95 green:0.95 blue:0.95 alpha:1.0)

        setDisplaysWhenScreenProfileChanges_(true)

        setReleasedWhenClosed_(true)

        makeKeyAndOrderFront_(me)

    end tell

    --

    if moveCenter then

        set theScreen to current application's class "NSScreen"'s screens()

        set {windowCenterX, winsowCenterY} to {windowX + (windowW / 2), windowY + (windowH / 2)}

        repeat with screenNo from 1 to (count of theScreen)

            set {{screenX1, screenY1}, {screenWidth, screenHeight}} to (item screenNo of theScreen)'s frame()

            set {screenX2, screenY2} to {screenX1 + screenWidth, screenY1 + screenHeight}

            if (windowCenterX > screenX1) and (windowCenterX < screenX2) and (winsowCenterY > screenY1) and (winsowCenterY < screenY2) then

                set originX to screenX1 + (screenWidth / 2) - (windowW / 2)

                set originY to screenY1 + (screenHeight / 2) - (windowH / 2)

                (aWindow's setFrameOrigin:(current application's NSMakePoint(originX, originY)))

                exit repeat

            end if

        end repeat

    end if

    --

    return aWindow

end makeNewWindow

 

(* 各オブジェクトの配置 *)

on makeObject()

    set mainView to theWindow's contentView

    set theWindowFrame to mainView's frame()

    set {{windowX, windowY}, {windowWidth, windowHeight}} to theWindowFrame

    set minXMargin to (current application's NSViewMinXMargin) as integer

    set maxXMargin to (current application's NSViewMaxXMargin) as integer

    set minYMargin to (current application's NSViewMinYMargin) as integer

    set maxYMargin to (current application's NSViewMaxYMargin) as integer

    set widthSizable to (current application's NSViewWidthSizable) as integer

    set heightSizable to (current application's NSViewHeightSizable) as integer

    set freeSizeWidthHeight to widthSizable + heightSizable

    set fixedBottomFreeLeftAndRight to maxYMargin + minXMargin + maxXMargin --  下を固定して左右センターに

    set positionFreeFixedSize to minXMargin + maxXMargin + minYMargin + maxYMargin -- 天地左右のサイズを柔軟に

    --

    try

        (* webView *)

        set theRect to current application's NSMakeRect(0, -700, 600, 800)

        set webView1 to current application's class "WKWebView"'s alloc()'s initWithFrame:theRect

        theWindow's contentView()'s addSubview:webView1

        webView1's setAlphaValue:0.5

        set locationUrl to "https://translate.google.co.jp"

        set aUrl to current application's class "NSURL"'s URLWithString:locationUrl

        set aRequest to current application's class "NSURLRequest"'s requestWithURL:aUrl

        webView1's loadRequest:aRequest

        

        (* textView *)

        set {x, y, w, h} to {windowX, windowY, windowWidth, windowHeight}

        set theRect to current application's NSMakeRect(x, y, w, h)

        set scrollview1 to current application's class "NSScrollView"'s alloc()'s initWithFrame:theRect

        tell scrollview1

            setBorderType_(0)

            setHasVerticalScroller_(true)

            setHasHorizontalScroller_(false)

            setAutoresizingMask_(freeSizeWidthHeight)

        end tell

        set textView1 to current application's class "NSTextView"'s alloc()'s initWithFrame:theRect

        tell textView1

            setMinSize_(current application's NSMakeSize(0, h))

            setMaxSize_(current application's NSMakeSize(10000, 10000))

            setVerticallyResizable_(true)

            setHorizontallyResizable_(false)

            setAutoresizingMask_(widthSizable)

            textContainer()'s setContainerSize:(current application's NSMakeSize(w - 20, 10000))

            textView1's setString:""

        end tell

        textView1's textContainer's setWidthTracksTextView:true

        scrollview1's setDocumentView:textView1

        theWindow's contentView()'s addSubview:scrollview1

        (* ProgressIndicator *)

        set theRect to current application's NSMakeRect((w / 2) - 15, (h / 2) - 15, 30, 30)

        set progressIndicator1 to current application's class "NSProgressIndicator"'s alloc()'s initWithFrame:theRect

        tell progressIndicator1

            setDoubleValue_(0.5)

            setMinValue_(0.0)

            setMaxValue_(1.0)

            setStyle_(1)

            setIndeterminate_(true)

            stopAnimation_(true)

            setAutoresizingMask_(positionFreeFixedSize)

            setAlphaValue_(0.0)

        end tell

        theWindow's contentView()'s addSubview:progressIndicator1

        (* button *)

        set theRect to current application's NSMakeRect(270, 0, 120, 24)

        set button1 to current application's class "NSButton"'s alloc()'s initWithFrame:theRect

        tell button1

            setBezelStyle_(1)

            setButtonType_(0)

            setTitle_("調べる")

            setTarget_(me)

            setAction_("action1:")

            setAutoresizingMask_(fixedBottomFreeLeftAndRight)

        end tell

        theWindow's contentView()'s addSubview:button1

    on error errText

        log errText

    end try

end makeObject

 

on action1:sender

    textView1's setString:"(翻訳開始)"

    delay 0.1

    set ans to my theTranslation()

    textView1's setString:ans

end action1:

 

on theTranslation()

    if application "Safari" is not running then return "Error : Safariが起動していません"

    

    set the clipboard to ""

    activate application "Safari"

    delay 0.5

    tell application "System Events"

        tell process "Safari"

            keystroke "c" using command down

            delay 0.1

            keystroke "c" using command down

            delay 0.1

        end tell

    end tell

    activate application currentAppName

    try

        set inputText to text of (the clipboard)

        if inputText = "" then return "Error : 選択されたテキストがありません"

    on error

        return "Error : テキストの読み取りができませんでした"

    end try

    

    progressIndicator1's startAnimation:true

    progressIndicator1's setAlphaValue:1.0

    set logText to "--- 翻訳中の元の文章 ---" & return & inputText & return

    textView1's setString:(logText)

    set appName to name of (current application)

    set outputData to ""

    repeat with oneLine in (paragraphs of inputText)

        set oneLine to oneLine as string

        set f to true

        if (count of oneLine) > 0 then

            repeat with oneChara in (characters of oneLine)

                set aId to id of (oneChara as string)

                if (aId ≠ 9) and (aId ≠ 32) then

                    set f to false

                    exit repeat

                end if

            end repeat

        end if

        if f = true then

            set outputData to outputData & oneLine & return

        else

            tell application "System Events"

                tell process appName

                    try

                        set oldText to name of static text 1 of group 1 of combo box 1 ¬

                            of group 4 of UI element 1 of scroll area 1 of group 1 of group 1 of window windowTitle

                    on error

                        set oldText to "No Data"

                    end try

                end tell

            end tell

            set urlText to my keywordDelimiter(oneLine)

            set locationUrl to "https://translate.google.co.jp/?hl=ja&sl=en&tl=ja&text=" & urlText & "&op=translate"

            set aUrl to (current application's class "NSURL"'s URLWithString:locationUrl)

            set aRequest to (current application's class "NSURLRequest"'s requestWithURL:aUrl)

            (webView1's loadRequest:aRequest)

            tell application "System Events"

                tell process appName

                    repeat 20 times

                        delay 0.2

                        try

                            set uiChack to name of static text 1 of UI element 1 of group 12 of group 4 ¬

                                of UI element 1 of scroll area 1 of group 1 of group 1 of window windowTitle

                            exit repeat

                        end try

                    end repeat

                    repeat 20 times

                        delay 0.2

                        try

                            set newText to name of static text 1 of group 1 of combo box 1 ¬

                                of group 4 of UI element 1 of scroll area 1 of group 1 of group 1 of window windowTitle

                            if newText ≠ oldText then

                                set aText to name of every UI element of group 1 of group 12 of group 4 ¬

                                    of UI element 1 of scroll area 1 of group 1 of group 1 of window windowTitle

                                set outputData to outputData & aText & return

                                exit repeat

                            end if

                        end try

                    end repeat

                end tell

            end tell

        end if

    end repeat

    set outputData to text 1 thru -2 of outputData

    progressIndicator1's stopAnimation:true

    progressIndicator1's setAlphaValue:0.0

    return outputData

end theTranslation

 

on keywordDelimiter(aText)

    set aText to aText as string

    if (aText contains (character id 37)) then -- %

        set aText to my setDelimiter(aText, (character id 37), "%25")

    end if

    if (aText contains (character id 34)) then -- ダブルクオート

        set aText to my setDelimiter(aText, (character id 34), "%22")

    end if

    if (aText contains (character id 92)) then -- バックスラッシュ

        set aText to my setDelimiter(aText, (character id 92), "%5C")

    end if

    if (aText contains (ASCII character 9)) or (aText contains (ASCII character 32)) then -- タブ&空白

        set aText to my setDelimiter(aText, {ASCII character 9, ASCII character 32}, "%20")

    end if

    set keyword to "#    %23

$    %24

&    %26

'    %27

+    %2B

,    %2C

/    %2F

:    %3A

;    %3B

<    %3C

=    %3D

>    %3E

?    %3F

@    %40

[    %5B

]    %5D

^    %5E

`    %60

{    %7B

|    %7C

}    %7D"

    repeat with obj in (paragraphs of keyword)

        set obj to obj as string

        set key1 to character 1 of obj

        set key2 to text 3 thru -1 of obj

        if aText contains key1 then

            set aText to my setDelimiter(aText, key1, key2)

        end if

    end repeat

    return aText

end keywordDelimiter

 

on setDelimiter(textItem, oldText, newText)

    set textItem to textItem as string

    set lastDelimit to AppleScript's text item delimiters

    set AppleScript's text item delimiters to oldText

    set obj to every text item of textItem

    set AppleScript's text item delimiters to newText

    set textItem to obj as string

    set AppleScript's text item delimiters to lastDelimit

    return textItem

end setDelimiter

 

on windowShouldClose:sender

    set closeFlg to true

end windowShouldClose:

 

on closeWin:aWindow

    aWindow's orderOut:me

    if currentAppName ≠ "Script Editor" then quit me

end closeWin:

 

on quit

    continue quit

end quit

 

 


nice!(0)  コメント(2) 

nice! 0

コメント 2

aaaa

そんな回りくどいことしなくてもbookmarkletでできますよ
https://jn64.github.io/bookmarklets/google-translate/
by aaaa (2022-01-30 06:13) 

かのつ

なかなか便利そうな機能の情報をありがとうございます。
常時、英語から日本語翻訳の項目に変更したら、なかなか便利そうですね。
ですが、翻訳をしたテキストを Applescript でここから拡張した利用をしたいという考えがありましたので、今回は無理をしました。
ただ、Safariで『選択された部分を取り込む』という部分を、SystemEventではなく『getSelection()』を使うことで、スマートにできるかもしれないという事は考えてもよさそうですね。

set theCode to "なんらかのコード"
run script (theCode) in "Javascript"

のような書き方を考えてみたいと思います。

貴重な情報をありがとうございました。
by かのつ (2022-01-30 09:09) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。