にわかVimmer始めました。rubydo
コマンドでバッファの各行にRubyを実行できることを知って使ってみたくなった。
URLをMarkdownのリンクにするコマンドを書いてみた。(実用性不明)
コマンド
:rubydorequire'uri';require'open-uri';$_.gsub!(URI.regexp(%w|http https|)){|u;t|open(u){|f|t=f.read.match(%r|<title>(.*?)</title>|)[1]}rescueputs"開けないよ。: #{u}";t.nil??u:"[#{t}](#{u})"}
実行前
やふー→http://www.yahoo.co.jp/←
ぐーぐる→http://www.google.co.jp/←
あっぷる→https://www.apple.com/jp/←
実行後
やふー→[Yahoo! JAPAN](http://www.yahoo.co.jp/)←
ぐーぐる→[Google](http://www.google.co.jp/)←
あっぷる→[Apple](https://www.apple.com/jp/)←
rubydo
は一行しか実行できないので、無理やり一行にした。
こんなのいちいち入力してられないので、コマンドを定義する。(雑)
:command MDLink rubydo require 'uri'; require 'open-uri'; $_.gsub!(URI.regexp(%w|http https|)){|u; t|open(u){|f| t = f.read.match(%r|<title>(.*?)</title>|)[1]} rescue puts "開けないよ。: #{u}"; t.nil? ? u : "[#{t}](#{u})"}
これで:MDLink
と打つだけで実行できるようになる。
実行を繰り返すとおかしいことになるけど「u」押してどうぞ。
以下説明。
参考
- Vim documentation: if_ruby
- Vimスクリプト基礎文法最速マスター - 永遠に未完成
- コマンドを定義する — 名無しのvim使い
- Vim documentation: if_ruby
Ruby
とりあえずVimは置いておいて、Rubyで置換するスクリプトを書いてみる。
URI.regexp
URI.regexpで、URIにマッチする正規表現を得られる。
URI.regexp
require'uri'URI.regexp%w|http https|
結果
/(?=(?-mix:http|https):)
([a-zA-Z][\-+.a-zA-Z\d]*): (?# 1: scheme)
(?:
((?:[\-_.!~*'()a-zA-Z\d;?:@&=+$,]|%[a-fA-F\d]{2})(?:[\-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]]|%[a-fA-F\d]{2})*) (?# 2: opaque)
|
(?:(?:
\/\/(?:
(?:(?:((?:[\-_.!~*'()a-zA-Z\d;:&=+$,]|%[a-fA-F\d]{2})*)@)? (?# 3: userinfo)
(?:((?:(?:[a-zA-Z0-9\-.]|%\h\h)+|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[(?:(?:[a-fA-F\d]{1,4}:)*(?:[a-fA-F\d]{1,4}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(?:(?:[a-fA-F\d]{1,4}:)*[a-fA-F\d]{1,4})?::(?:(?:[a-fA-F\d]{1,4}:)*(?:[a-fA-F\d]{1,4}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))?)\]))(?::(\d*))?))? (?# 4: host, 5: port)
|
((?:[\-_.!~*'()a-zA-Z\d$,;:@&=+]|%[a-fA-F\d]{2})+) (?# 6: registry)
)
|
(?!\/\/)) (?# XXX: '\/\/' is the mark for hostport)
(\/(?:[\-_.!~*'()a-zA-Z\d:@&=+$,]|%[a-fA-F\d]{2})*(?:;(?:[\-_.!~*'()a-zA-Z\d:@&=+$,]|%[a-fA-F\d]{2})*)*(?:\/(?:[\-_.!~*'()a-zA-Z\d:@&=+$,]|%[a-fA-F\d]{2})*(?:;(?:[\-_.!~*'()a-zA-Z\d:@&=+$,]|%[a-fA-F\d]{2})*)*)*)? (?# 7: path)
)(?:\?((?:[\-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]]|%[a-fA-F\d]{2})*))? (?# 8: query)
)
(?:\#((?:[\-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]]|%[a-fA-F\d]{2})*))? (?# 9: fragment)
/x
String#gsub
URI.regexpで得た正規表現を使ってURLを「●」に置き換えてみる。
String#gsub
sample=<<EOSやふー→http://www.yahoo.co.jp/←ぐーぐる→http://www.google.co.jp/←あっぷる→https://www.apple.com/jp/←EOSsample.gsub(URI.regexp(%w|http https|),'●')
結果
やふー→●←
ぐーぐる→●←
あっぷる→●←
open-uri
open-uriでソースをダウンロードしてタイトルを抜き出してみる。
open-uri
require'open-uri'url='http://www.yahoo.co.jp/'open(url){|f|f.read.match(%r|<title>(.*?)</title>|)[1]}
結果
Yahoo! JAPAN
終わり
上の3つを組み合わせる。
置換
sample=<<EOSやふー→http://www.yahoo.co.jp/←ぐーぐる→http://www.google.co.jp/←あっぷる→https://www.apple.com/jp/←EOSrequire'uri'require'open-uri'sample.gsub!URI.regexp(%w|http https|)do|url;title|open(url)do|f|title=f.read.match(%r|<title>(.*?)</title>|)[1]endrescueputs"#{url}を開けませんでした。"title.nil??url:"[#{title}](#{url})"endputssample
結果
やふー→[Yahoo! JAPAN](http://www.yahoo.co.jp/)←
ぐーぐる→[Google](http://www.google.co.jp/)←
あっぷる→[Apple](https://www.apple.com/jp/)←
Vimで実行
上で作ったソースを加工してVimで使ってみる。
rubydo
rubydo
はVimのバッファの各行にRubyを実行できるコマンド。
1行は$_
という変数に格納され、その変更も反映される。
バッファ.each_line{|$_| rubydoの処理 }
みたいな感じ。
例:
コマンド
:rubydo $_.upcase!
実行前
abcd
efgh
ijkl
実行後
ABCD
EFGH
(上の処理は大文字にしてるだけなので、ノーマルモードで「gggUG」と叩いても可能)
で、さっき作ったソースを加工してrubydo用にしたのがこの記事の最初にあるコマンド。