最終更新:2014-07-15 (火) 23:28:36 (1227d)

TeXマクロ

メモ帳/TeXマクロ2

upTeX と pTeX と JTeX と plainTeX の判別

これは \fmtname, \jfmtname, \pfmtname が定義されているか、どのように 定義されているかを判定することで判別できます。
単純に pLaTeX2e であるかを調べるには

\ifx\pfmtname\@undefined ?\else \pLaTeX!\fi

とすれば、\pfmtname が定義されていれば pLaTeX2e であるとします。
同様に JLaTeX2e も

\ifx\jfmtname\@undefined ?\else \JlaTeX!\fi

として判定できます。
もっと厳密に判定する時は次のようにします。

\ifx\pfmtname\@undefined
  \ifx\jfmtname\@undefined
    \def\temp@str{ptex}
    \ifx\fmtname\temp@str
      \ifx\ucs\@undefined
        \pTeX!
      \else
        u\pTeX!
      \fi
    \else
      \def\temp@str{jplain}
      \ifx\fmtname\temp@str
        \JTeX!
      \else
        \def\temp@str{plain}
        \ifx\fmtname\temp@str
          plain \TeX!
        \fi
      \fi
    \fi
  \fi
\else
  \makeatletter
  \ifx\ucs\@undefined
    \ifx\jfmtname\@undefined
      \ifx\pdfoutput\@undefined
        \makeatother
        \documentclass{jsarticle}
        \begin{document}
        \pLaTeXe!
        \end{document}
      \else
        \documentclass{article}
        \begin{document}
        \LaTeXe!
        \end{document}
      \fi
    \else
      \documentclass{jarticle}
      \begin{document}
      \JLaTeXe!
      \end{document}
    \fi
  \else
    \documentclass[uplatex]{jsarticle}
    \begin{document}
    u\pLaTeXe!
    \end{document}
  \fi
\fi

この方法を用いた場合は upLaTeX2e, pLaTeX2e, JLaTeX2e, LaTeX2e, upTeX, pTeX, JTeX, plain TeX の 判定ができます。

参考文献一覧における著者名の重複

由緒正しい書籍では参考文献の著者名の重複にダッシュを使う。
これは欧文組版の 場合は three em-dash である。
でも\TeX でこれをどうやって出力するのだろう。

\DeclareRobustCommand*\iiiemdash{%
   ---\kern-.5em---\kern-.5em---\kern-.5em---\kern-.5em---}

上記のように定義して、\iiiemdash 程度に使えばよいのだろう。
他にもハイフンや ダッシュの位置を前後のグリフに合わせてくれるDTP ソフト(もちろん InDesign? ) があるようだ。
明日大学に行ったらちょっとやってみよう。
他にも \TeX の世界では Type tools なるものがあるようだ。

電話番号などのハイフンの位置

電話番号や郵便番号でハイフンを使うのは en-dash を使うのか、忘れてしまいましたが、とりあえず、次のようのマクロを作りました。

\documentclass[11pt,uplatex]{jsarticle}
  
\makeatletter
% 電話番号中に出現するハイフン `-' を字上げする長さ
\newdimen\raiseDim
% 初期値は エックスハイトの 20%
\raiseDim=0.2ex
% 実際にハイフンを上げるコマンド
\newcommand*\raise@hyphen[1]{%
% 文字列処理用に \temp@char := '-' を定義
   \def\temp@char{-}%  
% 一文字一文字処理する
   \@tfor\string@temp:=#1\do{%  
% ある文字 \string@temp が \temp@char と等しい (ハイフンならば)
      \ifx\string@temp\temp@char  
% 字上げをする
         \raise\the\raiseDim\hbox{\temp@char}%  
% ハイフンではないならば、なにもしない
      \else  
         \string@temp  
    \fi  
   }%  
}%
%
% 市内局番か市外局番かを判定するブール型レジスタ
\newif\if@sinai
% 市内へ切り替え
\newcommand*\sinai{\@sinaitrue}
% 市外へ切り替え
\newcommand*\sigai{\@sinaifalse}
% 電話番号を記述する環境 \phoneNum[#1]{#2} = #1 :=市外局番, #2 := 市内局番.
\newcommand*\phoneNum{\@ifnextchar[{\@phoneNum}{\@@phoneNum}}
% 市外局番がある場合 市外・市内を判定して出力する
\def\@phoneNum[#1]#2{%
   \if@sinai   
      \raise@hyphen{#2}%  
   \else  
      (#1)~\raise@hyphen{#2}%  
   \fi  
}
% 市内局番のみの場合
\def\@@phoneNum#1{\raise@hyphen{#1}}
\makeatother

\begin{document}
  
10-1111, (011)~10-3333\par
\sinai
\phoneNum{10-1111}, \phoneNum[011]{10-3333}\par
\sigai
\phoneNum{10-1111}, \phoneNum[011]{10-3333}
  
\end{document}

文字列の積み重ね

\documentclass[11pt,papersize,uplatex]{jsarticle}
\makeatletter
\def\stack{\@ifstar{\s@stack}{\bgroup\@stack}}
\def\s@stack{\bgroup\scriptsize\@stack}
\def\@stack#1{%
   \ensuremath{%  
      \left\{%  
         \vcenter{%  
            \@for\member:=#1\do{%  
               \hbox{\member}%  
            }%  
         }%  
      \right\}%  
   }%  
\egroup}
\makeatother
\begin{document}
  
\newcommand*\va[1]{\mbox{\mbox{$\langle$}\itshape#1\mbox{$\rangle$}}}
\newcommand*\Vec[1]{\ensuremath{{#1}_1,{#1}_2,\ldots,{#1}_n}}
The \verb|\stack| command's syntax: 
\begin{quote}
 \verb|\stack*|\verb|{|\Vec{\va{member}}\verb|}|  
\end{quote}
Star `*' makes the members in scriptsize.
  
