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's gravatar image

Pathe ♦♦
7.4k28196245
Taux d'acceptation : 55%

Modifiée 26 Sep '15, 20:09

3

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'éditeur Texstudio permet aussi de couper et coller des colonnes.

(26 Sep '15, 20:22) denis ♦♦ denis's gravatar image
1

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.

(27 Sep '15, 10:26) Paul Gaborit Paul%20Gaborit's gravatar image

La piste proposée par Paul me fait penser à un autre package permettant lui aussi de travailler à partir de fichiers .csv : pgfplotstable.

(27 Sep '15, 12:37) denis ♦♦ denis's gravatar image

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 fonction orgtbl-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

Ouvrir dans l'éditeur
(info '"(org)Tables")
(info "(org)The Orgtbl minor mode")
(16 Oct '15, 00:24) Jean-jacques Rétorré Jean-jacques%20R%C3%A9torr%C3%A9's gravatar image

@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.

(16 Oct '15, 11:38) denis ♦♦ denis's gravatar image

@Pathe Il semble que ma réponse ne s'adresse pas à la question. Pour quoi vous n'avez pas déclaré?

(23 Nov '15, 23:20) touhami touhami's gravatar image

@Pathe Il semble que ma réponse ne s'adresse pas à la question. Pour quoi vous n'avez pas déclaré?

(23 Nov '15, 23:21) touhami touhami's gravatar image
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 \movetab attend des mouvements de colonnes sous la forme a->b (a est le numéro de la colonne à déplacer et b est celui de la colonne cible). S'il y a plusieurs mouvements à exécuter, il faut les séparer par des virgules, mais attention, il faut tenir compte des mouvements déjà faits pour les mouvements qui suivent.

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 \begin{<nom>}{préambule}<corps du tableau>\end{<nom>} sont possibles, mais pour simplifier, l'argument optionnel de l'environnement n'est pas admis.

La macro \movextab est identique sauf qu'elle soit être utilisée avec l'environnement tabularx.

Au niveau des limitations :

  • les caractères de changement de colonnes doivent être &, de catcode 4 evidemment ;
  • les fins de lignes doivent être \\, avec éventuellement un argument optionnel du type [<dimension>]. Pour changer cette macro en une autre telle que \tabularnewline, utiliser \STeol{<nouvelle macro} ;
  • après le changement de ligne par \\, les commandes suivantes sont admises, quel que soit leur nombre : \hline, \cline, \hhline, \noalign, toprule, \midrule, \bottomrule, addlinespace, \morecmidrule et \specialrule, ainsi que leur éventuels arguments optionnels ou obligatoires
  • pour simplifier par rapport à spreadtab, la macro \multicolumn n'est pas gérée : elle est bêtement déplacée dans la colonne cible, avec toutes les fâcheuses conséquences que cela peut avoir.

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}
Lien permanent

Publiée 24 Nov '15, 22:07

unbonpetit's gravatar image

unbonpetit ♦♦
1.8k18
Taux d'acceptation : 68%

Modifiée 24 Nov '15, 22:18

Ces nouvelles et utiles commandes pourraient faire partie d'une extension.

(24 Nov '15, 23:15) Pathe ♦♦ Pathe's gravatar image

@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 ♦♦ unbonpetit's gravatar image
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's gravatar image

@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 ♦♦ unbonpetit's gravatar image
Votre réponse
(dés)activer l'aperçu

Suivre cette question

Par courriel :

Une fois que vous serez enregistré, vous pourrez souscrire à n'importe quelle mise à jour ici

Par flux RSS :

Réponses

Réponses et commentaires

Bases de Markdown

  • *italique* ou _italique_
  • **gras** ou __gras__
  • Lien ::[texte](http://url.com/ "Titre ")
  • Image : ?![alt texte](/path/img.jpg "Titre ")
  • Liste numérotée : 1. Foo 2. Bar
  • Pour ajouter un passage à la ligne, ajoutez deux espaces à l'endroit où vous souhaitez que la ligne commence.
  • Les balises HTML de base sont également prises en charge.