Apple の脅威の通知と金銭目当てのスパイウェアへの対策について

しばらく返答が寄せられていないようです。 再度ディスカッションを開始するには、新たに質問してください。

Apple Scriptによる選択範囲の文字カウント(改行、スペース抜き)について

初めて質問させて頂きます。


文書作成でテキストエディットを使っているのですが、文字数のカウントができないため、以下の様なサイトを使用して文字数を都度調べている状態です。


http://www2u.biglobe.ne.jp/~yuichi/rest/strcount.html


上記のサイトは、改行を除いた文字数、改行、空白を除いた文字数を表示できるため、非常にありがたく使わせていただいていますが、Apple Scriptで同じことができないかと調べています。


以下のサイトにワードカウントの機能のApple Scriptがあるのですが、このscriptに改行、空白を除いた文字数カウントをするようにはどのようにできるのか、お教え願えればと思います。


http://macfan.jp/guide/2010/05/13/post_671.html


また、今回の件でApple Scriptを活用して色々と便利にMacを使いこなしたいので、上級者の方はどのような本などで勉強されてきたのかもお教え願えれば幸いです。

Mac mini, Mac OS X (10.7.5)

投稿日 2012/10/11 11:13

返信
スレッドに付いたマーク ベストな回答

投稿日 2012/10/12 07:17

こんにちは


ご指摘のJavascriptを用いた文字数カウンタと類似する機能のAppleScript例を下記に示します。

参考になれば幸いです。

--

on run

tell application "TextEdit"

set theText to the text of document 1

set word_count to count words of document 1

set char_count to count characters of document 1

set para_count to count paragraphs of document 1

end tell


set theLF to ASCII character 10

set LF_count to countSubstring(theText, theLF)

set space_count to countSubstring(theText, " ")

set show_words to "文字数:" & (char_count as string) & return & "改行を除いた文字数:" & ((char_count - LF_count) as string) & return & "空白、改行を除いた文字数:" & ((char_count - space_count - LF_count) as string) & return & "行数:" & (para_count as string)

set dialog_title to "TextEdit Word Count"

display dialog show_words with icon 1 with title dialog_title buttons {"OK"} default button "Ok"

end run


-- e.g. countSubstring("abc abc abc", "abc") --> 3


on countSubstring(theText, theSubstring)

