読者です 読者をやめる 読者になる 読者になる

erbTeXを作ってみた

Ruby TeX

TeXってなんでもできるのが特徴。webとかなんかより全然自由度高いし、webページだと html + css + javascript でやってることも TeXTeX 自身オンリーでできちゃうわけです。
ただそんな風に高機能すぎるのと、設計されたのが古いのと、Knuth先生が作ったことのせいであんまりユーザーフレンドリーではありません。マクロはコピペするのが精一杯。自分でマクロ定義とかかなり無理ゲー。イミフなエラー出まくり。
そこで別の処理系を持ってきて強制的に別のレイヤーを作って処理してやればいいんじゃないかな、と作ったのがこのerbTeX。
名前の通りRubyのerb(eruby)という、phpみたいなのを使ってます。

サンプル1

helloErb.erb

<%= t.header %>
<%= t.title(:title=>'Hello Tex! Hello Eruby', :author=>'yayugu') %>
This is the first sample of erbTex!

erbTex の最初のサンプルだよ!

<%= t.footer %>

出力
helloErb.erb.tex

\documentclass[a4j]{jarticle}
\usepackage{amsmath, amssymb}
\usepackage{framed}
\usepackage{eclbkbox}
\usepackage{ascmac}
\usepackage{multirow}
\usepackage{fancyvrb}

\begin{document}

\title{Hello Tex! Hello Eruby}
\author{yayugu}
\date{}
\maketitle

This is the first sample of erbTex!

erbTex の最初のサンプルだよ!

\end{document}

完成したpdf

サンプル2

TeX でプログラムのソースコードを貼り付けるときなんか、普通はverbatimを使うとおもうのですが、自分はこんなふうにしてます。

\begin{breakbox}
\begin{Verbatim}[baselinestretch=1, fontsize=\scriptsize, numbers=left, showspaces=false]
#include <stdio.h>

int main(void){
    printf("Hello, World!");

    return 0;
}
\end{Verbatim}
\end{breakbox}

こうすると

  • 行番号が付く
  • コード全体を四角い枠で囲める
  • 改ページ対応

と良いことずくめです。ただ、コマンドが少し長い、コピペするのもなんかめんどくさい。マクロ書こうとしたらverbatimの終端判定が特殊らしく、うまくできない。
こんなときこそerbTeXの出番です。

sample2.erb

<%= t.header %>
<%= t.title(:title=>'Hello Tex! Hello Eruby', :author=>'yayugu') %>
こんにちは世界!

こんにちは\TeX!
\\

<%= t.beginErbVerb %>
#include <stdio.h>

int main(void){
    printf("Hello, World!");

    return 0;
}
<%= t.endErbVerb %>

<%= t.footer %>

出力
sample2.erb.tex

\documentclass[a4j]{jarticle}
\usepackage{amsmath, amssymb}
\usepackage{framed}
\usepackage{eclbkbox}
\usepackage{ascmac}
\usepackage{multirow}
\usepackage{fancyvrb}

\begin{document}

\title{Hello Tex! Hello Eruby}
\author{yayugu}
\date{}
\maketitle

こんにちは世界!

こんにちは\TeX\\

\begin{breakbox}
\begin{Verbatim}[baselinestretch=1, fontsize=\scriptsize, numbers=left, showspaces=false]
#include <stdio.h>

int main(void){
    printf("Hello, World!");

    return 0;
}
\end{Verbatim}
\end{breakbox}


\end{document}

完成したpdf

若干指定がコンパクトにできました!
これをながーいコードに指定した結果のPDFも置いときます。
http://sites.google.com/site/yayugu/sample3.erb.pdf (rubytter.rb)

手順

こんなかんじ。簡単ですね!

$ ruby erbTex.rb sample3.erb
$ platex sample3.erb.tex
$ dvipdfmx sample3.erb.dvi

ソースコード

erbTex.rb

require 'erb'

class ErbTex
  @title = ''
  @author = ''
  @date = ''

  def header()
    <<EOF
\\documentclass[a4j]{jarticle}
\\usepackage{amsmath, amssymb}
\\usepackage{framed}
\\usepackage{eclbkbox}
\\usepackage{ascmac}
\\usepackage{multirow}
\\usepackage{fancyvrb}

\\begin{document}
EOF
  end

  def footer()
    <<EOF
\\end{document}
EOF
  end

  def title(option)
    @title = option[:title]
    @author = option[:author]
    @date = option[:date]
    <<EOF
\\title{#{@title}}
\\author{#{@author}}
\\date{#{@date}}
\\maketitle
EOF
  end

  def beginErbVerb()
    '\\begin{breakbox}
\\begin{Verbatim}[baselinestretch=1, fontsize=\\scriptsize, numbers=left, showspaces=false]'
  end

  def endErbVerb()
    <<EOF
\\end{Verbatim}
\\end{breakbox}
EOF
  end

end

t = ErbTex.new
source = open(ARGV[0], 'r').read
open(ARGV[0] + '.tex', 'w').write(ERB.new(source).result)

erbによるマクロを追加したい場合はErbTexクラスにメソッドを追加していけばおkです。簡単!



というわけで、TeXがよくわからないなら、適当に知ってるものでラッパを作っちゃえばいいんじゃないかという話でした。


TeXは奥が深い症候群というやつで、最初は「なんだこのクソ!」と思っていても、気づけばヤバいほどハマっています。みんなもやってみよう!