\verb|The \stack{robust,fragile}-commands| shows below, 
\begin{center}
The \stack{robust,fragile}-commands.\par
\end{center}
  
\verb|The \stack*{robust,fragile}-commands| shows below, 
\begin{center}
 The \stack*{robust,fragile}-commands.\par  
\end{center}
  
\verb|Tom loves \stack*{Alice,Becky,Catherine,Mary,Stephanie}| shows below,
\begin{center}
 Tom loves \stack*{Alice,Becky,Catherine,Mary,Stephanie}.  
\end{center}
  
The \verb|\stack| command's source code is below.
\begin{verbatim}
\def\stack{\@ifstar{\s@stack}{\bgroup\@stack}}
\def\s@stack{\bgroup\scriptsize\@stack}
\def\@stack#1{%
   \ensuremath{%  
      \left\{%  
         \vcenter{%  
            \@for\member:=#1\do{%  
               \hbox{\member}%  
            }%  
         }%  
      \right\}%  
   }%  
\egroup}
\end{verbatim}
\end{document}

BibTeX で出力した文献一覧 .bbl の著者名の重複処理

BibTeX で出力した文献一覧 .bbl、いわゆる thebibliography 環境中 にある \bibitem によるエントリを考慮します。 BibTeX の文献形式 *.bst ファイルにおいてこのような処理も実装できそうですが、 *.bst ファイルの編集が面倒だったので、LaTeX 側で対応します。下記の記述 を thebibliography 環境が始まる前に記述すると、著者名が続けて重複 している場合、二つ目以降を three em-dash で代用します。適宜全角物 の 4 倍角ダーシにすることもできます。 著者名が 5 人程度で、その人 たちの文献を 10 個以上引用していると、とんでもないことになるので、 応急処置的に作製しました。

% --------- では途切れることがあるので。
\DeclareRobustCommand*\iiiemdash{%
  ---\kern-.5em---\kern-.5em---\kern-.5em---\kern-.5em---} 
% 著者名が続けて同じならば three em-dash (\iiiemdash) で代替
\makeatletter
\let\orig@bibitem\bibitem
\let\temp@str\@empty
\global\def\bibitem#1#2\newblock{%
   \orig@bibitem{#1}% 
   \def\temp@str{#2} 
   \ifx\temp@str\previous@str 
      \iiiemdash.\space\newblock 
   \else 
      #2\newblock 
   \fi 
   \def\previous@str{#2}% 
}
\makeatother

参考文献で表示される著者名の終わりがピリオドではなくコンマにしたいのですが、

どうすればよいでしょうか? Q & A 33010

3 人以上の著者名を連記できないが BibTeX スタイル *.bst をいじらない方法。

\begin{filecontents*}{hoge.bib}
@Book{author04,
  author = {N. Author},
  title =  {title},
  publisher =  {publisher},
  year = 2004
}
@Book{taro00,
  author ={H. Taro and T. Osamu},
  title =  {title},
  publisher = {pub},
  year =  2000
}
\end{filecontents*}
\documentclass[uplatex]{jsarticle}
\bibliographystyle{jplain}
\makeatletter
\let\orig@bibitem\bibitem
\global\def\bibitem#1#2. \newblock{\orig@bibitem{#1} #2, \newblock}
\makeatother
\begin{document}
\nocite*
\bibliography{hoge}
\end{document}

MoeTeX logo

\DeclareRobustCommand*\MoeTeX{M\kern-.07em\lower.5ex\hbox{O}
   \kern-.1667em\lower.5ex\hbox{E}\kern-0.1667em\TeX} 

Thor TeX Typo Wiki のロゴ

\documentclass[36pt,papersize,uplatex]{jsarticle}
\pagestyle{empty}
\usepackage[T1]{fontenc}
\usepackage{newpxtext,newpxmath}
\begin{document}
$w_ik_i\neq\omega_\iota \kappa_\iota$
\end{document}

単項演算子と二項演算子

\documentclass{article}
\begin{document}
$-3 + 5 \neq 3 - 5$\par
$\mbox{} -3 + 5 \neq 3 - 5$\par
\end{document}

読者に分かりやすい例として。

コマンドの意味を調べる

LaTeX を使っていると頻繁にコマンドの定義内容を調べたくなるものです. 大抵は source2e.tex をタイプセットしたものから検索すればよいのですが, どこからやってきたのかも分からない場合はとりあえず,

\def\ccs#1{\noindent\bgroup\tt\char'134#1$=$
\expandafter\meaning\csname#1\endcsname\egroup
\par\vskip 1em}

なんて事をやるんですが、\protect で Robust に定義されている場合は

\hoge:->\protect\hoge

とか言われちゃうわけです.TeX Q & A で面白い投稿があったので.

{\let\protect\show\texttt}

で,エレガントに処理で来ちゃう.

\def\rcs#1{\noindent
\bgroup\tt\char'134#1$=$%
  \let\protect\meaning\csname#1\endcsname
\egroup
\par\vskip 1em}

