最終更新:2017-04-14 (金) 09:51:09 (579d)

TeXマクロ

メモ帳/TeXマクロ3

切り取り線

破線を描くためには picture 環境に備わっている \multiput 命令や epic + eepic にある \dashline などを使えば良い訳ですが,これだと 座標系に依存してしまうので,別のコマンドで実現したい物です。

そこで \hrulefill や \dotfill などに見られるようなコマンドで使われている leader の原理を使って、破線、切り取り線を実現します。ユーザが指定する のは 線の間隔、中央に表示する文字列、任意で線の太さとします。

破線の高さは日本語の全角の 0.4 倍程度にあれば良いと思われるので( 0.5 倍だと線の太さがあるのでちょっと高めに感じる)、高さに関しては 決め打ちでもなんとかなるでしょう。

次の \kiritori コマンドは 改行を行い 後空きも入れるものです。

\documentclass{ujarticle}
\catcode`\@11\relax
% \kiritori[線の太さ]{線の間隔}{中央の文字列}
\long\def\kiritori{\@ifnextchar[{\@kiritori}{\@kiritori[.2pt]}}%
\def\@kiritori[#1]#2#3{%
  \@tempdima=#2\relax% \vrule の width を指定するとき .5.5zw 
  \@tempdimb=.4zh\relax
  \advance\@tempdimb#1\relax% height := .4zh + #1
  \par\noindent\hb@xt@\hsize{% \hsize でやったほうが汎用性が高い
    % width, height, depth において depth に負の値を入れておき、
    % height := depth + #1 とする事で \raise/\lower した事と同等
    \xleaders\hb@xt@#2{\hss\vrule\@width.5\@tempdima
      \@height\@tempdimb\@depth-.4zh\hss}\hfill
      \setbox0\hbox{#3}\ifdim\wd0=\z@\else
        \space#3\space\fi % 出力する文字列
  \xleaders\hb@xt@#2{\hss\vrule\@width.5\@tempdima
      \@height\@tempdimb\@depth-.4zh\hss}\hfill
  }\par\vskip\cvs%
 }%
\catcode`\@12\relax
\begin{document}
\kiritori{1zw}{切り取り線}
\kiritori{.5zw}{切り取り線}
\kiritori[.4pt]{.5zw}{切り取り線}
\kiritori{.3zw}{切り取り線}
\kiritori{.3zw}{}
\end{document}

上記のコマンドでは 2つ目の必須引数がなかった時の処理もしていますので, 切り取り線以外にも単なる破線としても使えます。

欠点としては線の太さが .1zh を超えると全角の高さの中央から どんどんずれるという事です。宿題として、この問題を解決する ように改良してみてください。方法としては (1zh - <rule_height>)/2 の 位置に破線の下端を表示するようにすれば良いでしょう。

section 型見出しの定義の仕方

section 型見出しは専用のコマンド \@startsection を使って 定義します。すでに \documentclass 命令で定義されている場合は \renewcommand で再定義します。jsarticle においては slide オプションで

\if@slide \clearpage \fi

として改丁するようになっています。

\renewcommand{\section}{%
 \if@slide\clearpage\fi
 \@startsection % section 型見出し
 {section}% カウンタ名
 {1}% 見出しレベル
 {\z@}% 字下げ
 {.7\Cvs \@plus.5\Cdp \@minus.2\Cdp}% 前空き
 {.5\Cvs \@plus.3\Cdp}% 後空き
 {\reset@font % 書体を基本にリセットする
  \large % 基本 (\normalsize) よりも一段階大きく
  \headfont % 見出し用の書体選択
  \raggedright}% 左揃え
}% 書体と体裁

基本的には次のように \startsection 命令を用います。

\@startsection{カウンタ名}{見出しレベル}{字下げ}{前空き}{後空き}{体裁}

基本的には次のようにすると新しい section 型の見出しをつくる事ができます。

\newcounter{カウンタ名}[親カウンタ名]
\renewcommand \theカウンタ名 {\the親カウンタ名.\@arabic\c@カウンタ名} 
\newcommand*\l@カウンタ名 {\@dottedtocline{階層}{数字の幅}{数字と見出しの幅}}
\newcommand\カウンタ名{\@startsection{...}{...}{...}{...}{...}{...}}

書体部分にはまずは \reset@font や \normalfont で標準の書体を選択する ようにすると良いでしょう。そうしたら 書体の大きさの選択の後に書体の種類を 指定します。

\Large \gtfamily \bfseries

