法律文書起案用mi文法定義スクリプトとOpenOffice系マクロ

はじめに

 以前、はてなブログで公開していた法律文書起案用mi文法定義スクリプトとOpenOffice系マクロ(の改良版)のソースコードをこっちに置いておきます。将来、検索でここに辿り着いた、同じことをしようとしている誰かの参考になるために。ちなみにそのブログはその1記事しかありません。それはそのうち閉鎖します。

テキストエディタmiで色分け表示

 OS X(Macの現行OS)用テキストエディタmiで起案中のプレーンテキストをこのように色分け表示

kianmi

するための文法定義スクリプトとして今私が使っているのが以下のとおり(2015年10月25日注:miバージョン2用です。3用はさらに下にあります)。私は、今はこれなしでは文章が書けません。
【2015年11月1日追記】
 こういうことするために、Header(見出し)機能があったんですね……今頃気がつきました。
 このスクリプトはもはやあまり価値がないので、記事の末尾に回します。
【2015年11月1日追記終わり】

OpenOffice系ワープロソフトでインデントをつけるためのマクロ

 私は今はLibreOfficeを使っています。
 司法修習生の頃はそれで良かったんですが、弁護士となると書式集がMS Word形式になっているのでMS Wordに乗り換えた方がいいかなあと最近思っています。
 段落冒頭と最後の文字列に対応してスタイルを適用します。例えば、上に載せたmiの画面のテキストが、以下のようになります。(2015年10月28日注:今はもっと美しくなるように改善していますが、画像を差し替えるのがめんどくさいので画像は昔のままになっています。)

kianlibre

 使っているソースコードは以下のとおり。


REM  *****  BASIC  *****

Sub Main

Dim oDoc as Object
Dim oText
Dim pt as Integer
pt = 35.2778
Dim proc as Integer
proc = 0
Dim paraStr as String

oDoc = ThisComponent
oText = oDoc.Text

oSelections = oDoc.getCurrentSelection() 
oSel = oSelections.getByIndex(0)    

oPE = oSel.createEnumeration()

