/Applicationsフォルダ以下のすべてのアプリケーションのバンドル中のstringsファイル中を走査して、指定の言語における指定キーワード(”Quit”など)の指定言語におけるローカライズした文字列を取得するAppleScriptです。
自分でアプリケーションのローカライズを行う際に、既存のmacOS用のアプリケーションのバンドル内にあるstringsファイルを参考にするためのツールです。
もともとは、Shane StanleyがLate Night Softwareのフォーラムに投稿したプログラムですが、自分もいろいろ試していたように、アプリケーション側のローカライズのされ方(言語別のフォルダ名の名称指定)に「ゆらぎ」があるため、そのあたりは総当たりでテストしているようです。
オリジナルではデータが存在しない場合にはエラーにしていましたが、このようにすべてのアプリケーションに対してループで処理を行うような場合にはエラーで止まっては困るので、そのあたりを書き換えています。
/Applicationsフォルダ以下のSpotlight検索によるアプリケーションの取得についてはMetadata Libを用いています。自分の開発環境で1キーワード(x バンドル内のすべてのstringsファイル x すべてのアプリケーション)の問い合わせに3.6〜5秒程度かかっています。HDDの環境ではこれより大幅に長くかかるはずなので、ちょっと考えたくありません。
また、Stringsファイルで供給されるローカライズ情報については探すことができますが、OS側が強制的に供給するWindowメニューなどの内容については本Scriptで調査することはできません。ねんのため。
AppleScript名:指定Bundle IDのstringsファイル中における指定タイトルの指定言語のローカライズ版を求める.scptd |
— – Created by: Takaaki Naganoya – Created on: 2020/02/24 — – Copyright © 2020 Piyomaru Software, All Rights Reserved — use AppleScript version "2.5" — El Capitan (10.11) or later use framework "Foundation" use framework "AppKit" use scripting additions use mdLib : script "Metadata Lib" version "2.0.0" –https://macosxautomation.com/applescript/apps/Script_Libs.html property NSWorkspace : a reference to current application’s NSWorkspace set targStr to "Performance" set origLang to "en" –From set targLang to "hu" –To set tList to {} set origPath to POSIX path of (path to applications folder) set aResList to mdLib’s searchFolders:{origPath} searchString:("kMDItemContentType == %@") searchArgs:{"com.apple.application-bundle"} repeat with i in aResList set aTitleRes to getAppGUITitleWithCurrentLocale(i, targStr, origLang, targLang) of me if aTitleRes is not equal to missing value and aTitleRes is not in tList then set the end of tList to aTitleRes end if end repeat return tList –> {"Előadás", "Teljesítmény"} –指定Bundle IDのstringsファイル中における指定タイトルの現在実行中のロケールのローカライズ版を求める on getAppGUITitleWithCurrentLocale(aPath, aTargetTitle, origLang, targLang) return my localizedStringFor:aTargetTitle inBundle:aPath destLang:targLang sourceLang:origLang end getAppGUITitleWithCurrentLocale –Bundle IDからアプリケーションのPathを返す on retAppAbusolutePathFromBundleID(aBundleID) set appPath to NSWorkspace’s sharedWorkspace()’s absolutePathForAppBundleWithIdentifier:aBundleID if appPath = missing value then return false return appPath as string end retAppAbusolutePathFromBundleID –Original By Shane Stanley@Late Night Software –Modified By Takaaki Naganoya –https://forum.latenightsw.com/t/localizing-gui-scripts/2246 on localizedStringFor:baseString inBundle:aPOSIX destLang:destLangCode sourceLang:sourceLangCode set anURL to current application’s |NSURL|’s fileURLWithPath:aPOSIX set theBundle to current application’s NSBundle’s bundleWithURL:anURL if theBundle = missing value then return missing value set sourceLangString to current application’s NSString’s stringWithString:sourceLangCode set destLangString to current application’s NSString’s stringWithString:destLangCode — get source strings values set theURLs to theBundle’s URLsForResourcesWithExtension:"strings" subdirectory:"" localization:sourceLangString if theURLs = missing value then return missing value if theURLs’s |count|() < 2 and (sourceLangString’s containsString:"_") as boolean then — try stripping off country-specific part set sourceLangString to sourceLangString’s substringToIndex:2 set theURLs to theBundle’s URLsForResourcesWithExtension:"strings" subdirectory:"" localization:sourceLangString end if if theURLs’s |count|() < 2 then — try long name for localization set sourceLangString to (current application’s NSLocale’s localeWithLocaleIdentifier:"en")’s localizedStringForLocaleIdentifier:sourceLangString set theURLs to theBundle’s URLsForResourcesWithExtension:"strings" subdirectory:"" localization:sourceLangString end if if theURLs’s |count|() < 2 then return missing value –error "No " & sourceLangCode & " localization found" repeat with sourceURL in theURLs — skip unlocalized file if not (sourceURL’s URLByDeletingLastPathComponent()’s lastPathComponent()’s isEqualToString:"Resources") as boolean then set theData to (current application’s NSData’s alloc()’s initWithContentsOfURL:sourceURL) if theData is missing value then return — error "No " & sourceLangCode & " localization found" set sourceDict to (current application’s NSPropertyListSerialization’s propertyListWithData:theData options:0 format:0 |error|:(missing value)) if sourceDict = missing value then return missing value set theKey to (sourceDict’s allKeysForObject:baseString)’s firstObject() if theKey is not missing value then set stringsFileName to sourceURL’s lastPathComponent()’s stringByDeletingPathExtension() set localURL to (theBundle’s URLForResource:stringsFileName withExtension:"strings" subdirectory:"" localization:destLangString) if localURL is missing value and (destLangString’s containsString:"_") as boolean then — try stripping off country-specific part set destLangString to (destLangString’s substringToIndex:2) set localURL to (theBundle’s URLForResource:stringsFileName withExtension:"strings" subdirectory:"" localization:destLangString) end if if localURL is missing value then — try long name for localization set destLangString to ((current application’s NSLocale’s localeWithLocaleIdentifier:"en")’s localizedStringForLocaleIdentifier:destLangString) set localURL to (theBundle’s URLForResource:stringsFileName withExtension:"strings" subdirectory:"" localization:destLangString) end if if localURL is missing value then return missing value — "No " & destLangCode & " localization found" set theData to (current application’s NSData’s alloc()’s initWithContentsOfURL:localURL) if theData is missing value then missing value — "No " & destLangCode & " localization found" set destDict to (current application’s NSPropertyListSerialization’s propertyListWithData:theData options:0 format:0 |error|:(missing value)) set destValue to (destDict’s objectForKey:theKey) –if destValue is not missing value then return {destValue as text, stringsFileName as text} if destValue is not missing value then return destValue as text return missing value end if end if end repeat return missing value end localizedStringFor:inBundle:destLang:sourceLang: |