vimのカラースキームでLaTeXのコードを彩る、carbonpaper.vim


なにそれ

最強のvimプラグインcarbonpaper.vimを使うと、、、

このvimのコードが

そのままの色(カラースキーム: hybrid)でLaTeXに!

あるいはこんな感じにも!

(カラースキーム: PaperColor

概要

カーボン紙です。vimのカラースキームをLaTeXに転写します。
s417-lama/carbonpaper.vim

LaTeXのlistingsでソースコードを貼りたい、しかし

  • わかりにくい
  • そのままだときれいじゃない
  • シンタックスハイライティングがサポートされている言語が少ない

といった状況。

例えば上の例みたいなElixirのコードをTeXに貼りたい時、vimのカラースキームのまま貼り付けられると嬉しい。
LaTeX用の文法定義を書いて、、、みたいなことをすればハイライトできるかもしれないが、そんなことを新しい言語が出るたびにやりたくない。
じゃあせっかくvimでハイライトされているのだからそれを使えば良い、という流れで作成。

あとは単純に、お気に入りのカラースキームでコードがPDF化されるのは嬉しい。

いんすとーる

プラグインマネージャに応じて適当に。
dein.vimなら

call dein#add('s417-lama/carbonpaper.vim')

使い方

  1. vimのvisualモードでコードを選択
  2. :CarbonPaperコマンドを実行(visualモード中では:'<,'>CarbonPaperでもいい)
  3. 適当な名前を付けて変換されたファイル(hoge.tex)を保存
  4. LaTeXのコードにファイルを挿入(\input hoge.tex
  5. LaTeXをコンパイル

生成されるhoge.texはただのLaTeXのlistingsなので、そのまま\inputで挿入するだけで良い。

こんな感じ。

LaTeXには以下のようなことを書いておくといい感じになる。

\documentclass[a4paper]{scrartcl}

% フォントはinconsolataがおすすめ
\usepackage[T1]{fontenc}
\usepackage{inconsolata}

% 必須
\usepackage{listings}
\usepackage{xcolor}

% 普通のlistingsと同じように好みに応じて変える
\lstset{
  basicstyle=\ttfamily,
  basewidth=0.5em,
  numbers=left,
  numberstyle=\scriptsize,
  numbersep=1em,
  frame={tb},
  framexleftmargin=0.5em,
  showstringspaces=false,
}

\title{carbonpaper.vim Demo}
\date{}

\begin{document}

\maketitle

% ここ大事
\input quicksort.exs.tex

\end{document}

デモのソースコードは
https://github.com/s417-lama/carbonpaper.vim/tree/master/samples/demo
にも。

また、vimの矩形選択(Ctrl-V)で一部のみを選択してLaTeX化することも可能。

この例を見ると分かるように、実は現在のcolorschemeでなくても別のcolorschemeを指定することで変換可能。説明は以下。

諸々の設定

colorscheme

普段使いのカラースキームではないやつをcarbonpaper.vimでは使いたい場合は以下のように指定。

let g:carbonpaper#colorscheme = 'PaperColor'

PaperColorはオススメです)

background

vimのbackgroundオプション(lightdarkか)。
これもcolorschemeと同様に普段とは別のものを指定可能。LaTeXだとlightが相性が良い?

let g:carbonpaper#background = 'light'

set_background_color, set_foreground_color

\lstsetとかで元々定義されているデフォルトの色を上書きしたくない場合は0を設定。
つまりvimの地の文の色をそのまま使いたいなら1、そうでないなら0。
個人的にはset_background_colorを0にしてbackgroundlightにするのが好き。

let g:carbonpaper#set_background_color = 0
let g:carbonpaper#set_foreground_color = 0

(default: 1)

highlight_bold

色のついたテキストを全て太字(\bfseries)にする。

let g:carbonpaper#highlight_bold = 1

(default: 0)

ドキュメント

:h carbonpaper

をvimで実行すると読める。

PDF版は
carbonpaper.vim User Guide
に。
実はこれもvimのhelpをcarbonpaper.vimでPDFに変換したもの。

おわりに

LaTeXでドキュメントを作ったり、beamerでプレゼンスライドを作る際に使ってもらえればいいなあ、と思って作りました。
もしかするとpandasでごにょごにょするとLaTeXから色々なフォーマットに変換できるかもしれない。

自分の環境以外では動作確認ができていないので、ぜひフィードバックください。PRも歓迎です。
s417-lama/carbonpaper.vim

(おまけ)中では何が起こっているの?

では実際に生成されたLaTeXコードを見てみましょう。

\definecolor{cp-Number}{HTML}{d75f00}
\definecolor{cp-elixirVariable}{HTML}{005f87}
\definecolor{cp-Operator}{HTML}{0087af}
\definecolor{cp-Normal}{HTML}{444444}
\definecolor{cp-elixirModuleDefine}{HTML}{d70087}
\definecolor{cp-elixirBlockDefinition}{HTML}{d70087}
\definecolor{cp-elixirAtom}{HTML}{005f87}
\definecolor{cp-elixirAlias}{HTML}{005faf}
\definecolor{cp-elixirDefine}{HTML}{d70087}
\definecolor{cp-elixirModuleDeclaration}{HTML}{0087af}
\definecolor{cp-elixirFunctionDeclaration}{HTML}{0087af}
\lstdefinestyle{carbonpaper}{language=,moredelim=[is][\color{cp-Number}\bfseries]{(<cp--b>*\#Number*}{\#*<cp--e>)},moredelim=[is][\color{cp-elixirVariable}\bfseries]{(<cp--b>*\#elixirVariable*}{\#*<cp--e>)},moredelim=[is][\color{cp-Operator}\bfseries]{(<cp--b>*\#Operator*}{\#*<cp--e>)},moredelim=[is][\color{cp-Normal}]{(<cp--b>*\#Normal*}{\#*<cp--e>)},moredelim=[is][\color{cp-elixirModuleDefine}\bfseries]{(<cp--b>*\#elixirModuleDefine*}{\#*<cp--e>)},moredelim=[is][\color{cp-elixirBlockDefinition}\bfseries]{(<cp--b>*\#elixirBlockDefinition*}{\#*<cp--e>)},moredelim=[is][\color{cp-elixirAtom}\bfseries]{(<cp--b>*\#elixirAtom*}{\#*<cp--e>)},moredelim=[is][\color{cp-elixirAlias}\bfseries]{(<cp--b>*\#elixirAlias*}{\#*<cp--e>)},moredelim=[is][\color{cp-elixirDefine}\bfseries]{(<cp--b>*\#elixirDefine*}{\#*<cp--e>)},moredelim=[is][\color{cp-elixirModuleDeclaration}\bfseries]{(<cp--b>*\#elixirModuleDeclaration*}{\#*<cp--e>)},moredelim=[is][\color{cp-elixirFunctionDeclaration}\bfseries]{(<cp--b>*\#elixirFunctionDeclaration*}{\#*<cp--e>)}}
\begin{lstlisting}[style=carbonpaper]
(<cp--b>*#elixirModuleDefine*defmodule#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#elixirModuleDeclaration*Quicksort#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#elixirBlockDefinition*do#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#Normal*  #*<cp--e>)(<cp--b>*#elixirDefine*def#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#elixirFunctionDeclaration*sort#*<cp--e>)(<cp--b>*#Normal*([]            )#*<cp--e>)(<cp--b>*#Normal*, #*<cp--e>)(<cp--b>*#elixirAtom*do:#*<cp--e>)(<cp--b>*#Normal* []#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#Normal*  #*<cp--e>)(<cp--b>*#elixirDefine*def#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#elixirFunctionDeclaration*sort#*<cp--e>)(<cp--b>*#Normal*([pivot #*<cp--e>)(<cp--b>*#Operator*|#*<cp--e>)(<cp--b>*#Normal* rest])#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#elixirBlockDefinition*do#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#Normal*    #*<cp--e>)(<cp--b>*#Normal*{#*<cp--e>)(<cp--b>*#Normal*smaller#*<cp--e>)(<cp--b>*#Normal*, #*<cp--e>)(<cp--b>*#Normal*greater#*<cp--e>)(<cp--b>*#Normal*}#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#Operator*=#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#elixirAlias*Enum#*<cp--e>)(<cp--b>*#Operator*.#*<cp--e>)(<cp--b>*#Normal*split_with#*<cp--e>)(<cp--b>*#Normal*(#*<cp--e>)(<cp--b>*#Normal*rest#*<cp--e>)(<cp--b>*#Normal*, #*<cp--e>)(<cp--b>*#Operator*&#*<cp--e>)(<cp--b>*#Normal*(#*<cp--e>)(<cp--b>*#elixirVariable*&1#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#Operator*<#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#Normal*pivot#*<cp--e>)(<cp--b>*#Normal*))#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#Normal*    #*<cp--e>)(<cp--b>*#Normal*sort#*<cp--e>)(<cp--b>*#Normal*(#*<cp--e>)(<cp--b>*#Normal*smaller#*<cp--e>)(<cp--b>*#Normal*) #*<cp--e>)(<cp--b>*#Operator*++#*<cp--e>)(<cp--b>*#Normal* [#*<cp--e>)(<cp--b>*#Normal*pivot#*<cp--e>)(<cp--b>*#Normal*] #*<cp--e>)(<cp--b>*#Operator*++#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#Normal*sort#*<cp--e>)(<cp--b>*#Normal*(#*<cp--e>)(<cp--b>*#Normal*greater#*<cp--e>)(<cp--b>*#Normal*)#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#Normal*  #*<cp--e>)(<cp--b>*#elixirBlockDefinition*end#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#elixirBlockDefinition*end#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#Number*1#*<cp--e>)(<cp--b>*#Operator*..#*<cp--e>)(<cp--b>*#Number*1_000_000#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#Operator*|>#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#elixirAlias*Enum#*<cp--e>)(<cp--b>*#Operator*.#*<cp--e>)(<cp--b>*#Normal*shuffle#*<cp--e>)(<cp--b>*#Normal*()#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#Operator*|>#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#elixirAlias*Quicksort#*<cp--e>)(<cp--b>*#Operator*.#*<cp--e>)(<cp--b>*#Normal*sort#*<cp--e>)(<cp--b>*#Normal*()#*<cp--e>)(<cp--b>*#Normal*
#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)(<cp--b>*#Operator*|>#*<cp--e>)(<cp--b>*#Normal* #*<cp--e>)(<cp--b>*#elixirAlias*IO#*<cp--e>)(<cp--b>*#Operator*.#*<cp--e>)(<cp--b>*#Normal*inspect#*<cp--e>)(<cp--b>*#Normal*()#*<cp--e>)(<cp--b>*#Normal*#*<cp--e>)
\end{lstlisting}

分かりやすいですね。