Do While oPE.hasMoreElements()
	oPar = oPE.nextElement()
	If oPar.supportsService("com.sun.star.text.Paragraph") Then 
		paraStr = oPar.String
		
		'段落頭が全角スペース2つで始まらない場合はproc=0にする
		'段落頭が全角スペース2つで始まる場合又は「② 」等で始まる場合はprocの値が変わらないので前段落と同じになる
		If Not ( Left ( paraStr , 3 ) Like "  [! ]" And Right( paraStr, 1 ) Like "[! ]" ) And Not ( Left ( paraStr , 2 ) Like "[①-⑨] " ) Then
			proc = 0
		End If
		
		'「① 」で始まる場合は前段落より1字下げる
		If Left(paraStr,2)  = "① " Then
			proc = proc + 1
		End If

		'段落頭がマッチする場合
		If Left( paraStr, 3 ) Like "第[0-9] " Or Left( paraStr, 4 ) Like "第[0-9][0-9] " Then
			oPar.ParaLeftMargin = 24*pt
			oPar.ParaFirstLineIndent = -24*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 2

		ElseIf Left( paraStr, 2 ) Like "[0-9] " Or Left( paraStr, 3 ) Like "[0-9][0-9] " Or proc = 2 Then
			oPar.ParaLeftMargin = 24*pt
			oPar.ParaFirstLineIndent = -12*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 2
			
		ElseIf Left( paraStr, 5 ) Like "[0-9]([0-9]) " Or Left( paraStr, 6 ) Like "[0-9]([0-9][0-9]) " Or Left( paraStr, 6 ) Like "[0-9][0-9]([0-9]) " Or Left( oPar.String, 7 ) Like "[0-9][0-9]([0-9][0-9]) " Then
			oPar.ParaLeftMargin = 36*pt
			oPar.ParaFirstLineIndent = -24*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 3

		ElseIf Left( paraStr, 4 ) Like "([0-9]) " Or Left( paraStr, 5 ) Like "([0-9][0-9]) " Or proc = 3 Then
			oPar.ParaLeftMargin = 36*pt
			oPar.ParaFirstLineIndent = -12*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 3
			
		ElseIf Left( paraStr, 5 ) Like "([0-9])[ア-ン] " Or Left( paraStr, 8 ) Like "([0-9])([0-9])[ア-ン] " Then
			oPar.ParaLeftMargin = 48*pt
			oPar.ParaFirstLineIndent = -24*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 4

		ElseIf Left( paraStr, 2 ) Like "[ア-ン] " Or proc = 4 Then
			oPar.ParaLeftMargin = 48*pt
			oPar.ParaFirstLineIndent = -12*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 4
			
		ElseIf Left( paraStr, 5 ) Like "[ア-ン]([ア-ン]) " Then
			oPar.ParaLeftMargin = 60*pt
			oPar.ParaFirstLineIndent = -24*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 5

		ElseIf Left( paraStr, 4 ) Like "([ア-ン]) " Or proc = 5 Then
			oPar.ParaLeftMargin = 60*pt
			oPar.ParaFirstLineIndent = -12*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 5
			
		ElseIf Left( paraStr, 5 ) Like "([ア-ン])[a-z] " Then
			oPar.ParaLeftMargin = 72*pt
			oPar.ParaFirstLineIndent = -24*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 6

		ElseIf Left( paraStr, 2 ) Like "[a-z] " Or proc = 6 Then
			oPar.ParaLeftMargin = 72*pt
			oPar.ParaFirstLineIndent = -12*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 6
			
		ElseIf Left( paraStr, 5 ) Like "[a-z]([a-z]) " Then
			oPar.ParaLeftMargin = 84*pt
			oPar.ParaFirstLineIndent = -24*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 7

		ElseIf Left( paraStr, 4 ) Like "([a-z]) " Or proc = 7 Then
			oPar.ParaLeftMargin = 84*pt
			oPar.ParaFirstLineIndent = -12*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 7
			
		ElseIf proc = 8 Then
			oPar.ParaLeftMargin = 96*pt
			oPar.ParaFirstLineIndent = -12*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 8
			
		'契約書用条文番号
		ElseIf Left( paraStr, 3 ) Like "第[0-9]条" Or Left( paraStr, 4 ) Like "第[0-9][0-9]条" Or proc = 9 Then
			oPar.ParaLeftMargin = 12*pt
			oPar.ParaFirstLineIndent = -12*pt
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 9

		'paraAdjust等を半角スペースで指定する場合
		ElseIf Left( paraStr, 3 ) Like "  [! ]" And Right( paraStr, 2 ) Like "[! ] " Then
			oPar.ParaLeftMargin = 0
			oPar.ParaFirstLineIndent = 0
			oPar.ParaAdjust = 1
			oPar.CharHeightAsian = 12
			proc = 10
	
		ElseIf Left( paraStr, 3 ) Like "  [! ]" And Right( paraStr, 3 ) Like "[! ]  " Then
			oPar.ParaLeftMargin = 0
			oPar.ParaFirstLineIndent = 0
			oPar.ParaAdjust = 3
			oPar.CharHeightAsian = 12
			proc = 10

		ElseIf Left( paraStr, 4 ) Like "   [! ]" And Right( paraStr, 4 ) Like "[! ]   " Then
			oPar.ParaLeftMargin = 0
			oPar.ParaFirstLineIndent = 0
			oPar.ParaAdjust = 3
			oPar.CharHeightAsian = 14
			proc = 10

		ElseIf Left( paraStr, 5 ) Like "    [! ]" And Right( paraStr, 5 ) Like "[! ]    " Then
			oPar.ParaLeftMargin = 0
			oPar.ParaFirstLineIndent = 0
			oPar.ParaAdjust = 3
			oPar.CharHeightAsian = 16
			proc = 10

		'paraAdjust等を全角スペースで指定する場合
		ElseIf Left( paraStr, 3 ) Like "  [! ]" And Right( paraStr, 2 ) Like "[! ] " Then
			oPar.ParaLeftMargin = 0
			oPar.ParaFirstLineIndent = 0
			oPar.ParaAdjust = 1
			oPar.CharHeightAsian = 12
			proc = 10
	
		ElseIf Left( paraStr, 3 ) Like "  [! ]" And Right( paraStr, 3 ) Like "[! ]  " Then
			oPar.ParaLeftMargin = 0
			oPar.ParaFirstLineIndent = 0
			oPar.ParaAdjust = 3
			oPar.CharHeightAsian = 12
			proc = 10
	
		ElseIf Left( paraStr, 4 ) Like "   [! ]" And Right( paraStr, 4 ) Like "[! ]   " Then
			oPar.ParaLeftMargin = 0
			oPar.ParaFirstLineIndent = 0
			oPar.ParaAdjust = 3
			oPar.CharHeightAsian = 14
			proc = 10

		ElseIf Left( paraStr, 5 ) Like "    [! ]" And Right( paraStr, 5 ) Like "[! ]    " Then
			oPar.ParaLeftMargin = 0
			oPar.ParaFirstLineIndent = 0
			oPar.ParaAdjust = 3
			oPar.CharHeightAsian = 16
			proc = 10

		'デフォルトの段落
		ElseIf proc = 0 then
			oPar.ParaLeftMargin = 0
			oPar.ParaFirstLineIndent = 0
			oPar.ParaAdjust = 0
			oPar.CharHeightAsian = 12
			proc = 0
		End If
		
		'今回paraAdjust等をスペースで指定したら次回はデフォルトから出発
		If proc = 10 then
			proc = 0
		End If
		
	end if