LaTeX で「カタカナ」「ひらがな」相互変換

LaTeX でやるよりも ruby か何かでやったほうが早いと思うのだが...

\documentclass{ujarticle}
\makeatletter
\def\@tempkana{あ}
\def\hirakata#1{%
 \@tfor\member:=#1\do{%
   \ifcat\@tempkana\member
     \if\member あ\relax ア\else
     \if\member い\relax イ\else
     \if\member う\relax ウ\else
     \if\member え\relax エ\else
     \if\member お\relax オ\else
     \if\member か\relax カ\else
     \if\member き\relax キ\else
     % \if\member A\relax B\else ...
       \member
     \fi\fi\fi\fi\fi\fi\fi% \if の数だけ追加
   \else
     \member
   \fi
 }%
}
\makeatother
\begin{document}
\hirakata{えらあめっせーじ}\par
\end{document}

明らかなように、濁音、半濁音、拗音などを追加します。

``a. a and b. a, b and c.'' の自動出力

(中級編に掲載予定)まずは、問題の一般化をしましょう。

1
1 and 2
1, 2 and 3
1, 2, 3 and 4.
...
1, 2, 3,..., n-2, n-1 and n

しかし、TeX 側からすれば、n がいくつあるのかと言うことが分かりませんので、 まずは 総数 n を求めます。さらに問題となるのは、初めから i 番目という のではなく、 終わりから n - i 番目ということになります。ここで、 もう少し分かりやすいように問題を書き換えます。

総数\順番nn-1n-2...321
11
21 and2
31,2 and3
41,2,3 and4
......
n1,2,3,...,n-2,n-1 andn

このように考えると最後から 1 番目は直接出力し、 最後から2 番目は member and とし、最後から 3 番目以降は カンマ付にする、ということになります。 このように考えるとカウンタが一つ必要になりますし、リストのメンバー数を 数える処理が必要になります。

