I am posting this as the final result of taking Herbert's solution where I wanted it, which is a drop in replacement for \rule
that provides rounded line caps. Herbert deserves the credit and will get the points, but others (like me) might wish to see/use this more seamless drop-in for \rule
.
Herbert's solution needed to be placed into an hbox, as he allowed, but it needed substantially more adjustments, as well. The horizontal and vertical kernings were offset relative to that box, the vertical alignment of the rounded rule differed from that of a \rule
, just to name a few.
EDIT: I've also taken the initiative to force \mathrule
to make a rule with the rounded endcaps on side/side or else the top/bottom, depending on which dimension is larger, such that
\mathrule{2ex}{2ex}
\mathrule{3ex}{2ex}
\mathrule{2ex}{3ex}
gives
In my MWE below, I put the final result through the paces of placing the \mathrule
on a line by itself, placing it amongst text, stacking it, as well as \fbox
ing it, in all cases comparing to its equivalent \rule
. The \mystery@factor
in this MWE was later resolved by Dan in his comment. His correction is incorporated into the style file roundrule.sty
that I present at the end of this answer.
\pdfcompresslevel=0 %%% to see how it works in the pdf code
\documentclass{article}
\usepackage{graphicx}
\usepackage{stackengine}% Used for testing; not needed for \math(v)rule's
\parindent=0pt
\makeatletter
\newcommand\mathrule[3][0pt]{%
\ifdim#2>#3\math@hrule[#1]{#2}{#3}\else\math@vrule[#1]{#2}{#3}\fi}
\newcommand\math@hrule[3][0pt]{%
\gdef\mystery@factor{0.07}%
\@tempdima=#3%
\rule[#1]{0pt}{#3}% Needed to account for .5\@tempdima vertical offset of rounded rule
\raisebox{.5\@tempdima+#1}{%
\makebox[#2][l]{\kern-.5\@tempdima\@@mathrule{#2}{#3}}}%
}
\newcommand\math@vrule[3][0pt]{%
\gdef\mystery@factor{0.0}%
\@tempdima=#2%
\rule[#1]{0pt}{#3}% Needed to account for .5\@tempdima vertical offset of rounded rule
\raisebox{-.0\@tempdima+#1}{%
\kern0.5\@tempdima%
\rotatebox{90}{\kern-0.5\@tempdima\makebox[#3][l]{\@@mathrule{#3}{#2}}}%
\kern0.5\@tempdima}%
}
\def\@@mathrule#1#2{%
\@tempdimb=#2%
\@tempdima=\dimexpr#1-\mystery@factor\@tempdimb%Why 0.07 for \math@hrule?
\pdfliteral{%
q []0 d %
1 J % set line cap to rounded ends
\strip@pt\@tempdimb\space w \strip@pt\@tempdimb\space 0 m %
\strip@pt\@tempdima\space 0 l S Q }}
\makeatother
\begin{document}
\mathrule{60bp}{1bp}\par
\rule{60bp}{1bp}\par
x\mathrule[-1pt]{20bp}{1bp}x\mathrule{20bp}{1bp}x\par
x\rule[-1pt]{20bp}{1bp}x\rule{20bp}{1bp}x\par
\stackunder[2pt]{\rule{60bp}{3bp}}{\mathrule{60bp}{3bp}}\par
\fbox{\mathrule[-1ex]{4ex}{.5ex}}\fbox{\rule[-1ex]{4ex}{.5ex}}\par
\fbox{\mathrule[+1ex]{4ex}{.5ex}}\fbox{\rule[+1ex]{4ex}{.5ex}}\par
\clearpage
\mathrule{1bp}{60bp} \rule{1bp}{60bp}\par
x\mathrule[-1pt]{1bp}{20bp}x\mathrule{1bp}{20bp}x%
\rule[-1pt]{1bp}{20bp}x\rule{1bp}{20bp}x\par
x\rule[-1pt]{1bp}{20bp}x\rule{1bp}{20bp}x\par
\stackunder[2pt]{\rule{3bp}{10bp}\mathrule{3bp}{10bp}}%
{\mathrule{3bp}{10bp}\rule{3bp}{10bp}}\par
\fbox{\mathrule[-1ex]{.5ex}{4ex}}\fbox{\rule[-1ex]{.5ex}{4ex}}\par
\fbox{\mathrule[+1ex]{.5ex}{4ex}}\fbox{\rule[+1ex]{.5ex}{4ex}}\par
\end{document}
For those interested in an ad hoc package (and taking azetina's renaming suggestion since it functions outside of math mode), here is roundrule.sty
, introducing the macro \roundrule[]{}{}
. And thanks to Dan for resolving and eliminating the mystery factor. Of course, \roundrule
s can be used in text mode without the use of dollar delimiters. Feel free to \let\rrule\roundrule
in your preamble, if you get tired of typing the long name.
EDITED to require package calc
as well.
\ProvidesPackage{roundrule}
[2014/05/01 V1.01 Provides rules with rounded endcaps]
%
% THIS MATERIAL IS SUBJECT TO THE LaTeX Project Public License
%
% Special thanks to users Herbert and Prof. Dan Luecking at tex.stackexchange.com:
% http://tex.stackexchange.com/questions/161297/
% is-there-such-a-thing-as-a-mathrule-rounded-endcaps
%
% V1.00 - initial release
% V1.01 - require package calc, which was omitted as an oversight.
\pdfcompresslevel=0 %%% to see how it works in the pdf code
\RequirePackage{graphicx}
\RequirePackage{calc}
\newcommand\roundrule[3][0pt]{%
\ifdim#2>#3\round@hrule[#1]{#2}{#3}\else\round@vrule[#1]{#2}{#3}\fi}
\newcommand\round@hrule[3][0pt]{%
\@tempdima=#3%
\rule[#1]{0pt}{#3}% Needed to account for .5\@tempdima vertical offset of rounded rule
\raisebox{.5\@tempdima+#1}{%
\makebox[#2][l]{\kern-.5\@tempdima\@@roundrule{#2}{#3}}}%
}
\newcommand\round@vrule[3][0pt]{%
\@tempdima=#2%
\rule[#1]{0pt}{#3}% Needed to account for .5\@tempdima vertical offset of rounded rule
\raisebox{-.0\@tempdima+#1}{%
\kern0.5\@tempdima%
\rotatebox{90}{\kern-0.5\@tempdima\makebox[#3][l]{\@@roundrule{#3}{#2}}}%
\kern0.5\@tempdima}%
}
\def\@@roundrule#1#2{%
\@tempdima=#1%
\@tempdimb=#2%
\@tempdima=0.996264\@tempdima% LaTeX to PDF point conversion (72/72.27)
\@tempdimb=0.996264\@tempdimb% LaTeX to PDF point conversion (72/72.27)
\pdfliteral{%
q []0 d %
1 J % set line cap to rounded ends
\strip@pt\@tempdimb\space w \strip@pt\@tempdimb\space 0 m %
\strip@pt\@tempdima\space 0 l S Q }}
\endinput