Simple implementation of the abs function by getting rid of or by consuming the "-"?

You could use xfp (the package is very short, it contains only two definitions to create wrappers around \fp_eval:n and \int_eval:n):

\documentclass{article}
\usepackage{xfp}
\begin{document}

\fpeval{abs(-12.3)}

\end{document}

enter image description here

It is expandable, that means you can fed it to \num for formatting. Here I change the period to a command:

\documentclass{article}
\usepackage{xfp,siunitx}

\sisetup{locale=DE}
\begin{document}

\num{\fpeval{abs(-12.3)}}

\end{document}

enter image description here


You can define \gobbleminus by this way:

\def\gobbleminus#1{\ifx-#1\else#1\fi}

%test:
\gobbleminus -12

\gobbleminus 1234

\gobbleminus .24

I'm sure you get a LaTeX3 solution by one of the experts in no time and I really don't think that a string-based solution is the best you can do here, but while you wait here is a simple, argument-based solution.

The solution is not expandable, which might be a bit of deal-breaker depending on what you want to do (but: see below).

The main idea is to use delimited arguments (How does TeX look for delimited arguments?) to strip characters from a string. In order not to run into trouble here, we first check whether the characters are actually present.

\ifstrstartswith works by defining a helper macro \fstr@ifstrstartswith@i that grabs arguments as follows

#1<characters to find>#2&

if we now pass a string to \fstr@ifstrstartswith@i that starts with <characters to find>, TeX's argument parse rules make #1 come up empty. In order to avoid errors, we always call \fstr@ifstrstartswith@i with \fstr@ifstrstartswith@i <string><characters to find>&. This means that even if <string> does not contain <characters to find> at all, we still have called the macro with the right argument signature.

The characters stripping now works similarly. We check that <string> actually starts with <characters to remove> and then apply a helper macro \fstr@stripfromstart@i with signature

<characters to remove>#1&

which then strips off the <characters to remove> from the beginning of <string> when called as \fstr@stripfromstart@i <string>&.

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}

\usepackage{etoolbox}

\makeatletter
% {<characters to find>}{<string>}
\newrobustcmd*{\ifstrstartswith}[2]{%
  \def\fstr@ifstrstartswith@i##1#1##2&{%
    \ifblank{##1}}%
  \fstr@ifstrstartswith@i#2#1&}

% {<characters to remove>}{<string>}
\newrobustcmd*{\stripfromstart}[2]{%
  \def\fstr@stripfromstart@i#1##1&{##1}%
  \ifstrstartswith{#1}{#2}
    {\fstr@stripfromstart@i#2&}
    {#2}}
\makeatother

\newcommand*{\mysimpleabs}{\stripfromstart{-}}

\begin{document}
\mysimpleabs{4.5}

\mysimpleabs{-4.5}
\end{document}

4.5//4.5

Of course you don't want to try \mysimpleabs{-4.5-5} or \mysimpleabs{-4.5+5}.


edit Come to think of it, we can make this expandable if we hard-code the -. Still, string manipulation does not strike me as the best way to deal with this.

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}

\usepackage{etoolbox}

\makeatletter
\newcommand*{\fstr@ifstrstartswithminus@i}{} % just to reserve the name
\def\fstr@ifstrstartswithminus@i#1-#2&{\ifblank{#1}}

\newcommand*{\ifstrstartswithminus}[1]{%
  \fstr@ifstrstartswithminus@i#1-&}

\newcommand*{\fstr@stripminusfromstart@i}{} % just to reserve the name
\def\fstr@stripminusfromstart@i-#1&{#1}

\newcommand*{\stripminusfromstart}[1]{%
  \ifstrstartswithminus{#1}
    {\fstr@stripminusfromstart@i#1&}
    {#1}}
\makeatother

\newcommand*{\mysimpleabs}{\stripminusfromstart}

\begin{document}
\mysimpleabs{4.5}

\mysimpleabs{-4.5}

\edef\foo{\mysimpleabs{12.3}}
\meaning\foo

\edef\foo{\mysimpleabs{-12.3}}
\meaning\foo
\end{document}