Microsoft Office文書をOpenXML形式に変換する

Microsoft Office文書(Word,Excel,PowerPoint)をOpenXML形式に変換したい、そんなとき。

要は次のようにしたい。

  • Microsoft Word 97-2003 文書「.doc」 → Microsoft Word 文書「.docx」
  • Microsoft Excel 97-2003 ワークシート「.xls」→ Microsoft Excel ワークシート「.xlsx」
  • Microsoft PowerPoint 97-2003 プレゼンテーション「.ppt」→ Microsoft PowerPoint プレゼンテーション「.pptx」

もちろん、それぞれのソフトウェアを起動して「名前を付けて保存」するときに形式を指定してやればよいのだけれど、
ファイルが大量にあるときにはバッチ的に処理したい。

そこで、
Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint File Formats
2007 Microsoft Office System Migration Guidance: Microsoft Office Migration Planning Manager

以上の2つをインストールすればそれができるらしい。
後半のMicrosoft Office Migration Planning Managerを試してみた。
上のリンク先のガイド通りにインストールすると、 C:\ompm\ 以下にいろいろ展開される。
C:\ompm\Tools\ofc.ini の fldrに変換したい文書の入ってるフォルダを指定して実行。

ところがPowerPoint(.ppt)がうまく変換されない。64bitマシンを使っていたせいか、C:\Program Files\Microsoft Office\Office14 に
Wordconv.exeとexcelcnv.exe はあるのに、PowerPointを変換しそうなヤツが見当たらない。
C:\Program Files (x86)\Microsoft Office\Office12 にPPCNVCOM.exeがいました。ついでにここにWordconv.exeとexcelcnv.exeもいた。

というわけで、ofc.exeを使うのをやめて、この3つを直接使うことに決めた。
それでコマンドプロンプトでなんとかしようとしたら、前記事「Windowsのコマンド・プロンプトの拡張子の取り扱い」の罠にはまった。
テキトーにやるとdocとdocx,xlsとxlsx,pptとpptxが区別できなくなったりするので注意。

それぞれの使い方。出力ファイル名の拡張子にはxつけてあげるとよいね。

"C:\Program Files (x86)\Microsoft Office\Office12\Wordconv.exe" -oice -nme input_file output_file
"C:\Program Files (x86)\Microsoft Office\Office12\excelcnv.exe" -nme -oice input_file output_file
"C:\Program Files (x86)\Microsoft Office\Office12\PPCNVCOM.EXE" -oice input_file output_file

それにしてもこのコマンド群の統一感の無さ
convだったりcnvだったりCNVCOMだったり。大文字小文字がすべてバラバラだし。
しかもオプションの意味はよくわからんのだが、順番がわりと大事だったりする。excelcnv.exe で -oice -nme って書いても動いてくれないのだ。
PowerPointでは-nme付かないし、いったいどうしてこんなことになちゃうんだろうか。
「こいつら全く別物だぜ!」というアピールなんだろうか。ユーザーはそんなの望んでないよね。
インターフェースの悪い例の良い見本だね。勉強になるね!

ところでこのdocx,xlsx,pptxにしたらサイズが小さくなったのだけど、これって要はzipでXMLファイルが圧縮されているのだね。
docx,xlsx,pptxをそれぞれzipという拡張子に変更して展開すれば、中にXMLファイルが入っているよ。

カテゴリー: MS Office, Windows, batch | コメントは受け付けていません。

Windowsのコマンド・プロンプトの拡張子の取り扱い

[NT] コマンド プロンプトでの拡張子の取り扱い
http://support.microsoft.com/kb/164351/ja

コマンド プロンプトからワイルドカードを使ってファイル管理を行う場合、3 文字を超える長い拡張子は、3 文字に切り詰められて取り扱われます。

というわけで、上のリンクのガイドに従って、レジストリエディタで
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem
Win95TruncatedExtensions : REG_DWORD を 0 へ変更(デフォルトは 1)して、再起動

ところが、もう一度試してみても、やっぱり3 文字に切り詰められて取り扱われるのか、以下のようなコマンドを実行すると、ひっかかって欲しくない拡張子4文字以上のファイルもヒットしてしまう。

> dir /B *.htm
index.htm
index.html

このレジストリ値を変える以前に作ったファイルには効かないようだ。レジストリ変更後に作った拡張子4文字以降のファイルはちゃんとその通り扱われていた。

