Je compose des tableaux très larges, et il m'arrive d'avoir à déplacer des colonnes, ou à les reproduire dans un autre tableau. Ces opérations sont très faciles à effectuer à l'aide d'un tableur. Mais existe-t-il une méthode pour faire de même avec LaTeX ? Actuellement je fais ça à l'aide d'expressions rationnelles, mais ce n'est pas l'idéal pour un amateur. Posée 26 Sep '15, 19:57 Pathe ♦♦
Affichage de 5 parmi 7
Afficher 2 commentaire(s) en plus
|
Voici une solution (un peu) générale, dont la syntaxe est assez commode.
La macro Juste à la suite de ces mouvements doit se trouver le tableau dans lequel les colonnes seront déplacées. Normalement et si aucun bug n'est présent, tous les environnements de tableau du type La macro Au niveau des limitations :
Pour la sauvegarde de colonnes, je n'ai absolument pas compris dans quel but et je ne vois pas avec quelle syntaxe on pourrait faire en sorte qu'elles soient réutilisées dans un autre tableau. La demande est bien trop imprécise. Ouvrir dans l'éditeur
\documentclass{article} \usepackage{spreadtab,array,booktabs,tabularx} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \makeatletter \long\def\MT@get@body@env#1\end{\ST@add@tomacro\ST@tab{#1}\MT@find@end} \newcommand*\MT@find@end[1]{% \def\ST@temp@a{#1}% \ifx\ST@temp@a\MT@envname \expandafter\movetab@i \else \ST@add@tomacro\ST@tab{\end{#1}}% \expandafter\MT@get@body@env \fi } \def\movetab#1\begin#2#3{% \begingroup \def\MT@envname{#2}% \expandarg\noexploregroups \def\MT@tab@preamble{\begin{#2}{#3}}% \def\MT@tab@end{\end{#2}}% \def\MT@optcode{#1}% \let\ST@tab\@empty \MT@get@body@env } \def\movextab#1\begin#2#3#4{% \begingroup \def\MT@envname{#2}% \expandarg\noexploregroups \def\MT@tab@preamble{\begin{#2}{#3}{#4}}% \def\MT@tab@end{\end{#2}}% \def\MT@optcode{#1}% \let\ST@tab\@empty \MT@get@body@env } \newcommand*\movetab@i{% \MT@read@tab \MT@genlistcol \unless\ifx\MT@optcode\@empty\expandafter\MT@movecol\MT@optcode,\relax->\relax,\fi \let\ST@tab\MT@tab@preamble \MT@build@tab \ST@expadd@tomacro\ST@tab\MT@tab@end \ST@tab \restoreexpandmode\restoreexploremode \endgroup } \newcommand*\MT@read@tab{% \def\ST@total@colnumber{0}% \ST@rowcount\z@ \ST@search@hline \MT@read@tab@i } \newcommand*\MT@read@tab@i{% \advance\ST@rowcount\@ne \ST@Ifinstr\ST@tab{\ST@eol}% {\expandafter\ST@split\expandafter\ST@tab\expandafter{\ST@eol}\ST@current@row\ST@tab \@namedef{endrow@\number\ST@rowcount\expandafter}\expandafter{\ST@eol}% \ST@Iffirstis\ST@tab[% {\ST@between\ST@tab[]\ST@temp@a \ST@Ifinstr\ST@temp@a,% \relax {\ST@split\ST@tab]\ST@temp@a\ST@tab \expandafter\ST@expadd@tomacro\csname endrow@\number\ST@rowcount\endcsname{\ST@temp@a]}% }% }% \relax \ST@search@hline \ifx\ST@tab\@empty \let\ST@next@readrows\relax \edef\ST@total@rownumber{\number\ST@rowcount}% \else \let\ST@next@readrows\MT@read@tab@i \fi }% {\let\ST@current@row\ST@tab \let\ST@next@readrows\relax \edef\ST@total@rownumber{\number\ST@rowcount}% }% \ST@colcount\z@ \MT@read@cells \ST@next@readrows } \newcommand*\MT@read@cells{% \advance\ST@colcount\@ne \ST@Ifinstr\ST@current@row&% {\ST@split\ST@current@row&\ST@current@cell\ST@current@row \let\ST@next@readcells\MT@read@cells }% {\let\ST@current@cell\ST@current@row \let\ST@next@readcells\relax \ifnum\ST@colcount>\ST@total@colnumber\edef\ST@total@colnumber{\number\ST@colcount}\fi }% \ST@letname{text@\number\ST@colcount @\number\ST@rowcount}\ST@current@cell \ST@next@readcells } \newcommand*\MT@genlistcol{% \ST@colcount\z@ \def\MT@listcol{,}% \loop \advance\ST@colcount\@ne \unless\ifnum\ST@colcount>\ST@total@colnumber\space \edef\MT@listcol{\MT@listcol\number\ST@colcount,}% \repeat } \def\sanitize@listcol,#1,\@nil{\def\MT@listcol{#1}} \def\MT@movecol#1->#2,{% \unless\ifx\relax#1% \StrBetween[\numexpr#1,\numexpr#1+1]\MT@listcol,,[\ST@temp@a]% \StrSubstitute\MT@listcol{\expandafter,\ST@temp@a,},[\MT@listcol]% \StrCut[\numexpr#2]\MT@listcol,\MT@listcol\ST@temp@b \edef\MT@listcol{\MT@listcol,\ST@temp@a,\ST@temp@b}% \expandafter\MT@movecol \fi } \newcommand\MT@build@tab{% \expandafter\sanitize@listcol\MT@listcol\@nil \ST@rowcount\@ne \expandafter\ST@expadd@tomacro\expandafter\ST@tab\csname endrow@0\endcsname \MT@build@tab@i } \newcommand\MT@build@tab@i{% \ST@colcount\@ne \@for\MT@colnum:=\MT@listcol\do{% \ifcsname text@\MT@colnum @\number\ST@rowcount\endcsname \expandafter\ST@expadd@tomacro\expandafter\ST@tab\csname text@\MT@colnum @\number\ST@rowcount\endcsname \fi \advance\ST@colcount\@ne \unless\ifnum\ST@colcount>\ST@total@colnumber\relax\ST@add@tomacro\ST@tab&\fi }% \ifcsname endrow@\number\ST@rowcount\endcsname \expandafter\ST@expadd@tomacro\expandafter\ST@tab\csname endrow@\number\ST@rowcount\endcsname \fi \advance\ST@rowcount\@ne \unless\ifnum\ST@rowcount>\ST@total@rownumber \expandafter\MT@build@tab@i \fi } \makeatother \begin{document} \parindent=0pt Essai 1 : colonne 1->3 \movetab 1->3 \begin{tabular}{ccc}\hline foo & bar & BAZ \\[2ex] 123 & 456 & 789 \\ a & \textbf{b} & c \\\hline \end{tabular} \vskip2cm Essai 2 : échange des colonnes 1 et 5 \movetab 1->5,4->1% échange les colonnes 1 et 5 \begin{tabular}{|*6{>{\centering\arraybackslash}m{1cm}|}}\hline\hline 1 & 2 & 3 & 4 & 5 & 6\\ a & b & c & d & e & f\\\cline{1-4} 11& 22& 33& 44& 55&66\\\noalign{\vskip1ex} A & B & C & D & E & F\\\hline\hline \end{tabular} \vskip2cm Essai 3 : colonne 2->3, 4->5 et 6->1 \movetab 2->3,4->5,6->1 \begin{tabular}{*6{c}}\toprule[1.5pt] 1 & 2 & 3 & 4 & 5 & 6\\\midrule[0.5pt] a & b & c & d & e & f\\ 11& 22& 33& 44& 55&66\\ A & B & C & D & E & F\\\bottomrule \end{tabular} \vskip2cm Essai 4, tabularx : colonne 1->4 \hfill \movextab 1->4 \begin{tabularx}{0.75\linewidth}{|c|c|c|X|}\hline 1 & 2 & 3 & 4\\ 11111111111111111 & 222222 & 3333 & 44\\\hline \end{tabularx} \hfill\null \end{document} Publiée 24 Nov '15, 22:07 unbonpetit ♦♦ Ces nouvelles et utiles commandes pourraient faire partie d'une extension.
(24 Nov '15, 23:15)
Pathe ♦♦
@Pathe : je ne pense pas, non. Comme je le disais dans le commentaire d'une réponse qui a été supprimée, je n'y crois pas et donc, je ne pense pas le faire. À mon avis, des déplacements de colonnes sont l'affaire de l'éditeur, pas de TeX ou LaTeX.
(24 Nov '15, 23:19)
unbonpetit ♦♦
1
@pathe n'oublie pas de me remercier car j'ai poussé un bon petit à répondre à ta question (du 26 septembre) ;-)
(25 Nov '15, 00:10)
touhami
@touhami : ce n'est pas faux. J'avais déjà failli répondre à l'époque, mais comme je trouve ma solution extrêmement discutable, j'avais renoncé. C'est en voyant votre code que j'ai réagi. Ce n'est pas pour être méchant, mais il ne me semble pas nécessaire de vouloir répondre à tout prix, surtout pour une question comme celle-là et en donnant une solution aussi peu fonctionnelle que la vôtre. Ensuite pour les remerciements, je crois que ce site est le mauvais endroit pour les exprimer.
(25 Nov '15, 08:20)
unbonpetit ♦♦
|
Je pense que le plus simple pour cela est de recourir à des fonctionnalités de l'éditeur de texte utilisé, notamment la possibilité offerte par certains (
Emacs
entre autres) d'aligner verticalement les&
et de faire ensuite des copies, coupes et collages rectangulaires. L'éditeurTexstudio
permet aussi de couper et coller des colonnes.Pour des opérations ponctuelles, la proposition de Denis me semble la plus simple. Si, au contraire, c'est quelque chose que vous faites très régulièrement, il peut être intéressant de se pencher sur le package
datatool
qui permet de lire un fichier CSV et d'en extraire les colonnes voulues.La piste proposée par Paul me fait penser à un autre package permettant lui aussi de travailler à partir de fichiers
.csv
:pgfplotstable
.Avec le org-mode d'Emacs, c'est très simple. Pas besoin d'utiliser des copier-coller rectangulaires. Il suffit dans latex-mode d'activer le mode secondaire orgtbl (
M-x orgtbl-mode
) puis d'appeler la fonctionorgtbl-insert-radio-table
. Ensuite on édite la table en utilisant les fonctions d'édition de table, on peut réordonner les lignes ou les colonnes. Pour plus de détails, évaluer@Jean-jacques... Attention, ceci est plus un commentaire à mon commentaire sur Emacs qu'une réponse à la question. Je vais donc la transformer comme telle.
@Pathe Il semble que ma réponse ne s'adresse pas à la question. Pour quoi vous n'avez pas déclaré?
@Pathe Il semble que ma réponse ne s'adresse pas à la question. Pour quoi vous n'avez pas déclaré?