2008/01/31


vimscriptの発祥から考えると、vimで扱えるオブジェクトはあくまで数値、文字列レベルの物でしかないと思われがちですが、Dictionaryとfunction()を使えば、それとなく継承ぽい事が出来ます。
まぁ、javascriptに近い言語仕様というのもありますからね。
以下のコードでは、簡単なクラスとオブジェクトを定義しています。
function! Class_Prototype() dict
  return self
endfunction

function! Class_Override(...) dict
  if a:0 == 0|throw "Invalid Parameter"|endif
  let class = copy(self)
  let class.__NAME__ = a:1
  if type(a:2) == type(class.New)
    let class.New = a:2
  else
    let class.New = self.New
  endif
  let class.Super = self
  return class
endfunction

function! Class_New(...) dict
  let instance = copy(self)
  call remove(instance, "New")
  call remove(instance, "Override")
  let instance.Super = self
  return instance
endfunction

function! Class_ToString() dict
    return self.__NAME__
endfunction

let Object = {
 \ "__NAME__" : "Object",
 \ "Prototype"function("Class_Prototype"),
 \ "Override"function("Class_Override"),
 \ "Super"{},
 \ "New"function("Class_New"),
 \ "ToString"function("Class_ToString")}
この状態で if exists("object")|unlet object|endif
let object = Object.New()
echo object.ToString() . ":..."
とすると Object:... と表示されます。

ここで function! Human_Sing() dict
  return self.perfix . "は" . self.name . "。" . self.title
endfunction
function! Human_New(...) dict
  let instance = copy(self)
  let instance.perfix = a:1
  let instance.name = a:2
  let instance.title = a:3
  let instance.Sing = function("Human_Sing")
  return instance
endfunction
let Human = Object.Override("Human", function("Human_New"))
とすると、Objectクラスを継承するHumanクラスを定義する事が出来ます。
さらにこの状態で if exists("human")|unlet human|endif
let human = Human.New("私", "人間", "一般人")
echo human.ToString() . ":" . human.Sing()
とすると Human:私は人間。一般人 と表示されます。
つまり、Newメソッドをオーバーライドし、Singメソッドを追加した事になります。ToStringメソッドはObjectクラスのメソッドとなります。
vimscriptはJavascriptのように、メンバを動的に生成出来ますので
function! Gian_Boxing(who) dict
  return a:who . "のくせに生意気だぞ!!!"
endfunction
let Gian = Human.Override("Gian", {})
let Gian.Boxing = function("Gian_Boxing")
if exists("gian")|unlet gian|endif
let gian = Gian.New("俺", "ジャイアン", "ガキ大将")
echo gian.ToString() . ":" . gian.Sing()
echo gian.Boxing("のび太")
とすると Gian:俺はジャイアン。ガキ大将
のび太のくせに生意気だぞ!!!
とジャイアンが生成出来ます。
意外とやれるもんですね。