最後に \raggedright, \cetering, \raggedleft のいずれかにより、 左揃え、中央揃え、右揃えをします。位置を指定しない場合は左揃えされます。

例えば \subparagraph よりも下の階層の section 型見出しを定義するには 次のようにします。

\setcounter{tocdepth}{6}% 必要に応じて
\setcounter{secnumdepth}{6}% 必要に応じて
\makeatletter
\@ifundefined{headfont}{\let\headfont\bfseries}{}% 必要に応じて
\newcounter{subsubparagraph}[subparagraph]
\renewcommand{\thesubsubparagraph}{\thesubparagraph.\@arabic
   \c@subsubparagraph}
\newcommand\l@subsubparagraph{{6}{13em}{7em}}
\newcommand\subsubparagraph{%
  \@startsection{subsubparagraph}%
   {6}%
   {\z@}%
   {\z@}%
   {-1zw}%
   {\normalfont \normalsize \headfont}}
\let \subsubparagraphmark = \@gobble
\makeatother

まぁ、適宜体裁を決める数値は paragraph や subparagraph との相対的な 関係で決めるようにすれば良いでしょう。

このようにすることで LaTeX での section 型見出しを定義できます。 \part や \chater のようなものはもう少し高度なので (\@startsection を 用いないのが普通)、別の箇所で解説します。

そういえば

jsclasses の english オプションで \@afterindent をどうするべきか。

三角関数

一応 Carlisle が trig.sty という三角関数用のパッケージを提供して くれているので,特に苦労する事はないです。

\CalculateSin{degree}, \CalculateCos{degree}, \CalculateTan{degree}

\Calculate??? で degree の値を計算します。

\UseSin{degree}, \UseCos{degree}, \UseTan{degree}

\Calculate??? は計算しただけで実際にその値を参照するには \Use??? を 使います。これは毎回毎回 TeX に三角関数を計算させずに、速度をあげる 賢い例です。中でやっている事は

\CalculateSin{30} ::= \@namedef{sin(30)}{<計算結果>}

として、\sin(30) なる制御綴りを定義していることになります。さらに

\UseSin{30} ::= \@nameuse{sin(30)}

とすると \@nameuse{sin(30)} となる事から <計算結果> を拾う事が出来ます。

試しに picture 環境で三角関数のグラフでも表示した物です。ただし、 tan (x) は \pi/2 で無限大に発散するので適当に表示します。

\@tempcnta=\z@
\def\trifunc{%
  \@whilenum\@tempcnta<360\do{%
    \CalculateSin{\@tempcnta}%
    \edef\@tempa{\UseSin{\@tempcnta}}%
    \@tempdima=\@tempa\p@
    \multiply \@tempdima 100\relax
    \advance\@tempcnta\@ne
    \edef\@tempa{\noexpand\put(\number\@tempcnta,\strip@pt\@tempdima)}%
    \@tempa{\circle*{1}}%
  }%
}
\begin{center}
 \setlength \unitlength {.4pt}
 \begin{picture}(360,100)(0,0)
  \trifunc
 \end{picture}
\end{center}
\makeatother

ここで一つ重要なコマンドは \strip@pt というもので、LaTeX 2e では、 次のように定義されていると思います。