うっかり削除なんて事故も起きかねない。コマンド・プロンプトでワイルドカードを使うときは十分注意が必要だね。

カテゴリー: MS Office, Tips, Windows, batch | コメントは受け付けていません。

Google +1ボタンをWordPressに設置する

Google +1 ボタンをWordpressに設置する方法。
+1ボタンとは、字の通りイチオシといったところかな。


Google +1
  Add +1 to your pages to help your site stand out


上のリンク先に行って、SizeとLanguageを選ぶと埋め込みコードができるよ。

SizeをMedium(20px)、LanguageをJapaneseにした場合は次のようなコードができあがる。


<script type="text/javascript" src="http://apis.google.com/js/plusone.js">
  {lang: 'ja'}
</script>


<g:plusone size="medium"></g:plusone>

あとはこのコードのコメントにあるとおりにすればOK。
外観→テーマ編集で
ヘッダー(header.php)の</body>の直前に上の埋め込みコードの前半部分を貼り付ける。

<script type="text/javascript" src="http://apis.google.com/js/plusone.js">
  {lang: 'ja'}
</script>

単一記事の投稿(single.php)で表示したい部分に後半の

<g:plusone size="medium"></g:plusone>

を貼り付ければOK。

ところで、このブログのホームには記事が何件も並んでるけど、メインインデックスのテンプレート(index.php)に上のコードをそのまま貼り付けると、
記事ごとに+1ボタンをつけたつもりが、どれを押してもホームのURLに対しての+1になってしまう。

そんなときは、Wordpressのメインインデックスのテンプレート(index.php)で、href属性に記事のパーマリンクを指定すれば、個別の記事ごとへの+1ボタンが作れるよ。

<g:plusone size="medium" href="<?php the_permalink(); ?>"></g:plusone>

このURLを作為的にどこかのURLにしておけば、そうとは知らないユーザーが見ているページに+1をつけたつもりがほかのページがイチオシされちゃうわけだね。

たとえば、
個別記事の+1ボタンのhrefにすべてサイトのホームのURLを指定しておけば、どの記事で+1を押されてもサイト全体の+1として集約したりできるね。
これはFacebookのいいね!やTwitterのボタンでも同様だね。

その他の詳しい属性などについては、

+1 ボタンをサイトに追加(Google Code)

を見てくださいね。

カテゴリー: Chrome, Google, Tips, Wordpress | コメントは受け付けていません。

CaboChaの文字コードRecompileしてもうまくいかない、そんなとき

CaboCha 0.60pre4 Windows版で辞書の文字コードを変えようと思ったのだけどうまくいかなかったときの話

CaboChaをインストールすると、スタートメニューには

  • Recompile SHIFT-JIS Model
  • Recompile UTF-8 Dictionary

というのが用意されているのだけれど、これをこのまま実行してもCaboChaがうまく動作しないことがある。

症状

たとえば、文字コードをUTF-8からSHIFT-JISに変えようと思って「Recompile SHIFT-JIS Model」を実行。特にエラーもなく終了したので、CaboChaを実行すると、

morph.cpp(108) [charset() == decode_charset(dinfo->charset)] Incompatible charse
t: MeCab charset is SHIFT-JIS, Your charset is UTF8

となり係り受け解析ができない。

原因

Windows Vista以降で導入されたユーザーアカウント制御UAC(User Account Control)により、C:\Program Files\CaboCha\model\charset-file.txtの書き換えに失敗している。

C:\Program Files\CaboCha\model>echo SHIFT-JIS 1>charset-file.txt
アクセスが拒否されました。

対策

Recompileのバッチ実行後に直接C:\Program Files\CaboCha\model\charset-file.txtのファイルを書き換える。
もしくは、
C:\Program Files\CaboCha\model\mkmodel.batの1行目に以下を追加して、”管理者権限で”Recompileのバッチを実行する。

cd /d %~dp0

なぜだろう

UACにより書き込みが制限されるのであれば、最初からバッチコマンド自体を管理者権限で実行すればよいのでは?
しかし次のようになってしまう。

C:\Windows\system32>..\bin\cabocha-model-index -f SHIFT-JIS -t SHIFT-JIS dep.ipa
.txt dep.ipa.model
指定されたパスが見つかりません。

C:\Windows\system32>..\bin\cabocha-model-index -f SHIFT-JIS -t SHIFT-JIS chunk.i
pa.txt chunk.ipa.model
指定されたパスが見つかりません。

