使用 \rule 循环绘制五线谱

使用 \rule 循环绘制五线谱

我想只使用循环来绘制空白五线谱\rule。(我知道有 MusiXTeX 和 Lilypond,更不用说 Tikz 了,但实际上,我只想要一些水平线。)

在这个例子中,第一个命令\musicstaff成功地绘制了五线谱线,尽管每个线之间需要一个尴尬的负垂直调整。

但是,第二个命令无法循环并创建多个谱表。但是,如果我在循环体中用\musicstaves替换文本,它确实可以工作。我遗漏了什么?STAFF\musicstaff

\documentclass{article}

\newcounter{stafflines}
\newcommand{\musicstaff}{%                                                                                                                                     
  \setcounter{stafflines}{0}                                                                                                                                   
  \noindent                                                                                                                                                    
  \loop                                                                                                                                                        
    \rule{\linewidth}{0.4pt}%                                                                                                                                  
    \vspace*{-0.5\baselineskip}                                                                                                                                
    \stepcounter{stafflines}                                                                                                                                   
    \ifnum\value{stafflines} < 5                                                                                                                               
  \repeat%                                                                                                                                                     
}
\newcounter{staves}
\newcommand{\musicstaves}[1]{%                                                                                                                                 
  \setcounter{staves}{0}                                                                                                                                       
  \loop                                                                                                                                                        
    \musicstaff\par\vspace*{5\baselineskip} % doesn't work                                                                                                                
    \stepcounter{staves}                                                                                                                                       
    \ifnum\value{staves} < #1                                                                                                                                  
  \repeat%                                                                                                                                                     
}

\begin{document}

\musicstaves{3} % only prints one staff

\end{document}

答案1

\loop是一个非常简单的宏,不能在同一组级别嵌套:

\documentclass{article}

\newcounter{stafflines}
\newcommand{\musicstaff}{%                                                                                                                                     
  \setcounter{stafflines}{0}                                                                                                                                   
  \noindent                                                                                                                                                    
  \loop                                                                                                                                                        
    \rule{\linewidth}{0.4pt}%                                                                                                                                  
    \vspace*{-0.5\baselineskip}                                                                                                                                
    \stepcounter{stafflines}                                                                                                                                   
    \ifnum\value{stafflines} < 5                                                                                                                               
  \repeat%                                                                                                                                                     
}
\newcounter{staves}
\newcommand{\musicstaves}[1]{%                                                                                                                                 
  \setcounter{staves}{0}                                                                                                                                       
  \loop                                                                                                                                                        
    {\musicstaff\par\vspace*{5\baselineskip}} % does work                                                                                                                
    \stepcounter{staves}                                                                                                                                       
    \ifnum\value{staves} < #1                                                                                                                                  
  \repeat%                                                                                                                                                     
}

\begin{document}

\musicstaves{3} % only prints one staff

\end{document}

或者再次修复空白,这样你就不会得到填充不足的水平盒警告和虚假空格

\documentclass{article}

\newcounter{stafflines}
\newcommand{\musicstaff}{%
  \setcounter{stafflines}{0}%
  \noindent
  \loop
    \rule{\linewidth}{0.4pt}%
    \vspace*{-0.5\baselineskip}
    \stepcounter{stafflines}%
    \ifnum\value{stafflines} < 5
  \repeat
}
\newcounter{staves}
\newcommand{\musicstaves}[1]{%
  \setcounter{staves}{0}%
  \loop
    {\musicstaff\par\vspace*{5\baselineskip}}% does work
    \stepcounter{staves}%
    \ifnum\value{staves} < #1
  \repeat
}

\begin{document}

\musicstaves{3} % only prints one staff

\end{document}

答案2

\foreach我是的粉丝pgffor.sty,所以......

\documentclass{article}

\usepackage{pgffor}

