2011年5月31日火曜日

makeファイルの内部マクロ

$@ - ターゲット名
$(@F) - ターゲット名(パスを除く)
$% - ターゲットメンバ名
$(@:"変更したい文字列"="変更後の文字列") - 文字列の変換
$(subst "変更したい文字列","変更後の文字列","全体の文字列") - 文字列の変換

参考
http://www.c.csce.kyushu-u.ac.jp/~seiichirou/wiki/index.php?Makefile%A4%CE%BD%F1%A4%AD%CA%FD#content_1_10

-- 使用例 --
1.ファイルの拡張子を変更(%はワイルドカードとして機能)
$(@:%.text=%.txt)

2.ファイルの拡張子を変更して、パスの"/"を"\"に変更
$(subst /,\,$(@:%.text=%.txt))
1を入れ子にする方法ではできなかった(正しい記述が出来ていなかったのかもしれない)。substで入れ子にする方法はまだ試していない。

2011年5月30日月曜日

OpenOffice > Java > Googleの翻訳サービスを利用してピンインを取得

マクロの配置方法は以前の記事を参照して下さい。

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.zip.GZIPInputStream;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.script.provider.XScriptContext;

public class B {

private static final String URL = "http://translate.google.co.jp/translate_a/t?client=t&hl=ja&sl=zh-CN&tl=ja&multires=1&otf=1&pc=1&srcrom=1&ssel=0&tsel=0&sc=1&text=";

public static void a(XScriptContext sc) throws IndexOutOfBoundsException,
WrappedTargetException, IOException, ScriptException {

String word = Util.getSelectedCellValue(sc);

if ("".equals(word)) {
return;
}
getPinyin(word);
}

private static void getPinyin(String word) throws IOException, ScriptException {

String response = getHttpResponse(word);
if (response == null || "".equals(response)) {
return;
}
String pinyin = extractPinYin(response);
setStringToClipBoard(pinyin);
}

private static void setStringToClipBoard(String s) {
Toolkit kit = Toolkit.getDefaultToolkit();
Clipboard clip = kit.getSystemClipboard();
StringSelection ss = new StringSelection(s);
clip.setContents(ss, null);
}

private static String extractPinYin(String response) throws ScriptException {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
String s = "";
engine.put("s", s);
engine.eval("var a = " + response);
engine.eval("s = a[0][0][3]");
return (String) engine.get("s");
}

private static String getHttpResponse(String word) throws IOException {

String response = "";
BufferedReader br = null;
try {
URL url = new URL(URL + URLEncoder.encode(word, "UTF-8"));
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Accept", "*/*");
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
conn.setRequestProperty(
"User-Agent",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.connect();

int rc = conn.getResponseCode();
// String rs = conn.getResponseMessage();
// System.out.printf("%d %s\n", rc, rs);

if (rc == HttpURLConnection.HTTP_OK) {
br = new BufferedReader(new InputStreamReader(
new GZIPInputStream(conn.getInputStream()), "UTF-8"));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
response = sb.toString();
}
return response;
} catch (IOException e) {
throw e;
} finally {
if (br != null) {
br.close();
}
}
}
}

2011年5月29日日曜日

vbsでショートカットの作成

インストーラを使用しない配置するだけのプログラムがたまってきたので、それらへのショートカットをつくるスクリプトを作成した。vbsは初めてだが、便利な機能があっていいなと思った。これからも活用していきたい。

** 参考にしたサイト **
フォルダの再帰
http://www1.u-netsurf.ne.jp/~tomo_c/tips/R23Lev15.html
拡張子の取得
http://www1.u-netsurf.ne.jp/~tomo_c/tips/WSH003.html
ショートカットの作成
http://www.atmarkit.co.jp/fwin2k/operation/wsh06/wsh06_03.html
DimとSetの違い
http://www.mhl.janis.or.jp/~winarrow/vbscript/htm/vbs598.htm


Sub CreateShortCusts(sFolder)

Set folder = fso.GetFolder(sFolder)

For Each f In folder.Files
If fso.GetExtensionName(f.Path)="exe" Then
Set objShortCut = objShell.CreateShortcut(f.Name + ".lnk")
objShortCut.TargetPath = f.Path
objShortCut.Save
End If
Next

For Each f In folder.Subfolders
CreateShortCusts(f.Path)
Next

End Sub

Set objShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Dim sFolder
sFolder = "D:\Applications"
CreateShortCusts(sFolder)

2011年5月26日木曜日

OpenOffice > Java > Googleの発音サービスを利用

SpreadSheetの選択されたセルの文字列の発音を再生するマクロを以前OpenOfficeBasicで作成したが、中国語の再生はうまくいかなかったので、Javaのマクロで作成した。

Javaマクロの作成手順(大雑把に)。

  1. クラスファイルを作成。呼び出されるメソッドのシグネチャは「public static void method_name(XScriptContext)」。
  2. クラスファイルをコンパイルし、jarに固める。
  3. jarファイルを%USER_HOME%\Application Data\OpenOffice.org\3\user\Scripts\Java\Library1に置く。
  4. jarファイルと同じフォルダにparcel-descriptor.xmlという設定ファイルを置く。
  5. OpenOfficeのメニュー「ツール > マクロ > マクロを実行」でダイアログを開き、作成したマクロを選択して実行。
補足1:外部ライブラリ等を利用する場合は、OpenOfficeのメニュー「ツール > オプション」でダイアログを開き、「OpenOffice.org > Java」にてクラスパスを追加する。
(今回は、音声ファイルの再生に、「MpegAudioSPI1.9.5」(http://www.javazoom.net/mp3spi/mp3spi.html) を利用した)

補足2:デバッグしたい場合は、補足1と同じところでJavaの起動パラメータを指定できるので
「-Xrunjdwp:transport=dt_socket,server=y,address=12345,suspend=n」等を指定して、IDE等からリモートデバッグできる。OpenOfficeがJavaVMを起動させるタイミングは、OpenOfficeのメニュー「ツール > マクロ > マクロを実行」でダイアログを開いたときなので、そのタイミングでIDE等から接続すればよい。

参考にしたサイト

-- A.java --
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;

import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.script.provider.XScriptContext;

public class A {

private static final String URL = "http://translate.google.com/translate_tts?tl=zh-CN&q=";

public static void a(XScriptContext sc) throws IndexOutOfBoundsException,
WrappedTargetException, IOException, JavaLayerException,
InterruptedException {

String word = Util.getSelectedCellValue(sc);

if ("".equals(word)) {
return;
}
play(word);
}

private static void play(String word) throws IOException,
JavaLayerException, InterruptedException {

InputStream in = null;
Player player = null;
try {
URL url = new URL(URL + URLEncoder.encode(word, "UTF-8"));
URLConnection conn = url.openConnection();
conn.setRequestProperty("Accept", "*/*");
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
conn.setRequestProperty(
"User-Agent",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.connect();
in = conn.getInputStream();

player = new Player(in);
player.play();
while (!player.isComplete()) {
Thread.sleep(500);
}

} catch (IOException e) {
throw e;
} catch (JavaLayerException e) {
throw e;
} finally {
if (in != null) {
in.close();
}
if (player != null) {
player.close();
}
}
}
}

-- Util.java -- 
import com.sun.star.frame.XController;
import com.sun.star.frame.XModel;
import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.script.provider.XScriptContext;
import com.sun.star.table.XCell;
import com.sun.star.table.XCellRange;
import com.sun.star.text.XText;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.view.XSelectionSupplier;

public class Util {

static String getSelectedCellValue(XScriptContext sc)
throws IndexOutOfBoundsException, WrappedTargetException {

XModel oDoc = (XModel) sc.getDocument();
XModel xSpreadsheetModel = UnoRuntime
.queryInterface(XModel.class, oDoc);
XController xController = xSpreadsheetModel.getCurrentController();

XSelectionSupplier xSel = (XSelectionSupplier) UnoRuntime
.queryInterface(XSelectionSupplier.class, xController);
Object Selection = xSel.getSelection();

XServiceInfo xServiceInfo = (XServiceInfo) UnoRuntime.queryInterface(
XServiceInfo.class, Selection);
String info = xServiceInfo.getImplementationName();

if (info.equals("ScCellRangeObj") || info.equals("ScCellObj")) {
XCellRange xSelectedRange = (XCellRange) UnoRuntime.queryInterface(
XCellRange.class, Selection);
XCell oCell = xSelectedRange.getCellByPosition(0, 0);
XText xCellText = (XText) UnoRuntime.queryInterface(XText.class,
oCell);
return xCellText.getString();
}

return "";
}

}

-- parcel-descriptor.xml --
<?xml version="1.0" encoding="UTF-8"?>
<parcel language="Java" xmlns:parcel="scripting.dtd">
    <script language="Java">
        <locale lang="en">
            <displayname value="pronounce chinese"/>
            <description>
                pronounce chinese. 
            </description>
        </locale>
        <functionname value="A.a"/>
        <logicalname value="A.a"/>
        <languagedepprops>
            <prop name="classpath" value="a.jar"/>
        </languagedepprops>
    </script>
</parcel>

2011年5月25日水曜日

Evernote Chrome拡張アップデート

ブログやニュースサイトの中から記事を自動で認識する機能が追加された。これは便利。トラックパッドで範囲選択するのって面倒くさいからね。

2011年5月24日火曜日

OpenOffice > Java > チュートリアルをやってみる

UNOをJavaで実装するチュートリアルをやってみました。
http://hermione.s41.xrea.com/pukiwiki/index.php?OOoSDK%2Fjava%2FTutorial%2FHello

SDKはインストールしてあったが、IDLmakeを使用するのでMinGWをインストールした。Zipツールはavast!に警告されたのでインストールはしなかった(なんとかなるかな?)。そして「%SDK_HOME%\setsdkenv_windows.bat」を実行し、表示される質問に応えて設定完了。設定を変更したい場合は、「%USER_HOME%\Application Data\openoffice.org3.3_sdk」 以下に「setsdkenv_windows.bat」が生成されているので、それを修正すればよい。以後、各種SDK関連コマンドを実行する場合は、上記どちらかのbatファイルを実行すればパスが通る。

