Exportar cuadrícula con estilo a látex
Me gustaría escribir una ExportStringfunción -type para convertir Grido TextGriden tablas de Latex conservando elementos de estilo básicos, incluido el texto con estilo , los separadores de celdas con estilo y los colores de fondo de las celdas .
A continuación, se muestra un ejemplo del tipo de tabla que intento exportar. La entrada tendría un estilo TextGridcomo este:
TextGrid[{{"","x","y","w","z"},{Style["variable 1",Italic],"a","b","c","d"},{Style["variable 2",Bold],"a","b","c","d"},
{Style["variable 3",Blue],"a","b","c","d"},{"variable 4","a","b","c","d"},{"variable 5","a","b","c","d"}},
Background->{{White,{LightGray,White}},{1->LightCyan}},Dividers->{{False,{True},False},
{True,True,{False},True},{{{1,2},{2,-2}}->False,{{1,1},{2,-2}}->True,
{{2,2},{2,-2}}->True}},Alignment->{Center,Center},Spacings->{{1,{3}},1}]
Una solución debería poder generar algo como el \begin{tablular}...\end{tabular}bloque en el documento a continuación:
\documentclass{article}
\usepackage{xcolor,colortbl} % (* you may assume these packages *)
\newcommand{\mc}[2]{\multicolumn{#1}{c}{#2}}
\definecolor{Gray}{gray}{0.85}
\definecolor{LightCyan}{rgb}{0.88,1,1}
\definecolor{LightBlue}{rgb}{0,0,1}
\newcolumntype{a}{>{\columncolor{Gray}}c}
\newcolumntype{b}{>{\columncolor{white}}c}
\begin{document}
\begin{table} % (* the generated portion *) \begin{tabular}{l | a | b | a | b} \hline \rowcolor{LightCyan} \mc{1}{} & \mc{1}{x} & \mc{1}{y} & \mc{1}{w} & \mc{1}{z} \\ \hline variable 1 & a & b & c & d \\ variable 2 & a & b & c & d \\ variable 3 & a & b & c & d \\ variable 4 & a & b & c & d \\ variable 5 & a & b & c & d \\ \hline \end{tabular} \end{table}
\end{document}
¿Qué látex rinde maravillosamente como:
Esto parece razonablemente parecido al TextGridresultado original anterior.
Respuestas
Nunca usé LaTex, así que decidí jugar con esto por un tiempo y usar latexbase.com para verificar la salida. Ésta no es una solución completa. Funciona para la plantilla proporcionada. Esto es lo que hace:
- Permite la modificación del color de todo el texto, fondo de la fila del encabezado, fondo de la primera columna y fondo alterno para las columnas siguientes. Se
\definecoloremite una línea para todos los colores y estos se denominan color1 , color2 ... etc. - Permite el uso de
Style[]para delimitar texto y admite una combinación de negrita, cursiva, subrayado y color. - El color debe ser RGBColor o GrayLevel, o el nombre de color equivalente.
Spacingsse aplica uniformemente para todas las columnas y filas y debe ingresarse en el formato{x,y}.Backgrounddebe ingresarse en el formato que se muestra en la pregunta. La primera entrada (amarilla en el ejemplo) es el fondo de la primera columna. Luego vienen los dos colores (LightGray, White) utilizados para alternar el color de otras columnas, y luego la regla (1-> LightCyan) es el color de fondo de la fila del encabezado.- El texto de la primera columna está alineado a la izquierda. Está alineado al centro en las otras columnas.
- La
Dividersopción no se analizó (es decir, las líneas se dibujaron arbitrariamente para coincidir con el modelo dado en la pregunta).
Aquí hay un ejemplo basado en la pregunta, pero con más variación en los estilos.
tg = TextGrid[{{"", "x", Style["y", Italic, Bold, Red],
Style["w", Underlined],
Style["z", RGBColor[1, 0, 1]]}, {Style["variable 1", Italic], "a",
"b", "c", "d"}, {Style["variable 2", Bold], "a", "b", "c",
"d"}, {Style["variable 3", Blue], "a", "b", "c",
"d"}, {"variable 4", "a", Style["b", Gray],
Style["c", Brown, Bold], "d"}, {"variable 5", "a", "b", "c",
Style["d", Blue]}},
Background -> {{Yellow, {LightGray, White}}, {1 -> LightCyan}},
Spacings -> {3, 1.5},
Dividers -> {{Opacity[0], {True}, Opacity[0]}, {True, True, {False},
True}, {{{1, 2}, {2, -2}} -> False, {{1, 1}, {2, -2}} ->
True, {{2, 2}, {2, -2}} -> True}},
Alignment -> {Center, Center}]
(* Conversion function *)
textGridAsTeX[tg_TextGrid] := (
processStyle[s_] := ( Module[{n, m, colorToken, token, colorName},
If[Length[s] == 0 , Return[s]];
token = s[[1]];
n = 2;
While[n <= Length[s],
If[Head[s[[n]]] == RGBColor || Head[s[[n]]] == GrayLevel,
colorToken = s[[n]]];
If[s[[n]] == Italic,
token = StringJoin["\\textit{", token, "}"]];
If[s[[n]] == Bold,
token = StringJoin["\\textbf{", token, "}"]];
If[s[[n]] == Underlined,
token = StringJoin["\\underline{", token, "}"]];
n++;
];
If[Head[colorToken] == RGBColor || Head[colorToken] == GrayLevel ,
If[! MemberQ[colorsDefined, ToString[colorToken]],
colorName =
StringJoin["color", ToString[Length[colorsDefined] + 1]];
AppendTo[colorsDefined, ToString[colorToken]];
l = Apply[List, colorToken];
If[Length[l] == 3, colorModel = "}{rgb}",
colorModel = "}{gray}"];
ltex =
Insert[ltex,
StringJoin["\\definecolor{" , colorName, colorModel,
ToString[Apply[List, colorToken]], "\r"], 1],
p = Flatten[Position[colorsDefined, ToString[colorToken]]];
colorName = StringJoin["color", ToString[p[[1]]]];
];
token = StringJoin["\\textcolor{", colorName, "}{", token, "}" ];
];
Return[token];]
);
cName[col_] := (
If[! MemberQ[colorsDefined, ToString[col]],
colorName =
StringJoin["color", ToString[Length[colorsDefined] + 1]];
AppendTo[colorsDefined, ToString[col]];
l = Apply[List, col];
If[Length[l] == 3, colorModel = "}{rgb}", colorModel = "}{gray}"];
ltex =
Insert[ltex,
StringJoin["\\definecolor{" , colorName, colorModel,
ToString[l], "\r"], 1],
p = Flatten[Position[colorsDefined, ToString[col]]];
colorName = StringJoin["color", ToString[p[[1]]]];
];
colorName
);
colorsDefined = {};
tgList = Apply[List, tg];
rows = Length[tgList[[1]]];
cols = Length[tgList[[1]][[1]]];
ltex = {};
(* spacing *)
spacing =
FilterRules[tgList[[2 ;; Length[tgList]]], Spacings][[1]][[2]];
v = spacing[[1]];
AppendTo[ltex,
StringJoin["\\setlength{\\tabcolsep}{", ToString[v*6], "pt}\r"]];
v = spacing[[2]];
AppendTo[ltex,
StringJoin["\\renewcommand{\\arraystretch}{", ToString[v],
"}\r"]];
(* new column types *)
bck = FilterRules[tgList[[2 ;; Length[tgList]]], Background];
newcol = bck[[1]][[2]][[1]][[2]];
n = 1;
While[n <= Length[newcol],
AppendTo[ltex,
StringJoin["\\newcolumntype{", {"a", "b"}[[n]],
"}{>{\\columncolor{" , cName[newcol[[n]]], "}}c}\r"]];
n++;
];
newCol = bck[[1]][[2]][[1]][[1]];
AppendTo[ltex,
StringJoin["\\newcolumntype{", "d", "}{>{\\columncolor{" ,
cName[newCol], "}}l}\r"]];
(* new command *)
AppendTo[ltex,
"\\newcommand{\\mc}[2]{\\multicolumn{#1}{c}{#2}}\r"];
(* begin document *)
AppendTo[ltex, "\\begin{document}\r"];
(* the table *)
AppendTo[ltex, "\\begin{table}\r"];
(* tabular *)
AppendTo[ltex, "\\begin{tabular}"];
(* columns description *)
aCols = Table["a", cols];
bCols = Table["b", cols];
rCols = Riffle[aCols, bCols];
rfCols = Take[rCols, cols - 1];
colTypes = {"{d"};
n = 1;
While[n <= cols - 1,
AppendTo[colTypes, StringJoin[" | ", rfCols[[n]]]];
n++;
];
AppendTo[ltex, StringJoin[colTypes, "}\r"]];
(* Header row *)
AppendTo[ltex, "\\hline\r"];
rowNumber = bck[[1]][[2]][[2]][[1]][[1]];
rowVal = cName[bck[[1]][[2]][[2]][[1]][[2]]];
AppendTo[ltex, StringJoin["\\rowcolor{", rowVal, "}\r"]];
cList = tgList[[1]][[1]];
n = 1;
While[n <= cols,
AppendTo[ltex,
StringJoin["\\mc{1}{", processStyle[cList[[n]]], "}"]];
If[n == cols, AppendTo[ltex, " \\\\\r"], AppendTo[ltex, " & \r"]];
n++;
];
AppendTo[ltex, "\\hline\r"];
(* Rows *)
m = 2;
While[m <= rows,
cList = tgList[[1]][[m]];
n = 1;
While[n <= cols,
AppendTo[ltex, processStyle[cList[[n]]]];
If[n == cols, AppendTo[ltex, " \\\\\r"], AppendTo[ltex, " & "]];
n++;
];
m++;
];
AppendTo[ltex, "\\hline\r"];
(* End tabular*)
AppendTo[ltex, "\\end{tabular}\r"];
(* end table *)
AppendTo[ltex, "\\end{table}\r"];
(* end document *)
AppendTo[ltex, "\\end{document}\r"];
(* package *)
ltex = Insert[ltex, "\\usepackage{colortbl}\r", 1];
(* the documentclass *)
ltex = Insert[ltex, "\\documentclass{article}\r", 1];
StringJoin[ltex]
)
(* calling the function *)
textGridAsTeX[tg]
Este es el resultado:
Mathematica:
Látex: