スポンサーサイト

上記の広告は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

※追記1:2017/12/22)環境中でカテゴリコードを変更するだけならできたのですが(これだけなら簡単),環境中でのカテゴリコードの変更を保ったまま中身を¥countingmacroに引数として渡すところでつまづきました。引数を渡せるはず(?)のコードを書いてもなぜかエラーではじかれたりして散々だったので途中から諦めましたorz。¥begin{xlstabular}〜¥end{xlstabular}と「普通に」書けるよう,現在も改善を模索中です。

※追記2:2017/12/22)行末タブ文字についての「バグ」フィックスにより,当該問題はTeX Live 2018より解決するそうです!やったぜ!→zrさんのtweetaminophenさんのtweet

スポンサーサイト

コメントの投稿

Secret

検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

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