3

I made this LaTeX function:

\newcommand{\Hrule}[2]{\vspace{#1}\hrule\vspace{#2}}

Now, I'd like to edit this function in this way: I want add a #3 in whose specify the color of this \Hrule.

And I want add a #4 to declare the thickness of \hrule.

Is it possible?

For example if I write \Hrule{2mm}{2mm}{red}{2.5mm} I would obtain a red \hrule ... .

Must I provide a minimum MWE?

Thank you so much.

Puck
  • 1,208

2 Answers2

5

You should use \par\addvspace rather than \vspace at the beginning.

Next, you can start a group to set the color. The default value of the optional argument is . that in xcolor stands for the current color.

\documentclass{article}
\usepackage{xcolor}

\newcommand{\Hrule}[3][.]{% \par\addvspace{#2}% \begingroup\color{#1}% \hrule \endgroup \addvspace{#3}% }

\begin{document}

Some text

\Hrule{3pt}{1pt}

Some other text

\Hrule[red!40]{3pt}{1pt}

Some other text

\end{document}

enter image description here

If you want to add another argument to set the thickness you can do

\documentclass{article}
\usepackage{xcolor}

\newcommand{\Hrule}[4][.]{% \par\addvspace{#2}% \begingroup\color{#1}% \hrule height #4 \endgroup \addvspace{#3}% }

\begin{document}

Some text

\Hrule{3pt}{1pt}{0.4pt}

Some other text

\Hrule[red!40]{3pt}{1pt}{2pt}

Some other text

\end{document}

enter image description here

However, using four arguments is error prone, so I suggest a key-value based approach.

\documentclass{article}
\usepackage{xcolor}

\ExplSyntaxOn

\NewDocumentCommand{\Hrule}{m} { \group_begin: \keys_set:nn { puck/hrule } { #1 } \par\addvspace{\l_puck_hrule_before_skip} \color{\l_puck_hrule_color_tl} \hrule height \l_puck_hrule_thickness_dim \addvspace{\l_puck_hrule_after_skip}% \group_end: }

\keys_define:nn { puck/hrule } { before .skip_set:N = \l_puck_hrule_before_skip, after .skip_set:N = \l_puck_hrule_after_skip, thickness .dim_set:N = \l_puck_hrule_thickness_dim, thickness .initial:n = 0.4pt, color .tl_set:N = \l_puck_hrule_color_tl, color .initial:n = ., }

\ExplSyntaxOff

\begin{document}

Some text

\Hrule{before=3pt,after=1pt}

Some other text

\Hrule{color=red!40,before=3pt,after=1pt,thickness=2pt}

Some other text

\end{document}

The output is the same as in the previous picture.

Comparison between my solution and Sergio Llorente's

\documentclass[twocolumn]{article}
\usepackage{xcolor}

\newcommand{\HruleEgreg}[4][.]{% \par\addvspace{#2}% \begingroup\color{#1}% \hrule height #4 \endgroup \addvspace{#3}% } \newcommand{\HruleSergio}[4]{% \par\noindent\vspace{#1}% {\color{#3}\rule{\columnwidth}{#4}}% \columnwidth instead of \textwidth \par\vspace{#2}% }

\begin{document}

\textbf{Egreg}

\medskip

Some text

\HruleEgreg{3pt}{1pt}{0.4pt}

Some other text

\HruleEgreg[red!40]{3pt}{1pt}{2pt}

Some other text

\newpage

\textbf{Sergio}

\medskip

Some text

\HruleSergio{3pt}{1pt}{black}{0.4pt}

Some other text

\HruleSergio{3pt}{1pt}{red!40}{2pt}

Some other text

\end{document}

enter image description here

You can see that the amount of spacing with my solution is exactly what's requested.

egreg
  • 1,121,712
  • Thank you egreg, but the previous answer is easier then yours. – Puck Sep 25 '21 at 00:20
  • @Puck You mean that you prefer a version where you don't control the spaces? I added a comparison. – egreg Sep 25 '21 at 17:47
  • Thank you, but at line \keys_define:nn { puck/hrule }, Overlaef gives me an error because the "_" after \keys. How can I solv it? Thank you again – Puck Sep 25 '21 at 23:58
  • @Puck Add \usepackage{xparse} – egreg Sep 26 '21 at 07:16
  • Already done, but is it normal that Overleaf emphasizes the "_" in pink? – Puck Sep 26 '21 at 10:07
  • @Puck Ask them. – egreg Sep 26 '21 at 13:47
  • Nice solution. Thank you for the explanation. Why is better use \begingroup...\engroup than {...}? and Why you prefer addvspace rather than vspace? – Sergio Llorente Sep 27 '21 at 13:12
  • @SergioLlorente There's not such a great difference in this particular case as regards to the group delimiters. If this is followed by something else that uses \addvspace (lists, section titles,…) the largest of the two spaces will be used. – egreg Sep 27 '21 at 13:17
4

You can use:

\newcommand{\Hrule}[4]{\vspace{#1}{\color{#3}\rule{\textwidth}{#4}}\vspace{#2}}

Note that you must use color or xcolor package.

Note also that this command may have an unexpected behaviour if you use it without start a new paragraph. Usually the line is going to break always the paragraph, so you can use:

\newcommand{\Hrule}[4]{\par\noindent\vspace{#1}{\color{#3}\rule{\textwidth}{#4}}\par\vspace{#2}}