WordでMarkdownっぽいことをするマクロ(Word)
やりたいこと
- 先頭に
#
を付けた段落には、「#
」の数に応じた階層の「見出し」スタイルを当てる。 - その他の「標準」スタイルの段落には、「本文」のスタイルを当てる。
こういうことがしたい。
仕事柄、文章の資料を作成することが多い。下書き段階ではテキストエディタでぐりぐり書いていきたいのだが、見出しとかの表現がmachine-readableでなくていまいちだった。
「だったら、Markdown的に書けるようにしたらいいんじゃね?」と思って、冗談半分で作り始めたのがきっかけ。
今ではいろんな表現に対応した立派な〝インチキMarkdownマクロ〟になり、非常に重宝しているのだが、今回は「見出し」だけに対応した簡易ヴァージョンをご紹介、というわけ。
こんなコード
Document
オブジェクトを渡したら、その配下のParagraphs
コレクションの要素であるParagraph
オブジェクトを一つづつ調べ、先頭に「#
」があったら「#
」の数に応じた「見出し」スタイルを、先頭に「#
」がなくて、なおかつ「標準」スタイルの段落なら、「本文」用のスタイルを当てる、というもの。
さっそくコードをお示ししよう。
リスト1
Public Sub SetHeaderStyle(ByVal a_Document As Document) Dim tgtDoc As Document Set tgtDoc = a_Document Dim tgtPara As Paragraph Dim tmpLen As Long Dim tmpStr As String Dim i As Long Dim j As Long For Each tgtPara In tgtDoc.Paragraphs With tgtPara With .Range '「#」で始まらない段落は飛ばす。' If .Characters.Item(1).Text <> "#" Then GoTo Continue tmpLen = Len(.Text) - 1 '改段落文字分を引く。' '2文字未満なら見出しのわけがないので飛ばす' If tmpLen < 2 Then GoTo Continue '見出しレベル9でも10字にしかならないので最大10字で切る。' If tmpLen > 10 Then tmpLen = 10 tmpStr = Left(.Text, tmpLen) '「# 」が含まれていなかったら飛ばす。' If InStr(1, tmpStr, "# ") < 1 Then GoTo Continue '先頭が〈「#」の連続+半角スペース〉になっていたら見出し。' For i = tmpLen To 2 Step -1 '……(*)' If Left(tmpStr, i) = String(i - 1, "#") & " " Then tgtPara.Style = "見出し " & CStr(i - 1) For j = i To 1 Step -1 Call .Characters.Item(j).Delete Next End If Next End With End With Continue: '見出しでない標準スタイルの段落には本文字下げスタイル。' If tgtPara.Style = "標準" Then tgtPara.Style = "My本文字下げ1" '……(**)' End If Next End Sub
だいたい見ての通りなので、説明は省略。
ただし、「(*)
」のところだけ簡単に説明しておく。
For i = tmpLen To 2 Step -1 '……(1)' If Left(tmpStr, i) = String(i - 1, "#") & " " Then '……(2)' tgtPara.Style = "見出し " & CStr(i - 1) '……(3)' For j = i To 1 Step -1 '……(4)' Call .Characters.Item(j).Delete Next End If Next
まず、(1)の
For i = tmpLen To 2 Step -1
では、段落先頭から最大10まで(段落の文字数が、改段落マークを除いて10字未満なら、10よりも小さな数になる。)の数値を表す変数tmpLen
を1
づつ減じながらループする。
(2)の
If Left(tmpStr, i) = String(i - 1, "#") & " " Then
で、tmpStr
に入っている文字列(段落先頭からtmpLen
字分切り取った文字列。)を先頭からi
字分切り取った文字列を調べる。
たとえば、i
が4
のときに、tmpStr
の先頭i
文字、つまり先頭4字が「###
」(#
3個と半角スペース)だったら、見出しレベル3を適用すれば良いことになる。
(2)の条件式がTrue
になると、(3)の
tgtPara.Style = "見出し " & CStr(i - 1)
で、当該の段落に「見出し」スタイルを適用する。
先の例でいうと、i
が4
のときには、見出しレベル「3
」を適用するのだから、"見出し " & CStr(i - 1)
とすれば、めでたく「見出し 3」という文字列を組み立てることができる。
あとは、(4)からの3行、
For j = i To 1 Step -1 '……(4)' Call .Characters.Item(j).Delete Next
で、見出しであることを表す「# 」を削除する。
コレクションの要素を削除すると、自動でインデックスが繰り上がる仕様なので、こうしないとおかしなことになる。
「削除はケツから!」は常識中の常識である!
ちなみに、(**)
の
If tgtPara.Style = "標準" Then tgtPara.Style = "My本文字下げ1" End If
のところに出てくる「My本文字下げ1
」というのは、私が勝手に作ったスタイルの名前。めちゃくちゃダサい名前にしてしまって、激しく後悔している。
使ってみる
原稿をテキストエディタで作って、Wordに貼り付ける。
次のリスト2を実行する。
リスト2
Private Sub test01() Dim tgtDoc As Document Set tgtDoc = ActiveDocument Call SetHeaderStyle(tgtDoc) End Sub
すると、一瞬で
こうなる。
ナビゲーション ウインドウも
この通り!
バッチリである!
おわりに
このほか、アンダーライン、太字強調、傍点、ルビ、引用、箇条書きに対応済み(ただし、箇条書きは1階層にしか対応していません。)なのですが、めちゃくちゃ便利です。
今回ご紹介した「見出し」対応だけでも十分便利だと思います。