{\catcode`t=12\catcode`p=12\gdef\strip@pt#1pt{#1}}

さらに数値の後に \space を挿入する事により欲張り TeX に 勝手に値を飲み込まれないようにするために

\def\remove@pt#{\expandafter\sprit@pt\the#1\space}

なるコマンドを定義する事もあります。

\documentclass[papersize,uplatex]{jsarticle}
%\usepackage{calc}% 計算
%\usepackage{ifthen}% 条件分岐
\usepackage{trig}% 三角関数 sin, cos, tan を使うため
\usepackage{color}
\begin{document}
\makeatletter
% \cosfunc{振幅}{位相}
\def\cosfunc#1#2{%
  \@tempcnta=\z@
  \@whilenum\@tempcnta<360\do{%
    \CalculateCos{\@tempcnta}%
    \edef\@tempa{\UseCos{\@tempcnta}}%
    \@tempdima=\@tempa\p@
    \multiply \@tempdima 100\relax
    \multiply \@tempdima #1\relax
    \advance\@tempcnta\@ne
    \@tempcntb=\@tempcnta\relax
    \advance \@tempcntb #2\relax
    \edef\@tempa{\noexpand\put(\number\@tempcntb,\strip@pt\@tempdima)}%
    \@tempa{\circle*{1}}%
  }%
}
% \sinfun{振幅}{位相}
\def\sinfunc#1#2{%
  \@tempcnta=\z@
  \@whilenum\@tempcnta<360\do{%
    \CalculateSin{\@tempcnta}%
    \edef\@tempa{\UseSin{\@tempcnta}}%
    \@tempdima=\@tempa\p@
    \multiply \@tempdima 100\relax
    \multiply \@tempdima #1\relax
    \advance\@tempcnta\@ne
    \@tempcntb=\@tempcnta\relax
    \advance \@tempcntb #2\relax
    \edef\@tempa{\noexpand\put(\number\@tempcntb,\strip@pt\@tempdima)}%
    \@tempa{\circle*{1}}%
  }%
}
% \tanfun{振幅}{位相}
\def\tanfunc#1#2{%
  \@tempcnta=\z@
  \@whilenum\@tempcnta<65\do{%
    \CalculateTan{\@tempcnta}%
    \edef\@tempa{\UseTan{\@tempcnta}}%
    \@tempdima=\@tempa\p@
    \multiply \@tempdima 100\relax
    \multiply \@tempdima #1\relax
    \advance\@tempcnta\@ne
    \@tempcntb=\@tempcnta\relax
    \advance \@tempcntb #2\relax
    \edef\@tempa{\noexpand\put(\number\@tempcntb,\strip@pt\@tempdima)}%
    \@tempa{\circle*{1}}%
  }%
}
\begin{center}
 \setlength \unitlength {.4pt}
 \begin{picture}(360,100)(0,0)
  \put(0,0){\line(1,0){360}}%
  \put(0,-100){\line(0,1){200}}%
  \multiput(0,-5)(30,0){12}{\line(0,1){10}}%
  \multiput(-5,-100)(0,10){20}{\line(1,0){10}}%
%
  {\color{blue}\cosfunc{1}{0}}%
  {\color{red}\sinfunc{2}{30}}%
  {\color{cyan}\cosfunc{2}{0}}%
  {\color{magenta}\sinfunc{1}{45}}%
  {\color{green}\tanfunc{1}{0}}%
%
 \end{picture}
\end{center}
\makeatother
\end{document}

宿題として楕円を描画するようなコマンドを作成してください。これは 楕円の公式 であることか ら

となる事を考えます。反対側は z = -y としてマイナスを付与するだけで 描画できます。パラメータ a, b を与えると x 軸は [-a, a] の変域、 y 軸は [-b, b] の値域になるようにしてみましょう。 問題となるのは平方根 sqrt() だけでしょう。これは次のような コマンドを使うと実現できるでしょう。

% 作成中

暇つぶし

\def\mth@e        {2.7182818284590452354}%  e 
\def\mth@pi       {3.14159265358979323846}% pi
\def\mth@sqrt@two {1.41421356237309504880}% sqrt (2)

問題

適当に int, round ceil, floor などのコマンドを作ってみましょう。

階乗

過去に色々と作成した気もするのですが、決め打ちでやったほうが多分 格段に早くなるでしょう。

\def\factorial#1{%
   \@tempcnta=#1\relax
   \@tempcntb=\@ne \relax
   \@whilenum \@tempcnta>\@ne \do{%
      \multiply \@tempcntb \@tempcnta 
      \advance \@tempcnta \m@ne
   }%
   \the\@tempcntb
}

表題と \maketitle

実際問題、\maketitle とか裏でナニをやっているんでしょうか。