-- ljr (http://applescript.bratis-lover.net/library/string/), modified from Aurelio.net (http://aurelio.net/doc/as4pp.html)

local ASTID, theText, theSubstring, i

set ASTID to AppleScript's text item delimiters

try

set AppleScript's text item delimiters to theSubstring

set i to (count theText's text items) - 1

set AppleScript's text item delimiters to ASTID

return i

on error eMsg number eNum

set AppleScript's text item delimiters to ASTID

error "Can't countSubstring: " & eMsg number eNum

end try

end countSubstring

--

参考文献:

http://applescript.bratis-lover.net/library/string/#countSubstring

http://hints.macworld.com/article.php?story=20070730101510623


動作環境:

-Mac OSX 10.6.8 Snow Leopard

-AppleScriptエディタ 2.3(118) / AppleScript 2.1.2

-テキストエディット 1.6(264)

返信: 45

2012/10/14 16:02 milestone への返信

実を言いますと、なぜ「文字数カウント」が必要なのかが疑問でした。なにしろ途中から参加したのでお聞きするタイミングを逸してしまったというか...。これでやっとわかりました。やはりちゃんと聞かなきゃダメですね。(笑)


・原稿用紙何枚というようなスタイルで文章を書く人にとっては、改行を除いた文字数がないと不便だと思いますし、原稿用紙換算で何枚かを換算する機能


・HTML形式でWebサイトのコンテンツを直打ちで既成のページのソースをベースに書き直すことなどもあるのですが、その際に、タグをカウント対象から外し、なおかつ実際にサイトを見るユーザーが見る文字数のみをカウントするという機能


両方とも Perl でできます。このような処理は Perl、Python、Ruby、PHP といったスクリプト言語で処理すると良いでしょう。これらの言語は milestone さんの想像を遥かに超える程強力です。テキストが何千何万行あっても滞りなく処理してくれます。AppleScript では荷が重すぎるかもしれません。


例えば、HTML ソースからタグを取り除くのは Perl でも良いですし、PHP だと strip_tags() なんて、そのものズバリがあります。


これからスクリプトを始めようとしてる方にあれもこれもというのもなんですが、AppleScript はダイアログ周りと、ごく基本的なものにとどめ、スクリプト言語を勉強すると良いと思います。


さて、上の2つのご提案ですが、ここでは勘弁してください。というか、スクリプト言語やプログラム言語は「すべて自分で解決」がお作法であります。


あと、「原稿用紙何枚?」は結構需要がありそうなので、Google 検索してみるとか、DTP ユーザのコミュニティで聞いてみるのも良いかもしれませんよ。

2012/10/14 16:21 Hiro__S への返信

Hiro.S様


お世話になっております。


実際、エディタやWordにはワードカウントの機能がありますが、テキストエディットくらいシンプルな方が分掌を書く上では集中できるのと、原稿があって、同じくらいの文字数でという指定がなされることもあり、その際には、文字カウントの機能がサービス経由でできるといいなと思っており、Mac Fanの記事を見つけて、色々なブログを見ましたが、このディスカッションでご回答いただく中で、分からないことは多いですが、こんなこともできるんだという認識を持つことができました。


実際、業務にてMacを使用していますので、多くの要望をさせて頂き、ご回答いただく中で、申し訳ないようなありがたいような気持ちが同居しておりまして、前の2つの機能については、あくまでできるかどうか?という点に疑問がありました。


スクリプトやプログラムは非常に興味深い分野であるので、ご紹介いただいた本やサイトなどを参照し、勉強して行こうと思います。


原稿用紙何枚というのは、以前サイトで見たことはあるのですが、文字数をカウントするサイト同様、サイトによって計測される文字数が違っており、なぜか理解出来ずにいました。


様々な言語があるようですが、それぞれの言語について、調べてみようと思います。

2012/10/14 16:32 milestone への返信

ご回答いただきました皆様へ


この度は、ご丁寧にご回答いただき、ありがとうございました。


当方のミスにより、皆様にこの回答が参考になったという事でボタンを押させていただこうとしたところ、誤って自分自身にボタンを押してしまいました。


どのように取り消せるのか探しましたが、見当たらず、問い合わせ先もわからない状態で、ご回答いただいた皆様に大変申し訳無い気持ちです。


ここまでMacユーザーの皆様がご丁寧に、親切にご回答いただけるとは、感激を覚えるほどで、これからもっとMacを使いこなせるようになりたいと思うようになりました。


今までスクリプト、プログラムというと難しい、訳の分からないものというイメージでしたが、それ以上に実際に活用できると便利だという事がわかり、ご回答頂いたスクリプトの文字列を変えて、表示がどうなるか見てみたりすることで、一喜一憂しておりました。


このような楽しみを与えてくださった皆様に感謝いたします。


milestone

2012/10/14 17:05 milestone への返信

また、OKボタンをマウスクリックではなく、returnキーで押せるようにして、できるだけマウス操作を減らし、


on run {input}

try

set str to item 1 of input

set len to length of paragraphs of str

if last paragraph of str is "" then set len to len - 1

set s3 to "改行と空白を除外:" & length of new_str(str, "\\s")

set ss to s3

tell me to activate

using terms from application "Finder"

set btn1 to "OK"

set ttl1 to "文字数カウンター"

display dialog ss buttons {btn1} default button {btn1} with title ttl1 with icon 1 giving up after 90

end using terms from

end try

end run


ダイアログボックスが表示された状態でも他ウィンドウで文字入力の操作をしたり、ファイルやフォルダの作成をしたいので、


ダイアログはウインドウではありませんので出しっ放しというわけにはいきません。ここではタイムアウトを 90秒 として、それを超えると終了するようにしてあります。なので、90 秒以内になんとかしてください (笑)。また、ダイアログではなくウインドウで、ということになるとプログラム言語ということになります。


このメッセージは次により編集されています:Hiro.S

2012/10/14 19:11 milestone への返信

コメント、ありがとうございます。

ご指摘のコードにおけるエラーの原因は、変数spaceJ_countの定義漏れにあるかと思います。

修正案(★部)を下記に示します。また、ご要望のタブのカウントにつきましても補足(●部)いたしましたので、参考にしていただければ幸いです。

--

on run

tell application "TextEdit"

set theText to the text of (the clipboard)

set word_count to count words of (the clipboard)

set char_count to count characters of (the clipboard)

set para_count to count paragraphs of (the clipboard)

end tell


set theLF to ASCII character 10

set LF_count to countSubstring(theText, theLF)

set theTAB to ASCII character 9 --●

set TAB_count to countSubstring(theText, theTAB) --●

set space_count to countSubstring(theText, " ")

set spaceJ_count to countSubstring(theText, " ") --★

set show_words to "文字数:" & (char_count as string) & return & "改行を除いた文字数:" & ((char_count - LF_count) as string) & return & "空白、改行を除いた文字数:" & ((char_count - space_count - spaceJ_count - TAB_count - LF_count) as string) & return & "行数:" & (para_count as string) --★●

tell application "TextEdit" --表示の改善

display dialog show_words with icon 1 buttons {"OK"} default button "OK"

end tell

end run


-- e.g. countSubstring("abc abc abc", "abc") --> 3


on countSubstring(theText, theSubstring)

(略)

end countSubstring

--

注意:本スクリプトで得られた結果の正当性の評価は行っておりませんので、予めご了承下さい。

補足ですが、高度な文字列の処理をご要望のようですので、下記が参考になるかと思います。

http://ja.wikipedia.org/wiki/Perl

http://ja.wikipedia.org/wiki/正規表現

お役に立てれば幸いです。

2012/10/16 09:06 Hiro__S への返信

皆様へ


この度は、ご回答いただき、ありがとうございました。


様々な方法で議題が解決できると知り、時間をかけて取り組んでみたいと思います。


Hiro.S様のご回答を選ばせていただきましたが、kimukazu様のAppleScriptも再三の投稿を頂き、ありがとうございました。


非常にありがたかったです。


どうもありがとうございました。

2012/10/21 12:35 kimukazu への返信

> また、Automator のダイアログはタイムアウトしないので注意が必要です。


トップレベルなのでタイムアウトしないのは当然ですね。また、タイムアウトの設定もできるので挙動は StandardAdditions と同じ。挙動が違うのは Automator 独自のアラートダイアログの方で、こちらはタイムアウト設定ができません。すみません。完全に混同してました...。

2012/10/21 12:37 kimukazu への返信

kimukazu さんのスクリプトを基に「選択したテキストを取得」するものを拵えてみました。何度も書き換えたので原型をとどめてませんが...、要するに Perl を使わないバージョンです。文字のフィルタリングは「改行、タブ、全半角スペース」。


なお、applescript.bratis-lover.net に掲載のサブルーチンを使うなら、RemoveFromString() と RemoveListFromString() の組み合わせで同じことができます。


on run {input}

try

set str to item 1 of input

set msg to "改行と空白を除外:" & length of new_str(str, {character id 10, tab, space, character id 12288})

tell me to activate

using terms from application "Finder"

set btn1 to "OK"

set ttl1 to "文字数カウンター"

display dialog msg buttons {btn1} default button {btn1} with title ttl1 with icon 1 giving up after 90

end using terms from

end try

end run

--

on new_str(str, ary)

set new to str

repeat with i in ary

set new to replace_str(new, contents of i, "")

end repeat

end new_str

--

on replace_str(str, old, new)

set ifs to text item delimiters of AppleScript

set text item delimiters of AppleScript to {old}

set str to text items of str

set text item delimiters of AppleScript to {new}

set str to str as text

set text item delimiters of AppleScript to ifs

return str

end replace_str

2012/10/21 12:42 Hiro__S への返信

前回は投稿の下書き中に最終コメントらしきものがアップされたので焦ってしまい、不十分なポストとなってしまいました。若干日が経ってしまいましたが以下はその積み残し分です。


スクリプトに関して:

前回は余分なものが付いたままアップしてしまいました。動作に支障はありませんが、奇麗に整えたものを v3 としてアップします。


タイムアウトに関して:

giving up after 90 の「90」をもっと大きな値にすることもできますし、giving up after 90 を削除するとタイムアウトなしになりますが、長時間の出しっ放しはおすすめできません。その辺をふまえて秒数の設定をいろいろ試してみてください。前回は、押し付けがましい書き方になってしまったことをお詫びします。


質問にお答えしきれなかったこと:

tell me to activate


ダイアログがほかのアプリのウインドウの背面に表示されないように自分自身を最前面に持ってきます。


using terms from application "Finder"


「選択したテキストを取得する」対象を「すべてのアプリケーション」にしたので、ダイアログを出してね、という命令を出す相手は TextEdit ではなく、自分自身 (Automator Runner) になります。


こうすると、Automator 独自のダイアログが表示されますが、(少なくとも Leopard と Snow Leopard では) 少々難ありの代物なので、Finder.app からちょいとお借りするという書き方です。


この辺が Lion 以降どうなっているのか分からないので、安全策としてこのような書き方にしました。

2012/10/21 12:44 Hiro__S への返信

Automator サービス v3


https://discussionsjapan.apple.com/message/100714221#100714221

↑前回のスクリプトを清書しました。


on run {input}

try

set str to item 1 of input

set msg to "改行と空白を除外:" & length of new_str(str, "\\s")

tell me to activate

using terms from application "Finder"

set btn1 to "OK"

set ttl1 to "文字数カウンター"

display dialog msg buttons {btn1} default button {btn1} with title ttl1 with icon 1 giving up after 90

end using terms from

end try

end run

--

on new_str(str, opt)

set sh1 to "printf '%s' " & quoted form of str & " | "

set sh2 to "perl -CIO -pe 's|" & opt & "||g;'"

do shell script sh1 & sh2

end new_str

2012/10/21 12:47 Hiro__S への返信

最後に、AppleScript の「教材」ですが、とても少なくて私も困ってます。とりあえず役に立ちそうなところをリストアップしておきますので、ほかの方がご紹介の書籍やサイトと併せてご覧いただければと。


AppleScript: The Language of Automation

http://www.macosxautomation.com/applescript/


AppleScript: Beginner's Tutorial

http://www.macosxautomation.com/applescript/firsttutorial/index.html


AppleScript Overview

AppleScript Language Guide

Automator AppleScript Actions Tutorial

https://developer.apple.com/library/mac/search/?q=AppleScript


MacScripter

http://macscripter.net/


Piyomaru Software

http://piyocast.com/as/


鳶嶋工房

http://www.tonbi.jp/AppleScript/index.html


そのほかは Google 検索で。


-----


それと、各アプリの「辞書」を是非お読みください。AppleScript Editor のメニューバー > ファイル > 用語説明を開く、もしくは、メニューバー > ウインドウ > ライブラリからアクセスできます。ここには何ができるか、どのようにするかが書かれています。


-----


また、Perl や Ruby は難しいので、まずは CotEditor や mi 等のテキストエディタで「正規表現」を使った検索/置き換えの練習を積んでから挑戦すると良いかもしれません。


CotEditor

http://sourceforge.jp/projects/coteditor/


mi

http://www.mimikaki.net/


Jedit X (有料)

http://www.artman21.com/jp/jedit_x/


-----


最初はキツいかもしれませんが、コツコツとやればきっと習得できます。頑張ってください。

2012/10/26 00:51 Hiro__S への返信

Hiro.S様


ご返信が遅くなりまして、申し訳ございません。


実はあの後、なぜかスクリプトが動作しないというトラブルが起こってしまい、自分でタイムアウトの項目を変えたり、名前を変えてサービスに保存していたら、歯車のようなマークが時刻などが表示される部分に表示され、Macの挙動が遅くなりました。


原因はよくわかりませんが、タイムアウトせず、出しっぱなしにしてしまったことがあったので、やはりご忠告の通り、タイムアウトをさせる必要があるようです。


Automator サービスv3のスクリプトを使わせていただこうと思います。


普段、Macを使っていて、もっと知りたいと思うのに、情報があまりないという事が多いです。


今後、様々な書籍等をあたり、よりMacを使いこなせるように出来ればと考えています。


多くの情報と再三のご回答、ありがとうございました。


エディタも色々種類があるようですが、やはりApple謹製ではないので、開発終了などの心配をしてしまいます。


オススメしていただいたものを調べ、検討してみようと思います。


今後とも、よろしくお願いいたします。

2012/10/26 18:04 milestone への返信

歯車のようなマークが時刻などが表示される部分に表示され、


これは正常な挙動です。歯車をクリックすると「xxx を中止する」のサブメニューがでます。ここからワークフローを中止できます。この機能は、v3 では半分しか機能しません。後から投稿した Perl を使わないバージョンは大丈夫です。


Macの挙動が遅くなりました。


これはちょっと問題ですね...。この1週間あれこれテストしていたのですが私の環境 (Snow Leopard) では問題ありませんでした。これに関してはちょっと分かりません。


とりあえず、後から投稿した Perl を使わないバージョンも試してみてください。

https://discussionsjapan.apple.com/message/100716231#100716231

2012/10/26 18:57 milestone への返信

Macの挙動が遅くなりました。

ここだけ。

これはAutomatorの実行中に、何か(キーボード操作とか)ユーザ(あるいは同時に起動している他の言語の自動スクリプトの実行)の割り込みが入ったときに起きる場合があります。

Apple Scriptによる選択範囲の文字カウント(改行、スペース抜き)について

Apple サポートコミュニティへようこそ
Apple ユーザ同士でお使いの製品について助け合うフォーラムです。Apple ID を使ってご参加ください。