\makeatletter
\def\and@for#1{%
  \@tempcnta=\z@% ここでカウンタをクリア
  \@for\member:=#1\do{\advance\@tempcnta\@ne}% メンバー数の計算
  \@for\member:=#1\do{% 実際の処理
    \ifnum\@tempcnta>2\relax% 2 以上ならばカンマ付
      \member,\space
    \else
      \ifnum\@tempcnta=2\relax% 最後から二つ目ならば `\member and'
        \member\space and\space
      \else
        \ifnum\@tempcnta=1\relax% 最後の一つなら直接出力
          \member
        \fi% \end{ifnum}
      \fi% \end{ifnum}
    \fi% \end{ifnum}
    \advance\@tempcnta\m@ne% カウンタを一つ減少させる
  }% \end{for}
}
\let\andfor\and@for
\makeatother

このようにして作成したマクロを

\andfor{\TeX}\par
\andfor{\TeX,\LaTeX}\par
\andfor{\TeX,\LaTeX,\LaTeXe}\par
\andfor{Knuth,Lamport,Carlisle,Rahtz,Sc\"opf}\par

とした場合の出力は

TeX
TeX and LaTeX 
TeX, LaTeX and LaTeX2e
Knuth, Lamport, Carlisle, Rahtz and Sc\"opf

となります(実際はカーニングと字上げ字下げが行なわれます)。

色々と応用できそうな感じですよね、活用してみてください。

Re: PDFアノテーション機能のメモアイコン位置 (qa:32740)

\documentclass[papersize,uplatex,dvipdfmx]{jsarticle}
\usepackage[bookmarks=false]{hyperref}
\usepackage{pxjahyper}
% \pdfAnnote[<見出し>]{<内容>}
\newcommand\pdfAnnote[2][]{\marginpar{\mbox{}%
  \special{pdf: ann %width 4cm height 2.5cm %
    << /Type /Annot /Subtype /Text /Open true /C [0 0 1] %
    /T (\space#1) /Contents (#2) >>}}}
% \pdfAnnoteXY{x,y}{<内容>} [単位: cm]
\newcommand\pdfAnnoteXY[3][]{%
   \setlength\unitlength{1truecm}%
   \begin{picture}(0,0)%
      \put(#2){
       \special{pdf: ann %width 4cm height 3cm %
          << /Type /Annot /Subtype /Text /Open true %
          /C [0 0 1] /T (\space#1) /Contents (#3) >>}}%
   \end{picture}}%
\begin{document}
日本国憲法\pdfAnnote[憲法]{第1章はGHQではなく、日本国が独自に
盛り込んだもの。}において第9条で戦争の放棄が宣言されている。\par
日本国憲法\pdfAnnote{第1章はGHQではなく、日本国が独自に
盛り込んだもの。}において第9条で戦争の放棄が宣言されている。\par
日本国憲法\pdfAnnoteXY[憲法]{0,5}{第1章はGHQではなく、日本国が独自に
盛り込んだもの。}において第9条で戦争の放棄が宣言されている。\par
日本国憲法\pdfAnnoteXY{1,5}{第1章はGHQではなく、日本国が独自に
盛り込んだもの。}において第9条で戦争の放棄が宣言されている。
\end{document}

柱に出力する方が面倒なので、傍注として出力した方が手っ取り早い気がします。

\documentclass[11pt,papersize,uplatex]{jsbook}
\makeatletter
\newcounter{pdfnote}
\newcommand*\pdfAnnote[2][]{%
  \stepcounter{pdfnote}%
  \mbox{${}^{*\thepdfnote}$}%
  \marginpar{\mbox{}\special{pdf: ann %
  << /Type /Annot /Subtype /Text /Open false /C [0 0 1] %
  /T (*\thepdfnote\space#1) /Contents (#2) >>}}}
\makeatother
\begin{document}
\tableofcontents
\chapter{これから}
ほげほげ\pdfAnnote[ほげほげ]{ここはよく見てね。}ほげほげ
\chapter{それから}
ほげほげ\pdfAnnote{げほげほ、げほげほ、げほげほ。}。
\chapter{どれから}
日本国憲法第 9 条\pdfAnnote{戦争を放棄する・陸海空一切の軍事力を持たない、
という事がかかれている、}には云々。
\clearpage
日本国憲法第 9 条\pdfAnnote{戦争を放棄する・陸海空一切の軍事力を持たない、
という事がかかれている、}には云々。
\par
日本国憲法第 9 条\pdfAnnote{戦争を放棄する・陸海空一切の軍事力を持たない、
という事がかかれている、}には云々。
\end{document}

忘れていましたが、pdfnote LaTeX カウンタ は適当に chapter LaTeX カウンタを親にした方がいいのかもしれません。

\makeatletter
\newcounter{pdfnote}[chapter]
\renewcommand\thepdfnote{\@arabic\c@pdfnote}%
   \@arabic\c@chapter.\@arabic\c@pdfnote
\newcommand*\pdfAnnote[2][]{\stepcounter{pdfnote}\mbox{${}^{*\thepdfnote}$}%
  \marginpar{\mbox{}\special{pdf: ann << /Type /Annot /Subtype /Text /Open  false /C [0 0 1] %
  /T (*\@arabic\c@pdfnote\space#1) /Contents (#2) >>}}}
\makeatother

Re: 図表参照時に「図」や「表」を自動的につけたい

もう解決されたと思いますが、prettyrefと言って

CTAN/macros/latex/contrib/supported/prettyref/

に同じようなものがあるのでした。

hyperref において hyperlink が nest になる例

例えば、次のようにすると目次のリンクがnestになります。

\documentclass[uplatex,dvipdfmx]{jsarticle}
\usepackage{hyperref}
\usepackage{pxjahyper}
\begin{document}
\tableofcontents
\section{図~\ref{figure}について}
\clearpage
\begin{figure}[p]
 \caption{サンプル}\label{figure}
\end{figure}
\end{document}

ハイフンの位置 (qa:30449)

>>30445

とりあえず,手持ちの洋書を数冊眺めた限りでは,ハイフンの前後の

文字によってハイフンの位置を変えるような処理をしている箇所は

見当たりません.

ほとんどの書籍でこのような「ハイフンの位置調整」が行われていないのは事実で すが、Knuthのフォントデザインの姿勢を少し考えると、そうとも言い切れない気が します。Knuthはローマン体のハイフンの位置をエックスハイトの中心になるように デザインしています。ローマン体では主にアルファベット小文字にハイフンが使用さ れるのがその理由です(TeXではジャスティフィケーションを頻繁に行い、行末を揃え るグリッド指向のため、単語境界のアルファベット小文字にハイフンが多用される)。

しかし、タイプライタ体では高さ(ボディ+アッセンダ)の中心になります。タイプラ イタ体では、ハイフンがむしろプログラミング言語の「マイナス」記号として用いられ ている気がします。コマンドラインオプションをタイプライタ体で示す時に妙な違和感 をいつも感じていたのはこのせいでした (\textrm{-x}\texttt{-x})。

他のフォントのタイプライタ体はエックスハイトの中央にハイフンが来ます。 これはその時々に応じて高さとペアカーニングを調整するのが一番良いと思います。

こう考えると Knuth は確率的に多い方に基準を合わせたと考えられます。

しかし、近年のフォント(モニター用の多くも同様に)はこの位置が曖昧で、 丁度小文字でも大文字でも喧嘩の少ないデザインになっている気がします。

% H-HがComputer Modern Romanで不自然に見えてしまうのは私だけでしょうか。

最近、ハイフンの位置の調整を、なんとか自動化できないかと考えています。 それともこのような処理は必要ないのでしょうか。 現在は

  1. 文書の中にハイフンが登場したならば、その両隣の文字を調べる。
  2. 両隣が大文字かアラビア数字ならば、そのフォントに見合った高さの調節をする。
  3. レター`D'が左側に存在するときは\thinspace程度の空白調節をする。 程度の事ができればよいのかな、と考えています(他にも必要な処理がある のでしょうか)。TFMのペアカーニングをいじった方が早いのでしょうか。

