Index > mif2xml ... mif を XMLに変換(FrameMaker,jython)
Mon, May 25, 2009

mif2xml ... mif を XMLに変換(FrameMaker,jython)

Structured FrameMaker はルールベースで、レイアウトを作り出せるので、 ページ数が多いドキュメント作成に重宝しますが、 テンプレートのマスターページ管理が気に入りません... 具体的には以下の通り。

少しだけ異なるマスターページがたくさん必要・・・という状況

本をつくるとき、 ツメ以外は全く同じレイアウトなのですが、 ツメだけ章ごとに位置が異なるため、 章の数だけマスターページをコピーしてツメ調整しなければならない。

ツメの位置の差分だけを簡単に管理できないものかと、 FDK関係の情報を探していたところ、mifを直接操作する方法があることがわかりました。

しかし、mifをそのまま手作業で直していたのでは効率が悪い。 (FrameMaker上で作業した方がよっぽどはやい) そこをなんとか、と調査したところ、 mif2xmlというツールがあることがわかりました。

mifはXMLに似た構造になっているので、相互変換は問題なさそうです。 できれば既存ツールを使いたかったのですが、自分のニーズにあうものがなかったので、 とりあえずjythonで実装したので、ここでメモとして置いておきます。

実行には jdom.jar が必要です。

現在のところ、ごく簡単な mif データで変換できることを確認しただけです。

mif2xml.py

import sys

import java.lang as lang
import java.io as io
import java.util as util

import java.util.regex as re


import org.jdom as jdom



false=0
true=1


ENC="UTF-8"


inf=sys.argv[1]
outf=sys.argv[2]


patElementStartAndTerminal=re.Pattern.compile("^<([^ ]*) (.*)>$")
patCommentout=re.Pattern.compile("(^.*>) +#.*$")
patElementStart=re.Pattern.compile("^<(.*)?")


def cleanup(lines):

    lines2=util.ArrayList()
    for line in lines :
        if lang.String(line).startsWith("#"):
            continue;

        m=patCommentout.matcher(lang.String(line))
        if m.matches():
            str=m.group(1)
            if len(str)>0:
                lines2.add( lang.String(str) )
        else :
            lines2.add( line )

    return lines2



f=io.File(inf)

br=io.BufferedReader( io.InputStreamReader( io.FileInputStream(f),ENC ) )

lines=util.ArrayList()
while(true) :
    line=br.readLine()
    if line==None:
        break

    lines.add(line)

lines=cleanup(lines)


stack=util.Stack()

eRoot=jdom.Element("root")
stack.push( eRoot )

for line in lines :

    str= lang.String(line).trim()
    #print str

    m=patElementStartAndTerminal.matcher(str)
    if m.matches():
        eleName = m.group(1)
        eleName = lang.String(eleName).trim()
        #print eleName
        e=jdom.Element(eleName)
        e.text=m.group(2)
        stack.peek().addContent( e )

        continue


    m=patElementStart.matcher(str)
    if m.matches():
        eleName = m.group(1)
        eleName = lang.String(eleName).trim()
        e=jdom.Element(eleName)

        stack.peek().addContent( e )
        stack.push( e )

    else :
        if lang.String(str).startsWith(">") :
            e=stack.pop()
        else :
            #print str
            print "something is wrong(2)."


doc=jdom.Document()
doc.setRootElement( eRoot )

format=jdom.output.Format.getPrettyFormat()
format.encoding="UTF-8"

w=io.OutputStreamWriter( io.FileOutputStream(io.File(outf)),"UTF-8" )
jdom.output.XMLOutputter(format).output( doc, w )
w.close()

実行方法

jdom.jar をクラスパスに通してからjythonで実行。

$ export CLASSPATH=/path/to/jdom.jar;jython mif2xml.py foo.mif foo.xml

xml2mif.py

import sys

import java.lang as lang
import java.io as io
import java.util as util

import java.util.regex as re


import org.jdom as jdom



false=0
true=1


ENC="UTF-8"


inf=sys.argv[1]
outf=sys.argv[2]


def parse( pw, e ):
    if e.getChildren().size()<1 :
        pw.println( "<"+e.name+" "+e.text+">" )
    else :
        isRoot=false
        if e.name=="root" :
            isRoot=true

        if isRoot==false:
            pw.println( "<"+e.name )

        for ec in e.children :
            parse( pw,ec )

        if isRoot==false:
            pw.println( "> # end of "+e.name )




doc=jdom.input.SAXBuilder().build(inf)
eRoot=doc.rootElement
print eRoot

pw=io.PrintWriter( io.OutputStreamWriter( io.FileOutputStream(outf),ENC ) )
parse( pw, eRoot )
pw.close()

実行方法

jdom.jar をクラスパスに通してからjythonで実行。

$ export CLASSPATH=/path/to/jdom.jar;jython xml2mif.py foo.xml foo.mif
 Twitter
follow me on Twitter
 Categories