2018年12月19日

CSVってカンマで区切ればいいってもんじゃないだろーってのが流れてきて,そりゃそうだよな,と.データにカンマを入れたいときもあるし.で,改めて仕様を調べてみるべくWikipedia見てみたけど,思ったより複雑.まぁもともと色々とオレオレCSVああって,まぁ共通部分とるとこんなもんだろと決めたものみたいだけど.改行コードCRLF限定とか,データ内に改行を入れてもいいとか知らなかった.ちょうどTeX ForumにCSVな話が来ていたので,なんとなく読むのを書いてみた.TeXで…….別に特別なことは何もしていないですが.

  • e-TeX必須.
  • データはすべてカテゴリーコード12にして読み込む.
  • csv@<レコード番号>@<フィールド番号>に読んだデータを入れる.
  • 空白は消える(おい)
\documentclass{article}
\usepackage[T1]{fontenc}
\makeatletter
{%
  \catcode13=12\relax\gdef\CR{^^M}%
  \catcode10=12\relax\gdef\LF{^^J}%
}
\newcount\@itemnum
\newcount\@linenum
\newread\@csvread
\newif\ifinquote
% CSVファイル#1を読む.
\def\readcsv#1{%
  \openin\@csvread=#1
  \def\@csvdata{}%
  \loop\unless\ifeof\@csvread
    \readline\@csvread to \@line
    \edef\@csvdata{\@csvdata\@line}%
  \repeat
  \inquotefalse
  \@itemnum=0
  \@linenum=0
  \def\@currentdata{}%
  \expandafter\@readcsv\@csvdata\@undefined
}
\def\@readcsv#1{%
  \ifx#1\@undefined
    \expandafter\edef\csname csv@\the\@linenum @\the\@itemnum\endcsname{\@currentdata}%
    \expandafter\let\csname csv@\the\@linenum @\the\numexpr\@itemnum + 1\relax\endcsname\relax
    \expandafter\let\csname csv@\the\numexpr\@linenum - 1\relax @0\endcsname\relax
  \else
    \def\next{\@readcsv}%
    \ifx#1"%
      \def\next{\futurelet\@nextchar\@readcsv@checkquote}%
    \else
      \ifinquote
        \if#1\CR
          \edef\@currentdata{\@currentdata\CR\LF}%
        \else
          \edef\@currentdata{\@currentdata#1}%
        \fi
        \def\next{\@readcsv}%
      \else
        \if#1\CR
          \expandafter\edef\csname csv@\the\@linenum @\the\@itemnum\endcsname{\@currentdata}%
          \expandafter\let\csname csv@\the\@linenum @\the\numexpr\@itemnum + 1\relax\endcsname\relax
          \def\@currentdata{}%
          \@linenum=\numexpr\@linenum + 1\relax
          \@itemnum=0
        \else\ifx#1,%
          \expandafter\edef\csname csv@\the\@linenum @\the\@itemnum\endcsname{\@currentdata}%
          \def\@currentdata{}%
          \@itemnum=\numexpr\@itemnum + 1\relax
        \else
          \edef\@currentdata{\@currentdata#1}%
        \fi\fi
      \fi
    \fi
    \expandafter\next
  \fi
}
\def\@readcsv@checkquote{%
  \ifx\@nextchar"%
    \edef\@currentdata{\@currentdata"}%
    \def\next{\expandafter\@readcsv\@gobble}%
  \else
    \ifinquote\inquotefalse\else\inquotetrue\fi
    \def\next{\@readcsv}%
  \fi
  \next
}

\begin{document}
\readcsv{sample.csv}
\@linenum=0
\@itemnum=0
\begin{itemize}
\loop{\expandafter\unless\expandafter\ifx\csname csv@\the\@linenum @0\endcsname\relax
  {%
    \loop{\expandafter\unless\expandafter\ifx\csname csv@\the\@linenum @\the\@itemnum\endcsname\relax
      \item (\the\@linenum,\the\@itemnum) \@nameuse{csv@\the\@linenum @\the\@itemnum}
      \@itemnum=\numexpr\@itemnum + 1\relax
    }\repeat
  }%
  \@linenum=\numexpr\@linenum + 1\relax
  \@itemnum=0
}\repeat
\end{itemize}
\end{document}

0 件のコメント:

コメントを投稿

コメントの追加にはサードパーティーCookieの許可が必要です