C:\Windows\system32>..\bin\cabocha-model-index -f SHIFT-JIS -t SHIFT-JIS ne.ipa.
txt ne.ipa.model
指定されたパスが見つかりません。

C:\Windows\system32>echo SHIFT-JIS 1>charset-file.txt

実行ディレクトリがC:\Windows\system32になってしまうのだ。
そこで、バッチの先頭で実行ディレクトリに一旦移動する必要がある。それが上で追加したcd /d %~dp0だ。
これは他のバッチファイルでもよくハマるので、なんとなく心の片隅に入れとくとよい。

ちなみに毎回管理者として実行するには、
バッチのアイコンを右クリック→プロパティ→ショートカット→詳細設定→管理者として実行にチェック

カテゴリー: CaboCha, MeCab, NLP, Tips, Windows, batch | コメントは受け付けていません。

Hudson/JenkinsでVisual Studioプロジェクトのビルドをする – MSBuild Plugin

Hudson/JenkinsでVisual Studioのプロジェクトをビルドしたい、そんなとき。
MSBuild Pluginを使うよ。

MSBuild Pluginの導入

「Hudsonの管理」→「プラグインの管理」→「利用可能」タブ→
Hudson MSBuild Plugin」にチェックを入れて「インストール」
インストールが完了したら、「ジョブが実行中でなければ再起動」ボタンを押してHudson/Jenkinsを再起動。

MSBuild Pluginの設定

導入ができたら、プラグインの設定をする。

「Hudsonの管理」→「システムの設定」

MSBuild Builderの項目が新たにできているので、nameとpathを指定する。
nameは、ジョブの設定時、MSBuildの選択肢として出てくるのでわかりやすい名前をつける。Path To msbuild.exeにはmsbuild.exeの場所を指定すればよい。
たいていの場合、C:\WINDOWS\Microsoft.NET\Framework\[version]\MSBuild.exe 
私の環境では以下のバージョンがあったよ。

  • v1.0.3705
  • v1.1.4322
  • v2.0.50727
  • v3.0
  • v3.5
  • v4.030319

設定例

とりあえず、最新のだけ使うので
name: v4.030319
path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
と入力して保存。必要に応じて他のバージョンも追加できる。

ジョブの設定

「ビルド手順の追加」で
Build a Visual Studio project or solution using MSBuild.
を追加

  • MsBuild Versionはプルダウンメニューから使用するMSBuildを選ぶ。上のシステム設定でnameに指定したものが一覧に出る
  • MsBuild Build Fileにはビルドしたいプロジェクトの.projか.slnのパスを指定
  • Command Line ArgumentsにはMSBuildのオプションを設定

設定例

MsBuild Version: v4.030319
MsBuild Build File: C:\hudson\jobs\ジョブ名\workspace\プロジェクト名\プロジェクト名.sln
Command Line Arguments: /t:Rebuild /p:Configuration=Release

私の場合gitプラグインでプロジェクトをHudson/Jenkinsワークスペース以下にcloneして来てるので、cloneしてきたソリューションファイルの場所を指定しているよ。
Command Line Argumentsでリリース版のみをリビルドするよう設定。/t:は/target:、/p:は/property:の省略値。/t:cleanとかを組み合わせればクリーンビルドとかもできるね。
これでVC++のプロジェクトがビルドできたよ。

MSBuildの詳しい使い方

カテゴリー: Hudson, Jenkins, Visual Studio, Windows | コメントは受け付けていません。

コマンドラインでUTF-8テキストのBOMを追加したり削除したりする

BOM(バイト順マーク)を削除することはよくあるんだけど、つけたことってあまりなかった。
エディタの機能を使えばできるものもあるけど、大量なファイルをいちいちエディタで開いて処理するわけにもいかないので、コマンドでまとめて処理したい、そんなとき。
結論としては、uconvを使えば割と手軽にBOMを付けたり消したりできる。
「BOMのマークの文字なんだったっけ?」とか考えなくてもよい方法

BOMの確認

fileコマンドを使う。

$ file *.cpp
foo.cpp:   UTF-8 Unicode text
bar.cpp:   UTF-8 Unicode (with BOM) text

BOMが付いてるテキストは「(with BOM)」となるので、エディタなどで開かずにBOMが付いてるかどうかを確認できる。

現在のディレクトリ以下にあるC++のソースファイル(c,h,cpp,hpp)でBOMが付いてないファイルのファイル名を取り出すには