Loop

End Sub

更新履歴

・2015年10月26日更新
 Like演算子というものを知ったので、全面的に書き直しました。今回のバージョンではスタイルを使わずにマクロから直接インデント等を設定します。前回のバージョンでは文書全体を処理しましたが、今回のバージョンでは選択範囲だけ処理します。
 なお、こっちの記事(法律文書起案用MS Word用VBAマクロ)にあるMS Word用マクロとだいたい同じ処理になるようにしました。
・2015年10月27日午前更新
 ElseIfで書き直しました。
・2015年10月27日午後更新
 「2(1) 」や「(3)ア 」等の表現に対応しました。
 ①〜⑨が列挙される際、①の前の段落と比較して1字下がるようにしました。
・2015年10月29日更新
 スペースで指定する場合のバグフィックス。

おわりに

 色分けがないとソースコード貼ったときに不格好ですね。WordPressでもプラグインを入れれば簡単にできるようですが、ここはプログラミングのブログではないのでそこまではしません。

miの文法定義スクリプト


GlobalAttribute_SDFVersion("1.0")
GlobalAttribute_SDFName("kian")

state(idle)
{
	StateAttribute_Stable
	StateAttribute_DisableAllCategory
	StateAttribute_DefaultColor("000000")
	{lineend,{ChangeState(gyoto)}}
}

state(gyoto)
{
	StateAttribute_DefaultColor("000000")
	{"第1 ",{ChangeState(dai)}}
	{"第2 ",{ChangeState(dai)}}
	{"第3 ",{ChangeState(dai)}}
	{"第4 ",{ChangeState(dai)}}
	{"第5 ",{ChangeState(dai)}}
	{"第6 ",{ChangeState(dai)}}
	{"第7 ",{ChangeState(dai)}}
	{"第8 ",{ChangeState(dai)}}
	{"第9 ",{ChangeState(dai)}}
	{"第1条 ",{ChangeState(dai)}}
	{"第2条 ",{ChangeState(dai)}}
	{"第3条 ",{ChangeState(dai)}}
	{"第4条 ",{ChangeState(dai)}}
	{"第5条 ",{ChangeState(dai)}}
	{"第6条 ",{ChangeState(dai)}}
	{"第7条 ",{ChangeState(dai)}}
	{"第8条 ",{ChangeState(dai)}}
	{"第9条 ",{ChangeState(dai)}}
	{"第10条 ",{ChangeState(dai)}}
	{"第11条 ",{ChangeState(dai)}}
	{"第12条 ",{ChangeState(dai)}}
	{"第13条 ",{ChangeState(dai)}}
	{"第14条 ",{ChangeState(dai)}}
	{"第15条 ",{ChangeState(dai)}}
	{"第16条 ",{ChangeState(dai)}}
	{"第17条 ",{ChangeState(dai)}}
	{"第18条 ",{ChangeState(dai)}}
	{"第19条 ",{ChangeState(dai)}}
	{"第20条 ",{ChangeState(dai)}}
	{"第21条 ",{ChangeState(dai)}}
	{"第22条 ",{ChangeState(dai)}}
	{"第23条 ",{ChangeState(dai)}}
	{"第24条 ",{ChangeState(dai)}}
	{"第25条 ",{ChangeState(dai)}}
	{"第26条 ",{ChangeState(dai)}}
	{"第27条 ",{ChangeState(dai)}}
	{"第28条 ",{ChangeState(dai)}}
	{"第29条 ",{ChangeState(dai)}}
	{"1 ",{ChangeState(suu)}}
	{"2 ",{ChangeState(suu)}}
	{"3 ",{ChangeState(suu)}}
	{"4 ",{ChangeState(suu)}}
	{"5 ",{ChangeState(suu)}}
	{"6 ",{ChangeState(suu)}}
	{"7 ",{ChangeState(suu)}}
	{"8 ",{ChangeState(suu)}}
	{"9 ",{ChangeState(suu)}}
	{"(1) ",{ChangeState(kakkosuu)}}
	{"(2) ",{ChangeState(kakkosuu)}}
	{"(3) ",{ChangeState(kakkosuu)}}
	{"(4) ",{ChangeState(kakkosuu)}}
	{"(5) ",{ChangeState(kakkosuu)}}
	{"(6) ",{ChangeState(kakkosuu)}}
	{"(7) ",{ChangeState(kakkosuu)}}
	{"(8) ",{ChangeState(kakkosuu)}}
	{"(9) ",{ChangeState(kakkosuu)}}
	{"ア ",{ChangeState(kana)}}
	{"イ ",{ChangeState(kana)}}
	{"ウ ",{ChangeState(kana)}}
	{"エ ",{ChangeState(kana)}}
	{"オ ",{ChangeState(kana)}}
	{"カ ",{ChangeState(kana)}}
	{"キ ",{ChangeState(kana)}}
	{"ク ",{ChangeState(kana)}}
	{"ケ ",{ChangeState(kana)}}
	{"(ア) ",{ChangeState(kakkokana)}}
	{"(イ) ",{ChangeState(kakkokana)}}
	{"(ウ) ",{ChangeState(kakkokana)}}
	{"(エ) ",{ChangeState(kakkokana)}}
	{"(オ) ",{ChangeState(kakkokana)}}
	{"(カ) ",{ChangeState(kakkokana)}}
	{"(キ) ",{ChangeState(kakkokana)}}
	{"(ク) ",{ChangeState(kakkokana)}}
	{"(ケ) ",{ChangeState(kakkokana)}}
	{default,{ChangeState(idle)}}
	{lineend,{ChangeState(gyoto)}}
}