\author{A. U. Th\'or}
\title{No Subject}
\maketitle

としたときに \author, \title, \date (初期値) が使われて \maketitle でそれらが出力されます.時には abstract 環境の中身も その下部などに配置されます. LaTeX ではこれを大まかに次のように実装しています.

\def\hoge#1{\gdef\@hoge{#1}}
\def\@hoge{<標準値>}

\@hoge で <標準値> を決めています。 \hoge を定義しているところで \gdef を使っているのは定義の中の定義が外にも影響させるためです。 そこで \title, \author, \date などは次のようにLaTeX 側で定義されます。

\def\title#1{\gdef\@title{#1}}
\def\@title{\@latex@error{No \noexpand\title given}\@ehc}
\def\author#1{\gdef\@author{#1}}
\def\@author{\@latex@warning@no@line{No \noexpand\author given}}
\def\date#1{\gdef\@date{#1}}
\def\@date{\today}
% 他にも \thanks, \@thanks などの記述もあります.\and もあったりして。

\maketitle などのコマンドは文書の体裁を決定するようなコマンドであるため、 クラスファイル側で定義されています。

\def\maketitle{%
 \pagestyle{empty}%
 \begin{titlepage}%
   \null\vskip5\cvs
   \centerline{\Large\@title}\par\vskip\cvs
   \centerline{\@author}\par\vskip.5\cvs
   \centerline{\@date}%
 \end{titlepage}%
}

などなど、出力の方法は様々です.ここで \author の引数中に 含める事が出来る \and コマンドについて考えてみましょう.

\author{A. U. Th\'or \\ thor@hoge.com \and 
   Taro Hokkai \\ taro@hoge.co.jp}

上記のような使い方が出来る訳ですが、これは結果的に、次のように展開される 事になります。

{%
  \begin{tabular}[t]{c}%
    A. U. Th\'or \\
    thor@hoge.com 
  \end{tabular}
  \hskip 1em \@plus .17fil%
  \begin{tabular}[t]{c}%
    Taro Hokkai \\
    taro@hoge.co.jp 
  \end{tabular}
}

これをどのように実現するかと言うと、足りないのは最初と最後の tabular の くくりなので、単に次のようにするだけです。

\begin{tabular}[t]{c}%
  \@author
\end{tabular}\par\vskip\cvs

あとは適当に空きの調整をしたり、出力される体裁を調整します. 例えば次のようにするのでしょうか.

\def\subtitle#1{\gdef\@subtitle{#1}}
\author{...}
\title{...}
\date{...}
\subtitle{...}
\def\maketitle{%
  \null\vskip5\cvs
  \begin{flushleft}%
    {\huge\headfont\@title}\par\vskip\fboxsep
    \hrule\@height1ex
  \end{flushleft}%
  \begin{flushright}%
    {\large---\@subtitle---}%
  \end{flushright}%
  \vfill
  \begin{flushleft}%
    {\@author}\par\vskip\cvs
    {\@date}%
  \end{flushleft}%

かなり適当ですけど、まぁ、こんな感じです.

CSV/TSV 形式のデータを扱う方法 (^^_ ^^M など)

CSV: Comma Seperated Values or TSV: Tab Seperated Values 基本的には次のような構造をしている plain text のファイルを TeX 上から 扱う事を考えます(簡単のためカンマ区切りのものは除外します)。

a_11 <タブ> a_12 <タブ> ... <タブ> a_1n <改行>
a_21 <タブ> a_22 <タブ> ... <タブ> a_2n <改行>
 ......
a_m1 <タブ> a_m2 <タブ> ... <タブ> a_mn <改行>

上記のようなデータ構造があったとすれば次のようなアルゴリズムを適用して それぞれの成分 a_ij を読み込む事が出来るようになります。

procedure read_csv (file read_filename):
   begin
   file_handle = fopen (read_filename);
   {行ごとにファイルを読み込み line に各行を入れて処理する}
   while (line = buffer_read (file_handle)) \ne EOF do 
      begin
         while (element = split (line, ^^I)) \ne empty do
            edit_element (element);
         print <tabular/array \cr>;
      end
   end

LaTeX で表計算

\documentclass[a4j,papersize,uplatex,dvipdfmx]{jsarticle}
\usepackage{color,graphicx}
\usepackage{array,dcolumn,delarray,hhline,longtable,tabularx}
\usepackage{calc,ifthen}
\usepackage{okumacro}
\begin{document}
\makeatletter
\newdimen \xls@row
\newdimen \xls@col
\newcount \cnt@xls@row
\newcount \cnt@xls@col
\newcount \cnt@old@xls@row
\newcounter{xls@sum}
\newcommand*\gadd[2]{\global \advance #1 by #2\relax}
\newcommand*\gdiv[2]{\global \divide #1 by #2\relax}
\newcommand*\gset[2]{\global #1 = #2\relax}
\newcommand*\greset[1]{\gset{#1}{\z@}}
\newcommand*\gstep[1]{\gadd{#1}{\@ne}}
\@ifdefinable \R {%
   \def \R#1 {\gadd \xls@row {#1pt}\gstep \cnt@xls@row  #1\relax
%   [\number\cnt@xls@col,\number\cnt@xls@row]% for debug
   \@ifundefined{c@xls@\number\cnt@xls@row}{%
      \expandafter\newcounter{xls@\number\cnt@xls@row}%
      \setcounter{xls@\number\cnt@xls@row}{#1}}%
      {\addtocounter{xls@\number\cnt@xls@row}{#1}}%
%   (\showcnt{c@xls@\number\cnt@xls@row})% for debug
   }%
}
%   \def \C#1 {\gadd \xls@col {#1pt}\gadd \cnt@xls@col \@ne  #1\relax}
\@ifdefinable \C {%
%   \def \C#1{\showcnt{c@xls@#1}%
%   \gstep \cnt@xls@row
   \def \C{%
     \gstep \cnt@xls@row
     \showcnt{c@xls@\number\cnt@xls@row}%
%   [\number\cnt@xls@col,\number\cnt@xls@row]% for debug
%   (\showcnt{c@xls@\number\cnt@xls@row})% for debug
   }%
}
\newcommand*\showcnt[1]{\@arabic\expandafter\@nameuse{#1}}
\newcommand*\theR {\strip@pt \xls@row}
%\newcommand*\theC {\strip@pt \xls@col}
\newcommand*\aveR {\gdiv \xls@row \cnt@xls@row  \strip@pt \xls@row}
%\newcommand*\aveC {\gdiv \xls@col \cnt@xls@col  \strip@pt \xls@col}
\newcommand*\resetR {\greset \xls@row  \greset \cnt@xls@row}
\newcommand*\resetC {\greset \xls@col  \greset \cnt@xls@col
  \gstep \cnt@xls@row
  \@whilenum \cnt@xls@row > 1\do{%
     \gadd \cnt@xls@row \m@ne
     \setcounter{xls@\number\cnt@xls@row}{\z@}%
  }%
}
\newcommand*\Sum{%
%   \expandafter\setcounter{xls@sum}{#1}
%   [\number\cnt@xls@col,\number\cnt@xls@row]% for debug
   \gset \@tempcnta \z@
   \gset \@tempcntb \z@
   \gset \cnt@old@xls@row \cnt@xls@row
   \gstep \cnt@old@xls@row
   \@whilenum \cnt@old@xls@row > 1\do{%
      \gadd \cnt@old@xls@row \m@ne
%      [%\number\cnt@xls@row$=$% for debug
      \gset \@tempcnta {\showcnt{%
        c@xls@\number\cnt@old@xls@row}}%\number\@tempcnta]% for debug
      \gadd \@tempcntb \@tempcnta
   }%
   \gset \c@xls@sum \@tempcntb
   \showcnt{c@xls@sum}%
}
\newcommand*\Avr{%
%  \number\c@xls@sum,\number\cnt@xls@row % for debug
  \gset \@tempcnta \c@xls@sum
  \gdiv \@tempcnta \cnt@xls@row
  \number\@tempcnta
}
\newcolumntype{.}{D{.}{.}{2}}
\newcommand* \HC[1]{\multicolumn{1}{c}{#1}}
\newcommand \N{\resetR \gstep \cnt@xls@col}

\begin{center}
 \begin{tabular}{lrrrrrD{.}{.}{3.2}}
 \hline
 名前{\BS}科目  & 国語 & 算数 & 理科 & 社会 & 総点  & \HC{平均点} \N \\
 \hline
 太郎     & \R80  & \R50 & \R70 & \R65    & \theR & \aveR \N \\
 花子     & \R40  & \R38 & \R57 & \R66    & \theR & \aveR \N \\
 一郎     & \R20  & \R58 & \R89 & \R35    & \theR & \aveR \N \\
 次郎     & \R100 & \R89 & \R89 & \R90    & \theR & \aveR \N \\
 \hline 
 全平均点 & \C & \C   & \C   & \C  & \Sum  & \Avr \resetC \\ 
 \hline
 \end{tabular}
\par\vskip\cvs
 \begin{tabular}{lrrrrrD{.}{.}{3.2}}
 \hline
 名前{\BS}科目  & 国語 & 算数 & 理科 & 社会 & 総点  & \HC{平均点} \N \\
 \hline
 太郎     & \R80  & \R50 & \R70 & \R65    & \theR & \aveR \N \\
 花子     & \R40  & \R38 & \R57 & \R66    & \theR & \aveR \N \\
 一郎     & \R20  & \R58 & \R89 & \R35    & \theR & \aveR \N \\
 次郎     & \R100 & \R89 & \R89 & \R90    & \theR & \aveR \N \\
 \hline 
 全平均点 & \C & \C   & \C   & \C  & \Sum  & \Avr \resetC \\ 
 \hline
 \end{tabular}
\end{center}

\makeatother
\end{document}

NFSS 2 実装への道

\relax
\catcode`\@=11\relax
% current font value
\let \@now@encoding = \@empty
\let \@now@family = \@empty
\let \@now@series = \@empty
\let \@now@shape = \@empty
\let \@now@fontsize = \@empty
% default font value
\def \@default@encoding {OT1}
\def \@default@family   {\rm@default}
\def \@default@series   {\md@default}
\def \@default@shape    {\up@default}
\def \@default@fontsize     {\normalsize}
% font family
\def \rm@default {cmr}
\def \sf@default {cmss}
\def \tt@default {cmtt}
% font series
\def \bf@default {bx}
\def \md@default {m}
% font shape
\def \it@default {it}
\def \sl@default {sl}
\def \sc@default {sc}
\def \up@default {n}
% chanage current font value
\def \fontencoding#1{\edef \@now@encoding {#1}}
\def \fontfamily#1{\edef   \@now@family   {#1}}
\def \fontseries#1{\edef   \@now@series   {#1}}
\def \fontshape#1{\edef    \@now@shape    {#1}}
\def \fontsize#1{\edef     \@now@fontsize {#1}}
% show current font shape
\def \@now@fontshape {%
   \@now@encoding/\@now@family/\@now@series/\@now@shape}
% declare font size
\def \@vpt    {5}
\def \@vipt   {6}
\def \@viipt  {7}
\def \@viiipt {8}
\def \@ixpt   {9}
\def \@xpt    {10}
\def \@xipt   {10.95}
\def \@xiipt  {12}
\def \@xivpt  {14.4}
\def \@xviipt {17.28}
\def \@xxpt   {20.74}
\def \@xxvpt  {24.88}
% declare use font size command
\def \tiny         {\@vpt}%     5 pt
\def \scriptsize   {\@vipt}%    7 pt
\def \footnotesize {\@viiipt}%  8 pt
\def \small        {\@ixpt}%    9 pt
\def \normalsize   {\@xpt}%    10 pt
\def \large        {\@xiipt}%  12 pt
\def \Large        {\@xivpt}%  14 pt
\def \LARGE        {\@xviipt}% 17 pt
\def \huge         {\@xxpt}%   20 pt
\def \Huge         {\@xxvpt}%  25 pt
% user command `\usefont'
\def \usefont#1#2#3#4{%
  \fontencoding {#1}%
  \fontfamily   {#2}%
  \fontseries   {#3}%
  \fontshape    {#4}%
}
\def \normalfont {%
  \usefont{\@default@encoding}{\@default@family}% 
     {\@default@series}{\@default@shape}}
%
%\expandafter \xdef
%\csname#1/#2/#3/#4\endcsname{\expandafter\noexpand\csname#5\endcsname}
%\def\reserved@a{#6}
%\global \expandafter \let \csname #5\expandfter \endcsname
% \ifx\reserved@a\@empty
% \@empty
% \else
%   \reserved@a
% \fi
%
\catcode`\@=12\relax
%
\normalfont

ほげほげ.

\bye

まだまだ先は長い.....

ちょっと不完全な目次の体裁

\documentclass[a5j,papersize,uplatex]{jsbook}
\usepackage{multicol}
\makeatletter
\def\l@chapter#1#2{%
  \end{multicols}% <=== ここが肝心
  \ifnum \c@tocdepth >\m@ne
    \begingroup
      \parindent\z@
      \leavevmode\headfont
      \hb@xt@\linewidth{\hss{\def\numberline##1{##1\hskip1zw}%
         #1}\hss}\par\nopagebreak%
    \endgroup
  \fi
  \begin{multicols}{2}% <=== ここが肝心
  \setlength\columnseprule{.4pt}%
}
\def\l@section{\@dottedtocline{1}{1zw}{2zw}}
\setcounter{tocdepth}{1}
\makeatother
%
\begin{document}
\def \tempcs {\newpage}
\def \tempcmd {\section{およよ}\tempcs\section{うほほ}\tempcs%
  \section{あやや}\tempcs\section{どれどれ}\tempcs%
  \section{それぞれ}\tempcs\subsection{ほげほげ}\tempcs}
%
\begin{multicols}{2}
\tableofcontents
\end{multicols}

\chapter{これから}\tempcmd
\chapter{どこまで}\tempcmd
\chapter{それぞれ}\tempcmd
\chapter{それから}\tempcmd
\chapter{ははまで}\tempcmd
\chapter{あれから}\tempcmd
\chapter{いつまでも}\tempcmd

%\showthe\premulticols % 50.0pt
%\showthe\postmulticols % 20.0 pt
%\showthe\multicolsep % 12.0pt plus 4.0pt minus 3.0pt
%\showthe\columnsep % 18.49374pt
%\showthe\multicolbaselineskip %  0.0pt

\end{document}

めもめも

\documentclass{ujarticle}

\makeatletter
% redefined `\usepackage' command
\let \orig@usepackage = \usepackage
\def \usepackage {\@ifnextchar[{\new@usepackage}{\new@usepackage[]}}
\def \new@usepackage[#1]#2{%
  \expandafter \edef \csname opt@#2\endcsname{#1}%
  \orig@usepackage[#1]{#2}%
}
\makeatother

\usepackage[usenames,dvipsnames]{color}
\usepackage[dvipdfmx]{graphicx}
\usepackage[dvipdfmx,pagebackref,pdfpagemode=none,colorlinks,pdfmenubar=false,%
  pdftoolbar=false,pdffitwindow=true,pdfcenterwindow=true,%
  pdfwindowui=false,menucolor=menucolor,pdfview=Fit,%
  pdfstartview=Fit]{hyperref}
\usepackage{pxjahyper}

\begin{document}

\makeatletter
% show package options
\def \showPackageOptions#1{%
  \edef \tempcs {\@nameuse{opt@#1}}%
  #1:~\tempcs.
}
% show packages options as a list
\def \showPackageOptionlist#1{%
  \edef \tempcs {\@nameuse{opt@#1}}%
  \@tempcnta = \z@ \relax
  \@for \member:=\tempcs\do{%
    \advance \@tempcnta \@ne \relax
    \number \@tempcnta:~\member.\space
  }%
}
% #1 := option, #2 := package name
\def \isExistsOptionInPackage#1#2{%
  \edef \temp@cs {\@nameuse{opt@#2}}%
  \edef \temp@opt {#1}%
  \@for \member:=\temp@cs\do{%
    \ifx \member \temp@opt
      (#2 に \temp@opt あったよ) # この辺を適当に変更する。
    \fi
  }%
}
% global flag
\newif\ifexistsAnyOption

\makeatother

\begin{ttfamily}
 \showPackageOptions{color}\par
 \showPackageOptions{graphicx}\par 
 \showPackageOptionlist{color}\par
 \showPackageOptionlist{hyperref}\par
 \isExistsOptionInPackage{dvipsnames}{color}
\end{ttfamily}

\end{document}

久々に tricky だと思ったコード

\documentclass{article}
\usepacakge{type1ec}
\usepackage{multicol}
\usepackage[dvipdfmx]{color}
\pagestyle{empty}
\begin{document}
\begin{multicols}{3}
   \begin{small}
      \renewcommand \DefineNamedColor[4]{%
       \textcolor[#3]{#4}{\rule{1ex}{1ex}}~{\rmfamily #2}\\
      }%
      \input{dvipsnam.def}%
   \end{small}
 \end{multicols}
\end{document}

金額のカンマの追加・削除

% 金額表示のカンマの追加・削除の例
\documentclass[uplatex]{jsarticle}
\makeatletter
% 一応新設しておこう
\newcount \@cnt@apcma
\newcount \@cnt@apcmc
% カンマを取り除く
\def\strip@comma#1{%
  \def\@tempstr{,}%
  \expandafter\@tfor \expandafter\member
     \expandafter:\expandafter=#1\expandafter\do{%
    % もしカンマなら捨てる、それ以外は表示
    \ifx\member\@tempstr\else\member\fi
  }%
}
% カンマを追加する
\def \append@comma#1{%
  \def \@tempstr {,}%
  \let \@temp@reversed \@empty
  \expandafter\@tfor \expandafter\member
     \expandafter:\expandafter=#1\expandafter\do{%
    % まずは全ての要素を逆転させる
    \edef \@temp@reversed {\member \@temp@reversed}%
  }%
  \@cnt@apcma \z@
  \let \@temp@appended \@empty
  \expandafter\@tfor \expandafter\member
     \expandafter:\expandafter=\@temp@reversed \expandafter\do{%
     % 四つ目の要素の場合は {0000} となっているのを car と cdr で
     %   \@tempcmda := car (\@temp@appended) [先頭]
     %   \@tempcmdb := cdr (\@temp@appended) [先頭以外]
     % にして {[先頭],[先頭以外]}という処理ができるように前処理.
     % ここで \@temp@appended に \member を追加(\member が空の時も
     % ある).
     %    \@temp@appended := {\member \@tempcmda,\@tempcmdb}
     \ifnum \@cnt@apcma = 4
       \edef \@tempcmda {\expandafter \@car \@temp@appended \@nil}%
       \edef \@tempcmdb {\expandafter \@cdr \@temp@appended \@nil}%
       \edef \@temp@appended {\member \@tempcmda,\@tempcmdb}%
       %o(\the\@cnt@apcma-\@tempcmda:\@tempcmdb)o% for debug
       % ここでカウンタを次のカンマのために 1 に設定する
       % この分岐にいる時点で $5i (i = 0, 1, \ldots, k)$ 番目のため.
       \@cnt@apcma \@ne 
     \else
       % 4番目ではない要素の場合はそのまま \member をリストに追加
       % \@temp@appended := {\member \@temp@appended}
       \edef \@temp@appended {\member \@temp@appended}%
     \fi
     \advance \@cnt@apcma \@ne
  }%
  % 最期にリストを表示する
  \@temp@appended 
}
% 
\let \stripComma \strip@comma
\let \appendComma \append@comma
\makeatother
\begin{document}
\newcommand*\hoge[2]{これは#1{#2}円だニョ.\par}
\hoge\stripComma{1}
\hoge\stripComma{20}
\hoge\stripComma{600}
\hoge\stripComma{5,000}
\hoge\stripComma{60,000}
\hoge\stripComma{700,000}
\hoge\stripComma{1,000,000}
\hoge\stripComma{10,000,000}
\hoge\stripComma{100,000,000}
\hoge\stripComma{1,000,000,000}
\hoge\stripComma{20,000,000,000}
\null
\hoge\stripComma{1}
\hoge\appendComma{20}\par
\hoge\appendComma{600}\par
\hoge\appendComma{5000}\par
\hoge\appendComma{60000}\par
\hoge\appendComma{700000}\par
\hoge\appendComma{1000000}\par
\hoge\appendComma{10000000}\par
\hoge\appendComma{100000000}\par
\hoge\appendComma{1000000000}\par
\hoge\appendComma{20000000000}
\null
\def\foo{5,899,898}
\def\bar{5899898}
\stripComma \foo \par 
\appendComma \bar
\appendComma {\bar\bar\bar\bar\bar\bar}
\end{document}

9 桁限定の追加であれば科研費マクロの中に以下のようなコマンド \Number が存在する(こちらはカウンタを使っているので早いのと違うかな).

\documentclass{ujarticle}
\makeatletter
% \Number{number} : 数字の3桁毎にコンマを入れるマクロ(9桁まで)
\newif\ifコンマ付数字 \コンマ付数字true
\def\コンマ付数字{\コンマ付数字true}
\def\コンマなし数字{\コンマ付数字false}
\newcount\Numa
\newcount\Numb
\def\Numempty{}%文字列「-0」が与えられると空白を出力する
\def\Number#1{%
   \edef\Numpar{#1}%
   \ifx\Numempty\Numpar\else
      \ifコンマ付数字\Numa=#1\relax
         \ifnum\Numa>999999\divide\Numa by 1000000
            \number\Numa,%
            \multiply\Numa by -1000000
            \advance\Numa by #1\relax
            \Numb=\Numa\divide\Numa by 1000
            \ifnum\Numa<100 
               \ifnum\Numa<10 0\fi
               0%
            \fi
            \number\Numa,%
            \multiply\Numa by -1000
            \advance\Numa by \Numb
            \ifnum\Numa<100
               \ifnum\Numa<10 0\fi
               0%
            \fi
            \number\Numa%
         \else
            \ifnum\Numa>999
               \divide\Numa by 1000
               \number\Numa,%
               \multiply\Numa by -1000
               \advance\Numa by #1\relax
               \ifnum\Numa<100
                  \ifnum\Numa<10 0\fi
                  0%
               \fi
               \number\Numa%
            \else
               \number\Numa
            \fi
         \fi
      \else
         \number#1
      \fi
   \fi}
\makeatother
\begin{document}
ほげ\Number{1}ほげ\par
 \Number{10}\par
 \Number{100}\par
 \Number{1000}\par
 \Number{10000}\par
 \Number{100000}\par
 \Number{1000000}\par
 \Number{10000000}\par
 \Number{100000000}\par
 \Number{1000000000}\par% 10 桁あるので最初のカンマがない
\end{document}

TODO