prehistoric.me

Mewarnai Source Code dengan Vim

Vim bisa dipakai untuk mewarnai source code. Mewarnai di sini maksudnya menghasilkan dokumen dengan sisipan elemen <code> atau <pre> yang berwarna, seperti tampilan saat dibuka di IDE atau text editor. CMS atau static site generator biasanya memakai library tambahan untuk bisa menghasilkan kode yang berwarna, seperti pygments, coderay, atau highlightjs. Padahal, sudah ada vim, dan karena vim sering dipakai, tentu sudah tersedia tema warna yang paling disukai penulis.

Ketika sedang membuka source code dengan vim, misalnya dengan nama index.js, menjalankan perintah :TOhtml akan menghasilkan berkas HTML dengan nama index.js.html. Dokumen yang dihasilkan berupa kode yang dibungkus element <pre> dilengkapi dengan stylesheet CSS yang mendefinisikan warna untuk tiap bagian kode.

Text editor vim setelah menjalankan perintah TOhtml

Otomasi

Harus membuka file kemudian menjalankan beberapa urutan perintah rasanya merepotkan, apalagi jika dilakukan berulang. Tenang saja, vim sudah mendukung otomasi. Vim bisa dijalankan dari commandline dan langsung menjalankan perintah internal dengan opsi -c. Misal, kita ingin vim membuka file, menjalankan TOhtml, menulis hasilnya, kemudian keluar, kita bisa menjalankan baris perintah berikut:

vim -c 'TOhtml' -c 'wqa' index.js

Perintah tersebut akan menghasilkan file index.js.html. Jika ingin menyimpan file HTML ke file dengan nama berbeda, kita mesti menambahkan nama filenya sebagai parameter saat menulis.

vim -c 'TOhtml' -c 'w namafile.html' -c '!qa' index.js

Di situ terlihat kita menjalankan perintah !qa untuk menutup vim secara paksa. Ini karena secara bawaan vim tetap membuka dan menulis file dengan nama index.js.html. Kalau tidak dipaksa untuk tutup, vim akan meminta kita menyimpan dulu file tersebut.

Tergantung pengaturan sehari-hari saat menggunakan vim, dokumen yang dihasilkan mungkin dilengkapi dengan nomer baris. Jika ingin tanpa nomer baris, jalankan pengaturan set nonumber. Sebaliknya, jika biasanya tidak ada nomer baris dan ingin dokumen yang dihasilkan dilengkapi nomer baris, jalankan pengaturan set number.

vim -c 'set nonumber' -c 'TOhtml' -c 'w namafile' -c '!qa' index.js

Seringkali kita sudah mengatur supaya vim memiliki tampilan latar belakang gelap, nantinya dokumen yang dihasilkan akan memiliki latar belakang gelap juga. Supaya terang, bisa ditambahkan pengaturan background=light, atau sebaliknya background=dark jika ingin menggelapkan hasil.

vim -c 'set background=light' -c 'set nonumber' -c 'TOhtml' -c 'w namafile' -c '!qa' index.js

Adakalanya kita ingin tema warna yang dihasilkan sebagai HTML berbeda dengan yang biasa ditampilkan saat digunakan secara interaktif, ini bisa dilakukan dengan perintah pengaturann colorscheme.

vim -c 'colorscheme default' -c 'set background=light' -c 'set nonumber' -c 'TOhtml' -c 'wqa' index.js

Perintah-perintah tersebut bisa dipersingkat dengan memasukkannya ke dalam shell script, alias, atau definisi function di dalam .bashrc dan semacamnya. Tetapi saya tidak melakukannya, karena ada keperluan lebih lanjut yang sulit untuk dilakukan dengan shell script.

Mengekstrak HTML yang penting saja dan stylesheetnya

Hasil dari perintah TOhtml di vim adalah dokumen HTML lengkap dengan doctype, header, dan lain-lain. Saya sendiri biasanya hanya membutuhkan bagian kodenya dan CSSnya saja. Untuk mengekstraknya, saya membuat script perl dan menggunakan library HTML5::DOM. Dengan HTML5::DOM, saya mengambil kode HTML dari tag elemen <pre> dan definisi CSS dari elemen <style>.

Pertama, dibuat dulu file temporary untuk menentukan tempat menyimpan hasil konversi ke HTML oleh vim.

use File::Temp;
my $temp = File::Temp->new;

Kemudian, jalankan perintah vim untuk menghasilkan HTML ke file yang sudah dipersiapkan tadi, baca isi file hasil dan simpan ke variabel $text.

system(
  'vim',
  '-c', 'colorscheme default',
  '-c', 'set nonumber',
  '-c', 'let g:html_no_progress=1',
  '-c', 'set background=light',
  '-c', 'TOhtml',
  '-c', "w! $temp",
  '-c', 'qa!',
  $filename
);

my $text;

$temp->seek(0, 0);
while(<$temp>) {
  $text .= $_;
}

Setelah itu, menggunakan library HTML5::DOM, kita ambil kode HTML dari elemen <pre> dan isi CSS dari elemen <style>.

use HTML5::DOM;
my $parser = HTML5::DOM->new;
my $doc = $parser->parse($text);

my $pre = $doc->at('pre');
my $style = $doc->at('style');

my $html = $pre->html . "\n";
my $css =  $style->firstNode->nodeValue . "\n";

Secara lengkap script tersebut akhirnya seperti ini. Ketika dijalankan, script ini akan menampilkan kode HTML dan CSS di layar shell. Script inilah yang saya pakai untuk membantu menghasilkan teks source code berwarna di tulisan blog ini.

#!/usr/bin/env perl
# vi: ft=perl

use strict;
use warnings;
use File::Temp;
use HTML5::DOM;

my $text;
my $temp;
my $parser;
my $doc;
my $pre;
my $style;

$temp = File::Temp->new;

print "$temp\n";

system(
  'vim',
  '-c', 'colorscheme default',
  '-c', 'set nonumber',
  '-c', 'let g:html_no_progress=1',
  '-c', 'set background=light',
  '-c', 'TOhtml',
  '-c', "w! $temp",
  '-c', 'qa!',
  $ARGV[0]
);

$temp->seek(0, 0);


while(<$temp>) {
  $text .= $_;
}

$parser = HTML5::DOM->new;
$doc = $parser->parse($text);

$pre = $doc->at('pre');
$style = $doc->at('style');

$pre->removeAttr('id');

print $pre->html . "\n";
print $style->firstNode->nodeValue . "\n";

Script tohtml saat dijalankan, tampilan HTML yang dihasilkan untuk disalin-tempel (output dipotong)

Script tohtml saat dijalankan, tampilan CSS yang dihasilkan untuk disalin-tempel (output dipotong)


Halaman depan / Semua Tulisan / Perihal / Blogroll