JAMWikiでWikipedia記事をパースする

JAMWikiというJavaMediaWiki実装があります。以前はコンポーネント間の結合が強くて利用しづらい印象だったんですが、0.6.xからはコアエンジンが分離されたり、mavenizeされたりと使いやすくなっているようです。

JAMWikiのパーサにWikipediaの記事を読ませてみたら、表組み等の複雑なマークアップも含めて問題なくHTML化できたので、パーサ単体での使用手順を書いてみます。バージョンは0.6.5です。

1. JAMWikiをダウンロードしてビルドする(Mavenのセントラルリポジトリには上がっていないっぽい)。

2. jamwiki-war/src/main/resourcesから、ApplicationResources.properties, interwiki.properties, jamwiki-configuration.xml, logging.propertiesをクラスパスルートにコピーする。

3. パース中にコールバックされるUserHandler, DataHandler, SearchEngineの各インターフェイスを空実装する。

import org.jamwiki.UserHandler;

public class EmptyDataHandler implements UserHandler {
    // 以下空実装
}
import org.jamwiki.DataHandler;

public class EmptyDataHandler implements DataHandler {
    // 以下空実装
}
import org.jamwiki.SearchEngine;

public class EmptySearchEngine implements SearchEngine {
    // 以下空実装
}

4. クラスパスルートにjamwiki.propertiesを新規作成し、上記のクラスを登録する。

user-handler=test.EmptyUserHandler
database-type=test.EmptyDataHandler
search-engine=test.EmptySearchEngine

5. 実際にパースを行うサンプルプログラムです。

public class WikiParser {
    private static final Pattern ENTITY_PATTERN =
        Pattern.compile("\\&(amp;)?\\#([0-9]+);");

    public String parse(String wikiText) throws Exception {
        ParserInput in = new ParserInput();
        in.setContext("/some_context");
        in.setTopicName("some_topic");
        in.setVirtualWiki("ja");
        in.setAllowSectionEdit(false);

        JFlexParser parser = new JFlexParser(in);
        String html = parser.parseHTML(new ParserOutput(), wikiText);

        // 日本語が実体参照に変換されてしまうので元に戻す
        Matcher matcher = ENTITY_PATTERN.matcher(html);
        StringBuffer buf = new StringBuffer();
        while (matcher.find()) {
            int code = Integer.parseInt(matcher.group(2));
            char ch = (char) code;
            matcher.appendReplacement(buf, String.valueOf(ch));
        }
        matcher.appendTail(buf);

        return buf.toString();
    }
}