Conflict between personal macro and Babel French

I wrote a personal command that allows you to place a text next to a figure. This macro has been corrected for an incompatibility with the tikz calc library here: Personal command incompatible with tikz calc library

But this correction induces a bad typographical spacing in the French language precisely for the two characters that caused problems with the tikz calc library. Here is a screenshot:

Fine spaces after the double point ":" or after the exclamation point "!" (the first line is correct) have disappeared on the second line.

\documentclass{article}
\usepackage[french]{babel}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{babel}

\newlength{\colG}\newlength{\colD}
% Wrapper command just changes catcodes and calls helper
\newcommand\compo{%
\shorthandoff{!:}% Change the catcodes
\compohelper % call helper to grab arguments
}
\newcommand{\compohelper}[3][0.5]{% do actual work
\setlength{\colG}{#1\linewidth}%
\setlength{\colD}{\linewidth}%
\par \noindent%
\begin{minipage}[t]{\colG}#2\end{minipage}\hfill\vrule\hfill%
\begin{minipage}[t]{\colD}#3\end{minipage}%
\par
\shorthandon{!:}% restore catcodes
}

\begin{document}
Car: En effet!

\dotfill

\bigskip
\compo[.5]{
Car: En effet!

}{
\begin{tikzpicture}
\coordinate (B) at (0,0);
\coordinate  (C) at (3,0);
\coordinate(D) at (2,0);
\draw(B)--(C)--(D)--cycle;
\coordinate (Ap) at ($(C)!.35!-90:(B)$);
\draw (Ap)--(B)--(C)--cycle;
\end{tikzpicture}
}
\end{document}

Is it possible to allow tikz and babel french to be used in parallel on this macro so that the typographical spaces conform to the French language?

Use an environment:

\documentclass{article}
\usepackage[french]{babel}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{babel}

\newlength{\colG}\newlength{\colD}
\newenvironment{compo}[1][0.5]
{%
\setlength{\colG}{#1\linewidth}%
\setlength{\colD}{\linewidth}%
\par\noindent
\begin{minipage}[t]{\colG}%
}
{%
\end{minipage}%
\par
}
\newcommand{\compobreak}{%
\end{minipage}\hfill\vrule\hfill
\begin{minipage}[t]{\colD}%
}

\begin{document}
Car: En effet!

\dotfill

\bigskip

\begin{compo}[.5]
Car: En effet!
\compobreak
\begin{tikzpicture}
\coordinate (B) at (0,0);
\coordinate  (C) at (3,0);
\coordinate(D) at (2,0);
\draw(B)--(C)--(D)--cycle;
\coordinate (Ap) at ($(C)!.35!-90:(B)$);
\draw (Ap)--(B)--(C)--cycle;
\end{tikzpicture}
\end{compo}

\begin{compo}[.5]
\begin{tikzpicture}
\coordinate (B) at (0,0);
\coordinate  (C) at (3,0);
\coordinate(D) at (2,0);
\draw(B)--(C)--(D)--cycle;
\coordinate (Ap) at ($(C)!.35!-90:(B)$);
\draw (Ap)--(B)--(C)--cycle;
\end{tikzpicture}
\compobreak
Car: En effet!
\end{compo}

\end{document}

• That's great, you save me, thank you very much! – AndréC Nov 29 '17 at 4:57

Just grab the first argument with the original catcodes.

\documentclass{article}
\usepackage[french]{babel}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{babel}

\newlength{\colG}\newlength{\colD}
% Wrapper command just changes catcodes and calls helper
\newcommand\compo[2][0.5]{%
\shorthandoff{!:}% Change the catcodes
\compohelper[#1]{#2} % call helper to grab arguments
}
\newcommand{\compohelper}[3][0.5]{% do actual work
\setlength{\colG}{#1\linewidth}%
\setlength{\colD}{\linewidth}%
\par \noindent%
\begin{minipage}[t]{\colG}#2\end{minipage}\hfill\vrule\hfill%
\begin{minipage}[t]{\colD}#3\end{minipage}%
\par
\shorthandon{!:}% restore catcodes
}

\begin{document}
Car: En effet!

\dotfill

\bigskip
\compo[.5]{
Car: En effet!

}{
\begin{tikzpicture}
\coordinate (B) at (0,0);
\coordinate  (C) at (3,0);
\coordinate(D) at (2,0);
\draw(B)--(C)--(D)--cycle;
\coordinate (Ap) at ($(C)!.35!-90:(B)$);
\draw (Ap)--(B)--(C)--cycle;
\end{tikzpicture}
}
\end{document}
• The problem is that according to the handouts I write, I sometimes place the image on the left, the text on the right or the opposite: the image on the right, the text on the left. This will force me to create two different macros! – AndréC Nov 28 '17 at 20:22
• @AndréC or a * form that switches the order or some such, I think it is far more "the latex way" to have semantic markup where 1st argument = description and 2nd argument=figure, and then separately specify left or right alignment, it also has the advantage of working:-) you really need to know ahead of parsing which catcodes are in use, you can not decide after you have read the arguments as it is too late (well you could try with \scantokens to reparse but that always leads to pain) – David Carlisle Nov 28 '17 at 21:32