はてなブログを書いていて、必ず使うタグが2種類あります。
<br> 改行 <span style="color: #b388dd"> </span> 見出しのテキスト色を指定
今まで brタグは必要な箇所に手入力し、spanタグは辞書登録して使っていました。しかし、文章を全て書き終えてから一発でタグを挿入した方が手間が少ないので、Vimコマンドにすることにしました。
目次
この記事には ^M という文字が登場します。この文字を.vimrcに記述する場合は、 または とする必要があります。 たとえば、次のような文章があったとします(Markdown)。 この文章に登場する見出しは # で始まる「卵の中身を取り出す」と「卵をとく」です。これらのテキスト色を変更するためにspanタグを挿入して、以下のようにしようと思います。 ちなみに、[^<] は、既にタグを挿入してある見出しにこのコマンドが適用されないようにするためのものです。 これをコマンドとして利用できるよう、.vimrcに次の1行を追記しました。 次はbrタグの挿入です。次のようなテキストがあるとします。 このテキストに登場する3つのパートのうち、(2)と(3)の間には空行が2つあります。しかし、はてなブログにこのテキストを貼り付けると、この空行2つは1つの空行にまとめられてしまいます。 上記のように個々のコマンドとして利用してもよいのですが、どちらのコマンドも毎回使用するので、まとめて関数にしてみました(Vimの関数について余り分かっていないため手探りですが・・・)。 これらのいずれかを.vimrcに記述して を実行します。 試してみたところ、functionを使った場合とdefを使った場合とで次の違いがありました。 上述の内容を実際に使ってみたら、少々物足りないことに気づいたのでもう少し手を加えてみました。なお、以下の自作関数では、H1レベルではなくH4レベルの見出し(####)に対してテキスト色を指定しています。 はてなブログでは「```html」や「```vim」等の行末に半角スペースがあるとシンタックスハイライトが有効にならなかったので、4行目で半角スペースを除去しています。 このコードを書くまで知らなかったのですが、silent!は便利だと感じました。留意事項(特殊文字の入力)
CTRL + v CTRL + m
CTRL + v RETURN
H1レベルの見出しにspanタグを挿入する
# 卵の中身を取り出す
器の縁に卵をぶつけて、ヒビを入れます。ヒビが入ったら両手で
卵を支えながら、慎重に器に中身を落とします。
# 卵をとく
精神を統一し、器を片手で支え、もう一方の手に持った道具(箸
など)で卵をかき回します。
# <span style="color: #b388dd">卵の中身を取り出す</span>
器の縁に卵をぶつけて、ヒビを入れます。ヒビが入ったら両手で
卵を支えながら、慎重に器に中身を落とします。
# <span style="color: #b388dd">卵をとく</span>
精神を統一し、器を片手で支え、もう一方の手に持った道具(箸
など)で卵をかき回します。
substituteコマンドで実行するなら、次のような感じでしょうか。:%s/^# \([^<]..*\)/# \<span style="color: #b388dd"\>\1\<\/span\>/
" SetH1 コマンド
command SetH1 %s/^# \([^<]..*\)/# \<span style="color: #b388dd"\>\1\<\/span\>/
段落の後に空行が2つあったらbrタグを挿入
(1) 卵を割って容器に中身を落とします。
(2) 箸などで卵をかき回します。
(3)卵をとき終えたら、卵に醤油をたらします。
そこで、(2)の行末に半角スペースを2つ挿入し、その次の行にbrタグを挿入します。イメージとしては次のような感じです。(1) 卵を割って容器に中身を落とします。
(2) 箸などで卵をかき回します。[space][space]
<br>
(3)卵をとき終えたら、卵に醤油をたらします。
substituteコマンドで実行するなら、次のような感じでしょうか。:%s/\n^\n^\n/ ^M<br>^M^M/
これをコマンドとして利用できるよう、.vimrcに次の1行を追記しました。" SetBRtag コマンド
command SetBRtag %s/\n^\n^\n/ ^M<br>^M^M/
関数にまとめたもの
" functionを使ったもの
function SetBlogTags()
" [^<]はタグ挿入済みの行を除外するためのもの
silent %s/^# \([^<]..*\)/# \<span style="color: #b388dd"\>\1\<\/span\>/
silent %s/\n^\n^\n/ ^M<br>^M^M/
endfunction
command SetBlogTags call SetBlogTags()
" defを使ったもの
def SetBlogTags()
silent :%s/^# \([^<]..*\)/# \<span style="color: #b388dd"\>\1\<\/span\>/
silent :%s/\n^\n^\n/ ^M<br>^M^M/
enddef
command SetBlogTags call SetBlogTags()
:SetBlogTags
defとfunctionの違い
・defを使ったものでは、%sの前に : が必要(functionを使ったものでは不要)
・defを使ったものでは、関数定義の途中にコメントを入れるとエラーになる
少し手を加えたもの(実験)
function SetBlog()
silent %s/^#### \([^<]..*\)/#### \<span style="color: #b388dd"\>\1\<\/span\>/
silent %s/\n/ ^M/ " 行末に半角スペース2つを挿入
silent %s/^\(```[a-z].*\) \n/\1^M/ " ```hitmlや```vim等の行末にある半角スペースを除去
silent %s/^ \n^ \n/<br>^M ^M/ " 空行が2つ連続している部分は1行目をbrタグにする
silent %s/ \n^ \n/ ^M<br>^M/ " 半角space2つの直後にある空行をbrタグにする
call cursor(1,1) " カーソルをファイルの先頭に移動
endfunction
(追記)
試してみたら問題が生じました。具体的には、```で囲んだ範囲(コード等を記述してある範囲)の中にまで、半角スペースやbrタグが挿入されてしまいました。
そこで、ろくに書いたことのないVimscriptを書いてみました。function SetBlog()
silent! %s/^ *```/```/ " ```の前にspaceがあったら除去
let inside_quote = 0
for i in range(1, line("$"))
call cursor(i, 1)
let line_content = getline(line("."))
if line_content[:2] =~ "```"
if inside_quote == 0
let inside_quote = 1
else
let inside_quote = 0
endif
endif
if inside_quote == 0
silent s/\n/ ^M/ " 行末に半角spaceを2つ挿入
endif
endfor
unlet inside_quote
unlet line_content
silent! %s/^ \n^ \n/<br>^M ^M/ " 半角space2つの行が2つ連続している部分は1行目を<br>にする
silent! %s/ \n^ \n/ ^M<br>^M/ "「半角space2つ(行末)」「(行頭)半角space2つ(行末)」の後半を<br>にする
silent! %s/^#### \([^<]..*\) /#### \<span style="color: #b388dd"\>\1\<\/span\>/ " H4見出しの色を設定
call cursor(1,1) " カーソルをファイルの先頭に移動
endfunction
たとえば、2行目では「バッククォート3つ」の前に半角spaceがあったら半角spaceを除去していますが、そのような箇所が存在しない場合、エラーメッセージが表示されます。これを抑制するためにsilent!を使用しています。
恥をさらしますと、ファイルの行数を取得する方法が分からなくて、line("$")の代わりに、当初は以下のようなコードを書いていました(汗)。let line_count = len(readfile(expand('%:t')))
ひとまず問題は解決したものの、美しくないですね。正規表現の知識があったらもっと簡潔に処理できるんじゃないかしらと思いまして・・・。