2009年12月31日木曜日

SpringSource Tool Suite (Eclipse) でGrailsの.propertiesファイルの日本語が化ける件。

正月休みにGrailsを再勉強しようと思い、せっかくなので SpringSource Tool Suite(以下STS)を使ってみようと思った。

STSの使い方、Groovy,Grails環境の設定については、tyama氏が詳しい説明を書いてくれています。
SpringSource Tool Suite 2.2.0でGrailsをためしてみた。 - leftovers...

ダウンロードしてインストールして、設定して、create-appして、順調に行っていたのだが、i18nの messeages_ja.properties の中にある日本語が、全部化けているのに気がつく。

日本語の設定場所を探したが見つからない。そういえばこれもEclipseなんだから、と思ってEcripseをキーワードに検索したら、なんだかいろいろこみいった事情があることが分かった。
  • Javaでは、Propertiesクラスは7バイトまでしか対応していない(Java6でマルチバイトに対応)。
  • .propertiesのエンコーディングはISO 8859-1が使用される。
  • Javaの場合、.propertiesで日本語を使用する場合は、native2asciiを使って、Unicodeコードに変換する。
そんなわけで、Eclipse標準のProperties File EditorはUTF8の日本語を開けないのが仕様みたい。

Grailsの.propertiesファイルには日本語をそのまま書いていいはず(create-appして生成されるファイルには日本語そのまま書いてある)ので、これでは困る。
Eclipseのいろんなサイトに書いてあったプロパティエディタを入れることにした。

http://sourceforge.jp/projects/propedit/
から、jp.gr.java_conf.ussiy.app.propedit_4.8.2_for_eclipse3.0.zip を落として解凍する。
できたフォルダの、featuresの中身をspringsource/sts-2.3.0.RELEASE/features/、
pluginsの中身をspringsource/sts-2.3.0.RELEASE/plugins/の中に入れる。
STSを再起動し、環境設定の
General > Editors > File Associations から *.properties のデフォルトエディタにする。

プロパティエディタ から、変換オプションで"全てユニコード変換しない"にチェック。

これで日本語が表示される。OK。

2009年12月21日月曜日

XmlSlurperで属性をそのままテキストだけを入れ替える。

GroovyではXML処理に、XmlPerserとXmlSlurper(他いろいろ……)が用意されてあって、ただ読み込む場合はXmlSlurper、編集するなり書き換える場合はXmlPerserを使うように、って棲み分けがされている。
だけどSlurperでもいちおう簡単な編集機能は用意されてるみたいで、
XmlSlurper を使った XML の加工 - なんとなくな Developer のメモ
  • 要素の追加: appendNode メソッドを使用
  • 属性の追加: @属性名 に値を設定
  • 要素の置換: replaceNode メソッドを使用
  • 要素の削除: replaceNode メソッドを使用(実装を空にする)

となるらしい。なのでこれを使ってXMLのテキストを入れ替えようと思った。
import groovy.xml.StreamingMarkupBuilder

String myXml='''<root>
<species order="甲虫目" family="コガネムシ科">カブトムシ</species>
<species order="甲虫目" family="カミキリムシ科">シロスジカミキリ</species>
<species order="チョウ目" family="アゲハチョウ科">アゲハチョウ</species>
</root>'''

def doc = new XmlSlurper().parseText(myXml)

doc.species[0].replaceNode{species('クロカナブン')}

//テキストに戻す
StreamingMarkupBuilder builder = new StreamingMarkupBuilder()
builder.encoding = "UTF8"
def newXml = builder.bind{mkp.yield doc};

println(newXml)
こうすると、当然「カブトムシ」の要素ごと書き変わってしまうので、クロカナブンの目と科がわからなくなってしまう。少し(かなり)考えて、属性を保存して、新しく入れ替える要素にコピーできるんじゃないかな?
import groovy.xml.StreamingMarkupBuilder

String myXml='''<root>
<species order="甲虫目" family="コガネムシ科">カブトムシ</species>
<species order="甲虫目" family="カミキリムシ科">シロスジカミキリ</species>
<species order="チョウ目" family="アゲハチョウ科">アゲハチョウ</species>
</root>'''

def doc = new XmlSlurper().parseText(myXml)
//assert doc.species[0] == 'カブトムシ'

Map attr = doc.species[0].attributes();
//assert attr == [family:'コガネムシ科', order:'甲虫目']

//ノードを置き換える時に属性をそのままコピー
doc.species[0].replaceNode{species('クロカナブン',attr)}

//テキストに戻す
StreamingMarkupBuilder builder = new StreamingMarkupBuilder()
builder.encoding = "UTF8"
def newXml = builder.bind{mkp.yield doc};