  1. IDLファイルの作成、コンパイル - 成功。
  2. レジストリファイルの作成 - 成功。
  3. javamakerコマンドでjavaファイルの作成
    作成されるのはjavaファイルとなっているが、classファイルが作成された。
    コマンドの仕様が変わったらしい。アップしてあるソースを利用する。
  4. サービス、その他のクラスの実装、コンパイル - 成功。
  5. jarファイル、zipファイルの作成 - 成功。
  6. パッケージのインストール
    pkgchkコマンドがみつからなかった。インストール方法が変わったらしい。
    unopkgコマンドでインストールするもOpenOfficeBasicからサービスを利用することはできなかった。

OpenOfficeのアップデートによって動かすことはできなかったが、概要は理解できた。うまくいかなかった点も、DeveloperGuideを読み進めていけば解決できると思う。

--- 追記 ---
SDKのサンプルの中にある”JavaComponent”(%SDK_HOME%\examples\DevelopersGuide\Components\JavaComponent)と似た構成になっているので、そちらを参考にしながら進めたら無事動作した。

makefileの修正箇所

  • COMPONENT_NAME=JavaComponent
            > COMPONENT_NAME=ooo_hello  
  • APP1_NAME=TestJavaComponent
            > APP1_NAME=ooo_hello
  • IDLFILES = XSomethingA.idl \  .....
            > IDLFILES = XHello.idl \  ....
  • PACKAGE = com/sun/star/test
            > PACKAGE = com/sun/star/demo
  • COMPJAVAFILES  = TestComponentA.java \ ....
            > COMPJAVAFILES  = com/sun/star/comp/demo/Hello.java \ ....
  • @echo RegistrationClassName: TestServiceProvider>> $@
            > @echo RegistrationClassName: com.sun.star.comp.demo.Hello>> $@

2011年5月23日月曜日

Googleドキュメントを使いこなそう

マイコミジャーナルの連載です。

Officeレベルの文書を作ろう! Google Appsドキュメント実践講座
http://journal.mycom.co.jp/series/googledoc/003/

勉強になります。

Googleドキュメント、どんどん便利になっていきますね。共有やバージョン管理ができるのはオンラインアプリケーションの強みですね。

OpenOffice > Java > チュートリアルをやってみる

OpenOfficeのディベロッパーガイドのチュートリアルを実行してみました。
http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/FirstSteps/First_Contact

Eclipseから実行すると。コンソールにエラーが...

com.sun.star.comp.helper.BootstrapException: no office executable found!
at com.sun.star.comp.helper.Bootstrap.bootstrap(Bootstrap.java:253)

ネットで調べると、OpenOfficeの実行ファイルにclasspathを通さなければいけないそうだ。
http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/FirstSteps/Configuration
Add a classpath variable. On the previous dialog window, select Java > Build Path > Classpath Variables. Press New to create a new Variable Entry. A name of the variable might be OO_PROGRAM. A path for a standard installation of 3.2.1 on unix is /opt/openoffice.org/program.  

OpenOffice > 拡張機能

OpenOfficeの拡張機能を作成時につまずいたこと。
  • OOEclipseという拡張機能作成を支援するEclipseのプラグインが動かなかった。(バージョンのせい?)
  • NetBeansのプラグインを利用しようとしたが、利用出来るプラグインの一覧に関連するものがなかった。(これもバージョンのせい?)
  • ネット上のサンプルを参考にツールバーを利用するプラグインを作成したが、アンインストールできなかった。
いろいろ作りたいものがあるが、最初の一歩のハードルが高いなあと思った。日本語の資料が少ないのでたいへんだ。

最後の項目は、OpenOfficeを停止して(クイック起動も停止)、%USER_HOME%\Application Data\OpenOffice.org\3\user\extensions以下のフォルダ と %USER_HOME%\Application Data\OpenOffice.org\3\user\uno_packages\cacheを削除して起動すれば削除(アンインストール)できた。全部削除されてしまうが...。原因は、description.xmlやMETA-INF\manifest.xmlを作成していなかったからみたい。

2011年5月16日月曜日

OpenOffice > Basic > Googleの発音サービスを利用

OpenOfficeのcalcを使用して英単語を管理しています。発音を調べる際には、google翻訳のサイトに単語を貼りつけてチェックしていたのですが、面倒くさいのでOpenOfficeから直接googleのサービスを利用するようにしました。

1. メニュー ツール→マクロ→マクロの管理→OpenOffice.org Basic を選択
2. マクロの記録先のエリアで マイマクロ→Standard を選択し、新規作成ボタンを押す
3. マクロの編集画面が開くので以下のスクリプトを貼り付け、保存し、閉じる

Sub PronounceEn
Dim manager As Object
Dim player As Object
Dim url As String
Dim words As String
Dim column As Integer
Dim row As Integer
Dim controller As Object

controller = ThisComponent.CurrentController
column = controller.getSelection().RangeAddress.StartColumn
row = controller.getSelection().RangeAddress.StartRow
words = controller.ActiveSheet.getCellByPosition(column, row).string

If words = "" Then
Exit Sub
End If

url = "http://translate.google.com/translate_tts?tl=en&q=" + words
manager = CreateUnoService("com.sun.star.media.Manager_DirectX")
player =  manager.createPlayer(ConvertToURL(url))
player.start()
While player.MediaTime < player.StopTime
Wait 100
WEnd
End Sub

4. メニュー ツール→カスタマイズ ツールバータブの追加ボタンを押して”範囲”の中から上記マクロを選択
5. 英単語が入力されているセルを選択して、先ほど作成したツールバーのボタンを押すと、発音が再生される

中国語の再生もやってみましたが、単語がUTF-8でURLエンコードされないようでうまくいきませんでした。Javaやpythonを使って試してみたいと思います。

OpenOfficeを侮っていましたが、いろいろできるみたいですね。Oralceが放出を決めたらしいですし、LibreOfficeの動向もあり、ちゃんと維持されていくのか心配です。