ただ、せっかくローカルスコープ、スクリプトスコープ、グローバルスコープ等、名前空間は既にしっかり存在してるんだから、もう少し他のオブジェクト指向言語(JavaやJavaString、C#やVB.NET)のように既定メソッドとかデフォルトコンストラクタみたいな概念が欲しいなぁ...
あと関数名は先頭大文字強制ってのは痛い。
ま、その辺はまた今度...

mattn the vimscripter
Posted at by




vimのtipsに何かいいのがないか探してたら...
:help scroll-smooth なんてのを発見。

中身みたら...
==============================================================================
Smooth scrolling                                        *scroll-smooth*

If you like the scrolling to go a bit smoother, you can use these mappings: >
        :map <C-U> <C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y>
        :map <C-D> <C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E>

(Type this literally, make sure the '<' flag is not in 'cpoptions').

==============================================================================
と...

まぁスムースですわな。
書いた奴出て来い
Posted at by




vim_html 普段vimを使っていらっしゃる方は、ソースコードや/etcにある設定ファイル等をブログに書きたいと思う事が多いかと思います。
私のブログでもほぼ7割方ソースコードが含まれるブログ記事となっています。

ソースコードをブログにアップする際、やはりテキストエディタの様にシンタックスに色が付いた常態だと分かりやすいですよね。
世の中には色んな方法があるようです。

ただ、私としてはやはり静的ファイルでHTMLを出力したいし、なるべく多くのフォーマットで、かつマルチバイトに対応していてほしい。
私は普段テキストエディタとしてvimを使っていますが、vimのソースコードハイライト機能はタダモノではなく、かつ対応しているファイルフォーマットの数も :echo len(split(globpath(&rtp, "syntax/*.vim"),"\n"))
とするだけでも500個以上のファイルフォーマットに対応している事が分かります。
さらにvimのオフィシャルサイトに行けば世の中に存在するプログラミング言語のほぼ全てのsyntaxファイルが揃うでしょう。
vimにも、HTML出力の機能が無いわけではありません。「tohtml.vim」を使えば現在ハイライトされているバッファの中身をHTMLファイルにしてくれる機能があります。
#include <stdio.h>

int main(int argc, char* argv[]) {
    printf("Hello, World\n");
    return 0;
}
こんなファイルであれば :TOHtml
とする事で <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>C:/temp/helloworld.c.html</title>
<meta name="Generator" content="Vim/7.1">
</head>
<body bgcolor="#000000" text="#c0c0c0"><font face="monospace">
<font color="#ff6060">#include </font><font color="#ff40ff">&lt;stdio.h&gt;</font><br>
<br>
<font color="#00ff00">int</font>&nbsp;main(<font color="#00ff00">int</font>&nbsp;argc, <font color="#00ff00">char</font>* argv[]) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;printf(<font color="#ff40ff">&quot;Hello, World</font><font color="#008080">\n</font><font color="#ff40ff">&quot;</font>);<br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#00ffff">return</font>&nbsp;<font color="#ff40ff">0</font>;<br>
}<br>
</font></body>
</html>
こんなHTMLを出力してくれます。
ただ...<font>はいただけませんね。

最近のHTMLでは御法度です。HTML Validatorも許しません。HTMLに直接色を埋め込むなんて最近ではタブー化しつつあります。(このサイトには沢山ありますが...)

今回は、「tohtml.vim」から実行される「2html.vim」を使用してブログに最適なHTMLを出力出来るコツを説明して行きます。
「2html.vim」は基本動作を変えられるように複数のオプションを持っています。以下そのオプションについて説明します。

use_xhtml

出力するHTMLをXHTMLに強制します。たとえば<br>は<br />と出力されます。
また<DOCTYPE>も合わせて変更されます。

html_number_lines

HTMLを出力する際に行番号を出力してくれます。ただし同一要素内に出力されますのでマウスで選択すると行番号まで選択されてしまいます。

html_font

HTMLのフォントを強制出来ます。通常はmonospaceが使われますが、これよりも優先したいフォントがある場合に使用します。

html_use_css

コードのシンタックスを<font>ではなく<span>で出力します。
class属性は上記「Comment」や「Statement」といった識別が使用されます。

html_use_encoding

metaタグでcharset指定できます。但し現状の「2html.vim」にはencodingが「cp932」の場合の処理がありませんので、以下のパッチを「2html.vim」に当てる必要があります。
*** 2html.vim   Fri Aug 03 13:23:20 2007
--- 2html.vim.org   Tue Jul 31 09:48:00 2007
***************
*** 162,168 ****
      let s:html_encoding = 'iso-8859-1'
    elseif s:vim_encoding =~ "^cp12"
      let s:html_encoding = substitute(s:vim_encoding, 'cp', 'windows-', '')
!   elseif s:vim_encoding == 'sjis' || s:vim_encoding == 'cp932'
      let s:html_encoding = 'Shift_JIS'
    elseif s:vim_encoding == 'big5'
      let s:html_encoding = "Big5"
--- 162,168 ----
      let s:html_encoding = 'iso-8859-1'
    elseif s:vim_encoding =~ "^cp12"
      let s:html_encoding = substitute(s:vim_encoding, 'cp', 'windows-', '')
