\documentclass{ctexart}
\usepackage{tabular2}


\ExplSyntaxOn
\cs_new:Npn \ttt #1
  { \texttt{\tl_to_str:n{#1}} }
\ExplSyntaxOff
\begin{document}

\title{tabular2 宏包示例文档}
\author{Ms\_yam}
\date{\today}
\maketitle

\begin{abstract}
  本文档是 tabular2 宏包文档的扩展文档，展示了 tabular2 的一些基本功能及用法。
  同时，本文档也是 tabular2 的功能测试文档。
  文档本身只作功能介绍及效果展示，并未同时显示生成表格的相关代码，
  需要用户自行查看原代码\footnote{现在编辑器和 PDF 阅读器均支持反向查看，要找对应的源代码几乎无难度。}。
  查看原代码之前，应当先阅读 tabular2 宏包文档的用户部分。
\end{abstract}

{\small \tableofcontents}

\section{行列名设置}

行列名用于输入时定位，任一行列均可以有多个列名，但一个行列名只能映射到唯一的行或列。
行列名映射是可以修改的，但修改后不会影响已录入数据。

单纯的设置行列名会得到一张空表。其中，\ttt{\excelcolname}命令不影响表的行列数；
而 \ttt{\rowname}与 \ttt{\colname}命令则会影响。
设置列名会修改对应的表头\footnote{表头为最后设置的有效的列名。}。
下面是第一个示例\footnote{以框架及三线表两种方式输出。【下同】}：\par

\begin{xtable}
\excelcolname
\colname(3){AA,BB,CC}
\colname{5}
\rowname[|]{2|A}
\cell(2,5){data}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

注：此时的行名对应关系为 \ttt{<2>} = $1$（无效），\ttt{<A>} = $2$；
如果这时输入行坐标 $2$，它会识别为第 $2$ 行而非第 $1$ 行。
对于列名同理，虽然列名 \ttt{<5>} = $1$，但因其不生效，所以最终修改的是第 $5$ 列。 \par

注：行列名暂时不支持特殊字符，后续是否支持待考量。

\section{data 环境录入数据}

\subsection{标准输入}

\subsubsection{默认效果}

以下是全部使用默认值（逗号分隔，\ttt{\\}换行）的标准输入的效果：\par

\begin{xtable}
\begin{data}
  Name, Sex,    Age\\
  John, man,    18\\  
  Leon,    ,    20\\
  \\
  Lily, woman,  21\\  
  ,\\
\end{data}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

其中：首行为表头（兼列名），中间的行会保留，尾随的空行不会。
不强制要求所有行的列数相同。

\subsubsection{特殊字符}

标准输入不对特殊字符进行任何预处理，所有输入均为凭据表，直接由 \TeX 的默认方式处理。
但由于“\ttt{\\}”用于分隔表格行，因此单元格换行需要使用“\ttt{\newline}”。
如果单元格本身带逗号，则可通过指定其它分隔符来规避。\par

\begin{xtable}
\begin{data}[sep={=}]
  AA        = BB          = CC \\
  A\{[\#\$  = a\newline b = "\_ \\  
  B\}]\%\&  = c\\d        = ,\textbackslash\\  % 此处的 c\\d 生成的不是单元格换行
\end{data}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

\subsection{CSV 输入}

\subsubsection{默认效果}

需要指定输入选项为 “\ttt{csv}” 才能让本环境按 CSV 格式处理。\par

\begin{xtable}
\begin{data}[format=csv]
  AA , BB , CC\\
  A  , ab , 1 \\
  B  , cd , 2 \\
              \\
     ,    , 3 
\end{data}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

虽然本宏包也支持指定分隔符，但是仍建议遵守约定，使用默认值“\ttt{,}”。

\subsubsection{特殊字符【待处理】}

\subsection{JSON 输入}

\subsubsection{默认效果}

需要指定输入选项为 “\ttt{json}” 才能让本环境按 JSON 格式处理。\par

\begin{xtable}
\begin{data}[format=json]
[
 { "A" : "a",  "B" : true,  "C" : 1 },
 { "A" : "bc", "C" : 2 },
 { "A" : "d",  "C" : 3 },
 {},
 { "A" : "e",  "B" : false, "C" : 4 }
]
\end{data}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

JSON 的输入方式与标准输入迥异，不需要使用“\ttt{\\}”来换行。
其属性名为表头（兼列名），属性值为表体。

\subsubsection{特殊字符【待处理】}


\subsection{输入位置}

对于标准输入（含 CSV 格式），可以通过选项来指定输入的起点位置\footnote{注：如果某列没有列名，则其表头为 “\texttt{<i>}”。}。
后续位置则依次往后延。如果未指定，则默认为“\{1, 1\}”。

\begin{xtable}
\begin{data}[loc={2,3}]
  Name, Sex,    Age\\
  John, man,    18\\  
  Leon,    ,    20\\
  Lily, woman,  21\\  
\end{data}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par


如果原有列名映射的位置与现有位置不同，则会更新列名映射。
但之前按列名输入的数据不会变。

\begin{xtable}
\begin{data}
  Sex, Name\\
  man, John 
\end{data}
\begin{data}[loc={2,3}, format=json]
[
 { "Name": "John", "Sex": "man",   "Age": 18 },
 { "Name": "Leon", "Sex": "",      "Age": 20 },
 { "Name": "Lily", "Sex": "woman", "Age": 21 },
]
\end{data}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

但对于 JSON 格式，则是完全不一样的逻辑：
如果列名已经存在，则直接填充数据；如果列名不存在，则在指定位置及之后依次添加新列名。

% 需要指定输入选项才能按 CSV 格式输入。\par
%
% \begin{xtable}
% \begin{data}[format=csv]
% "A\{\}""",B,C\\
% "a""",,1\\
% "b\\
% c",,2\\
% "d,",,3\\
% e,,4\\
% \end{data}
% \end{xtable}
% \rendertable \rule{2em}{0pt} \rendertable[booktabs] \par
% \logtable

\subsection{无表头输入}

在标准输入与 CSV 输入中，默认第一行为表头（列名），但这可能通过 \ttt{header} 选项来修改这一设定。

\begin{xtable}
\begin{data}[header=false]
  Name, Sex,    Age\\
  John, man,    18\\  
  Leon,    ,    20\\
  Lily, woman,  21\\  
\end{data}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

如果该选项只在 \ttt{data} 层级设置，那么它的作用只限制为把第 $1$ 行当作数据行处理
\footnote{此时如果没有额外设置列名，则会出现如示例所示的默认表头。}。
如果需要一个无表头的表，则需要在 \ttt{xtable} 层级中设置
\footnote{此时，\ttt{data} 层级默认会继承这个设置，除非手动指定。}。

\begin{xtable}[header=false]
\begin{data}
  John, man,    18\\  
  Leon,    ,    20\\
  Lily, woman,  21\\  
\end{data}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par


\subsection[文件导入【待实现】]{文件导入\ttt{\file}【待实现】}

\ttt{\file} 是的功能与 \ttt{data} 的功能几乎一致，除了其是以文件作为输入及换行有特殊处理。

\section{行列与单元格输入}

此本部分是本宏包与传统表格之间的最大差异点之一。

\subsection[按行输入]{按行输入\ttt{\row}}

以下是按行输入的示例，如果某行数据超出现有列数，则会自动添加列（无列名）。

\begin{xtable}
\begin{data}
  Name, Sex,    Age\\
  John, man,    18\\ 
\end{data}
\row[|]{Lily||20}
\row(4){Jacob, man, 21}
\row(3,2){woman, 18, newcol}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

\subsection[按列输入]{按列输入\ttt{\col}}

以下是按列输入的示例，如果某列数据超出现有行数，则会自动添加行。

\begin{xtable}
\begin{data}
  Name, Sex,    Age\\
  John, man,    18\\ 
\end{data}
\col(newcol)[|]{A|B}
\col{1,2}
\col(2,Sex){woman, man}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

\subsection[按单元格输入]{按单元格输入\ttt{\cell}}

以下是按单元格输入的示例，如果某列数据超出现有行数，则会自动添加行。

\begin{xtable}
\begin{data}
  Name, Sex,    Age\\
  John, man,    18\\ 
\end{data}
\cell(3,newcol){newdata}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par


\section{加载与保存}

当存在大量相似的表的时，可以使用本功能与减少录入工作。

\subsection{保存表格}

以下是一个基础表，并使用保存命令保存了部分节点（保存数据没有直接体现）。

\begin{xtable}
\begin{data}[format=json]
[
 { "Name": "John", "Sex": "man",   "Age": 18 },
 { "Name": "Leon", "Sex": "",      "Age": 20 },
 { "Name": "Lily", "Sex": "woman", "Age": 21 },
]
\end{data}
\savetable{abc} % 注意保存的节点
\cell(2,Age){19}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

请注意保存的节点，在保存命令之后做的修改不会影响已经保存的表格。

\subsection{加载表格}

以下是复用的表格数据：

\begin{xtable}
\col(Name){A,B,C,D}
\loadtable{abc} 
\cell(2,Sex){man}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

注，加载表格会覆盖之前的设置，因此通常把它放置到第一行。

\section{格式设置}

\subsection{宽度与高度}

默认表格会自动计算所需的尺寸，以包容单元格。

\begin{xtable}
\begin{data}
  AA, BB, CC, EE\\
  abcde, 12, dd, abccba\\
  ab, 12, xy, abc\\
\end{data}
\cell(2,BB){19\\20}
\savetable{abc}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

但可以通过 \ttt{\rowheight}与 \ttt{\colwidth}来指定其它方式。

\begin{xtable}
\loadtable{abc}
\rowheight[same]{auto}
\colwidth[auto][0.45\textwidth]{same,same,fill,1em}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par

注：如果宽度设置过小，会导致数据超出单元格。

\subsection{对齐方式}

默认情况，表格是左右居中，上下底对齐的，但可通用\ttt{\rowalign}与 \ttt{\colalign}来指定对齐方式。

\begin{xtable}
\loadtable{abc}
\rowheight[same]{auto}
\rowalign[b]{b,m,m}
\colalign{l,c,c,r}
\end{xtable}
\rendertable \rule{2em}{0pt} \rendertable[booktabs] \par
注：对齐 Bug 待修复。

\section{合并单元格【待实现】}

\section{渲染输出【待更新】}

\end{document}
