- Draw a circular node with the required dimensions.
- Add a label to its center
- with the actual content but with no drawing
- that is xscaled so that it fits the specified
circledNumber base width
.
In the xscale
formula the base width (one or two digits) is divided by the width of the actual content. The min(1,<factor>)
makes sure we don't widen content that is actually small enough to fit into it on its own. This is only needed when the base width is more than one digit, otherwise every sane integer number fits perfectly or needs to be squished.
I've added a debug label
style that shows the text box that the outer node uses to measure its dimensions and which the inner node is scaled to.
This is not a very efficient way since we're only dealing with a handful of dimensions and PGFmath determined all the widths and heights and stuff again and again (though, for every font if needed).
Code
\input tikz.tex
\tikzset{
every circledNumber/.style={
shape=circle, draw, anchor=base, inner sep=+.1em, text height=height("0"),
text width=\pgfkeysvalueof{/tikz/circledNumber base width}},
circledNumber label/.style={
label={[%
xscale={min(1,\pgfkeysvalueof{/tikz/circledNumber base width}/width("#1"))},
every circledNumber label]center:#1}},
every circledNumber label/.style={
draw=none, inner sep=+0pt, outer sep=+0pt, shape=rectangle},
circledNumber base width/.initial=width("0"),
debug label/.style={
label={[%
every circledNumber,
every circledNumber label,
draw, gray, ultra thin]center:}}}
\def\circledNumber#1{%
\tikz[baseline=+0pt]
\node[every circledNumber, circledNumber label={#1}, debug label/.try]{};%
}
% \begin{document}
\circledNumber{1}
\circledNumber{10}
\circledNumber{100}
{%
\tikzset{circledNumber base width=width("00")}
\circledNumber{1}
\circledNumber{10}
\circledNumber{100}
}
% \end{document}
\bye
Output