リニアスケーリングのフォントではこれが顕著に表れる気がします。

\documentclass{article}
\newcommand*\Hh{\lower-.25ex\hbox{-}}
\newcommand*\ms[1][1]{$\mskip#1mu$}
\begin{document}
NKH-Hakodate broadcasted about SQL-95.\par
NKH\Hh Hakodate broadcasted about SQL\Hh 95.\par
A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-Z\par
A\Hh B\Hh C\Hh D\Hh E\Hh F\Hh G\Hh H\Hh I\Hh J\Hh K\Hh%
L\Hh M\Hh N\Hh O\Hh P\Hh Q\Hh R\Hh S\Hh T\Hh U\Hh V\Hh%
W\Hh X\Hh Y\Hh Z\par
a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z\par
\begin{center}
 \begin{tabular}{lll}
 \hline
 A-A    & D-D                 &\\
 A\Hh A & D\Hh D              &\\
 A\Hh A & D\hspace{.1em}\Hh D &\verb|\hspace{.1em}|\\
        & D\ms[1]\Hh D        &\verb|\mskip1mu| \\
        & D\ms[2]\Hh D        &\verb|\mskip2mu| \\
 \hline
 \end{tabular}
\end{center}
\end{document}

marginpar に table を

>>28025

次の例を吟味して下さい。

\documentclass{ujarticle}
\usepackage{okumacro}
\begin{document}
{\LaTeX}において傍注(\texttt{\yen marginpar})は浮動体。
table環境もfigure環境も浮動体。浮動体の
中(\texttt{\yen marginpar})に浮動体(table)を入れられても
困るでしょう。\vskip2em
次のように浮動体にしない表環境を新設します。
これは傍注用に使うようにすれば良いでしょう。
\makeatletter
\newenvironment{margintable}%
   {\vbox\bgroup\centering\def\@captype{table}}%
   {\egroup}
\makeatother
使い方は以下のようになります。\vskip2em
{\LaTeX}の変遷については表~\ref{tab:hoge}\marginpar{%
   \begin{margintable} \centering
     \caption{ほげ\label{tab:hoge}}
    \begin{tabular}{|c|}
     \hline\LaTeX2.09\\\LaTeXe\\\LaTeX3\\\hline
    \end{tabular}
   \end{margintable}}を見てね。\vskip2em
普通の表(表~\ref{tab:ara})も次のようになります。
\begin{table}[htpb] \centering
 \caption{普通の表\label{tab:ara}}
 \begin{tabular}{|ccc|} 
\hline  ほげ& げほ& どれ\\\hline
 \end{tabular}
\end{table}
\vskip2em
傍注の表~\ref{tab:geho}\marginpar{%
   \begin{margintable} \centering
     \caption{げほ\label{tab:geho}}
    \begin{tabular}{|c|}
     \hline\TeX\\\LaTeX\\何か\\\hline
    \end{tabular}
   \end{margintable}}%
はどこに旅立つかは分かりませんけどね。
\end{document}

sarticle,headings,makeidx,ページ番号について

qa 19652 はじめの投稿が粗探しとは、なんとも。

初めて投稿させていただきます、渡辺です。 テフをはじめて、jsarticle を使い始めて、気づいたことがあります。

\documentclass[uplatex]{jsarticle}
\pagestyle{headings}
\usepackage{makeidx}
\makeindex
\begin{docment}
hoge hoge...
\printindex
\end{documen}

とした時に索引の 1 ページ目のページ番号が ページの下端に表示されてしまいます。 \thispagestyle{headings} では歯が立ちません。 ページスタイルを柱にした時、索引のはじめのページの 何が原因でこうなるのかわかりません。 過去ログにもない見たいのなので、質問させていただきました。

ちょっとした HTML から LaTeX に

ローカルな変換法則。

#!/usr/bin/perl -w 
while (<>){
   last if ( /(<body>|<body .*>)/i ); 
}
while (<>){
   last if ( /<\/body>/i );
   next if ( /<a href=\".*?\">.*<\/a>/i );
   if ( /<pre>/ ){
	while (<>){
	    last if ( /<\/pre>/ );
	}
   }
   s/<h2>(.*?)<\/h2>/\\chapter{$1}/gi;
   s/<h3>(.*?)<\/h3>/\\section{$1}/gi;
   s/<h4>(.*?)<\/h4>/\\subsection{$1}/gi;
   s/<h5>(.*?)<\/h5>/\\paragraph{$1}/gi;
   s/<h6>(.*?)<\/h6>/\\subparagraph{$1}/gi;
   s/<!--(.*)-->/\%$1/i;
   s/(<hr>|<hr .*?>)//gi;
   s/<p>/\n/gi;
   s/<\/p>/\n/gi;
   s/<ul>/\\begin{itemize}/gi;
   s/<\/ul>/\\end{itemize}/gi;
   s/<li>/\\item /gi;
   s/<dl>/\\begin{description}/gi;
   s/<\/dl>/\\end{description}/gi;
   s/<dt>(.*?)<dd>(.*?)/\\item[$1] $2/gi;
   s/ /\n/gi;
   print;
}

簡単な再帰の例

\documentclass{article}
\begin{document}

\makeatletter
\newcount\dot@point
\dot@point=\@ne
\def\@dot@points[#1]{% 描画する点の大きさ
   \dot@point=#1\relax
   \dot@points
}
\def\dot@points(#1,#2){% 再帰的に点を描画するための命令
   \put(#1,#2){\circle*{\dot@point}}%
   \@ifnextchar({\dot@points}{}%)
}
\def\dottedpoints{% 点の大きさが指定されているかどうかの判定
   \@ifnextchar[{\@dot@points}{\dot@points}%]
}
\makeatother

\begin{picture}(100,100)(0,0)
\setlength\unitlength{1pt}
\dottedpoints(0,0)(10,10)(20,50)(20,100)
\dottedpoints[10](100,100)(50,0)(50,50)(30,30)(20,20)
\end{picture}
\end{document}

問題、星を付けたときだけに中黒にするにはどうすれば良いでしょう? ヒントは \@ifstar とか

リスト処理(簡略化バージョン)

あらかじめコントロールシークエンス \hoge にすでに 整数値のリストが {a_1, a_2, \ldots, a_n} が格納されている事を前提とする。

\documentclass{ujarticle}
\makeatletter
% リスト #1 が空かどうかを判定する
\def\list@empty#1{}
% リスト #1 の先頭に #2 を追加する
\def\list@push#1#2{\edef#1{#2,#1}}
% リスト #1 の末尾に #2 を追加する
\def\list@append#1#2{\edef#1{#1,#2}}
% リスト #1 の先頭から要素を一つ取り除く
\def\list@pop#1{%
   \@tempcnta=\z@
   \let\list@save@list\@empty
   \@for\member:=#1\do{%
      \ifnum\@tempcnta=\z@
         \member
      \else
        \ifnum\@tempcnta=\@ne
           \edef\list@save@list{\member}
        \else
           \edef\list@save@list{\list@save@list,\member}%
        \fi
      \fi
      \advance\@tempcnta\@ne
   }%
   \edef#1{\list@save@list}%
}
% リスト #1 のサイズを求める
\def\list@size#1{%
   \@tempcnta=\z@
   \@for\member:=#1\do{\advance\@tempcnta\@ne}%
   \number\@tempcnta
}
% リスト #1 を逆順に並び替える
\def\list@reverse#1{%
   \@tempcnta=\z@
   \let\list@save@list\@empty
   \@for\member:=#1\do{%
      \ifnum\@tempcnta=\z@
         \edef\list@save@list{\member}%
      \else
         \edef\list@save@list{\member,\list@save@list}%
      \fi
     \advance\@tempcnta\@ne
   }%
   \edef#1{\list@save@list}%
}
% リスト #1 の直和を表示する
\def\list@sum#1{%
   \@tempcnta=\z@
   \@for\member:=#1\do{%
      \advance \@tempcnta \member
   }%
   \number\@tempcnta
}
% リスト #1 の直積を表示する
\def\list@prod#1{%
   \@tempcnta=\@ne
   \@for\member:=#1\do{%
      \multiply \@tempcnta \member
   }%
   \number\@tempcnta
}
% リストの要素を表示する
\def\list@show{\@ifnextchar[{\@list@show}{\@list@show[\@empty]}}
% 書式 #1 付で リスト #2 を表示する
\def\@list@show[#1]#2{%
   \@tempcnta=\z@
   \@for\member:=#2\do{\advance\@tempcnta\@ne}%
   \@for\member:=#2\do{%
      \ifnum\@tempcnta>\@ne
         \member#1
      \else
         \member
      \fi
      \advance\@tempcnta\m@ne
   }%
}
\makeatother
\begin{document}
\makeatletter
\def\hoge{9,10,5,7,10,100}
\list@show[,]{\hoge}\par
\list@append{\hoge}{4}
\list@show[,]{\hoge}\par
\list@push{\hoge}{8}
\list@push{\hoge}{27}
\list@show[,]{\hoge}\par
ポップ:\list@pop{\hoge}\par
\list@show[,]{\hoge}\par
逆順:\list@reverse{\hoge}
\list@show[,]{\hoge}\par
直和:\list@sum{\hoge}\par
直積:\list@prod{\hoge}\par
\makeatother
\end{document}

