Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to create a new environment that will contain the following displayed counter (at least something like it):

\documentclass[letterpaper]{article}
\usepackage{amsmath,amssymb}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node[draw, rounded corners=1pt,fill,text=white] at (0,0) {\large 9} node at +(0,0.35) {\footnotesize\sc practice};
\end{tikzpicture}
\end{document}

enter image description here

The problem I have is how to put the word PRACTICE immediately above (at a reasonable height above) the boxed node and so that node is of the same width as the word PRACTICE. The node will eventually be a square box. Of course the number 9 will be a counter who's size will be determined to match the aesthetics of the display and which I will work its settings later. I am looking for a simple way of doing this. I am thinking right now of defining a length in the for \settolength{PRACTICE}.

share|improve this question
add comment

2 Answers 2

up vote 13 down vote accepted

How about this. I added some explanations in the code. You may ask for details if a line is unclear :-)

number boxes

Code

\documentclass{article}

% load TikZ and the required library package
\usepackage{tikz}
\usetikzlibrary{positioning}
% load lmodern to get free scalable fonts
\usepackage{lmodern}

% define the label, it's font and mesure it's length
\newcommand{\practicename}{practice}
\newcommand{\practicelabelfont}{\footnotesize\scshape}
\newlength{\practicelabellength}
\settowidth{\practicelabellength}{\practicelabelfont\practicename}

% define the number font size according to the label
\newlength{\practicenumsize}
\setlength{\practicenumsize}{\practicelabellength}
\addtolength{\practicenumsize}{-10pt}
\newcommand{\practicenumfont}{%
    \fontsize{\practicenumsize}{\practicenumsize}\selectfont
    \sffamily\bfseries
}

% define TikZ styles for the number and the label
\tikzset{
    practice num/.style={
        name=PRACTICE NUM NODE,
        minimum size=\practicelabellength,
        font=\practicenumfont,
        fill=black,
        text=white,
        outer sep=0pt,
        inner sep=0pt,
        rounded corners=2pt,
    },
    practice label/.style={
        font=\practicelabelfont,
        inner sep=0pt,
        outer sep=0pt,
        above=2pt of PRACTICE NUM NODE,% change the distance between
                                       % the box and the lable here
    },
}

% define a command that prints one argument in the box
\newcommand{\practice}[1]{
    \begin{tikzpicture}
        \node [practice num] {#1};
        \node [practice label] {\practicename};
    \end{tikzpicture}
}

\begin{document}
    \noindent
    It'll only work with numbers from 0 to 99:\\[\baselineskip]
    \practice{9}\quad\practice{99}\quad\practice{999}
\end{document}

To increase the possible range to 999 you may increase the label font size or decrease the number font size.

Some explanations

Label, fonts and lengthen

The first thing we do is to setup some TeX macros, that make changes easy. Of course we could include all thin in the TikZ picture but I prefer to dived things in smaller pieces and approve a few more lines of code. So define the Label as a macro named \practicename,

\newcommand{\practicename}{practice}

set a font for it \practicelabelfont

\newcommand{\practicelabelfont}{\footnotesize\scshape}

and measure it’s width \practicelablewidth.

\newlength{\practicelabellength}
\settowidth{\practicelabellength}{\practicelabelfont\practicename}

The next step is to set up the number font \practicenumfont. To make the fontsize depending to on the label width we set a new length \practicenumsize to the width of the label and decrease it by 10 pt:

\newlength{\practicenumsize}
\setlength{\practicenumsize}{\practicelabellength}
\addtolength{\practicenumsize}{-10pt}

With this length we are able to set the fontsize using \fontsize{<size>}{<baselineskip>}. Since this is a basic font command it’s necessary to activate it with \selectfont.

\newcommand{\practicenumfont}{%
    \fontsize{\practicenumsize}{\practicenumsize}\selectfont
    \sffamily\bfseries
}

Styles

Now we define two TikZ styles. One for the label and another for the number. We use \tikzset, which can do all settings for TikZ. To create a new style one must use the syntax <name>/.style={<options>}. We define the style to set the fonts and node size/shapes/filling. Furthermore we define a name for the number node

name=PRACTICE NUM NODE,

This is basically the same as if we say

\node (PRACTICE NUM NODE) [<options>] {<num>};

later in the code. But we can ensure that this name is unique and always refers to the right, i.e. the last specified, node. We know that the number node will always have the name PRACTICE NUM NODE so we can set the position of the label as part of it’s style

above=2pt of PRACTICE NUM NODE,

Now the label will be centered exactly 2 pt above the number node. Not that we set all outer and inner sep to 0pt.

Wrapper

The last step is to define a new macro setting up the two nodes. The macro should take on argument holding the practice number. All it has to do is to build a {tikzpicture} with two nodes in the right style and with the right contents, i.e. #1 for the number node and the predefined \practicename for the label node.

\newcommand{\practice}[1]{
    \begin{tikzpicture}
        \node [practice num] {#1};
        \node [practice label] {\practicename};
    \end{tikzpicture}
}

Usage

Prepared with that we can print the practice number with \practice{}. Assuming we set up a counter practice holding the right number we’d call

\practice{\thepractice}
share|improve this answer
    
I like how you defined the position of the second node relative to the first. Interesting! Can the height of the box be as the width you defined, \practicelength? And can the font size of the number line be dependent on this length may be with an inner separation of about 2 pt or something that is reasonable? –  azetina Jun 14 '12 at 23:04
    
I just figured out the height with minimum height=\practicelength. Now its just the font size. –  azetina Jun 14 '12 at 23:06
    
@azetina: See my edit … –  Tobi Jun 14 '12 at 23:20
    
The only thing am not good at is with the \tikzset. Its one thing I have not really looked into to try to master. Nodes are my very weakness too. –  azetina Jun 15 '12 at 14:28
    
@azetina: I extended my answer with some explanations. Does this help? –  Tobi Jun 15 '12 at 15:31
show 2 more comments

You can use TikZ's calc library to measure the node with 'practice' and size the second node with the number accordantly.

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage{lmodern}

\usepackage{tikz}
\usetikzlibrary{calc}

\newcounter{practice}

% define a command that prints one argument in the box
\newcommand{\practice}{%
    \refstepcounter{practice}%
    \begin{tikzpicture}
        \node [inner sep=0pt,outer sep=0pt] (practice) {\footnotesize\textsc{practice}};
        \path let \p1 = (practice.north west), \p2 = (practice.north east) in
            node [minimum size=\x2-\x1,fill=black,text=white,rounded corners,anchor=north]
                at ([yshift=-2pt]practice.south) {\bfseries\sffamily\Huge\thepractice};
    \end{tikzpicture}%
}

\begin{document}

\practice

\clearpage

\practice

\clearpage

\practice

\clearpage
\setcounter{practice}{8}

\practice

\clearpage

\practice

\clearpage
\setcounter{practice}{98}

\practice

\clearpage

\practice

\end{document}

Result

The number size here was chosen to work for number up to 99. If you need more either make it smaller that 100 still fits or add some code to resize larger numbers. The \maxsizebox macro from the adjustbox package is useful here.

share|improve this answer
    
Nice coding. Straight to the point.:-) –  azetina Jun 18 '12 at 13:49
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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