\newcommand{\staff}[2][5]{%[# of lines per staff]{# of staves}
    \begingroup
    \parindent0pt
    \noindent
    \foreach \y in {1,...,#2}{%
        \foreach \x in {1,2,...,#1}{%
            \rule{\textwidth}{0.4pt}% {<staff width>}{<line thickness>}
            \par
            \nointerlineskip
            \vskip6pt% Distance between the lines
        }%
        \vspace{0.25in}% Distance between staves
    }%
    \endgroup
}


\begin{document}

\staff{5}

\vspace{0.5in}

\staff[4]{3}

\end{document}

默认情况下,这将绘制一个 5 线谱表,但您可以使用可选参数轻松更改它\staff。我修改了我的原始答案,以允许指定要绘制的谱表数量。

在此处输入图片描述

答案3

可定制版本expl3

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\keys_define:nn { cashner/staff }
 {
  width  .dim_set:N = \l_cashner_staff_width_dim,
  number .int_set:N = \l_cashner_staff_number_int,
  gap    .dim_set:N = \l_cashner_staff_gap_dim,
  width  .initial:n = \linewidth,
  number .initial:n = 1,
  gap    .initial:n = 5\baselineskip,
 }

\NewDocumentCommand{\musicstaves}{O{number=1}}
 {
  \par
  \group_begin:
  \keys_set:nn { cashner/staff } { #1 }
  \cashner_staves:
  \group_end:
 }

\cs_new_protected:Nn \cashner_staves:
 {
  \cashner_staff:
  \prg_replicate:nn { \l_cashner_staff_number_int - 1 }
   {
    \vspace{ \l_cashner_staff_gap_dim }
    \cashner_staff:
   }
 }

\cs_new_protected:Nn \cashner_staff:
 {
  \hrule width \l_cashner_staff_width_dim
  \prg_replicate:nn { 4 }
   {
    \vspace{4pt}
    \hrule width \l_cashner_staff_width_dim
   }
 }
\ExplSyntaxOff


\begin{document}

\musicstaves[number=3]

\bigskip

\musicstaves[width=3cm] % only one

\bigskip

\musicstaves[number=2,gap=1cm,width=5cm]

\end{document}

在此处输入图片描述

具有“填充”功能的变体;此外fill您还可以指定所有其他键(当然设置number没有效果)。

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\keys_define:nn { cashner/staff }
 {
  fill   .bool_set:N = \l_cashner_staff_fill_bool,
  width  .dim_set:N  = \l_cashner_staff_width_dim,
  number .int_set:N  = \l_cashner_staff_number_int,
  gap    .dim_set:N  = \l_cashner_staff_gap_dim,
  fill   .initial:n  = false,
  fill   .default:n  = true,
  width  .initial:n  = \linewidth,
  number .initial:n  = 1,
  gap    .initial:n  = 5\baselineskip,
 }

\box_new:N \l_cashner_staff_box

\NewDocumentCommand{\musicstaves}{O{number=1}}
 {
  \par
  \group_begin:
  \keys_set:nn { cashner/staff } { #1 }
  \bool_if:NTF \l_cashner_staff_fill_bool
   { \cashner_staves_fill: }
   { \cashner_staves: }
  \group_end:
 }

\cs_new_protected:Nn \cashner_staves:
 {
  \cashner_staff:
  \prg_replicate:nn { \l_cashner_staff_number_int - 1 }
   {
    \vspace{ \l_cashner_staff_gap_dim }
    \cashner_staff:
   }
 }

\cs_new_protected:Nn \cashner_staff:
 {
  \hrule width \l_cashner_staff_width_dim
  \prg_replicate:nn { 4 }
   {
    \vspace{4pt}
    \hrule width \l_cashner_staff_width_dim
   }
 }

\cs_new_protected:Nn \cashner_staves_fill:
 {
  \cashner_staff:
  \vbox_set:Nn \l_cashner_staff_box
   {
    \vspace{ \l_cashner_staff_gap_dim }
    \cashner_staff:
   }
  \xleaders \box_use:N \l_cashner_staff_box \vfill
  \vspace*{0pt}
 }

\ExplSyntaxOff


\begin{document}

\musicstaves[number=3]

\bigskip

\musicstaves[width=3cm] % only one

\bigskip

\musicstaves[number=2,gap=1cm,width=5cm]

\clearpage

\musicstaves[fill]

\end{document}

答案4

我从每个答案中汲取了一些经验,制作了一个满足我需求的简单程序包。您可以绘制任意数量的五线谱,每条五线谱有任意数量的线条,并且可以控制五线谱之间和内部的间距。程序包如下,后面是演示不同用途的示例文档。


包裹musicstaves.sty

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{musicstaves}[2015/09/08 Draw blank music staff lines]

% Adjustable spacing lengths
% Space between the lines inside the staff
\newlength{\insidestaffspace}
\setlength{\insidestaffspace}{4pt}
% Can adjust spacing between staves
\newlength{\betweenstaffspace}
\setlength{\betweenstaffspace}{1cm}

%% Draw a single staff with a specified number of lines per staff
\newcounter{stafflines}
% #1 lines per staff
\newcommand{\musicstaff}[1]{%
  \setcounter{stafflines}{0}%
  \noindent
    \loop
    \vspace{\insidestaffspace}%
    \hrule width\linewidth \nobreak
   \stepcounter{stafflines}%
   \ifnum\value{stafflines} < #1
   \repeat%
}

%% Draw multiple staves
\newcounter{staves}
% #1 lines per staff (optional, defaults to 5)
% #2 total staves to print
\newcommand{\musicstaves}[2][5]{%
  \setcounter{staves}{0}%
  \loop
    {\musicstaff{#1}\par\vspace*{\betweenstaffspace}}
    \stepcounter{staves}%
    \ifnum\value{staves} < #2
  \repeat%
}

%% Set lengths for widely spaced staves (inside staff and between staves)
\newcommand{\widestaves}{%
  \setlength{\insidestaffspace}{2\insidestaffspace}
  \setlength{\betweenstaffspace}{2\betweenstaffspace}
}

\endinput

示例文档mwe.tex

\documentclass{article}
\usepackage{musicstaves}

\begin{document}

\section*{4-line staff}

\musicstaff{4}

\section*{5-line default staves}

\musicstaves{4}

\section*{6-line staves}

\musicstaves[6]{2}

\section*{Default staves with increased spacing}

{\setlength{\betweenstaffspace}{1.5\betweenstaffspace}
\musicstaves{3}
}

\section*{Wide staves}

{\setwidestaves \musicstaves{4} }

\end{document}

在此处输入图片描述 在此处输入图片描述

相关内容