TeXの記憶(123) — tabularで作った表を\noalignでちょっと詰める

tabular環境で表組みをしたら縦の罫線が上の罫線につながらず、すき間ができるので何とかしてという連絡を受けました。

同じクラスファイルを使ってこちらで処理しても再現できないので、ほかのマクロか、フォントの定義か、どこかに原因があるのだと思います。ですがすぐには確かめることができない事情があるので、\noalignを使ってちょこっと詰めることで対処してもらいました。

\begin{tabular}{l|l}\hline\noalign{\vskip-.25mm}
あいうえお & かきくけこ \\
さしすせそ & たちつてと \\
\hline
\end{tabular}

今のところ対応する箇所の数が少ないので何とかなりますが、このあと大量に修正箇所が出てしまったらどうしよう。私が入力するわけではないのですが気になります。そもそも原因を追求しないといけませんね。

TeXの記憶(123)—左ページ専用floatを作る

書籍の中には奇数ページ(または偶数ページ)だけ別デザインのレイアウトの場合があります。図表を奇数ページにまとめて、本文中には入れないといったデザインです。

0413

LaTeXで強制的にページすると、当たり前ですが本文を修正するとズレていってしまいます。今回のマクロは奇数ページを専用のフロート環境にして、何とか実現しようとしたものです。

新規のフロート環境は2のn乗の番号がふられます。デフォルトのフロートはたいていfigure (2^0), table(2^1)だけですから、2^2を使うことにしました。

奇数ページ用に専用の垂直ボックスを用意しました。こうすれば奇数ページの中身が多すぎてもそのページの下にはみ出すだけなので、後のページに影響を与えません。

これの残念なところは、本文の変更によってOddPage環境を挿入する場所を調整しないとズレてしまうところです。うまい位置を決める試行錯誤が必要になって、それはそれで無駄な時間が費やされてしまいます。

まぁ、これはフロートの性質なのでしかたないのですが面倒です。

\documentclass{jbook}

\makeatletter

% 奇数ページ専用の\vboxを定義
\newbox\Oddpage@box
% 専用ボックスの高さ
\newdimen\Oddpage@ht

% figure(2^0),table(2^1)に続く3つめのフロートとして定義
\def\ftype@Oddpage{4}       % 2^n

\newenvironment{OddPage}
{\Oddpage@ht=.99\textheight % 100%でもページ収まるけど、念のため小さく設定
  \setbox\Oddpage@box=\vbox\bgroup} % 奇数ページ用のボックス開始
{\egroup                            % 奇数ページ用ボックスを閉じる
  \@float{Oddpage}
  \vbox to \Oddpage@ht{%              新たにvboxを作ってから
    % 仕事では罫線などを入れることが多い
    % \rlap{\includegraphics{keisenTop.eps}}%
    \box\Oddpage@box                % 奇数ページ用ボックスの中身を出力
    % \rlap{\includegraphics{keisenBot.eps}}%
    \vfill}%
\end@float}

\makeatother

\begin{document}

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
...省略...
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□■
\begin{OddPage}
奇数ページです。\par
△△△
...省略...
△△△
はみ出してもOK
\end{OddPage}
●□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
...省略...
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□▼▲□□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
...省略...

\end{document}

TeXの記憶(122)–オプション引き数と星付きコマンドを定義する

コマンドの引き数をオプションにしたり、「*」が付いた場合に別の動作をさせるには、
\@ifnextcharと\@ifstarが使われます。

\@ifnextchar自体の引き数は3つです。

  • #1 — マッチしたい文字
  • #2 — マッチした場合の動作
  • #3 — しなかった場合の動作

\@ifstarは2つで、マッチしたかどうかの動作です。

  • #1 — マッチした場合の動作
  • #2 — しなかった場合の動作

この2つの要素を両方とも使った例を作って見ました。こんな状況はなさそうですが。