find . -type f \( -name '*.[ch]' -o -name '*.cpp' -o -name '*.hpp' \) -exec file {} + | grep -v "(with BOM)" | cut -d: -f1

BOMが付いてるファイル名を取り出すにはgrepの-vを取って、

find . -type f \( -name '*.[ch]' -o -name '*.cpp' -o -name '*.hpp' \) -exec file {} + | grep "(with BOM)" | cut -d: -f1


BOMの追加と削除

uconvを使う。
詳しくは、International Components for Unicode http://site.icu-project.org/
debianの場合最初から使えたけど、ない人はaptitudeでlibicu-dev辺りを入れればいいんだと思う。Windowsのバイナリもある。

BOMを追加する

uconv -f utf-8 -t utf-8 --add-signature foo.cpp > foo_bom.cpp

BOMを削除する

uconv -f utf-8 -t utf-8 --remove-signature bar.cpp > bar_nobom.cpp

出力ファイルに入力ファイルと同じ名前を指定して消してしまわないように注意。
-fと-tはプラットホームのエンコーディングがutf-8以外の場合は省略するとうまくいかないことがあるので明示してる。
localeコマンドを実行してLANG=ja_JP.utf8とかだったら-f,-tオプションは省略できるよ。

上のBOMの確認の例と組み合わせれば、お手軽にまとめて変換できるね。

なんでBOMつけようとか思ったの

Windowsにつけろって言われたから。

VC++はBOM付きUTF-8

UTF-8はバイト順に依らないので、本当はBOMは要らないのだけどWindowsのVisual Studio C++では、BOM付きじゃないとUTF-8で書かれてるかどうか判断できないらしい。
ソースにマルチバイト文字を含んでる場合にはコンパイル時にC4819という警告が出て、正しく動作しないことがある。

ソースコードにUTF-8を使う場合はBOMつきのみサポート。

gccはどっちでもよい

でもgccはBOMどうなの?と思ったらBOM付きで問題なくコンパイルできる。この辺で直ったようだ
BOM付けてはいけないみたいな文書を見かけるが、イマドキは意外と付いててもなんとかなる。

カテゴリー: C++, Windows, bash, encoding | コメントは受け付けていません。

jqueryのdatepicker / datetimepickerを最前面に表示したいのにelrteが部分的に優先して表示されてしまう、そんなとき

日付の入力にjqueryのdatepicker / datetimepickerを使い、本文の入力にWYSIWYGエディタであるelrteを使って開発をしていました。 datepickerの下にelrteを配置したところ [...]
カテゴリー: 開発 | コメントは受け付けていません。

sfc-tools tutorial

社内勉強会で話した sfc-tools のチュートリアル資料です。

カテゴリー: debian, linux | コメントは受け付けていません。

Gitプロトコルでリモートリポジトリにアクセス

普段はssh経由でgitを使っているのだけれどhudsonでgit cloneするときにちょっと困ったので、認証の要らないGitプロトコルを使ってみることにしたよ。

