9

I am creating my own CV and I want to add a command to produce the following :

enter image description here

I did succeed in doing that, with the following :

\usepackage{scalerel}
\usepackage{amssymb}

\newcommand\openbigstar[1][0.7]{%
  \scalerel*{%
    \stackinset{c}{-.125pt}{c}{}{\scalebox{#1}{\color{white}{$\bigstar$}}}{%
      $\bigstar$}%
  }{\bigstar}
}

$\bigstar\bigstar\openbigstar[0.5]\openbigstar[.9]\openbigstar[.9]$

But each time I need to type five commands, can we dot it in one command taking an argument between 1 and 5 ? (basically do complex loop)

3
  • 1
    Your code doesn't compile; what do you include to get the command \bigstar? Nov 9, 2019 at 22:18
  • I included a lot of other packages, I think its in amssymb
    – Elaqqad
    Nov 9, 2019 at 22:39
  • 3
    I'm unsure if this is what you're going for, but putting ratings on your CV might not have the effect you want as it can be subjective. See this question for reference: workplace.stackexchange.com/questions/48510/…
    – JS Lavertu
    Nov 10, 2019 at 13:16

5 Answers 5

13

Welcome! To first approximation you could do

\documentclass{article}
\usepackage{xcolor}
\usepackage{amssymb}
\usepackage{scalerel}
\usepackage{stackengine}
\newcounter{iloop}
\newcommand\openbigstar[1][0.7]{%
  \scalerel*{%
    \stackinset{c}{-.125pt}{c}{}{\scalebox{#1}{\color{white}{$\bigstar$}}}{%
      $\bigstar$}%
  }{\bigstar}
}
\newcommand{\Stars}[1]{\ensuremath{\setcounter{iloop}{0}%
\loop\stepcounter{iloop}\ifnum\value{iloop}<#1
\bigstar\repeat
\openbigstar[0.5]
\setcounter{iloop}{0}%
\loop\stepcounter{iloop}\ifnum\value{iloop}<\the\numexpr6-#1\relax
\openbigstar[.9]\repeat}}
\begin{document}
\Stars{5}

\Stars{4}

\Stars{3}

\Stars{2}

\Stars{1}
\end{document}

enter image description here

It is not clear to me whether you also want to award fractional stars.

ADDENDUM: If you want to allow for fractional ratings, you could do

\documentclass{article}
\usepackage{xcolor}
\usepackage{amssymb}
\usepackage{scalerel}
\usepackage{stackengine}
\usepackage{pgf}
\newcounter{iloop}
\newcommand\openbigstar[1][0.7]{%
  \scalerel*{%
    \stackinset{c}{-.125pt}{c}{}{\scalebox{#1}{\color{white}{$\bigstar$}}}{%
      $\bigstar$}%
  }{\bigstar}
}
\newcommand{\Stars}[1]{\ensuremath{%
\pgfmathtruncatemacro{\imax}{ifthenelse(int(#1)==#1,#1-1,#1)}%
\pgfmathsetmacro{\xrest}{0.9*(1-#1+\imax)}%
\setcounter{iloop}{0}%
\loop\stepcounter{iloop}\ifnum\value{iloop}<\the\numexpr\imax+1
\bigstar\repeat
\openbigstar[\xrest]%
\setcounter{iloop}{0}%
\loop\stepcounter{iloop}\ifnum\value{iloop}<\the\numexpr5-\imax\relax
\openbigstar[.9]\repeat}}
\begin{document}
\Stars{5}

\Stars{4.2}

\Stars{3.6}

\Stars{2}

\Stars{1.3}

\Stars{0.3}

\end{document}

enter image description here

If you have problems with missing arms of the last filled star when using round numbers, simply subtract 0.01, i.e. 4.99 instead of 5.

Or a TikZ version, which is obviously much more customizable.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\newcommand{\Stars}[2][fill=yellow,draw=orange]{\begin{tikzpicture}[baseline=-0.35em,#1]
\foreach \X in {1,...,5}
{\pgfmathsetmacro{\xfill}{min(1,max(1+#2-\X,0))}
\path (\X*1.1em,0) 
node[star,draw,star point height=0.25em,minimum size=1em,inner sep=0pt,
path picture={\fill (path picture bounding box.south west) 
rectangle  ([xshift=\xfill*1em]path picture bounding box.north west);}]{};
}
\end{tikzpicture}}
\begin{document}
\Stars{4.5}
 
\Stars{4.2}

\Stars{3.6}

\Stars{2}

\Stars{1.3}

\Stars{0.3}
\end{document}

enter image description here

5
  • thank you for the answer, this is what I was looking for, but it would be more perfect if fractional stars are included.
    – Elaqqad
    Nov 9, 2019 at 22:40
  • @Elaqqad I added them. Please note that if you were to consider using tikz, the fractional fill could be adjusted more easily/precisely.
    – user194703
    Nov 9, 2019 at 22:42
  • Perfect, I have already included tickz in my packages for other reasons, how could you go to adjust that precisely ?
    – Elaqqad
    Nov 9, 2019 at 22:52
  • that's Perfect, I ended up using tickz.
    – Elaqqad
    Nov 10, 2019 at 18:21
  • @Elaqqad Glad to hear! If you look at the code in my user profile, you can see why I am very supportive of this choice. ;-)
    – user194703
    Nov 10, 2019 at 22:37
6

TeX is technically Turing-complete, but some programming concepts are a bit more difficult than in other languages. Loops are one. But they are certainly doable. I don't know where you're getting \bigstar from, so I can't do that specifically; but here's the general, TeX way to do a loop:

\documentclass{article}
\begin{document}
\newcount\loopi\loopi=0
\loop\ifnum\loopi<5
    Hey
    \advance\loopi by1
\repeat
\end{document}

You use \loop, then an \ifnum to give your condition. It will then repeat whatever is between that \ifnum and your \repeat command. Make sure that you increment your loop-control variable (here, \loopi) within your loop, or you'll get an infinite loop.

The above will print "Hey" five times. I understand that there are more LaTeXy ways to do this, and that pgf may have some very easy loop commands; but I can't speak to them. This is the basic TeX way, anyway.

Your specific question seems to require manipulating fractional values, which is also a bit tougher in TeX; maybe look into the fp package? You could also perhaps use an integer and just append it to 0.:

\newcount\loopi\loopi=1
\loop\ifnum\loopi<6
    0.\the\loopi,
    \advance\loopi by1%
\repeat

That will print 0.1,0.2,0.3,0.4,0.5; maybe you could use this in your \openbigstar commands.

1
  • 1
    I did not know that it is Turing Complete ! very cool information.
    – Elaqqad
    Nov 9, 2019 at 22:43
4

Adjusted TikZ version from accepted answer

\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\newcommand{\stars}[2][fill=black,draw=black]{
\begin{tikzpicture}[baseline=-0.34em,#1]
\foreach \X in {1,...,5}
{
\pgfmathsetmacro{\xfill}{min(1,max(1+#2-\X,0))}
\path (\X*1em,0) 
node[star,draw, ultra thin,star point height=0.23em,minimum size=0.75em,inner sep=0pt,
path picture={\fill (path picture bounding box.south west) 
rectangle  ([xshift=\xfill*0.722em]path picture bounding box.north west);}]{};
}
\end{tikzpicture}}

\begin{document}

\stars{4.5}
 
\stars{4.2}

\stars{3.6}

\stars{2}

\stars{1.3}

\stars{0.3}

\end{document}

stars

1

I used this in komacv:

\usepackage{forloop}
\newcounter{x}
\newcommand{\skill}[1]{%
    \forloop{x}{0}{\value{x} < #1}{%
        $\textcolor{colortheme}\bullet$
    }%
    \forloop{x}{#1}{\value{x} < 5}{%
        $\textcolor{colortheme}\circ$
    }%
}

enter image description here

0

In case somebody needs a solution for circles instead of stars use this:

\usepackage{scalerel}
\usepackage{stackengine}

% open bullet macro
\newcommand{\openbullet}{\ensuremath{\circ}}%
\newcommand{\solidbullet}{\ensuremath{\bullet}}%
\newcounter{counter_skilllevel}% counter variable
\newcommand{\skilllevel}[1]{% define skill-level function
    \setcounter{counter_skilllevel}{0}% reset counter
    \loop% solid bullet loop
        \textcolor{color1}{\Large\solidbullet}\,% draw filled circle and small space
        \stepcounter{counter_skilllevel}% i++
        \ifnum \value{counter_skilllevel}<#1% continue if target level not reached yet
    \repeat% close loop
    \loop% open bullet loop
        \ifnum \value{counter_skilllevel}<5% check max condition first
        \stepcounter{counter_skilllevel}% i++
        \textcolor{darkgray}{\Large\openbullet}\,% draw unfilled circle and small space
    \repeat%
}
1
  • That seems to be an answer to another question. Jan 21, 2022 at 15:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .