A challenging horizontal/vertical centering problem
Picture mode!
The side of the square is 5em, because \unitlength
is set to 1em (which will take into account the current font). Therefore 0.3 represents a distance of 0.3em, which is what you seem to want. Fix the size according to your taste.
\documentclass{article}
\usepackage{pict2e}
\newcommand{\compass}[1]{%
\begingroup
\setlength\unitlength{1em}%
\linethickness{0.2ex}%
\begin{picture}(5,5)
% the frame
\moveto(0,0)\lineto(0,5)\lineto(5,5)\lineto(5,0)\closepath\strokepath
% the cardinal points
\put(2.5,4.7){\makebox[0pt]{\raisebox{-\height}{N}}}
\put(2.5,0.3){\makebox[0pt]{S}}
\put(0.3,2.5){\makebox[0pt][l]{\raisebox{-0.5\height}{W}}}
\put(4.7,2.5){\makebox[0pt][r]{\raisebox{-0.5\height}{E}}}
% the center
\put(2.5,2.5){\makebox(0,0){#1}}
\end{picture}%
\endgroup
}
\begin{document}
X\compass{1}X\qquad{\footnotesize X\compass{3}X}\qquad{\tiny X\compass{5}X}
\bigskip
{\Large X\compass{12}X}\qquad{\Huge X\compass{24}X}
\end{document}
The following is a wild mix between LaTeX stuff and stuff you'd do using plain TeX. Change the default value of the optional argument of \compass
to change the overall size. The overall size is not equal to the optional argument, but to #1+.6em+.4ex
in width, #1+.3em+.2ex
in height and .3em+.2ex
in depth.
\documentclass[border=2mm]{standalone}
% this might already be defined depending on included packages
\providecommand\clap[1]{\hbox to 0pt{\hss #1\hss}}
\newcommand\compass[2][10ex]
{{%
\fboxrule=.2ex
\fboxsep=.3em
\fbox
{%
\vbox to #1{\hsize=#1
\hbox to #1{\hss N\hss}%
\vss
\hbox to #1{\rlap{W}\hss \clap{#2}\hss \llap{E}}%
\vss
\hbox to #1{\hss S\hss}%
}%
}%
}}
\begin{document}
\compass{1}
\end{document}
Vertically it only aligns the baselines of W x E
so if x
is recognizable smaller than W
and E
it would not look vertically centred.
Version that also vertically centres the middle line using $\vcenter{...}$
(and utilizing that the \xlap
macros use a \hbox
internally so the text is not typeset in math mode):
\documentclass[border=2mm]{standalone}
% this might already be defined depending on included packages
\providecommand\clap[1]{\hbox to 0pt{\hss #1\hss}}
\newcommand\compass[2][10ex]
{{%
\fboxrule=.2ex
\fboxsep=.3em
\fbox
{%
\vbox to #1{\hsize=#1
\hbox to #1{\hss N\hss}%
\vss
\hbox to #1{%
$\vcenter{\rlap{W}}$\hss
$\vcenter{\clap{#2}}$\hss
$\vcenter{\llap{E}}$%
}%
\vss
\hbox to #1{\hss S\hss}%
}%
}%
}}
\begin{document}
\compass{\tiny1}
\end{document}
Version that gives the same distance from the centre of the W and E to the border. Unfortunately it doesn't look as good as I thought.
\documentclass[border=2mm]{standalone}
% this might already be defined depending on included packages
\providecommand\clap[1]{\hbox to 0pt{\hss #1\hss}}
\newbox\myTestbox
\newdimen\myhoffset
\newcommand\compass[2][10ex]
{{%
\setbox\myTestbox\hbox{E}%
\myhoffset=.5\wd\myTestbox
\setbox\myTestbox\hbox{W}%
\ifdim\myhoffset<.5\wd\myTestbox
\myhoffset=.5\wd\myTestbox
\fi
\fboxrule=.2ex
\fboxsep=.3em
\fbox
{%
\vbox to #1{\hsize=#1
\hbox to #1{\hss N\hss}%
\vss
\hbox to #1{%
\hskip\myhoffset
$\vcenter{\clap{W}}$\hss
$\vcenter{\clap{#2}}$\hss
$\vcenter{\clap{E}}$%
\hskip\myhoffset
}%
\vss
\hbox to #1{\hss S\hss}%
}%
}%
}}
\begin{document}
\compass[8ex]{\tiny1}
\end{document}
As OP noted, the \vcenter
code has a small vertical offset from the middle. Therefore here another version, this time using some \smash
s and a calculated \raise
amount for #2
:
\documentclass[border=2mm]{standalone}
% this might already be defined depending on included packages
\providecommand\clap[1]{\hbox to 0pt{\hss #1\hss}}
\newdimen\myvoffset
\newbox\mytestboxA
\newbox\mytestboxB
\newcommand\compass[2][10ex]
{{%
\setbox\mytestboxA\hbox{WE}%
\setbox\mytestboxB\hbox{#2}%
\myvoffset=\dimexpr
\ht\mytestboxA-\ht\mytestboxB+\dp\mytestboxB-\dp\mytestboxA\relax
\myvoffset=.5\myvoffset
\fboxrule=.2ex
\fboxsep=.3em
\fbox
{%
\vbox to #1{\hsize=#1
\hbox to #1{\hss N\hss}%
\vss
\hbox to #1{%
\smash{\rlap{W}}\hss
\smash{\clap{\raise\myvoffset\hbox{#2}}}\hss
\smash{\llap{E}}%
}%
\vss
\hbox to #1{\hss S\hss}%
}%
}%
}}
\begin{document}
\compass[2.5em]{\tiny1}
\end{document}
Just for completeness (as this is overkill for the problem) a TikZ based answer (you'll need \usepackage{tikz}
in your preamble). The optional argument matches the size
\documentclass[tikz,border=2mm]{standalone}
\newcommand\compass[2][15ex]
{%
\begin{tikzpicture}[inner sep=0pt]
\draw[line width=.2ex,use as bounding box] (0,0) rectangle (#1,#1);
\node at (0.5*#1,0.5*#1) {#2};
\node[anchor=north] at (0.5*#1,#1-0.3em) {N};
\node[anchor=south] at (0.5*#1,0.3em) {S};
\node[anchor=west] at (0.3em,0.5*#1) {W};
\node[anchor=east] at (#1-0.3em,0.5*#1) {E};
\end{tikzpicture}%
}
\begin{document}
\compass{\tiny1}
\end{document}