TeX 四則演算

\documentclass[a4j,11pt,papersize,uplatex]{jsarticle}
\begin{document}
\makeatletter
\@tempcnta=\z@
% 足し算
\advance\@tempcnta by \@ne
\number\@tempcnta\par
\advance\@tempcnta by \thr@@
\number\@tempcnta\par
% 引き算
\advance\@tempcnta by -\@ne
\number\@tempcnta\par
% かけ算
\multiply\@tempcnta by \thr@@
\number\@tempcnta\par
% 割算
\divide\@tempcnta by \thr@@
\number\@tempcnta\par
\makeatother
\end{document}

代入と定義

TeX では定義 \def と 代入 \let は別々の働きをします。 \def による定義は置き換えテクストを明示的に与えなければいけないが、\let による代入はそうではない。 明示的に与える代わりに他のマクロやプリミティブの意味をもって代用できるのである。 使い道の例としては、動的に意味が変わるマクロやプリミティブをその時々で保存することや、マクロ定義では不可能なものを作ることである。

前者の例として、 \hoge というマクロを別のもうひとつのマクロ \fuga と同じ意味に定義したい場合を考える。 \fuga がマクロであって \def\fuga{text} のように定義されているのが分かっているのなら、 \let\hoge\fuga とせずとも直接 \def\hoge{text} としてしまえばよい。 これに対して、 \fuga の定義内容が動的に変わるようなものであってその現在の意味がどうなっているのか分からない場合には、\defの置き換えテクストに書くべきものが分からないから \def では実現できないので、\let\hoge\fuga とするのが効果的である。しかしながら実をいうとこのようなときでも、\fuga がプリミティブではなくて簡単なマクロであるならば

