辞書を引く.appを作ってみた
ルビについて調べていたら、ルビとは無関係だが、辞書ということで、次のようなページにいきあたった。
http://sakito.jp/mac/dictionary.html#url-scheme
http://macscripter.net/viewtopic.php?id=26661
「辞書.app」って使ったことがなかった。
コピーした文字列を辞書で調べるってアプリ、上の情報からできるなっと思って作ってみた。
調べたい言葉をコピーして、アプリを実行すると、ダイアログにこんな感じで表示します。
メインのapplesript部分は、
--* 自身のバンドル・パスを得る
set self to path to me
set scriptBundlePath to (path to resource "Scripts" in bundle self) as Unicode text
set iconPath to (path to resource "applet.icns" in bundle self) as Unicode text
--* スクリプトファイルのフルパスを作成する
set pyScriptFile to scriptBundlePath & "dict2.py"
--* Unix用のパスに変換する
set pyscriptpath to quoted form of (POSIX path of pyScriptFile)
--* paste値を変数にセット
set searchword to do shell script "pbpaste"
--* shell コマンド
set command to "/usr/bin/python2.5 " & pyscriptpath & " " & quoted form of searchword
--* コマンド実行
set theResult to do shell script command
--* 表示
display dialog theResult with title searchword buttons {"Close"} default button {"Close"} with icon file iconPath
Pythonスクリプトは、
#!/usr/bin/python2.5
import sys
from DictionaryServices import *
def main():
try:
searchword = sys.argv[1].decode('utf-8')
except IndexError:
errmsg = 'You did not enter any terms to look up in the Dictionary.'
print errmsg
sys.exit()
wordrange = (0, len(searchword))
dictresult = DCSCopyTextDefinition(None, searchword, wordrange)
if not dictresult:
errmsg = "'%s' not found in Dictionary." % (searchword)
print errmsg.encode('utf-8')
else:
print dictresult.encode('utf-8')
if __name__ == '__main__':
main()
弊社ダウンロードサイトから取得できます。
https://www.web-cte.co.jp/tools/
備忘録:ミリ秒を取得する
on getMilSecond()
set theCmnd to "perl -e 'use Time::HiRes;my ($wtime,$msec) = split(/\\./ , Time::HiRes::time);my @t = localtime($wtime);printf(\"%04d%02d%02d%02d%02d%02d.%03d\",$t[5]+1900,$t[4]+1,$t[3],$t[2],$t[1],$t[0],($msec/100));'"
return do shell script theCmnd
end getMilSecond
イラストレータで株価チャート作成
鎌田です。ご無沙汰しております。
ここしばらく、Excelを入稿データとした案件が3つ程続いています。それをご紹介しようと思います。
今日ご紹介するのは、イラストレータでの株価チャート作成です。
株価チャート(ロウソク足)、移動平均線、売買高、信用取引残高です。
入稿データのExcelの値を拾って、イラストレータの座標値に変換してプロットしていきます。
座標値を計算して「グラフを書く」という点では難易度は高いものでははありません。
しかし、制作にあたって労したところは次の3点になります。
1. 「レイアウトが確定していない時点で設計を開始する」
受注させていただいた時点では、グラフを書く領域のサイズが確定していません。
サイズ変更に柔軟に対応できる必要があります。
2. 「株価の目盛単位は原則100円。10円未満の端数をださない。
かつ、グラフ作成領域に合わせて、できるだけ大きくグラフを作成する」
株価から最大値最小値は求められますが、それを3〜5分割して株価の目盛を作成します。
そのときに、10円以下の端数を出してはならず、区切りのよい目盛にする必要があります。
分割数、目盛の作成ルールはなく、これらについては全て制作側で決めないといけません。
3. 「信用取引残高は、白地と墨アミの二つの折れ線グラフを重ねるが…」
墨アミのグラフを背後に、白地のグラフを前面に配置します。
墨アミの数値が大きく、白地の数値が小さい場合、墨アミのグラフは表示されます。
しかし、逆の場合は、白地の背後に墨アミありますので、墨アミのグラフが見えなくなります。
この場合には、墨アミの折線グラフの「線部」のみを前面に表示し、アミを表示させません。
1について
グラフ領域のサイズと原点の持ち方を工夫することで、対応できました。
2について
これは大変苦労しました。分割数、目盛のルールはないので、グラフを作成してみての判断となります。
日経会社情報が参考になりました。
結局のところ、株価範囲が何円〜何円の場合、分割数幾つで、目盛幾つというテーブルを作成しました。
グラフを作成させ、できるだけ大きいグラフとなるよう、値を調整していくことを繰り返しました。
3について
このようなグラフを作成する場合どうしたら良いか?
イラストレータの使い手に相談したところ「パスファインダー」を使用すれば良いことが分かりました。
しかし、「パスファインダー」はスクリプトで制御できません。
ネットでググっていくと、次の情報を見つけました。
“Can javascript execute pathfinder commands?”
http://forums.adobe.com/thread/433284
これに基づいてスクリプトを作成し、無事動作させることができました。
時間がかかっているのは、信用残高の読込み部分です。年52週の値を10年分、売買いでその2倍、約1000行を読込んでいるためです。株価、売買高は、12ヶ月の10年分、120行ですので、瞬間で終わります。
他のエクセル入稿の案件については、その制作が終わったタイミングで後日、紹介できればと思っています。
よろしくお願いします。
【InDesignCS4】【Excel2008】スクリプト2件ご紹介
InDesignCS4:全てのリンクをLinksフォルダの同名のファイルに置換
InDesignのリンク画像は、絶対パスで管理されているらしく、親フォルダの名称を変更したり、別フォルダに移動したりすると、次にドキュメントを開いたときにリンクが切れてしまっている場合が多いです。
リンクパレットから再リンクボタンをoptionクリックしてフォルダを選択し……とすると再リンクはできるのですが、ドキュメントの数が多いとそれも面倒なのでこのスクリプトを作成しました。
ドキュメントがパッケージされており、最新の画像データがドキュメントと同一階層の「Links」フォルダにあることを前提にしています。
ドキュメントを開き、このスクリプトを実行すると、全てのリンクをLinksフォルダの同名のファイルに再リンクします。
スクリプト名:全てのリンクをLinksフォルダの同名のファイルに置換.scpt |
tell application “Adobe InDesign CS4″ tell document 1 set myPath to file path as Unicode text set linkPath to myPath & “Links:” as Unicode text set allLinks to object reference of every link repeat with aLink in allLinks tell aLink set filePath to file path as Unicode text set itemName to item -1 of textToList(filePath, “:”) of me set newLink to linkPath & itemName as Unicode text set newLink to newLink as alias relink aLink to newLink end tell end repeat end tell end tell – —————————————————––テキストをデリミタでバラしてリストにして返すルーチン –—————————————————– on textToList(aText, aDelim) set retList to {} set oldDelim to AppleScript‘s text item delimiters set AppleScript‘s text item delimiters to aDelim set retList to every text item of aText set AppleScript‘s text item delimiters to oldDelim return retList end textToList |
▼新規書類にペースト ▼カーソル位置にペースト ▼ドキュメント末尾にペースト |
Excel2008:タブ区切りテキストを全列文字列フォーマットで開いてxlsで保存
UTF16BEのテキストを前提にしています。スクリプトを実行するとダイアログでファイルの選択を求められます。複数選択可能です。
選択したファイルを全て、全列文字列フォーマットで開いて、テキストファイルと同じ場所にxls形式で保存します。saveAsXLSX内の、「–xlsx形式」のコメントがついている行をアンコメントするとxlsx形式で保存します。その際は「–xls形式」のコメントがついている行はコメントアウトしてください。
スクリプト名:タブ区切りテキストを全列文字列フォーマットで開いてxlsで保存.scpt |
set tgtFiles to choose file with prompt “Excel形式で保存するテキストファイルを複数選択” with multiple selections allowed
repeat with tgtFile in tgtFilesset tgtFile to tgtFile as Unicode text openTabTxt(tgtFile) of openTabTxtKit –タブ区切りテキストを全列文字列フォーマットで開く saveAsXLSX(tgtFile) of saveAsXLSXKit –active workbookを指定のフォルダに保存 end repeat – —————————————————––タブ区切りテキストを全列文字列フォーマットで開く –—————————————————– script openTabTxtKit –タブ区切りテキストを全列文字列フォーマットで開く on openTabTxt(tgtFile) tell application “Microsoft Excel” set aDelim to tab set aFormat to text format set cntLabel to getCountLabel(tgtFile, aDelim) of me –テキストの一行目から,列見出しの数を取得 set fieldInfo to getFieldInfo(cntLabel, aFormat) of me –field infoを取得(全列text format) (* open text fileのパラメータ: data type delimited:区切り記号付き text qualifier text qualifier double quote:文字列の引用府=ダブルクオーテーション tab true:区切り文字=タブ *) open text file filename tgtFile data type delimited text qualifier text qualifier double quote field info fieldInfo with tab end tell end openTabTxt –field infoを取得(全列統一限定) on getFieldInfo(cntLabel, aFormat) tell application “Microsoft Excel” set fieldInfo to {} repeat with i from 1 to cntLabel set the end of fieldInfo to {i, aFormat} end repeat return fieldInfo end tell end getFieldInfo –テキストの一行目から,列見出しの数を取得 on getCountLabel(tgtFile, aDelim) set tgtFile to tgtFile as alias set inTxt to readFile(tgtFile) of me set aLabel to paragraph 1 of inTxt set aLabelList to textToList(aLabel, aDelim) of me set cntLabel to count of aLabelList return cntLabel end getCountLabel –テキストファイル読み込み(UTF16限定) on readFile(tgtFile) set aTxt to read tgtFile as Unicode text set aTxt to aTxt as Unicode text log aTxt return aTxt end readFile –—————————————————– –テキストをデリミタでバラしてリストにして返すルーチン –—————————————————– on textToList(aText, aDelim) set retList to {} set oldDelim to AppleScript‘s text item delimiters set AppleScript‘s text item delimiters to aDelim set retList to every text item of aText set AppleScript‘s text item delimiters to oldDelim return retList end textToList end script – —————————————————––active workbookを指定のフォルダに保存 –—————————————————– script saveAsXLSXKit on saveAsXLSX(tgtFile) set tgtFol to getParentFol(tgtFile) of me –親フォルダを取得 tell application “Microsoft Excel” tell active workbook –ファイル名から保存名を取得 tell active sheet set aName to name –set aName to replaceText(aName, “.txt”, “.xlsx”) of me –xlsx形式 set aName to replaceText(aName, “.txt”, “.xls”) of me –xls形式 set saveTo to tgtFol & aName as Unicode text end tell –xlsx形式で別名保存 –save as active sheet filename saveTo file format workbook normal file format –xlsx形式 save as active sheet filename saveTo file format Excel98to2004 file format –xls形式 end tell close active workbook end tell end saveAsXLSX on getParentFol(tgtFile) set tgtFile to tgtFile as alias tell application “Finder” set tgtFol to parent of tgtFile set tgtFol to tgtFol as Unicode text end tell return tgtFol end getParentFol –—————————————————– –文字置換ルーチン –—————————————————– on replaceText(origText, targetText, changeValue) set delim to AppleScript‘s text item delimiters set AppleScript‘s text item delimiters to targetText set str1 to text items of origText set AppleScript‘s text item delimiters to changeValue set str2 to str1 as string set AppleScript‘s text item delimiters to delim return str2 end replaceText end script |
▼新規書類にペースト ▼カーソル位置にペースト ▼ドキュメント末尾にペースト |
InDesigh JavaScriptのプログレスバーをAppleScriptで呼び出す
InDesignのSDKに、ScriptUIの箇所で、プログレスバーのJavaScriptサンプルがあります。これをAppleScriptでルーチン化してみました。下記の参考スクリプトは新規ドキュメントを作り、100ページ新規追加していきます。
こちらのサンプルムービーで、処理状況をご覧いただけます。
参考スクリプト
tell application “Adobe InDesign CS4″
activate
my doProgressBar() –スクリプトバー初期化
–ドキュメント作成
set myDocument to make document
my doProgressBarOpen(100) –スクリプトバーOpen
repeat with myCounter from 1 to 100
my doProgressBarRoop(myCounter) –スクリプトバーRoop
–ページ追加
tell myDocument to make page
end repeat
my doProgressBarClose() –スクリプトバーClose
delay 1
–保存しないで閉じる
close myDocument saving no
end tell
on doProgressBar()
set myJavaScript to ”
#targetengine \”session\”;
var myMaximumValue = 300;
var myProgressBarWidth = 300;
var myIncrement = myMaximumValue/myProgressBarWidth;
myCreateProgressPanel(myMaximumValue, myProgressBarWidth);
function myCreateProgressPanel(myMaximumValue, myProgressBarWidth){
myProgressPanel = new Window(‘window’, ‘myProgressBar’);
with(myProgressPanel){
myProgressPanel.myProgressBar = add(‘progressbar’, [12, 12,myProgressBarWidth, 24], 0, myMaximumValue);
}
}”
my doJavaScript(myJavaScript)
end doProgressBar
on doProgressBarOpen(maxValue)
set myJavaScript to ”
#targetengine \”session\”;
myCreateProgressPanel(” & maxValue & “, 300);
myProgressPanel.show();”
my doJavaScript(myJavaScript)
end doProgressBarOpen
on doProgressBarRoop(myCounter)
set myJavaScript to ”
#targetengine \”session\”;
myProgressPanel.myProgressBar.value = ” & myCounter & “/myIncrement;”
my doJavaScript(myJavaScript)
end doProgressBarRoop
on doProgressBarClose()
set myJavaScript to ”
#targetengine \”session\”;
myProgressPanel.myProgressBar.value = 0;
myProgressPanel.hide();”
my doJavaScript(myJavaScript)
end doProgressBarClose
on doJavaScript(theScript)
tell application “Adobe InDesign CS4″
do script theScript language javascript
end tell
end doJavaScript
【InDesignCS4】スクリプト2件ご紹介
Inomotoです.今日は,InDesign CS4向けのAppleScriptを2つ紹介します.
段落のtext style rangeを正しく取得
InDesignCS4での不具合を発見しました.AppleScriptで,段落内のtext style rangeを取得しようとすると,次の段落の頭の方まで段落内と認識されてしまうという現象です.
text style rangeのparentを再起的に取得していくと,paragraphではくstoryに行き着くので,おそらくそのあたりが関係しているのではないかと思われます.
正しく段落内のみのtext style rangeを取得するようスクリプトを作成しました.paragraphと,text frame内のtext 1のobject referenceを渡すとtext style rangeのリストを返します.
あまり多くの条件でテストしていないので,エラーが出たりするケースがあると思います.そのときはコメントなどいただけると幸いです.
スクリプト名:段落のtext style rangeを正しく取得.scpt |
tell application “Adobe InDesign CS4″ activate tell document 1 tell text frame 1 set tgtTxt to object reference of text 1 –text frame内のtext全て set allParas to object reference of every paragraph repeat with aPara in allParas set tStyleRanges to getStyleRanges(aPara, tgtTxt) of me repeat with aRange in tStyleRanges select aRange delay 0.5 end repeat display dialog “paragraph end” giving up after 1 end repeat end tell end tell end tell –段落のtext style rangeを正しく取得 |
▼新規書類にペースト ▼カーソル位置にペースト ▼ドキュメント末尾にペースト |
ライブラリからアンカーオブジェクトを配置
あらかじめライブラリにassetを登録しておき,このスクリプトを実行すると,指定の場所にアンカーオブジェクトとしてassetを配置します.
このサンプルでは1ページ目の最前面のtext frameの一番始めのinsertion pointに配置します.
スクリプト名:ライブラリからアンカーオブジェクトを配置.scpt |
set assetName to “xxxx” –ここにassetの名前を入れる
tell application “Adobe InDesign CS4″ –————————————– –————————————– |
▼新規書類にペースト ▼カーソル位置にペースト ▼ドキュメント末尾にペースト |
グラフとの格闘
先日、グラフを大量に作成しなければならない、という仕事が舞い込んできました。
なんでも、Illustrator上で折れ線グラフやら棒グラフやらを山ほど作らなくてはならないのだとか。
メインの担当者と話をしたところ、プログラムからExcelのデータをIllustratorのテンプレートに流し込むところまでお願いしたいとのこと。さっそく、自動処理をどの程度できるのか調査に入りました。
調べたところ、Illustratorのグラフ機能はAppleScriptによる自動処理に対応しておらず、一筋縄ではいかない雰囲気です。
そこで、メニューや画面を無理やりコントロールするやり方(GUI Scripting)で、強引にデータを入れることに成功。あくまで「無理やり」なので、処理の途中に適度に「待ち時間」を入れて安全第一で自動処理。
さらに、
グラフ上のマーカー図形を変更してみたり
一定のしきい値を下回る場合にはグラフから線を引き出して外周部に数字を配置してみたり
グラフの値の増減傾向を考慮しつつ値のデータを折れ線グラフと重ならないように配置してみたり
してみたところ、当初は必要とされていた手作業を大幅に削減!!!
それでも、メイン担当者はそれなりに大変な作業をこなしていたので、プログラムを用意しなかったらトンでもないことになっていたことが想像されました。
お客様から求められたアウトプットが、Illustrator CS3の書類ということだったので、Illustratorを制御するのはまちがったやりかたではなかったのですが……世の中にはもう少し楽ができるような解決策があってもよさそうなものです。
こうした用途には、DeltaGraphを外部からコントロールするとうまく行きそうですが……調べてみると、文字組みのクオリティがいまひとつで、コントロールできる範囲が大味なため、「かゆいところに手が届く」ような処理は、やはりIllustrator上でこまかい座標計算を行ってやるしかなさそうです。
AppleScript ミニツール2つご紹介
Inomotoです。初投稿です。
今回は私が業務でよく使っているAppleScriptを二つ紹介します。
1 個別にZip.app
OSXになってから、Finderからcontrol+クリックでファイルをZip圧縮できるようになりました。
ただ、この機能では複数のファイルを選択したときに、まとめて1つのファイルに圧縮されてしまいます。
ときにはたくさんのファイルを一つ一つ個別に圧縮したい場合もありますので、そんなときに役に立つのではと思います。
[applescript]
—————————————
–Drag&Dropしたアイテムを一つずつ処理
—————————————
on open inItems
with timeout of (1 * 60 * 60 * 12) seconds
repeat with tgtItem in inItems
tell application "Finder"
set tgtItem to tgtItem as alias
zipIt(tgtItem) of me
end tell
end repeat
end timeout
end open
—————————————
–エイリアスを渡すとそのアイテムをZIP圧縮するルーチン
—————————————
on zipIt(tgtItem)
tell application "Finder"
–処理対象の名前を取得
set tgtName to name of tgtItem as Unicode text
set tgtName to quoted form of tgtName
–カレントディレクトリを取得
set tgtParent to parent of tgtItem as alias
set tgtParent to quoted form of POSIX path of tgtParent
set zipName to tgtName & ".zip" –zip名
–フォルダの中身を全て階層的に圧縮
do shell script "cd " & tgtParent & " ; " & "zip -r " & zipName & " " & tgtName
end tell
end zipIt
[/applescript]
2 Dropしたファイルを指定したプログラムで処理.app
お客様からいただいたテキストファイルを使用する際、そのまま何もせずに使えることは稀です。大概の場合は何らかの処理が必要になります。
私はそのようなときには大概perlを用いて処理するのですが、perlを使いたい場合はターミナルを開いてコマンドラインから入力しなければならず、私のような面倒くさがりにはちょっと敷居が高い作業です。
このスクリプトをアプリケーション形式で保存すると下記の2手順でperl処理が行えます。
・処理したいファイルをまとめてDrag&Dropする
・どのプログラムで処理するかダイアログで指定
procFileの『do shell script “perl “』の『perl 』の部分を書き換えるとrubyやPHPなどでもできるのかなぁと思っていますが、まだ試していません。
[applescript]
on open inFiles
tell application "Finder"
set progSource to choose file with prompt "プログラムのファイルを選択"
end tell
repeat with tgtFile in inFiles
procFile(progSource, tgtFile) of me
end repeat
activate
display dialog "END" giving up after 2
end open
——————————————————-
–プロセスを呼び出して処理
——————————————————-
on procFile(progSource, tgtFile)
set progSource to quoted form of POSIX path of progSource
set tgtFile to quoted form of POSIX path of tgtFile
do shell script "perl " & progSource & " " & tgtFile
end procFile
[/applescript]
AppleScript 共有フォルダのリストを取得する
AppleScriptで共有フォルダのリストを取得できるだろうと思っていたが簡単ではなかった。
10.6だとフォルダを選び「情報を見る」と、共有フォルダのチェックボックスがある。そのチェックの有無を取得できると思っていたが、そんな属性はなかった。
いろいろ〜とググリ回って、できたスクリプトがこれ。
[applescript]
set cmd to "dscl . list /SharePoints"
set sharedTxt to do shell script cmd
set sharedList to {}
repeat with pp from 1 to (count paragraph of sharedTxt)
set spName to paragraph pp of sharedTxt
set cmd to "dscl . read /SharePoints/" & spName & " directory_path"
try
set thePathTxt to (do shell script cmd)
set len to (length of "dsAttrTypeNative:directory_path: ") + 1
set sharedList to sharedList & ((characters len thru -1 of thePathTxt) as Unicode text)
end try
end repeat
[/applescript]
AppleScript 環境による挙動の違う例
AppleScriptでツールを作成、配布した経験のある方なら、自分の環境で動作するが他の人の環境で動作しない経験をお持ちではないかと思います。
昨日もあるツールが10.4.11と10.6.6で異なる挙動をしました。ソースは同一です。いろいろと調べるとこんな原因にたどり着きました。
set X to “”
set AppleScript’s text item delimiters to space
every text item of X
10.4.11, 10.5.8 では {“”} と空文字列となりましたが、10.6.6では{}とヌルとなりました。text itemをcountすれば当然1と0と違いがでます。困ったもんです。
ただし、これはOSによる違いではなく、機械によって戻り値が異なるようです。要注意です。
記事投稿日
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
« 9月 | ||||||
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 |