summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/octave/octave.sty
blob: da268104f4ef97b6af047d073481a37962aca4ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{octave}
[2017/10/31 Octave designations in Helmholtz or traditional style]

% Copyright 2017 Andrew A. Cashner, andrewacashner@gmail.com

% This work may be distributed and/or modified under the 
% conditions of the LaTeX Project Public License, either
% version 1.3 of this license or (at your option) any 
% later version.
% The latest version of this license is in 
%    http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions
% of LaTeX version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
% The Current Maintainer of this work is Andrew A. Cashner.
% This work consists of the package file octave.sty
% and the documentation file octave.tex.

% CHANGE LOG
% 2017-10-31 Spelling corrections
% 2017-08-21 First version on CTAN

\newif\if@OctaveNumber
\@OctaveNumbertrue % Use Helmholtz numbers by default

\DeclareOption{prime}  {\@OctaveNumberfalse}
\DeclareOption{number} {\@OctaveNumbertrue}

\ProcessOptions\relax

\RequirePackage{xparse}

% Allow user to switch styles mid-document
\NewDocumentCommand{\octaveprimes}  {}{\@OctaveNumberfalse}
\NewDocumentCommand{\octavenumbers} {}{\@OctaveNumbertrue}

%****************************************************************************
% Main user command to enter pitch
% example: middle C is \pitch{c}{4}, semitone up is \pitch{C}[\sh]{4}
% #1 Pitch letter (can be lower or uppercase)
% #2 Optional accidental (e.g., $\flat$, or \fl{} from semantic-markup package)
% #3 Octave number (Helmholtz numbers, middle C = 4)
\NewDocumentCommand{\pitch}{ m o m }{%
    \if@OctaveNumber
        {\pitchfont{\MakeUppercase{#1}%
        \IfValueTF{#2}{#2}{}\textsubscript{#3}}}%
    \else
        {\pitchfont{%
            \@GetOctaveTick{#1}[#2]{#3}%
        }}%
    \fi
}

% Font for pitch and octave designation, default italics for prime style
% User can change with \renewcommand
\NewDocumentCommand{\pitchfont}{}{%
    \if@OctaveNumber\mdseries%
    \else\itshape%
    \fi
}

%***************************************************************************
% If using ticks, determine the right letter and octave symbols to print
%
% Octave  Designation
%      0  C''
%      1  C'
%      2  C
%      3  c
%      4  c'
%      5  c''
% 
% The input octave number can be less than zero or more than 5; this will just
% produce a lot of tick marks (e.g., \pitch{c}{8} => c'''''

% Mnemonic for selecting upper or lowercase letters, 
% used as argument to \@PrintLetter
\NewDocumentCommand{\@OctaveUpper}{}{1}
\NewDocumentCommand{\@OctaveLower}{}{0}

% Get the letter of the proper case and the right number of ticks.
% #1 Pitch letter
% #2 Optional accidental
% #3 Pitch number in Helmholtz notation
\newcount\@OctaveNum
\NewDocumentCommand{\@GetOctaveTick}{ m o m }{%
    \@OctaveNum = #3
    \ifnum\@OctaveNum < 3 
    % Octave < 3: Letter lowercase + (-OctaveNum + 2)ticks
        \@PrintLetter{\@OctaveUpper}{#1}%
        \multiply\@OctaveNum by -1 
        \advance\@OctaveNum by 2 
    \else
    % Octave >= 3: Letter uppercase + (OctaveNum - 3)ticks
        \ifnum\@OctaveNum > 2
            \@PrintLetter{\@OctaveLower}{#1}%
            \advance\@OctaveNum by -3
        \fi
    \fi
    % Print accidental if there is one
    \IfValueTF{#2}{\@SpacedAccidental{#2}}{}%
    % Print ticks; No need to do so if octave 2 or 3
    \ifnum\@OctaveNum > 0
        \kern1pt\@PrintTicks{\@OctaveNum}%
    \fi
}

% Accidental with spacing around it
%  #1 accidental symbol code
\NewDocumentCommand{\@SpacedAccidental}{ m }{%
    \kern0.4pt#1\kern-0.4pt%
}
% Print letter in proper case
% #1 \@OctaveUpper (=1) or \@OctaveLower (=0)
% #2 Character to print
\NewDocumentCommand{\@PrintLetter}{ m m }{%
    \ifnum #1 = \@OctaveLower
        \MakeLowercase{#2}%
    \else
        \MakeUppercase{#2}%
    \fi
}
        
% Print sequence of tick marks
\newcount\@TickNum
\NewDocumentCommand{\@PrintTicks}{ m }{%
   \@TickNum = #1%
   \loop
        \@Tick{}%
    \advance\@TickNum by -1
    \ifnum\@TickNum > 0
    \repeat
}
\NewDocumentCommand{\@Tick}{}{\ensuremath{'}}

%*******************************************
% Octave comparison table for demonstration
\newcounter{@TableOctave}
\NewDocumentCommand{\octavetable}{}{%
    \def\@TablePitchNames{}%
    \loop
    \edef\@TablePitchNames{%
        \@TablePitchNames
        {\octaveprimes \pitch{C}{\the@TableOctave}} & 
        {\octavenumbers \pitch{C}{\the@TableOctave}}\tabularnewline
    }%
    \stepcounter{@TableOctave}%
    \ifnum\value{@TableOctave} < 8
    \repeat
    %
    \begin{tabular}{ll}
        \@TablePitchNames
    \end{tabular}%
}

\endinput