\expandafter\def\expandafter\hoge\expandafter{\fuga}

としたり

\edef\hoge{\fuga}

とすれば済んでしまう。(簡単でなくとも \meaning などを使ってパラメータテクストと置き換えテクストを取得して \hoge を \fuga と同じ意味に定義することは可能である。) したがって \let が真価を発揮するのは \fuga が動的に意味を変えるコントロールシークエンスであって、時にはプリミティブになっているかもしれないようなケースであるといえる。

後者の例としては、プリミティブの機能を内包するようなマクロを作る場合である。以下略。

\iftrue \iffalse

\iftrue
ここは表示される
\fi
\iffalse
ここは常に表示されない
\fi
% \comment \endcomment を作る
\let\comment\iffalse
\let\endcomment\fi
\comment 
ここもコメントアウトされる。
\endcomment
\renewenvironment{comment}{\iffalse}{\fi}
\begin{comment}
ここはどうなるだろうか
\end{comment}

ホワイトスペース(空白、改行) が吸収されるか否か

\documentclass{ujarticle}
\AtBeginDocument{\parindent=0pt}
\begin{document}
ほげほげ\par
          ほげほげ。\par
A\hskip0emA\par
A\hskip 0em
A\par
\def\hoge{
   Foo Bar Foo Bar
   Foo Bar Foo Bar
}
\hoge dore\par
\def\hoge{%
   Foo Bar Foo Bar%
   Foo Bar Foo Bar%
}
\hoge dore\par
                               ほげほげ。
\end{document}

\def or \edef

例えば、あるマクロ \List の先頭・末尾にメンバーを追加したい、という場合は

\let\List\empty% リスト処理のためのダミーノードに相当する
\def\appendList#1{\def\List{\List#1}}
\def\pushList#1{\def\List{#1\List}}
\appendList{hoge}
\appendList{,foo}
\appendList{,bar}
\pushList{hoge,}
\List

というのは無限ループでエラーになる。\List というマクロを 定義するために自分自身を参照しているためである。ここで \edef という定義中のマクロを展開するプリミティブが存在する。 これを使えば次のように記述できる。

\let\List\empty% リスト処理のためのダミーノードに相当する
\def\appendList#1{\edef\List{\List#1}}
\def\pushList#1{\edef\List{#1\List}}
\appendList{hoge}
\appendList{,foo}
\appendList{,bar}
\pushList{hoge,}
\List

\List の出力は hoge,hoge,foo,bar となっていることから、\List を 再定義する前に \edef は前回の \List を展開していることが分かる。

ただし、 \group/\egroup, \begingroup/\endgroup, {/} による グループの中ではスコープが効いているので グループの外側にも 定義を有効にさせるには \gdef/\xdef を使うことになる。