\def\XXX{\@ifstar{\aaa}{\@ifnextchar[{\bbb}{\ccc[111][222]}}}
\def\aaa{000}
\def\bbb[#1]{\@ifnextchar[{\ccc[#1]}{\ccc[#1][333]}}
\def\ccc[#1][#2]{ccc---#1---#2---}

実行例

\XXX
\XXX*
\XXX[222]
\XXX[444][555]

結果

0302

[ ] はさらに細かい数値などが必要な場合、* は挙動を2手に分けるために便利なもので、\@ifnextchar と \@ifstar を同列に置くものではなさそうです。

ちなみに\raiseboxコマンドのように[ ]だけが2つ使われるコマンドは意外とあります。

TeXの記憶(121)–画像の幅を測ってminipageを使う

minipage環境を使って、画像サイズを測ってページ幅いっぱいに組んでみました。
キッチリとした指定はTeXではむずかしいし、それほど求められないのですが、たまに必要になることもあります。

0227b

\usepackage{graphicx}

\begin{document}
\makeatletter

\settowidth{\@tempdima}{\includegraphics{0227.eps}}%

\@tempdimb=\linewidth
\advance\@tempdimb - \@tempdima
\advance\@tempdimb - 1zw

\noindent\begin{minipage}{\@tempdimb}
□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□□□□□□□□□
\end{minipage}\hfill
\noindent\begin{minipage}{\@tempdima}
\centering
\includegraphics{0227.eps}\par
\small 実行例
\end{minipage}

\makeatother

TeXの記憶(120)-\prevdepth’ in horizontal modeのエラー

私の作ったマクロで

You can’t use \prevdepth’ in horizontal mode.

のエラーが出ると言われてしまいました。環境を閉じるときに「\nointerlineskip」を使っていたのが原因です。これは水平モードでは使えないために出るエラーです。

手前に「\par」を入れることで解決しました。ひさしぶりで\nointerlineskipを使ったので忘れていました。というか、何度も同じエラーを繰り返しながら学習していない自分が情けないのですが。

サンプルのコードには、その中に「enumerate」があったのでエラーが起きなかったようです。

“`
\begin{作ったマクロ}

\begin{enumerate}

\end{enumerate}
\end{作ったマクロ}

ところで、enumerate環境が終わると垂直モードになっているのでしょうか。偶然にたよらずにきちんとチェックしなければいけませんね。

TeXの記憶(119)–dvipsで欧文フォントが表示されない

Optimaというフォントがあります。TeXLieveあたりからデフォルトで含まれていますが、それ以前のteTeXなどには含まれていませんでした。

その古いTeXの環境にOptimaを入れたいという依頼があったので、フォントとmapファイルを渡したところ文字化けして表示できないとのこと。

PSファイルを表示してみると四角い枠だけが表示されています。ファイルの中身を見るとフォントは埋め込まれているようです。

dviファイルを私の手元で処理すると、問題なくOptimaが埋め込まれて、もちろん表示もされます。ということはdvipsの処理に問題があるのかもしれません。ログファイルを送ってもらうと、

Warning: module writet1 of dvips (file 8r.enc): cannot open encoding file for reading

のようなワーニングが表示されています。8r.encのファイルは存在して読み込まれているので、8r.encファイル自身に問題があるのでしょうか。

試しに手元にある新旧のバージョンの8r.encを見るといろいろ異なっているようですが、新しいファイルを入れたら正常になるとも思えません。他のファイルとの整合性が崩れてしまうような気がします。もしかして相手先の担当者がコピーを取らないで上書きして、整合性がなくなってしまったら、手がつけられない状態になってしまいます。

相手先に出向いて直すのはゴメンなので、なるべく相手に合わずに解決する方法を考えました。で、思いついたのは、dvipsが利用しているpsfonts.mapの項目から「8r.enc」の項目を取り除いてしまうこでした。

項目は

popbi8r Optima-BoldItalic " TeXBase1Encoding ReEncodeFont " <8r.enc <popbi8a.pfb

となっていたので

popbi8r Optima-BoldItalic " TeXBase1Encoding ReEncodeFont " <popbi8a.pfb

としてしまいました。手元のTeX環境で試したところうまく表示されたので、相手先の環境でもうまくいくかもしれません。

結果は、うまく表示されたようです。必要なのはOptimaの数字だけなので、全部の文字がどうなのかまったく試していません。

今がよければ本質を先送りする見本のような結果になってしました。ほんとはTeXの環境を新しくすべきなんですが、相手先はいくらなんでもマズイと思ってはいるようです。

TeXの記憶(118)–下線を引く

一定のスペースの中に左寄せで文字をいれて、その下に下線を引く方法です。本文中で使う機会はあまりありませんが、章や節の見出し、目次の見出しなどには割りと使われます。

ここでは適当に思いついた4種類の方法で線を描いてみました。

0208a

(1)\vboxの中に必要な幅の\hboxを作ってその下に\hruleを入れる

\vbox{\hbox to \WIDTH{あいうえお\hfil}\vskip2mm\hrule height.1mm}

こうすると\hruleは自動的に\vboxの幅いっぱいに広がります。文字と下線のかたまりを上下左右に移動させて、そのスペースに画像を入れたりする可能性があるときは、この方法をよく使います。

0208b

(2) 改行して\ruleで線を引く

あいうえお

\nointerlineskip\vskip2mm

\rule{\WIDTH}{.1mm}

単純です。ついでに

\raisebox{深さ}[0pt][0pt[{\rule...}

とすると、線を上下する必要があるときに、他に影響を与えないので便利です。

(3) 改行して\vruleで線を引く

あいうえお

\nointerlineskip\vskip2mm

\vrule width \WIDTH height .1mm

\vruleといっても高さと幅を指定すれば(結果的に)水平な線を引くことができます。

(4) tabularとして引く

\arrayrulewidth=.1mm
\tabcolsep=0pt
\begin{tabular}{l}
\hbox to \WIDTH{あいうえお\hfil}\\\hline
\end{tabular}

もうちょっと込み入った箇所で使ったことがあったと思います。

(5) \underlineを使う

\underline{\hbox to \WIDTH{あいうえお\hfil}}

下線のコマンドそのものです。線の位置や太さをコントロールするには別な定義を作って上書きする必要がありそうです。

(1)〜(5)は下線が単純な場合です。複雑な場合は、画像として作って取り込んでしまうほうが簡単です。

とくに、突然の仕様変更に対処するにはIllustratorなどで画像として作ってから張り込んだほうが短時間で必ず仕上がるので相手次第で対応を考えています。

TeXの記憶(117)–古いTeXでHelveticaのスケールが効かない

2010年ころに私が作った書籍データを他社が処理することになりました。というかもともと他社の仕事を私が引き受けたものです。こういう場合は増刷の場合も私が処理してきたのですが、このところ私はマクロのみで組版をしなくなったので、相手先が処理することになりました。

無事に処理が終わってるかと思ったころ、相手先からがHelveticaが大きく出力されるとの報告が寄せられました。データをもらって調べてみると13Qのはずが14Qになっています。これは何だろうか。tfmやvfが悪いのかmapファイルの設定が何か問題があるのか。

もう一度確認してもらいましたが、それでもダメなようです。応急処置としてHelveticaを使っている箇所だけ直接サイズを変更すれば何とかなるのですが、やっぱり原因を調べてはっきりとさせたいようです。そりゃそうでしょう。このままじゃ気持ちが悪いし、問題が先送りされるだけですから。

クラスファイルは自分で作ったものなので、該当箇所も分かっているつもりで調べましたが問題があるとは思えません。その他のマクロを見ても同じです。

ところがクラスファイルの最初のほうを見ると

\RequirePackage[scaled=0.925]{helvet}

という行が目に留まりました。これかな?試しにscaledの部分を取り除いてみたら14Qに表示されたのです。原因はこれのようです。どうも相手先のTeXではこれが無視されているようです。

試しに自分のところにある古いディストリビューションでも試してみたところ、この行でエラーが起きて処理自体が中断してしまいました。

エラーになってくれれば分かりやすいのですが、何もなしに無視されてしまうとなかなか原因にたどり着けません。(ほんとうはログにワーニングかなんかが出ているのを見逃したのかもしれませんが、私の手元のマシンじゃないので定かではありません。)

結局もっと新しいディストリビューションで処理するしかないようです。っていうかさっさと新しいのに切り替えてよ。

Word原稿をLaTeXに直すのは頭が痛い

Word原稿をLaTeXに直すのは頭が痛い

先日、LaTeX原稿の半角コンマについて書いてみましたが、考えてみるとコンマの全角半角の変換なんてWordの原稿の処理に比べればたいしたことはありません。所詮LaTeXの原稿ですから、数式にしても、式の番号にしても、原稿に大幅に手を加えることはありません。表組みだってせいぜい色を付けたり、文字を揃えるくらいでしょう。

原稿を書く際に著者自らがLaTeXのコマンドを入れるので、LaTeXの体裁を大きく逸脱するような原稿を書くはずがありません。自分が面倒ですから。LaTeXの\sectionやenumerateなどの環境にそって書き進めるのがいちばん簡単なはずです。

LaTeXの原稿に比べて圧倒的に面倒なのはLaTeX以外の原稿、具体的にはWordの原稿です。WordのデータをLaTeXに変換したとしても、もとの原稿が\sectionや\subsectionのような構造になってはいないのです。式の番号、参照などの形式もけっこうバラバラです。

ある式番号が

(1.3)

だとすると、次の式番号が

(新1.3)

その次の式はいきなり(1.5)になっていたり、なんてことはWordの原稿では珍しくありません。そのほか、複数の式が長い矢印で参照されていたり、けっこう自由奔放です。これらをLaTeX用に新しくマクロを作っていくか、その場しのぎで乗り切るか、どちらにしてもWord原稿の扱いは頭が痛いことばかりです。

TeXの記憶(116)–tabularの中にtabularを入れる

入り組んだ表をtabular環境を使って組むのは面倒です。

ほんとうに面倒な表なら最初からIllustratorで組もうと思うのですが、ちょこっと複雑な表の場合は全部LaTeXで組みたい欲求にかられてしまいます。これがいけません。たいていの場合や試行錯誤に時間をとられて結局は中途半端なマクロで終わってしまいます。

この例もそんな詰めが甘い組版の1つです。

0119

\begin{tabular}{|l|l|l|}\hline
あああ &
\kern-\tabcolsep\begin{tabular}{r|r}
XXX & YYY \\\hline
XXX & YYY \\\hline
Z &W
\end{tabular}\kern-\tabcolsep&
\dimen0=\ht\strutbox
\advance\dimen0\dp\strutbox
\multiply\dimen0 by 3
\divide\dimen0 by 2
\dimen1=\dimen0
\advance\dimen1 -2.5mm
\dimen2=\dimen0
\advance\dimen2 -\dimen1
\ht\strutbox=\dimen1
\dp\strutbox=\dimen2
\kern-\tabcolsep\begin{tabular}{l|l}
○○○ & □□□ \\\hline
●●● & ■■■
\end{tabular}\kern-\tabcolsep\\\hline
えええ & おおお & かかか\\\hline
\end{tabular}

XXX,YYYの部分、◯●の部分の内側それぞれtabularで組んでいます。

XXX,YYYの3段を自然な形で\tabularで組んでから、右側の2段を計算しています。

3段分の高さを\dimen0に入れてから、それを2で割り、中の要素が中央に収まるように高さと深さを決めています。

もっと考えれば、-2.5mmなんて固定の値を使わないで自動的に計算できると思いますが、中途半端ななま終わってしまいました。

いつもですが、終わってしまえば面倒だったことを忘れてしまいます。ちょっとの間に、あたかも瞬時にできたかのように脳内変換されています。

私が突き詰めたマクロを書けないのは、これも理由の1つに違いない。