!   elseif s:vim_encoding == 'sjis'
      let s:html_encoding = 'Shift_JIS'
    elseif s:vim_encoding == 'big5'
      let s:html_encoding = "Big5"
これでWindowsを使っていらっしゃる人でも「charset=Shift_JIS」と出力されます。

html_no_pre

<pre>を使わずHTML出力する際に使用します。最近はRSSで全文配信する風潮もあるみたいで、その際に<![CDATA[...]]>使いたくない人には有用かもしれません。

html_start_line

ソースからHTMLを生成する際の開始行番号を指定します。

html_end_ilne

ソースからHTMLを生成する際の終了行番号を指定します。

html_ignore_folding

ソースコードがfoldingされていても内部をHTML出力するように設定します。
設定せずにfoldingされているソースをHTML出力すると以下のようなHTMLが出力されます。
#include <stdio.h>

int main(int argc, char* argv[]) {
+---  2 行:printf("Hello, World\n");
}

html_whole_filler

foldingモード時に、追加された行を意味する行「... inserted lines」を表示したく無い場合に設定します。

以上が「2html.vim」で使用できるオプションです。
通常は何も設定されていませんが、以下ではブログ等に貼り付ける際の私なりのコツを示します。
  • スタイルシートを定義する
  • CSSファイルやHTMLファイルの<style>部に以下のコードを追加しておきます。
    .code {
     border-bottom    : 1px solid #777777;
     border-left      : 5px solid #777777;
     border-right     : 1px solid #777777;
     border-top       : 1px solid #777777;
     background       : #555555;
     color            : #ffffff;
     overflow-x       : auto;
     white-space      : nowrap;
     font-family      : monospace;
    }

    /* source code */
    .code>.Comment {
     color: #aaaaaa;
    }
    .code>.Constant,
    .code>.String,
    .code>.Character,
    .code>.Number,
    .code>.Boolean,
    .code>.Float {
      color: #aa7777;
    }
    .code>.Identifier,
    .code>.Function {
     color: #77aa77;
    }
    .code>.Statement,
    .code>.Conditional,
    .code>.Repeat,
    .code>.Label,
    .code>.Operator,
    .code>.Keyword,
    .code>.Exception {
     color: #77aaaa;
    }
    .code>.PreProc,
    .code>.Include,
    .code>.Define,
    .code>.Macro,
    .code>.PreCondit {
     color: #aaffff;
    }
    .code>.Type,
    .code>.StorageClass,
    .code>.Structure,
    .code>.Typedef {
     color: #aaaa55;
    }
    .code>.Special,
    .code>.SpecialChar,
    .code>.Tag,
    .code>.Delimiter,
    .code>.SpecialComment,
    .code>.Debug {
     color: #777777;
    }
    .code>.Underlined {
     color: #00ff00;
     text-decoration: underline;
    }
    .code>.Ignore {
     color: #777777;
    }
    .code>.Error {
     color: #ff0000;
    }
    .code>.Todo {
     color: #0000ff;
    }
    .code>.Folded {
     color: #aaffff;
     background-color: #aaaaaa;
    }
    Internet Explorer6ではセレクタが正しく動作しないかと思いますので修正が必要です。
  • オプションをXHTML使用,CSS使用,PRE未使用モードに設定する
  • ~/_vimrc(un*xでは~/.vimrc)に以下を追加します。
    let g:use_xhtml = 1
    let g:html_use_css = 1
    let g:html_no_pre = 1
  • ソースコードをHTML化する
  • 全体をHTML出力するならば何も選択せず、また部分的にHTML出力するならば行選択(linewise-visual)して
    :TOHtml
    と実行します。
    HTMLには<html>や<body>も含まれますので、実際には<body>から</body>を切り取るといいでしょう。

これで色んなソースコードを皆に見てもらうことが出来るようになります。この方法はあくまでmattnが良いと思った方法ですので、もしかしたらより便利な方法があるかもしれません。
一度CSSさえ設定してあれば、上記の手順1つで簡単にHTML出力出来ます。ぜひコードを晒け出してみて下さい。

mattn the OSS fan.
Posted at by