FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Excelの表をそのままTeXにコピペで貼り付ける話

この記事は TeX & LaTeX Advent Calendar 2017の20日目の記事です。19日目はdoraTeXさんでした。 20日目はbd_gfngfnさんです。

0. 目次

  1. 自己紹介
  2. xlstabular.sty開発の経緯
  3. xlstabular.styの使用方法
  4. 原理(概略)
  5. あとがき

1. 自己紹介

TeXユーザーの集いには3年連続で行っておりましたので認知してくださっている方も(もしかしたら……)いらっしゃるかもしれませんが,どうにせよTeX & LaTeX Advent Calendarに投稿するのは初めてですので簡単に自己紹介をしたいと思います。
TeXisfunjoinus
  • 東大TeX愛好会現代表です。普段の会の活動としては,TeX by Topic(VICTOR EIJKHOUT著)を読むゼミをやったり,『LaTeX2eまくろの八衢(藤田眞作)』と『LaTeX2ε マクロ&クラス プログラミング基礎解説(ページエンタープライゼズ:通称「黄色い本」)』を読むゼミをやったりしています。TeX言語によるコーディングをバリバリやっておられる方々に囲まれて生活しています。
  • ここ5日くらい,しばらくTeX愛好会でAdvent Calendarを占拠しています(汗)。昨日Adventに書かれたdoraTeXさんには外部顧問としてお世話になっています。明日からbd_gfngfnさん,VoDさん,wtsnjpさんと続きますが,普段ゼミを一緒にやってくださっている方々です。
  • 私もTeX言語によるコーディングを普段からバリバリやりたいところなのですが,そうもうまくはいかない人生です。学部がブラックなのでLaTeX文書の生成に追われ(この5ヶ月で A4 185枚のレポートを生成……ちなみに,卒論ではありません。。。)TeX言語でのコーディングの進捗は極めて悪いです(ちーん)。
  • 学部の勉強以外での主な関心事項はTeX,水泳(実は水泳部員),および理科のおもしろさを伝えること(某``TeX力会"で化学(とたまに物理,数学)を教えています)です。
  • twitterアカウントは@domperorですが,ほとんど使っていないので,もしフォローしてくださるのであれば@ut_tex_clubの方をお願いいたします。

2. xlstabular.sty開発の経緯

「自己紹介」のところで述べましたように,短期間で大量の生命科学系レポートを書くことになりました。このときついて回るのが,Excel表のLaTeXソースへの貼り付けです。ちなみに,Excel表をLaTeXに貼り付けるための既存の方法としては,次のようなものがあります。
  • Excel表をスクリーンショット,画像として貼り付け
    さすがに画質が落ちるのでやりたくありません。
  • Excel表をpdf化,pdfを画像として貼り付け
    画質は落ちませんが,あとからグラフを改変するときに大変です。
  • Excel2LaTeX
    これは非常に便利なVBAマクロで,CTANにも上がっています。Excelのセル結合や色塗り,罫線に至るまで忠実に再現したtabularソースを吐いてくれます。凝った表をLaTeXに貼り付けるならExcel2LaTeXの一択といってよいでしょう。例えば,次のようなセル結合や色塗りを伴った複雑なExcel表も……
    fukuzatsuxls
    該当範囲を選択し,書式>Convert Table to LaTeX(この辺はExcelのバージョンによっても違うかも……※私の環境はMac Excel 2011です)すると,割と時間がかかったあと(この表だと40秒固まりました),このようなダイアログが出てきます。
    excel2latex2
    ダイアログの下の方にあるCopy to ClipboardやSave to Fileでコマンドを外部に出力させてあげればちゃんとLaTeXソースが得られるのです。
  • 一括置換でtabularソースに変形
    セル結合とか無駄に複雑なことをしていないという前提で話します。(それをやってしまったらおとなしくExcel2LaTeXを使えという話)
    例えば,次のようなExcel表→LaTeXソースのワークフローとなります。
    ikkatsu


……というわけで,Excel2LaTeXや一括置換を活用した方法で,Excel表の貼り付けは快適に進むように思われることでしょう。いいえ,そうでないことも多いのです。
  • Excel2LaTeXに固有の問題点
    遅いです。
    あと,ものすごい量の余分な半角スペースを挿入してきます。たとえば,先ほどの例の表をCopy To Clipboardして貼り付けるとこんな感じになります(画面はTeXShopのもの)。なるべくアラインメントタブ(&のこと)を上下で揃えて見やすくしようとしてくれているのでしょうが……いかんせん完全には揃ってないですね。
    excel2latexCODE
    また,最大の問題点はこれ。
    Excel→LaTeXソースという方向の変形はできるが,逆はできない。
    出力を見ながら,LaTeXソース上で表をいじって微調整したくなるときってよくあると思うんです。LaTeXソース上で表をいじったら,当然元のExcelファイルも上書きしておきたいところです。しかし,挿入されたコマンドや余計なスペースを除去し,さらにはアラインメントタブ(&)を「Tab」に一括置換する必要があります。やってらんない。
  • 一括置換でtabularソースに変形する場合の問題点
    置換だけでも手間です。また,LaTeXソース→Excel方向の変形に,同等の手間が発生します。
    さらに,アラインメントタブが揃うとは限らず,割と見づらいです。
    また,tabularを使うんだから当たり前ですが,列数を自分でカウントして,table specを自分で書かなくてはいけません。これも面倒くさい(それくらい面倒がらずに書けよと言われそう^^;)
    tablespec

これらの問題点を解決すべく,次の2つのFeatureを備えたxlstabular.styレポートの進捗上仕方無く開発しました。
  • Excelからそのままコピペして貼り付けるだけでLaTeXソースとして成立する。だから,LaTeX→Excelの方向にも対応。
  • table specは動的に生成される。

3. xlstabular.styの使用方法

後述の「4. 原理(概略)」で説明しますが,xlstabularの機能を実現するため,内部で普通やらないようなカテゴリコードの変更を行っています。そのため,「普通の環境の作りかた(¥newenvironmentなど)」がDidn't Work!!(orz)でした。(もし解決方法を見つけてくださったらコメント欄やGitHubのIssue,Pull Requestなどでご教授くださいませ……m(_ _)m)(※追記1

というわけで,書式が少し特殊ですがお許しください。\xlstabularstartと\xlstabularendで挟みます
\xlstabularstart[オプション引数]{
表は	この	空間に
Tabキー	で	区切って
記述	すること	ができます
Excel	から直で	コピペできる!
}\xlstabularend
オプション引数は7つ用意しています。
  1. 改行幅を指定する「kaigyouhaba」。デフォルトは1.2zw
  2. 縦線の有無を指定する「tatesen」。デフォルトはtrue(あり)。
  3. 一番左の列(見出し列)を仕切る縦線だけ二重にする「midasitate」。デフォルトはfalse(しない)。
  4. 横線の有無を指定する「yokosen」。デフォルトはtrue(あり)。
  5. 一番上の行(見出し行)を仕切る横線だけ二重にする「midasiyoko」。デフォルトはfalse(しない)。
  6. 一番左の列(見出し列)のアラインメントを指定する「midasi」。デフォルトはcenter(中央寄せ)。他にはleft(左寄せ),right(右寄せ)がある。
  7. 見出し列以外の列のアラインメントを指定する「nokori」。デフォルトはcenter(中央寄せ)。他にはleft(左寄せ),right(右寄せ)がある。
例えば,次のように記述すると……
\xlstabularstart[kaigyouhaba=0.5zw,midasiyoko=true,midasi=left,nokori=right]{
表は	この	空間に
Tabキー	で	区切って
記述	すること	ができます
Excel	から直で	コピペできる!
}\xlstabularend
次のような出力を得ます。
sample1-1


仕様でまだ不本意な点いくつか
  • 行の最後のコマが空欄の場合は,Tabと改行の間に{}(ブレースの組)を入れてTabと改行を仕切ってください。そうしないと,TeXの字句解析器の段階で改行が食われてしまい,うまくいきません。(※追記2
  • 行の最後のコマにコントロール・スペース(「¥+半角スペース」によるスペースのこと)を入れた場合には,コントロール・スペースと改行の間に{}(ブレースの組)を入れて両者を仕切ってください。そうしないと,TeXの字句解析器の段階で改行が食われてしまい,うまくいきません。
次のように記述することになります。
\xlstabularstart{
最後のコマが空欄なので	\{\}(ブレースの組)を挟みます→	{}
途中のコマが空欄なので→		←\{\}(ブレースの組)は不要です
最後のコマにコントロール・スペース	を入れたので\{\}(ブレースの組)を	挟みます→\ {}
}\xlstabularend
出力はこちら。
sample1-2

4. 原理(概略)

なお,
TabキーのTeXコーディング上での表し方は^^Iなので以降^^Iと表記します。
改行のTeXコーディング上での表し方は^^Mなので以降^^Mと表記します。
(この表記方法は「サーカムフレックス・メソッド」と呼ばれています。これを勉強されたい方は去年のAdventのwtsnjpさんの記事をご覧になるとよいでしょう。)

xlstabular.styが行っていることは大きく次の2つです。
  1. ^^Iおよび^^Mを通常と違う意味で用いる。そのために,カテゴリコードを変更する。
  2. table specを動的に取得するため,最初の^^Mまでの^^Iの個数をカウントする。

それぞれ説明して行きましょう。

  1. カテゴリコードの変更
    ^^Iがアラインメントタブ&の役割を,^^Mが「¥¥¥hline」のマクロの役割を担うようにすればよいわけです。
    そうした「文字に与えられた役割」を制御するのが「カテゴリコード」という数字です。
    多くのTeX関連の書籍に,次のようなカテゴリコード表を見つけることができるでしょう。
    catcoderef
    というわけで,通常空白文字(カテゴリコード10)扱いの^^Iをアラインメントタブ(カテゴリコード4)扱いしてあげればよいことになります。また,通常行の終了文字(カテゴリコード5)扱いの^^Mをアクティブ文字(カテゴリコード13,マクロ定義が可能な文字のこと)扱いしてあげればよいことになります。
    よって,xlstabular.styには次のような,カテゴリコードを変更する記述があります。
    \catcode`\^^I=4\catcode`\^^M=13%
    

    ※(追記)^^Iのカテゴリコードが10だとは普通の本には書いていませんが,¥the¥catcode`¥^^Iとすると10が出力されるので10ということにしています。
  2. 最初の^^Mまでの^^Iの個数をカウント(table specを動的に取得するため)
    ^^Mや^^Iを使うといたずらに難しく見えてしまいそうなので,次のような問題に落とし込んで考えてみます。
    \countingmacro{ABIICICIICMIABCACIBIBIIMAIIAIBIIM}
    を処理することで,
    最初のMが現れるまでのIの個数を求められるような,
    \countingmacro を考案せよ。
    
    どうでしょう,アイデアは浮かびましたか?TeX芸人の皆さんならできるはず……

    こうしたマクロを書けるようになるために我々が行っているのが『LaTeX2eまくろの八衢(藤田眞作)』と『LaTeX2ε マクロ&クラス プログラミング基礎解説(ページエンタープライゼズ:通称「黄色い本」)』を読むゼミです(宣伝)。多分このゼミがなかったら今回のコードは思いつかなかったでしょう(キリッ)。


5. あとがき

レポートを素早く書くという目的からは逸脱しますが,「Excel方眼紙で書いたドット絵を素早くLaTeX上に移植する」ためのパッケージとしても活用できます。
例えば,こんな可愛いExcel上の雪だるまを……
excelsnowman コピペして……(注:tabular環境純正の¥tabcolsepオプションでコラム間隔を詰めています)
\documentclass[a4paper,10pt,twoside,uplatex]{jsarticle}
\usepackage{xlstabular}
\setlength{\tabcolsep}{-0.13zw}
\begin{document}

Happy \TeX Mas!!

\xlstabularstart[kaigyouhaba=-1zw,tatesen=false,yokosen=false]{
□	□	□	□	□	□	□	□	□	□	□	■	■	□	□	□	□	□	□	□	□	□	□	□	■	■	□	□	□	□	□	□
□	□	□	□	□	□	□	□	□	□	■	□	□	■	□	□	□	□	□	□	□	□	□	■	□	□	■	□	□	□	□	□
□	□	□	□	□	□	□	□	□	□	■	□	□	■	□	□	□	□	■	■	□	□	□	■	□	□	■	□	□	□	□	□
□	□	□	□	□	□	□	□	□	□	□	■	■	□	□	□	□	■	■	■	■	□	□	□	■	■	□	□	□	□	□	□
□	□	□	□	□	□	■	■	□	□	□	□	□	□	□	□	■	■	■	■	■	■	□	□	□	□	□	□	□	□	□	□
□	□	□	□	□	■	□	□	■	□	□	□	□	□	□	■	■	■	■	■	■	■	■	□	□	□	□	■	■	□	□	□
□	□	□	□	□	■	□	□	■	□	□	□	□	□	■	■	■	■	■	■	■	■	■	□	□	□	■	□	□	■	□	□
□	■	■	□	□	□	■	■	□	□	□	■	■	■	■	■	■	■	■	■	■	■	■	□	□	□	■	□	□	■	□	□
■	□	□	■	□	□	□	□	□	■	■	□	□	□	□	■	■	■	■	■	■	■	■	□	□	□	□	■	■	□	□	□
■	□	□	■	□	□	□	□	■	□	□	□	□	□	□	□	□	■	■	■	■	■	■	□	□	□	□	□	□	□	□	□
□	■	■	□	□	□	□	■	□	□	□	□	□	□	□	□	□	□	□	■	■	■	■	□	□	□	□	□	■	■	□	□
□	□	□	□	□	□	■	□	□	□	□	■	■	□	□	□	□	■	■	□	□	□	□	■	□	□	□	■	□	□	■	□
□	□	□	□	□	□	■	□	□	□	□	■	■	□	□	□	□	■	■	□	□	□	□	■	□	□	□	■	□	□	■	□
□	□	□	□	□	□	■	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	■	□	□	□	□	■	■	□	□
□	□	□	■	□	□	□	■	□	□	□	■	□	□	□	□	□	□	■	□	□	□	■	□	□	□	■	□	□	□	□	□
■	□	□	■	□	□	□	■	■	□	□	□	■	■	■	■	■	■	□	□	□	■	■	□	□	□	■	□	□	■	□	□
□	■	■	■	□	□	□	■	■	■	□	□	□	□	□	□	□	□	□	□	■	■	■	■	□	□	■	■	■	□	□	□
□	□	□	■	■	□	□	■	■	■	■	■	■	■	■	■	■	■	■	■	■	■	■	■	□	■	■	□	□	□	□	□
□	□	□	□	■	■	■	□	■	■	■	■	■	■	■	■	■	■	■	■	■	■	■	□	■	■	□	□	□	□	□	□
■	□	□	□	■	■	□	□	□	□	■	■	■	■	■	■	■	■	■	■	■	■	■	□	■	■	□	□	□	□	□	□
□	■	□	□	■	■	□	□	□	□	□	□	□	□	□	□	□	□	□	□	■	■	■	□	■	■	□	□	□	□	□	□
□	■	□	□	■	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	■	■	■	□	□	■	□	□	□	■	■	□
■	□	□	■	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	■	■	■	■	□	□	■	□	■	□	□	■
□	□	□	■	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	■	□	■	□	□	■
□	□	□	□	■	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	■	□	□	□	■	■	□
□	□	□	□	■	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	■	□	□	□	□	□	□
□	□	□	□	□	■	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	□	■	□	□	□	□	□	□	□
□	□	□	□	□	□	■	■	■	■	■	■	■	■	■	■	■	■	■	■	■	■	■	■	□	□	□	□	□	□	□	□
}\xlstabularend
\end{document}
タイプセット!


じゃん!出来上がり!
dottoesnowman

続きを読む

スポンサーサイト

Are you TeXnicians, TeXies, or TeXperts?

この記事を見て思ったのですが,TeXnicians, TeXies, TeXpertsの用語の使い分けってどうなっているのでしょうね。
"TeXnicians"はTeXの技巧がうまそうなイメージ,簡単に名乗ると怒られそう。
"TeXperts"はTeX界の大御所感が溢れている,簡単に名乗ると怒られそう。
という意味では,単なる「TeXファン」の私としては"TeXies"を名乗りたい所ですが,残念ながらこのままでは複数形です。
……"TeXies"の単数形は何?TeXy?TeXie?なんだかしっくりきませんねぇ。
単なる「TeXファン」を形容する良い言葉を誰か教えて下さい。

さて,上の記事に出てきた面白い一文でこの記事を締めたいと思います。

But assuming you want to convert Word-users and other heathens, figuratively speaking, you could use a colophon.

でも,例えて言うなら君はマイクロソフト・ワードとか他の組版ソフトウエアで文章作成してる異教徒どもをTeXユーザーに改宗させようとしているのだろう?それなら奥付でTeXをアピールすれば良いのさ。

Word-userがheathen扱いされるのは私がかつて生徒として通っていた某塾を彷彿とさせますな。TeX界にはありがちなことなのでしょうね :) 。

google code prettify 導入!

fc2ブログ上でシンタックスハイライトを実装したいな,と思っていたところ,

  【google-code-prettify】

というよさげなものを発見したので使ってみる話です。

 TeX文書が……
\tracingcommands=2
\everypar={\begingroup\hrule\everypar{\endgroup}}%

\indent\indent a%
 
\indent\indent b%

\indent\indent c%

\bye

LaTeX文書が……
\documentclass[b5j,10pt,twoside,uplatex]{jsarticle}
\usepackage[dvipdfmx]{graphicx,xcolor}
\usepackage{ascmac}
%↓で環境の名称交換
\let\boxnoteOrig\boxnote
\let\endboxnoteOrig\endboxnote
\let\screenOrig\screen
\let\endscreenOrig\endscreen
\let\screen\boxnoteOrig
\let\endscreen\endboxnoteOrig
\let\boxnote\screenOrig
\let\endboxnote\endscreenOrig
\begin{document}
\begin{screen}
screen環境中です
\end{screen}
\begin{boxnote}
boxnote環境中です
\end{boxnote}
\end{document}

目指したのはTeXShopみたいな配色(↓こんなん)です。これで安心して今年からアドベントに参加できますわ。ふぅ。
1703TeXShop.png
えっ,TeX&LaTeXのシンタックスハイライトしか実装してないじゃんかって??

今更人に聞けない改行文字のキホン

今更人に聞けないTeXにおける「改行文字」の基本




0.前置き

TeX/LaTeXアドベントカレンダー2015を眺めていたら自分でも記事が書きたくなってしまって,乗り遅れての記事になります。
TeXの基本ということで,やっぱりだれもが使う「改行文字」について。一応LaTeXでの文書作成をやったことがある人なら分かるようには書いているはず。

「改行」の機能についてではなく,「改行文字」についてです。強制改行とか三回以上の改行は効果ないとかそういう話じゃなくて,「改行文字」についてです。




1.二種類の改行文字LF,CR

まず,TeXとか関係なく,一般に改行文字には二種類あることをご存知でしょうか。

LF (LineFeed) ASCIIコード 10(10進法表記),012(8進法表記),0A(16進法表記)
CR (CarriageReturn) ASCIIコード 13(10進法表記),015(8進法表記),0D(16進法表記)

の二種類ですね。こう二種類あるのは歴史的経緯によるものだそうです。そして,OSによってどの改行文字を使っているかが異なるんですね。

改行=LF一文字 : おもにUnix系 Mac OS X を含む
改行=CR+LF : おもにWindows
改行=CR一文字 : かつてのMac OS 9など

これはちょっと考えてみれば,厄介な話であることは容易に想像がつくはずです。

あなたがTeXの開発者だったと想像してください。
Mac OS Xユーザ,Windowsユーザ,Mac OS 9ユーザの三人が,全く同じ見た目のテキストファイルをTeXでコンパイルしたとしましょう(例を以下に示す)。ちなみに,\documentclassも\begin{document}もなくてLaTeXユーザには目新しいソースかもしれませんが,LaTeXではない,生のTeXに通すべきソースファイルっていうのはこんな感じです。文書の始まりを明示する\begin{document}みたいなのはなくて,代わりに\byeで文書の終わりを明示します。

———————————————————
hoge
hage

hige
\bye
———————————————————

3人のテキストファイルは,すべて見た目が上記のようで同じかもしれないけど,そこに含まれている改行文字は異なります。(LF)(CR)を仮想的に可視化して書いてあげると,こんな感じになっているはずです。
Mac OS Xユーザなら,

———————————————————
hoge(LF)
hage(LF)
(LF)
hige(LF)
\bye
———————————————————

Windowsユーザなら,

———————————————————
hoge(CR)(LF)
hage(CR)(LF)
(CR)(LF)
hige(CR)(LF)
\bye
———————————————————

Mac OS 9ユーザなら,

———————————————————
hoge(CR)
hage(CR)
(CR)
hige(CR)
\bye
———————————————————

になっているはずです。

これらに対して,全て同一の出力

===================
hogehage
hige
===================

をGetできなくてはいけません。Knuth氏はどのようにこれを解決したでしょうか。




2.TeXによる改行文字の処理(仮)

それはというと,
「一旦テキストファイル中の改行文字(CRおよびLF)を全て外した上で,一律にCRを入れる」
というものです。

改行文字(CR or LF)に遭遇した瞬間,それを外して,CRを入れるのです。
そして,必ずそのCRにより行を終了します。

先ほどの例では,行末の(LF)ないし(CR)(LF)ないし(CR)をすべて一旦外して,
次のように書き換えてしまいます。

———————————————————
hoge(CR)
hage(CR)
(CR)
hige(CR)
\bye
———————————————————

そして空行(つまり,いきなり(CR)が来る行)があったっらそこで改行します。二行以上空行がつづいても,出力の改行は一回です。

===================
hogehage
hige
===================

と出力されるわけですね。Mac OS Xユーザからしたら,「LFを入力したはずなのに,出力は全部CRになっている!」という事態が発生しているわけで,人によっては気に入らない人もいるかもしれませんが(いないか…?),そういう仕様です。

と,天下り的に説明してきたわけですが,本当にそうなっているのか確かめないことには意味がありませんな!というわけで確かめてみることにしましょう。そのためには,カテゴリコードについて理解し,入力した文字がASCIIコード何番の文字として認識されるかという知識を得る必要があります。というわけで,これからその2点について順に見て行った後,本当に「LF入力が全部CR化するか」を検証していきたいと思います。




3.カテゴリコード

「TeX Wiki TeX入門/マクロ作成」のページに詳しいですから,そちらをあわせてお読み下さればと思います。
そこから引用させていただくと,

(引用始め)

TeXはこのように文字の分類をしているわけですが,TeXはコンピュータプログラムなので,「英文字」とか「空白文字」という概念を理解しているわけではなくて,単に11番目のカテゴリーだとか5番目のカテゴリーだとか把握しているのです。例えば「“a”は英文字だ」という代わりに「文字コード97の文字は11番目のカテゴリーの文字だ」という具合です。TeXはある文字コードの文字がどの分類に属するかを記憶しているわけです。

(引用終わり:参照2015/12/29)

そして,その「n番目のカテゴリーの文字」の分類は次のようになっています。























































































カテゴリコード分類名デフォルトでこのカテゴリコードを持つ文字
0エスケープ文字\
1グループ開始文字{
2グループ終了文字}
3数式モードへの移行文字$
4アラインメントタブ&
5行の終了文字(CR):ASCII13
6パラメータ文字#
7上付き文字^
8下付き文字_
9無視する文字(NUL):ASCII0
10空白文字(SP):ASCII32,半角スペースのこと
11英文字A,B,C,…,Z,a,b,c,…,z
12その他文字!”()+-,.:;*<>=@/`[]1234567890の各文字と,(LF):ASCII10
13アクティブ文字~
14コメント文字%
15無効文字(DEL):ASCII127


というわけで,(CR)は通常,カテゴリコード5番の「行の終了文字」に分類されているので,ここで改行が起こせるということです。だから逆に,他にもカテゴリコード5番の文字をつくれば,それで改行が起こせるということですし,(CR)をカテゴリコード5番以外にして仕舞えば,行の終了以外の機能を持たせることができるようになります。

ちなみにカテゴリコード13の「アクティブ文字」について少し触れておきます。通常ここに含まれる文字は~(チルダ)のみです。この「アクティブ文字」というのは,\defによってその定義を変更することができるような文字です。そうして定義を変更しておけば,あたかも「\(バックスラッシュ/円文字)+英文字」で実現されるような,コマンドとして機能させることができます。たとえば,~(チルダ)は,デフォルトでは「改行禁止空白」の意味を持っていますが,たとえば

\def~{iamjatex}

と一旦打っておけば,~を文字列「iamjatex」の別名として定義することができるというわけです。あとでこのアクティブ文字の機能を存分に使っていきます。アクティブ文字については,アドベントカレンダー24人目のgolden_luckyさんの記事に詳しいです。




4.入力した文字がASCIIコードの何番の文字としてTeXに認識されるか

ASCIIコードは10進数表記で0〜127まであります。さっきのカテゴリコードよりもずっと量が多いので,ここに改めて書くようなことはできません。さすがにそんなことしたら疲れるわい。

というわけで,説明のページ(新規ウィンドウで開きます)。

この表を見ながらご覧ください。

見ていただければ分かる通り,ASCII32のスペースから,ASCII126の~チルダまでの文字は,キーボードで入力しやすい,いわゆる「普通の文字」です。だから,たとえば,TeXにASCII77番の文字として認識して欲しい文字を入力するときには,単にMと入力すればよろしいということになります。そうすれば出力もMと出ます。

しかしASCII1〜31と,ASCII127はどうも入力しにくそうなものが多いですね。これらは「制御コード」と呼ばれています。こうした制御コードを打ち込むのはなかなか難しいです。たとえばMac OS X環境だったら,改行はふつうLFになってしまうわけで,CRを打ち込むのかかなり大変です。ではこうした制御コードとTeXに認識して欲しいような文字を入力するためにはどうしたらいいでしょうか。そのために使うのが,^^(ハット2回)です。これは,{^^(ハット2回)に後置された文字のASCIIコード}から64を引いた文字を指定するために使うTeXの機能です。だから,先ほどMがASCII77であるということをお伝えしましたが,^^Mと入力すれば,ASCII13の文字(CRです)をTeXに渡すことができるんです。

同様に,
ASCII0の文字(NUL)=^^@で渡せる
ASCII1の文字(SOH)=^^Aで渡せる

ASCII10の文字(これLFでしたよね)=^^Jで渡せる

ASCII13の文字(これCRでしたよね)=^^Mで渡せる

ASCII31の文字(US)=^^_で渡せる
ASCII127の文字(DEL)=^^?で渡せる
となります。

127だけはちょっと変則的ですけど,?がASCII63なので63-64(mod128)≡127とすれば納得できるでしょう。

この^^Mを用いれば,Mac OS X環境でも簡単に(CR)をTeXに認識させられるわけですね。

ちなみに,そんな需要はないかもしれませんが,tはASCII116なので,^^tと打てばASCII52の文字(つまり4)をTeXに渡すことができます。キーボードの「4」のキーが壊れてしまったけど^のキーとtのキーが生きている場合に使えますね。他にも「5」と打つ代わりに^^uと打ったり,「6」と打つ代わりに^^vと打ったりすることもできます。




5.本当にLF入力が全部CR化するか

さて,カテゴリコード,ASCII文字の何番として認識されるかという二つの予備知識を導入したところで,本題の「本当にLF入力が全部CR化するか」に入っていきたいと思います。

先ほどの例

———————————————————
hoge
hage

hige
\bye
———————————————————

を使っていきます。今,Mac OS X環境だとすると,

———————————————————
hoge(LF)
hage(LF)
(LF)
hige(LF)
\bye
———————————————————

になっているはずですね。なんらかの16進エディタを用いて開けば,改行のところが0D(CRのことでしたね)ではなく0A(LFのことでしたね)になっていることが確かめられます。

さて,出力中に(LF)や(CR)が何回登場しているかをカウントしたいので,(LF)や(CR)の定義を変更します。定義を変更するために,次のように打ちます。

———————————————————
\catcode`\^^J=13
\catcode`\^^M=13
\def^^J{(Here is LF!)}
\def^^M{(Here is CR!)}
hoge
hage

hige
\bye
———————————————————

まず,最初の2行で,改行文字の定義を変更するために,^^J(LF),^^M(CR)のカテゴリコードを一旦13(アクティブ文字)に変えています(3.節で述べた理由による)。カテゴリコードを変えるためのコマンド\catcodeは覚えておくと便利でしょう。
そして,次の2行で,^^J(LF)や,^^M(CR)が出力中に現れると,それぞれ(Here is LF!),(Here is CR!)と叫んでくれるようにしています。

ここで不可視の(LF)を可視化してやると,次のようになっているはずです。

———————————————————
\catcode`\^^J=13(LF)
\catcode`\^^M=13(LF)
\def^^J{(Here is LF!)}(LF)
\def^^M{(Here is CR!)}(LF)
hoge(LF)
hage(LF)
(LF)
hige(LF)
\bye
———————————————————

さて,これがどのような挙動を示すでしょうか。このファイルをlf.texとでもなんらか日本語を含まない名前をつけて保存し,pdftexに通してやると,ほら,このとおり。

===================
(Here is CR!)hoge(Here is CR!)hage(Here is CR!)(Here is CR!)hige(Here is CR!)
===================

LFが全部CRに置き換えられて認識されているのがわかるでしょう。これで検証されましたが,まだまだ話は続きます。「(LF)の機能」の話と,「カテゴリコード5」についての話。




6.では,(LF)はどうなってるのか?

ここまで読んでいただいた根気強い読者の方にはお分かりのことと思いますが,Mac OS X環境ならば,TeXに(LF)を渡す方法は2通りあるわけです。

(1)普通に改行する
(2)^^Jと打ち込む

しかしながら,「TeXに(LF)を渡す」という表現が曖昧なのが原因ではあるのですが,両者の挙動は全く異なります。それぞれについてお話ししていきます。まずざっくりまとめるとこんな感じ。

(1)普通に改行した場合
「行末」と認識されるため,TeXの処理の第一段階で,それを一旦削除して,(CR)に置き換えられます。そして,TeXの処理の第二段階で,「カテゴリコード5の文字(CR)+行末」というふうに認識されます。

(2)^^Jと打ち込んだ場合
TeXの処理の第一段階で,^^Jは「ASCII10の文字を指定する記号」と思われるだけです。そして,TeXの処理の第二段階で,「カテゴリコード12の文字(LF)」というふうに認識されて処理されます。結果出力は…「Ω」になります。

はい。明らか挙動が違いますね…というか「Ω」が出てくるのって結構衝撃ですよね。

たとえば,

———————————————————
^^Japanese Spirit!
\bye
———————————————————

をコンパイルすると,

===================
Ωapanese Spirit!
===================

となってしまいます。これは一体どういうことでしょうか。そのヒントは,(LF)のカテゴリコードが12というところにあります。
カテゴリコードが12,つまり他の記号や数字と一緒なので,同様の処理を受けるわけです。

その処理,とは,ASCIIコードに対応する字形をフォントの中から拾ってくる,という処理です。
たとえば,カテゴリコード12かつASCIIコード52の文字(4のこと)をTeXが処理しようとする場合には,現在のフォントのグリフの中からASCII52に対応する部分を探し出してきて,出力に渡します。TeX標準のcmr10だったら,4の足の部分に出っ張りがあるような字形が渡されるでしょうし,斜体のcmti10だったら,4の足の部分に出っ張りがない字形が渡されるでしょう。だいたいどんなフォントであっても,ASCII52に対応する部分は,4の文字に飾りがついたり,飾りが落とされたりしたものになっています(OT1エンコーディングなら)。

OT1エンコーディングについての詳しい話は割愛しますが,TeX BookのAppendice Fや,このページのAppendice Aにエンコーディングの対応表が載っているので参考にすると良いでしょう。

このような処理を(LF)も受けます。(LF)はカテゴリコード12かつASCIIコード10の文字な訳ですから,たとえばcmr10とかだったらそこに対応する文字…Ωの両足に出っ張りがあるような字形が探し出されて,出力に渡されるわけです。OT1エンコーディングなら,ASCII10は文字Ωに対応しています。

そのせいで,^^Jは出力された文書中では,文字Ωとして現れることがわかります。もちろん,エンコーディングの違うフォントを使ったら違う文字になりますけど。




7.TeX文書中の(LF)と標準出力中の(LF)は違うという話
(12/31&1/2訂正あり through doraTeXさんの情報. 多謝!=新しく追記にしました。)

前節でみたとおり,^^Jを使って改行をするというのは,出力されたTeX文書中では難しいということがわかりました。多くの場合Ωになってしまうということです。

しかしながら,標準出力中では話が違います。標準出力って何?という方は,「標準出力=ターミナル」と思っていていただければいいでしょう(若干不正確ですが)。つまりコンパイル中に上から下へとすごい勢いで流れていくあの文字たちのことです。エラーがあるとその文字たちの動きが止まって警告を出してくれるわけですね。

その標準出力中の改行は,何を隠そう

^^J

で行うのです。試しに,標準出力中にメッセージを書き込む\immediate\write命令を使ってやってみましょう。\immediate\write命令の直後にある数字は本題とは全く無関係なので気にしないでください。

(以下,誤りを含む旧情報 2015/12/31 に書き換えました。)
———————————————————
In Terminal you should use LF
\immediate\write13{After this there is LF. ^^J After this there is CR. ^^M How did it go?}
\bye
———————————————————

これをコンパイルすると,

///////////////////
Runaway text?
After this there is LF.
After this there is CR.
! Forbidden control sequence found while scanning text of \write.
///////////////////

というエラーメッセージが標準出力中に現れてコンパイルがストップします。
After this there is LF.
のあとはちゃんと(LF)で改行されて,
After this there is CR.
のあとは(CR)が入力されてターミナルが「無理でーす」といってきたわけです。
ターミナル中ではあくまで改行は(LF)という原則(ターミナルはUnix系だしね)が働いています。

(ここまで旧情報)
(以下,12/31 追記)

間違いのご指摘を受けましたので訂正いたします。

———————————————————
In Terminal you should use LF
\immediate\write13{After this there is LF.^^J
After this there is CR.^^M
How did it go?}
\bye
———————————————————

これをコンパイルすると,

///////////////////
After this there is LF.
After this there is CR. How did it go?
///////////////////

とターミナル中に出てきます。そして,pdfには

===================
In Terminal you should use LF
===================

と出力されるというわけです。

ターミナル中で,(LF)のあった場所では改行が起こっているのに,(CR)のあった場所では起こっていないことに注意してください。
After this there is LF.
のあとはちゃんと(LF)で改行されて,
After this there is CR.
のあとは改行されていないわけです。
ターミナル中ではあくまで改行は(LF)という原則(ターミナルはUnix系だしね)が働いています。

(ここまで12/31 追記)


そういえばこのあいだのlatex.ltxリーディングでも誰かがエラーメッセージ中の^^Jについて喋っていたような…確か第8回か第9回だっけな…




8.カテゴリコード5の文字の挙動

しばらく(LF)の話をしてきましたが,最後は,(CR)に限らずカテゴリコード5(行末)の文字全般に言える性質について。
え?カテゴリコード5の文字なんて(CR)しかないじゃないかって?いやはい,デフォルトではそうですけど,先ほど紹介したカテゴリコード変更コマンド\catcodeを使えば色々な文字をカテゴリコード5にしてしまうことが可能です。そうした場合にどういうことが起きうるかというと…

~~~~~~~~~~~~~~~~~~~~~
|一行の中に複数行末が来る|
~~~~~~~~~~~~~~~~~~~~~

まいったな…ってかんじですけど,ありうる話です。たとえばこんなコードを書いたとしましょう。

———————————————————
\catcode`f=5
Moderate use of \expandafter makes your life better.

hoge
\bye
———————————————————

すると出力はこうなります。

===================
Moderate use o
hoge
===================

なぜでしょうか?(あんな変なところに某\expandafterがいるのにエラーすら出ませんね…)

それは,カテゴリコード5の文字の隠れた性質によるんです。改行周りでTeXはどういう処理をするかというと,先ほど2.節では次のように述べました。

+++++++++++++++++++
「一旦テキストファイル中の改行文字(CRおよびLF)を全て外した上で,一律にCRを入れる」
というものです。
改行文字(CR or LF)に遭遇した瞬間,それを外して,CRを入れるのです。
そして,必ずそのCRにより行を終了します。
+++++++++++++++++++

これをより正確に述べると,次のようになるのです。

+++++++++++++++++++
テキストファイル中で,カテゴリコード5の文字に遭遇したら,そこを行末として,行末までは無視する。
カテゴリコード5の文字に遭遇しないまま行末まで来てしまったら,行末にある(LF)や(CR+LF)を(CR)に変える。そして(CR)がカテゴリコード5ならばそこが当然行末となる。(CR)のカテゴリコードを変更してしまっていたせいで(CR)のカテゴリコードが5でない場合にはそこは行末とはならず次の行まで連続した行だとみなされる。
+++++++++++++++++++

ということなんですね。

先ほど5.節でコンパイルした

———————————————————
\catcode`\^^J=13(LF)
\catcode`\^^M=13(LF)
\def^^J{(Here is LF!)}(LF)
\def^^M{(Here is CR!)}(LF)
hoge(LF)
hage(LF)
(LF)
hige(LF)
\bye
———————————————————

というソースでは,出力が

===================
(Here is CR!)hoge(Here is CR!)hage(Here is CR!)(Here is CR!)hige(Here is CR!)
===================

となり改行が入っていませんでしたが,これは(CR)のカテゴリコードを13に変更してしまったため\def^^M{(Here is CR!)}〜\byeまでの行がすべて連続しているとみなされてしまった結果というわけなんですね。

また,
———————————————————
\catcode`f=5
Moderate use of \expandafter makes your life better.

hoge
\bye
———————————————————

の出力が

===================
Moderate use o
hoge
===================

になるというのは,二行目最初のfが出てきた時点で\expandafter makes your life better.を無視してしまったのでエラーも出ず出力が得られたということなんですね。

これを逆手にとればあたらしいコメント入力の仕方も開発できますね…そうそう,つまり,普段あまり使わない文字をカテゴリコード5にすれば,それでコメント開始文字として利用できますね。
でもそれをやるんだったらおとなしくカテゴリコード14(コメント文字)に変更したほうが安心だとは思いますが…





というわけで,今更人に聞けない「改行文字」の基本でした。誰もが何気なく使っている改行も奥が,深いわけですね。

この記事の執筆にあたり,doraTeXさんに幾つか質問をしたりしました。この場を借りて感謝いたします。




参考文献

(1)Donald Knuth の TeXBook (Appendix CとAppendix F)

(2)B. Beeton. Controlling ; ruling the depths. TUGboat, 9:182–183, 1988. 30

(3)LATEX2ε マクロ&クラス プログラミング基礎解説 単行本 – 2002/8 ISBN-13: 978-4774115467

参考文献の書き方適当でゴメンなさい。本の特定はできると思います...

続きを読む

仏日混じりの文書

つい先日,仏日混じりの文書をtypesetする機会があったのですが...

通常の jsarticle ないし jarticle で,プリアンプルに

\documentclass[b5j,10pt,twoside,uplatex]{jsarticle}
\usepackage[dvipdfmx]{graphicx,xcolor}
\begin{document}

とした場合は,どうにも組版が美しくないのです。

jsarticleFRS.png

É,À,Ç,è,ûなどアクサンやセディーユがついた文字の前後に若干のスペースが入り込んでしまうのです。

うむ,と思うわけですが,ここで,lualatex登場!

\documentclass{ltjsarticle}
\usepackage[hiragino-pron]{luatexja-preset}
\usepackage{luatexja-otf}
\begin{document}

というふうにプリアンプルを変えてあげると...

lualatexFRS.png

ときれいにいきましたね!

他にも同じ悩みを共有している人がいるかもと思って投げてみました。
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。