(この記事は旧ブログから2025年6月3日に移設したものです)
はじめに
以前、はてなブログで公開していた法律文書起案用mi文法定義スクリプトとOpenOffice系マクロ(の改良版)のソースコードをこっちに置いておきます。将来、検索でここに辿り着いた、同じことをしようとしている誰かの参考になるために。ちなみにそのブログはその1記事しかありません。それはそのうち閉鎖します。テキストエディタmiで色分け表示
OS X(Macの現行OS)用テキストエディタmiで起案中のプレーンテキストをこのように色分け表示するための文法定義スクリプトとして今私が使っているのが以下のとおり(2015年10月25日注:miバージョン2用です。3用はさらに下にあります)。私は、今はこれなしでは文章が書けません。
【2015年11月1日追記】
こういうことするために、Header(見出し)機能があったんですね……今頃気がつきました。
このスクリプトはもはやあまり価値がないので、記事の末尾に回します。
【2015年11月1日追記終わり】

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