state(dai)
{
	StateAttribute_DefaultColor("FF0000")
	{lineend,{ChangeState(gyoto)}}
}

state(suu)
{
	StateAttribute_DefaultColor("DD00DD")
	{lineend,{ChangeState(gyoto)}}
}

state(kakkosuu)
{
	StateAttribute_DefaultColor("0000FF")
	{lineend,{ChangeState(gyoto)}}
}

state(kana)
{
	StateAttribute_DefaultColor("00AA00")
	{lineend,{ChangeState(gyoto)}}
}

state(kakkokana)
{
	StateAttribute_DefaultColor("DD8800")
	{lineend,{ChangeState(gyoto)}}
}

state(sonota)
{
	StateAttribute_DefaultColor("000000")
	{lineend,{ChangeState(gyoto)}}
}

miバージョン3用スクリプト(2015年10月5日以降更新)

・2015年10月5日更新
 miのバージョン3のベータ版を使ってみたんですが、文法定義スクリプトの仕様が一部変更になっていますね。

	StateAttribute_DefaultColor("DD8800")

等の部分を

	StateAttribute_DefaultColor(1)

等と指定し、Mode PreferencesメニューのColorsタブで具体的な色を指定することになります。
・2015年10月7日更新
 バージョン3からは正規表現が使えるようになっているので、全面的に書き直しました。ついでに、手控え用として、「H271007」のような表現で始まる段落と、「#」で始まる段落にも色をつけることにしました。

GlobalAttribute_SDFVersion("3.0")
GlobalAttribute_SDFName("kian")

state(idle)
{
	{regexp"^(1 )?[H|S|T|M][\\d|x]{6,6}",{ChangeState(ymd)}}
	{regexp"^#",{ChangeState(comment)}}
	{regexp"^第[0-9]+ ",{ChangeState(dai)}}
	{regexp"^第[0-9]+条",{ChangeState(dai)}}
	{regexp"^[0-9]+(\\(\\d+\\))* ",{ChangeState(suu)}}
	{regexp"^\\(\\d+\\)[ア-ン]* ",{ChangeState(kakkosuu)}}
	{regexp"^[ア-ン](\\([ア-ン]\\))* ",{ChangeState(kana)}}
	{regexp"^\\([ア-ン]\\)[a-z]* ",{ChangeState(kakkokana)}}
	{regexp"^[a-z] |\\([a-z]\\) |^[①-⑨]+ |^[α-ω] ",{ChangeState(sonota)}}
}

state(ymd)
{
	StateAttribute_ColorSlot(0)
	{lineend,{ChangeState(idle)}}
}

state(comment)
{
	StateAttribute_ColorSlot(7)
	{lineend,{ChangeState(idle)}}
}

state(dai)
{
	StateAttribute_ColorSlot(1)
	{lineend,{ChangeState(idle)}}
}

state(suu)
{
	StateAttribute_ColorSlot(2)
	{lineend,{ChangeState(idle)}}
}

state(kakkosuu)
{
	StateAttribute_ColorSlot(3)
	{lineend,{ChangeState(idle)}}
}

state(kana)
{
	StateAttribute_ColorSlot(4)
	{lineend,{ChangeState(idle)}}
}

state(kakkokana)
{
	StateAttribute_ColorSlot(5)
	{lineend,{ChangeState(idle)}}
}

state(sonota)
{
	StateAttribute_ColorSlot(6)
	{lineend,{ChangeState(idle)}}
}

更新履歴

・2015年10月25日更新
 「第n条」の処理を単純化しました。何が続こうがとにかく行頭に「第n条」(n≧0)と書いてあればそれ用の処理をするようにしました。
・2015年10月27日更新
 バージョン3のスクリプトにおいて、例えば、「2(1) 」を「2 」と同様の、「(3)ア 」を「(3) 」と同様の色になるようにしました。

2件のピンバック

コメントは現在停止中です。