println(newXml)
これでOK。属性のマップをそのまま後ろに入れるだけで属性になる。へー。
結果はこう。
<root><species family='コガネムシ科' order='甲虫目'>クロカナブン</species><species family='カミキリムシ科' order='甲虫目'>シロスジカミキリ</species><species family='アゲハチョウ科' order='チョウ目'>アゲハチョウ</species></root>

groovyでWikiTextを使ってみる

仕事が煮詰まって頭モウロウとしながらひたすら検索してると、ちょっと気になるブログ記事を見つけた。
WikiTextことはじめ - Talking Nonstop
WikiTextとは、Javaで書かれたWikiパーサです。

なにこれ面白そう。Groovyから叩けるかな?そう思ってやってみた。
まず、MylynのページからWikiTextスタンドアロン版(mylyn-wikitext-standalone-latest.zip)を落として解凍、中に入ってる.jarを全て~/.groovy/lib/につっこむ。
import org.eclipse.mylyn.wikitext.core.parser.MarkupParser
import org.eclipse.mylyn.wikitext.confluence.core.ConfluenceLanguage
import org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder

String markupContent='''h1. 見出し1
ここは見出し1のテキスト部分

h2. 見出し2
ここは見出し2のテキスト部分

h3. 見出し3
ここは見出し3のテキスト部分
* 箇条書き1行目
* 箇条書き2行目
* 箇条書き3行目
** 3行目の1
** 3行目の2

# 番号つき1行目
# 番号つき2行目
# 番号つき3行目'''

StringWriter writer = new StringWriter();
HtmlDocumentBuilder builder = new HtmlDocumentBuilder(writer);

MarkupParser parser = new MarkupParser(new ConfluenceLanguage());
parser.setBuilder(builder);
parser.parse(markupContent);

String htmlContent = writer.toString();
println(htmlContent)
それの結果。
<?xml version='1.0' encoding='utf-8' ?><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/></head><body><h1 id="a1">見出し1</h1><p>ここは見出し1のテキスト部分</p><h2 id="a2">見出し2</h2><p>ここは見出し2のテキスト部分</p><h3 id="a3">見出し3</h3><p>ここは見出し3のテキスト部分</p><ul><li>箇条書き1行目</li><li>箇条書き2行目</li><li>箇条書き3行目<ul><li>3行目の1</li><li>3行目の2</li></ul></li></ul><ol><li>番号つき1行目</li><li>番号つき2行目</li><li>番号つき3行目</li></ol></body></html>

楽しい!いつか何か作ろう。

2009年12月14日月曜日

InDesignでガイド線に合わせて表を作成する。

何がやりたかったのかというと、これです。

様式のトレース。セルが複雑になってくると、意外と難しいんですよこれ。
これの線に合わせてガイドを引いて、表を作成した後余分な線を抜こうという計画。


ガイド線を引いた後、このスクリプトを実行すると

こんな感じに。(見やすくなるように、バックを薄くして、線を太くしてあります。)
InDesignCS3,MacOSX10.5.8上で動作確認。

2009年12月7日月曜日

なるほどreturnすりゃ止まるんだ

たぶん、分かってる人から見れば今更なエントリ。
var fol=Folder.selectDialog("フォルダを選択");
if(!fol){
alert("処理を中止しました。");
}else{

/*
















*/

}
みたいなコードを書いた事ないだろうか。
前に先輩から「こういう長いカッコ使うのやめなよ」と言われていたのだが、 そのときは実際どうすればいいのかは教わらなかったし、いままでどうするかも思いつかなかった。

ところで、人の書いてるスクリプトを読んでいるとたまに
(function(){
//処理
})();
みたいな感じに、全体をfunctionでつつみこんでそのまま実行しているスクリプトを見る。
この書き方については「組版時間を半減する! InDesign自動処理実例集」の99ページにふれてあって
 これは、各プログラム中で使用されている変数名などで共通のものがあるために、同時にサンプルプログラムを使用する際に干渉しないようにするためのものです。

ということで、functionの中で変数をvar宣言してあればその宣言はその中の範囲にしか適用されない。そういうもんなんだろなと思ってた。

ところがAdobeのサンプルコードを読んでいて、別の効果があることに気づいた。
(function(){
 var fol=Folder.selectDialog("フォルダを選択");
if(!fol){
alert("処理を中止しました。");
return;
}
//処理
})();
returnすればScriptを抜けられる!これで長い{}を書いて、カッコの閉じ忘れを気にしなくてすむ。
なるほどーー、そうかー。