19

A minimal working sample should be give first:

\documentclass{article}
\newcounter{mynumber}
\makeatletter 
\AtEndDocument{%
    \immediate\write\@auxout{%
        \string\setcounter{mynumber}{\number\value{mynumber}}%
    }%
}
\makeatother
\AtBeginDocument{%
    \stepcounter{mynumber}
}

\begin{document}
the version number is \themynumber.
\end{document}

Compiling it with XeLateX, we will get the version number such as 1. Then my QUESTION is

  • how to make 1 become 0001 and 23 become 0023 and so on (i.e., four-digit numbers)? Note that I want the format like 0001 but not 0 001 (i e., no unit, no space).
  • 2
    There is a numprint package additionally but I didn't tested (see sections 3.1 to 3.5 here: ftp.dante.de/tex-archive/macros/latex/contrib/numprint/…) – koleygr Jan 26 '18 at 9:01
  • Ah, good to know. The better option, perhaps. With more possibilities – AlexG Jan 26 '18 at 9:04
  • I think both solutions will be useful in the future... I don't know how can not find a duplicate on this question... Seems strange to me after these years of tex.se existence! – koleygr Jan 26 '18 at 9:41
  • It's surprising that this question is so popular... – Mogic Jan 27 '18 at 2:45
30

with package siunitx:

the version number is \num[minimum-integer-digits = 4]{\themynumber}.

and for Sans Serif

\textsf{\num[detect-family,minimum-integer-digits = 4]{\themynumber}}.
  • 2
    This is my favourite. – AlexG Jan 26 '18 at 9:59
  • Good solution! It's neater than any other ones. But this solution has an disadvantage: we can't change the font of the numbers any more! – Mogic Jan 26 '18 at 15:04
  • 2
    Why can't you change the font?? It is simple! – user2478 Jan 26 '18 at 18:54
  • \mathrm{} can't work for it by XeLatex. In my document, \mathrm{} should produce old style numbers for \themynumber, but it can't work using your codes.It may be because that the numbers font is deigned by siunitx options, for example mode=text or mode=math. But I think your solution is so good that maybe many other people would like to pick it. – Mogic Jan 27 '18 at 2:56
  • \mathrm will also work ... – user2478 Jan 27 '18 at 7:41
14

Perhaps the fastest (and fully expandable, if that matters) solution, without additional packages:

\zeropad{<template>}{<integer>}
% <template> string of zeros defining desired width of output
\documentclass{article}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand\zeropad[2]{%
  \ifnum#2<0\relax%
    {\ensuremath-}\zeropadA{#1}{\the\numexpr#2*-1\relax}%
  \else%
    \zeropadA{#1}{#2}%
  \fi%
}
\def\zeropadA#1#2{%
  \ifnum1#2<1#1
    \zeropadA{#1}{0#2}%
  \else%
    #2%
  \fi%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcounter{mynumber}
\makeatletter
\AtEndDocument{%
  \immediate\write\@auxout{%
    \string\setcounter{mynumber}{\themynumber}%
  }%
}
\makeatother
\AtBeginDocument{%
  \stepcounter{mynumber}
}

\begin{document}
the version number is \zeropad{0000}{\themynumber}

this is a negative number: \zeropad{0000}{-\themynumber}

expandibility check: \edef\foo{\zeropad{0000}{-\themynumber}}\foo
\end{document}
  • Good work! But I can pick only one! – Mogic Jan 26 '18 at 15:22
  • For whosoever hath ( @egreg ), to him shall be given ... (Gospel of Matthew) – AlexG Jan 26 '18 at 16:00
  • @Kuttens. Note that my solution does not fail if the number get larger than the prescribed width. – AlexG Jan 26 '18 at 16:15
  • Neat solution. loved it. – João Lourenço Jan 30 '18 at 22:03
  • I like recursive macros. – AlexG Jan 31 '18 at 9:41
11

A fully expandable version

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\padinteger}{mm}
 {
  \int_compare:nNnTF { #2 } < { 0 }
   {
    - \kuttens_padinteger:nn { #1 } { -#2 }
   }
   {
    \kuttens_padinteger:nn { #1 } { #2 }
   }
 }

\cs_new:Nn \kuttens_padinteger:nn
 {
  \prg_replicate:nn { #1 - \tl_count:f { \int_to_arabic:n { #2 } } } { 0 }
  \int_to_arabic:n { #2 }
 }
\cs_generate_variant:Nn \tl_count:n { f }
\ExplSyntaxOff

% define the macro based on the number of digits you need, here four
\makeatletter
\newcommand{\padfour}[1]{\expandafter\@padfour\csname c@#1\endcsname}
\newcommand{\@padfour}[1]{\padinteger{4}{#1}}
\makeatother

\newcounter{mynumber}
\renewcommand{\themynumber}{\padfour{mynumber}}

\makeatletter 
\AtEndDocument{%
    \immediate\write\@auxout{%
        \string\setcounter{mynumber}{\themynumber}%
    }%
}
\makeatother
\AtBeginDocument{%
    \stepcounter{mynumber}
}


\begin{document}

\section{The version number}

Number: \themynumber

\section{Other tests}

\newcounter{test}

\padinteger{4}{\value{test}}

\setcounter{test}{23}

\padinteger{4}{\value{test}}

%\padinteger{4}{12345} % would raise an error

\padinteger{8}{12345}

\setcounter{test}{-123}

$\padinteger{4}{\value{test}}$

\end{document}

enter image description here

  • My sol. is expandable too. – AlexG Jan 26 '18 at 9:57
  • 1
    Your macro fails if the number gets larger than the prescribed width. Mine not. – AlexG Jan 26 '18 at 16:14
  • @AlexG That's a precise choice. The error can be easily removed or changed into a warning. – egreg Jan 26 '18 at 16:15
9

Here's a LuaLaTeX-based solution, which uses Lua's built-in string.format function and sets up a user macro called \padnum. Note that the \padnum macro is fully expandable.

The default number of padding digits is 4; this can be overridden by supplying the number of padding digits as the optional argument of \padnum. The macro handles negative numbers without any issues, and it can be executed in both text mode and math mode.

enter image description here

% !TEX TS-program = lualatex

%% Create an external file to contain the Lua code
\RequirePackage{filecontents}
\begin{filecontents*}{padnum.lua}
function padnum ( digits , n)
-- The "0" term in string.format ensures left-padding with zeroes, as needed:
  tex.sprint ( string.format ( "%0"..digits.."d" , n ) )
end
\end{filecontents*}

\documentclass{article}
\directlua{dofile("padnum.lua")} % load the Lua function
% "\padnum" creates 4-digit numbers by default:
\newcommand\padnum[2][4]{\directlua{padnum(#1,#2)}}

\begin{document}
\newcommand\mynum{23}
\padnum{\mynum}, \padnum[6]{1}, $\padnum[2]{-100000}$, $\padnum{-11}$
\end{document}
  • 1
    A good choice for LuaLatex! – Mogic Jan 27 '18 at 3:03
5

@koleygr Thank you! In fact, I have ever tried your method before you told me but failed. Now I get the right one.

\documentclass{article}
\usepackage{numprint}
\newcounter{mynumber}
\makeatletter 
\AtEndDocument{%
    \immediate\write\@auxout{%
        \string\setcounter{mynumber}{\number\value{mynumber}}%
    }%
}
\makeatother
\AtBeginDocument{%
    \stepcounter{mynumber}
}
\newcommand{\myversionnumber}{\npfourdigitnosep\nplpadding{4}\numprint{\themynumber}}

\begin{document}
the version number is \myversionnumber.
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.