\bgroup \def\hoge{hoge1} \egroup \hoge
\begingroup \def\hoge{hoge2} \endgroup \hoge
{\def\hoge{hoge3} \endgroup \hoge
% 上記三つはすべて未定義としてエラーになる。下記三つは有効。
\bgroup \gdef\hoge{hoge1} \egroup \hoge
\begingroup \gdef\hoge{hoge2} \endgroup \hoge
{g\def\hoge{hoge3} \endgroup \hoge

外部ファイルの書き出し/読み出しをする \section/\tableofcontents

\section や \caption の引数は必ず展開されるようになっています。 これは次の場合を想定しています。

\documentclass{ujarticle}
\begin{document}
\tableofcontents% この時点では \hoge の定義内容を知らない
\def\hoge{foo}% ここで \hoge が定義されている
\section{\hoge}% 見出しを出力すると同時に \jobname.aux に
% \@writefile{toc}{\contentsline {section}{\numberline {1}foo}{1}}
% を書き出す。 \jobname.toc には
% \contentsline {section}{\numberline {1}foo}{1}
% が文書の組版が終わった段階 (2 度目の \jobname.aux の読み込み時点)
% で書き出される。
\end{document}

この場合、\tableofcontents は \jobname.toc の中身を参照します。 これは \section 命令によって書き出されたものです。もしも、\hoge を 展開しなかったばあいは \hoge の定義の前に 目次を出力する羽目になります。 \section/\caption などの引数の中身を展開することにより、後方参照マクロの 未定義エラーを回避しているとも考えられます。

しかし、しばしばこの展開が悪さをする場合があります。

\section{見出し $f(x)=ax+b$}
\section{見出し \(f(x)=ax+b\)}

とした場合には $$ は TeX のプリミティブなので robust (頑丈) です。 しかし、 \(, \) は LaTeX のマクロなので \section などの 動く (moved) 引数 の中では fragile (脆弱) です。

パターンマッチング

馴染みやすい例として日付 (date) があります。
Arch Linux の date コマンドでは

date

とすれば

2014年  4月 29日 火曜日 09:27:28 JST

と表示されます。この出力を逆に英語のフォーマットに戻すマクロを 考えます。
これは常に

yyyy 年 mm 年 dd 日 ○曜日 hh:mm:ss JST

という決まった書式になっています。

echo "\hiduke `date`" >hoge.tex

として hoge.tex に日付を書き出します。このようにして file.tex において

\documentclass{ujarticle}
\begin{document}
\def\hiduke#1年#2月#3日#4曜日#5:#6:#7JST{#5:#6:#7\space#1/#2/#3}
\input{hoge}
\end{document}

\def の中の \def

例えば \aaa を定義するような記述

\def\aaa#1#2{#1 は #2 です}

というものがあり、このマクロの中で新たに \bbb という引数を取る命令を 作成したいとします。

\def\bbb#1{#1 とか}

この場合、

\def\aaa#1#2{#1 は #2 です、\def\bbb#1{#1 とか}}

としたのでは \bbb の引数が #1 となり、定義中の #1 は \aaa の一つ目の 引数として解釈されます。これを防止するためには 定義の深さの数だけ # を 増やします。

\def\aaa#1#2{#1 は #2 です、\def\bbb##1{##1 とか}}

例題として日付を定義するようなものを示します。

\def\Year#1{%
   \def\Month##1{%
      \def\Date####1{#1/##1/####1}%
   }%
}
\Year{2004}
\Month{11}
\Date{25}

# をエスケープさせるためには ## とするということになります (Make の $ みたいなもの)

\empty \relax

あぁ、たりぃ、めんどくせぇ。

ここで文章が終わる\\
[{\Large みだし}]\\
ここから文章が始まる。

はエラーになるぞぉ。

ここで文章が終わる\\\relax

とか

ここで文章が終わる\\{}

とか

ここで文章が終わる\\\empty

などとしないとだめぽ。

数式アクセント (1998 年追加分)

文中アクセントの \r を数式モードでも使えるようにしたものが

\mathring{<要素>}

として追加された。

mf ソースの Type 1 フォント化

自作の mf ソースや Postscript Type 1 フォントが提供されていないフォントは 自分で Type 1 フォントを作ってしまいましょう。 必要になるだろうプログラムは

  • mf2pt1
  • Type 1 Utilities
  • Perl
  • MetaPost
  • FontForge? (任意、mf2pt1 によって mf ソースから生成されたファイルを修正する等)

上記のプログラムを適当に導入したならば

cp mf2pt1 /usr/local/bin/
chmod +x /usr/local/bin/mf2pt1
mpost -progname=mpost -ini mf2pt1 \\dump
cp mf2pt1.mem /usr/share/texmf/web2c/

としてインストールを完了してください。 あとは適当に

mf2pt1 logo10.mf

とすれば

logo10.tfm logo10.afm logo10.pfb

などが作成されるので、これらを適切なディレクトリにコピーし、 それぞれのプログラムで適切なマップファイルを記述すれば OK (updmap).

TeX Live/Vine Linux

/etc/cron.daily/texlive.cron が存在する場合は、構わず rm する。

#!/bin/bash
# Remove and TeX fonts not used in 90 days
/usr/sbin/tmpwatch 2160 /var/lib/texmf
exit 0

plain TeX 風 section

\let\origsection\section
\def\section#1\par{\origsection{#1}}

とか

\let\origsection\section
\def\section#1.{\origsection{#1}}

ただし、マクロ側で勝手に \section{#1}とか定義しているところがある かもしれないので (bibliography環境や index 環境などで)、

\ifnextchar \bgroup {\@mysection}{\@@mysection}

とか適当に分岐して処理を分ける。

原稿のマークアップ

奥村晴彦氏の TeX Q & A の

31648: Subject: Re: \edef\hoge{\bm{huga}}でのエラーを回避する
31643: Subject: Re: \edef\hoge{\bm{huga}}でのエラーを回避する
31642: Subject: Re: \edef\hoge{\bm{huga}}でのエラーを回避する
31640: Subject: Re: \edef\hoge{\bm{huga}}でのエラーを回避する
31637: Subject: Re: \edef\hoge{\bm{huga}}でのエラーを回避する
31636: Subject: Re: \edef\hoge{\bm{huga}}でのエラーを回避する
31635: Subject: \edef\hoge{\bm{huga}}でのエラーを回避する

を参照せよ。