hudsonでリモートのgitリポジトリからソース取って来ようとしたのだけれど、ssh経由なのでビルド自動実行時にパスワードプロンプトが出ちゃってうまくいかない。
そこで認証のいらないGitプロトコル(git://)でアクセスできるようにしてみたよ。
最初にgitosisというのを試そうと思ったのだけど、プロジェクトを管理する方法煩雑になりそうだったので、git-daemonだけでなんとかすることにした。ちなみにdebian。

目標

  • リポジトリの取得(git clone)はssh経由でなくてもできるように、git-daemonを動かしてgitプロトコルでアクセスできるようにする。
  • 日々の開発でpushする場合はssh経由で行う。


gitリポジトリの作成

gitサーバーで作業。

リポジトリサーバー名:sever
公開リポジトリの場所:/home/repos/

とするよ。ユーザー別に管理したかったので公開リポジトリの下に各ユーザーのディレクトリを作ったよ。僕用のディレクトリはskmkという名前。

$ cd /home/repos/skmk

まずここに管理用のbareリポジトリを作るよ。

$ mkdir hoge.git
$ cd hoge.git
$ git init --bare --shared=true
Initialized empty shared Git repository in /home/repos/skmk/hoge.git/
$ echo "Project hoge" > description
$ touch git-daemon-export-ok

descriptionを書き換えたのは、これをやらないとgit pushするときに
*** Project description file hasn’t been set
と怒られてpushできなかったからだよ。
git-daemon-export-okという空のファイルをtouchコマンドで作ったね。これをhoge.gitの直下に置くことで、このリポジトリは公開用という印になるんだよ。

gitリポジトリへpush

開発マシンでの作業
ローカルの開発マシンからpush。今回は新規に作ったものをサーバーへpushするよ。日々の開発用なのでssh経由で。

$ mkdir hoge_devel
$ cd hoge_devel
$ git init
$ touch hoge.txt
$ git add .
$ git commit -a -m"initial import"
$ git add remote origin ssh://server/home/repos/skmk/hoge.git
$ git push origin master
skmk@server's password:
Counting objects: 3, done.
Writing objects: 100% (3/3), 206 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://server/home/repos/skmk/hoge.git
* [new branch] ? ? ?master -> master


git-daemonを動かす

gitサーバーで作業。
あとはgit-daemonを動かす。まずは以下のコマンドで試してみるよ。

$ sudo -u gitosis git-daemon --base-path=/home/repos/ --reuseaddr --verbose /home/repos/git

オプションについて簡単な説明。

  • あらかじめ作ったgitユーザーでdaemonを実行する。僕の場合面倒だったので、aptitude install gitosisすると自動で作られるgitosisユーザーを流用して動かしたの。だから -u gitosisとなってるのでした。
  • –base-pathは公開リポジトリのベースとなる場所を指定
  • –reuseaddrをつけておくと古いコネクションのタイムアウトを待たないので、設定調整しながら動かしたり止めたりするときに便利だよ。
  • –export-allをつけるとgit-daemon-export-okの有無に関わらず全部公開されるよ。
  • –enable-server=receive-packをつけるとgitプロトコルでpushできるようになる。ただし誰でも認証なしで好き勝手にpushできちゃうので注意


gitプロトコルを使ってgit-cloneしてみる

開発マシンなど任意のサーバで作業。
git-daemon動かした状態で、ローカルマシンとかでgitプロトコル使ってgit cloneしてみる。

$ git clone git://server/skmk/hoge.git

–base-pathを設定してgit-daemon起動したので、sshのようにフルパス書かなくても、サーバーの後ろに/home/repos以下のディレクトリから書けば大丈夫だよ。
git-daemon-export-okを作るのを忘れていると

Initialized empty Git repository in /home/skmk/test/hoge/.git/
fatal: The remote end hung up unexpectedly

となってcloneできないよ。

xinetdでgit-daemonを動かす

gitサーバーで作業。
うまく動いたらスーパーサーバーデーモンにgit-daemonを登録するよ。さっき動かしたgit-daemonは止めてね。
xinetdの例で説明。xinetdがない場合はaptitude install xinetdでインストールしてね。
他のファイルに倣って、/etc/xinetd.d/gitというファイルを作成。

# description: git daemon
# This is the tcp version.
service git
{
    disable        = no
    socket_type    = stream
    protocol    = tcp
    user        = gitosis
    wait        = no
    server        = /usr/bin/git-daemon
    server_args    = --base-path=/home/repos/git --inetd --verbose
    log_on_failure    += USERID
}

port = 9418は/etc/servicesに入ってたから、なんとなく略してみた。
それでは、xinetdを再起動してみます。

# cd /etc/init.d
# ./xinetd restart
Stopping internet superserver: xinetd.
Starting internet superserver: xinetd.

これで、他のサーバーからgitプロトコルでgit-cloneできるはず。お疲れ様でした。

カテゴリー: git, xinetd | コメントは受け付けていません。

一度に複数のリモートリポジトリにgit pushする方法

コマンドひとつで複数のリモートリポジトリにgit pushしたい、そんなとき。

作業中リポジトリの.git/configを直接編集して、push先のurlを複数書いちゃう。
試したのはgit version 1.5.6.5だよ。

[remote "foobar"]
        url = /hoge/foo.git
        url = /hoge/bar.git

あとはリモートリポジトリfoobarにpushすれば、foo.gitとbar.gitにpushされるよ。
でもgit remote -vとかgit showしたときに

warning: Remote origin has more than one URL

って怒られるけどね。
git config -l なら内容を確認できるよ。

remote.foobar.url=/hoge/foo.git
remote.foobar.url=/hoge/bar.git

わけわかんなくなるから複数登録するときはpush用にした方がいいかもね。

カテゴリー: Tips, git | コメントは受け付けていません。