我想只使用循环来绘制空白五线谱\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}