%GregorioTeX file.
%Copyright (C) 2007 Elie Roux <elie.roux@enst-bretagne.fr>
%
%This program is free software: you can redistribute it and/or modify
%it under the terms of the GNU General Public License as published by
%the Free Software Foundation, either version 3 of the License, or
%(at your option) any later version.
%
%This program is distributed in the hope that it will be useful,
%but WITHOUT ANY WARRANTY; without even the implied warranty of
%MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%GNU General Public License for more details.
%
%You should have received a copy of the GNU General Public License
%along with this program.  If not, see <http://www.gnu.org/licenses/>.

% this file contains definitions of the glyphs and the syllables

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% macros for the typesetting of the different glyphs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% \glyphraisevalue is the value of which we must raise one glyph (that will vary with every glyph)
\newdimen\glyphraisevalue 

% \addedraisevalue is for the vertical episema and the puncta
\newdimen\addedraisevalue

% a temporary count
\newcount\tempcount

% a boolean : 0 if the note is not a line, else 1
\newcount\isonaline

% a very useful macro : it determines the good height of a glyph : the argument is the "number" where the glyph should be : 4 for the first line, 6 for the second, etc.
% the second argument is for the cases of signs: for example if the note is on a line, the punctummora will be above, and the auctus duplex beneath. the possible values are:
%% 0: no modification
%% 1: puts the value on the interline just above if it is on a line
%% 2: puts the value on the interline just beneath if it is on a line
%% 3: case of the vertical episemus, which is not placed at the same place if the corresponding note is on a line or not
%% 4: case of the punctum mora, for the same reason
%% 5: case of the horizontal episemus under a note, that must be placed a bit lower if the note is on a line
%% 6: case of the signs above (accentus, etc.)
\def\calculateglyphraisevalue#1#2{%
\global\isonaline=\number 0%
\ifx a#1%
\global\tempcount=\number 1%
\fi%
\ifx b#1%
\global\tempcount=\number 2%
\ifnum#2=3\relax %
\else %
\global\isonaline=1 % if it is a vertical episemus, we don't care if it is on a line or not... which may cause some problems...
\fi %
\fi%
\ifx c#1%
\global\tempcount=\number 3%
\fi%
\ifx d#1%
\global\tempcount=\number 4%
\global\isonaline=1 %
\fi%
\ifx e#1%
\global\tempcount=\number 5%
\fi%
\ifx f#1%
\global\tempcount=\number 6%
\global\isonaline=1 %
\fi%
\ifx g#1%
\global\tempcount=\number 7%
\fi%
\ifx h#1%
\global\tempcount=\number 8 %
\global\isonaline=1 %
\fi%
\ifx i#1%
\global\tempcount=\number 9%
\fi%
\ifx j#1%
\global\tempcount=\number 10%
\global\isonaline=1 %
\fi%
\ifx k#1%
\global\tempcount=\number 11%
\fi%
\ifx l#1%
\global\tempcount=\number 12%
\global\isonaline=1 %
\fi%
\ifx m#1%
\global\tempcount=\number 13%
\fi%
% if the note is on a line, we change its height
\ifcase\isonaline%
\or%
\ifcase#2 %
\or% 1
\advance\tempcount by 1%
\or% 2
\advance\tempcount by -1%
\or% 3
\advance\tempcount by -1%
\or% 4
\advance\tempcount by 1%
\or% 5
\advance\tempcount by -1%
\fi%
\fi%
\advance\tempcount by -7 %
\glyphraisevalue = 15750 sp %
\multiply\glyphraisevalue by \the\grefactor %
\multiply\glyphraisevalue by \the\tempcount %
\addedraisevalue= 0 sp%
\ifcase#2 % 
\or\or\or%3: if it is a vertical episemus on a line, we shift it a bit higher, so that it's more beautiful
\ifnum\isonaline=1%
\addedraisevalue=7250 sp%
\multiply\addedraisevalue by \the\grefactor %
\advance\glyphraisevalue by \addedraisevalue %
\else % if it is not on a line, we shift it a bit lower
\addedraisevalue=-1380 sp%
\multiply\addedraisevalue by \the\grefactor %
\advance\glyphraisevalue by \addedraisevalue %
\fi %
\or% 4: if it is a punctum mora on a line, we shift it a bit lower, for the same reason
\ifnum\isonaline=1%
\addedraisevalue=-6900 sp%
\multiply\addedraisevalue by \the\grefactor %
\advance\glyphraisevalue by \addedraisevalue %
\fi%
\or% 5: if it is a horizontal episemus under a note which is on a line, we shift it lower
\ifnum\isonaline=0%
\addedraisevalue=-4980 sp%
\multiply\addedraisevalue by \the\grefactor %
\advance\glyphraisevalue by \addedraisevalue %
\else % if it is under a note between two lines, we shift it higher
\addedraisevalue=4000 sp%
\multiply\addedraisevalue by \the\grefactor %
\advance\glyphraisevalue by \addedraisevalue %
\fi %
\or% 6: if it is a sign, we put it at an arbitrary height
\addedraisevalue=-10000 sp%
\multiply\addedraisevalue by \the\grefactor %
\advance\glyphraisevalue by \addedraisevalue %
\fi%
\advance\glyphraisevalue by \constantglyphraise %
\global\tempcount=0%
\global\isonaline=0%
\relax%
}

% count that tells us if the current glyph is the first glyph or not. It it is the case, we determine
\newcount\firstglyph

\newcount\firstnote
\newcount\secondnote
\newcount\thirdnote
\newcount\fourthnote
\newcount\glyphnumber
\newcount\glyphnumbertemp
\newcount\interval
\newcount\notetemp

\def\assignnote#1#2{%
\ifcase#1%
\or%
\global\firstnote=#2%
\or%
\global\secondnote=#2%
\or%
\global\thirdnote=#2%
\or%
\global\fourthnote=#2%
\fi%
\relax%
}

\def\notetonumber#1#2{%
\ifx a#1%
\assignnote{#2}{1}%
\fi%
\ifx b#1%
\assignnote{#2}{2}%
\fi%
\ifx c#1%
\assignnote{#2}{3}%
\fi%
\ifx d#1%
\assignnote{#2}{4}%
\fi%
\ifx e#1%
\assignnote{#2}{5}%
\fi%
\ifx f#1%
\assignnote{#2}{6}%
\fi%
\ifx g#1%
\assignnote{#2}{7}%
\fi%
\ifx h#1%
\assignnote{#2}{8}%
\fi%
\ifx i#1%
\assignnote{#2}{9}%
\fi%
\ifx j#1%
\assignnote{#2}{10}%
\fi%
\ifx k#1%
\assignnote{#2}{11}%
\fi%
\ifx l#1%
\assignnote{#2}{12}%
\fi%
\ifx m#1%
\assignnote{#2}{13}%
\fi%
\relax%
}

% not working yet, do not use
\def\tor#1#2#3{%
\notetonumber{#1}{1}%
\notetonumber{#2}{2}%
\notetonumber{#3}{3}%
\interval=\secondnote%
\advance\interval by -\firstnote %
\multiply\interval by 25 %
\tempnote=\secondnote%
\advance\tempnote by -\thirdnote %
\advance\interval by \tempnote %
\advance\interval by 28672 %
\glyph{\char \the\interval}{#1}{#3}{0}%
\relax%
}

% the width of the last glyph
\newdimen\lastglyphwidth
% the width of the text which is after the glyph
%\newdimen\additionalwidth

% macro to typeset the glyph. attributes are :
% #1: character : the character that it must call
% #2: height : the height it must be raised : can be negative (must be calculated by a preprocessor)
% #3: height of the next note : we define the custo with that
% #4: type : the type of glyph, to determine the aligncenter; can be :
%%%%% 0 : one-note glyph or more than two notes glyph except porrectus : here we must put the aligncenter in the middle of the first note
%%%%% 1 : two notes glyph (podatus is considered as a one-note glyph) : here we put the aligncenter in the middle of the glyph
%%%%% 2 : porrectus : has a special align center
%%%%% 3 : initio-debilis : same as 1 but the first note is much smaller
%%%%% 4 : case of a glyph starting with a quilisma
%%%%% 5 : case of a glyph starting with an oriscus
%%%%% 6 : case of a punctum inclinatum
%%%%% 7 : case of a stropha
%%%%% 8 : flexus with an ambitus of one
%%%%% 9 : flexus deminutus
\def\glyph#1#2#3#4{%
\calculateglyphraisevalue{#2}{0}%
\setbox\Tempwidth=\hbox{\gregorianfont #1}%
\tempwidth=\wd\Tempwidth%
\global\lastglyphwidth=\tempwidth %
\raise \glyphraisevalue%
\copy\Tempwidth%
\ifnum\the\endofscore=0 %
\setcusto{#3}%
\fi %
\ifnum\the\firstglyph=1% we check if it is the first glyph
\findnotesaligncenter{#4}%
\global\firstglyph=0%
\fi%
%\lastglyphwidth=\tempwidth%
\relax%
}

% notes align center is the point of alignment for the notes
\newdimen\notesaligncenter

% this function is quite simple, it just sets \Tempwidth with a box of the good width, watch the next function for the complete thing
% we define the different alignments possible, of course they depend on the font
% the first 10 (0-9) possible values are the same as in glyph
%%%%% 0 : one-note glyph or more than two notes glyph except porrectus : here we must put the aligncenter in the middle of the first note
%%%%% 1 : two notes glyph (podatus is considered as a one-note glyph) : here we put the aligncenter in the middle of the glyph
%%%%% 2 : porrectus : has a special align center
%%%%% 3 : initio-debilis : same as 1 but the first note is much smaller
%%%%% 4 : case of a glyph starting with a quilisma
%%%%% 5 : case of a glyph starting with an oriscus
%%%%% 6 : case of a punctum inclinatum
%%%%% 7 : case of a stropha
%%%%% 8 : flexus with an ambitus of one
%%%%% 9 : flexus deminutus
%%%%% 10 : virgula
%%%%% 11 : divisio minima, minor and maior
%%%%% 12 : divisio finalis
% there is a tricky here : if notesaligncenter is not 0, it means that there is a flat before, so we simply add notes aligncenter
\def\findsimplenotesaligncenter#1{%
\ifcase#1%
%case of punctum
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 17}%
\or%
%case of flexus
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 4098}%
\or%
%case of porrectus (we consider it to have the same alignment as punctum)
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 17}%
\or%
%case of a initio debilis
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 13}%
\or %
%case of a quilisma
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 26}%
\or %
%case of an oriscus
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 28}%
\or %
%case of a punctum inclinatum
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 19}%
\or %
%case of a stropha
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 20}%
\or %
% case of flexus with ambitus of one
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 4097}%
\or %
% case of flexus deminutus
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 4225}%
\or %
% case of virgula
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 9}%
\or %
% case of divisio minima, minor, maior
\global\setbox\Tempwidth=\hbox{\gregorianfont \char 13}%
\or %
% case of divisiofinalis
\global\setbox\Tempwidth=\hbox{\divisiofinalissymbol}%
\fi%
\relax%
}

% the "hat" function, that calls the simple function with the good argument, according to the fact that it's a flat, natural, etc.
% warning: the behaviour of all this is quite difficult to understand: this function is called with simple arguments (between 0 and 20) by the glyph function. In this case we add the align center of the argument to notesaligncenter ; and notesaligncenter can be already set to something by flat and natural.
\def\findnotesaligncenter#1{%
\findsimplenotesaligncenter{#1}%
\temp=\wd\Tempwidth %
\divide\temp by 2\relax %
\global\advance\notesaligncenter by \temp %
\relax %
}

% this is the function that we call when we try to determine the next aligncenter of the notes. In this case we call this function with normal arguments if there is no flat nor natural ; we call it with argument + 20 if there is a flat and argument + 40 if there is a natural... I know this is dirty... but... this is TeX...
\def\findnextnotesaligncenter#1{%
\ifnum#1<20\relax %
\findsimplenotesaligncenter{#1}%
\temp=\wd\Tempwidth %
\divide\temp by 2\relax %
\global\notesaligncenter=\temp %
\else %\ifnum#1<20
\tempcount=#1 %
\ifnum#1<40\relax%
\advance\tempcount by -20\relax %
\findsimplenotesaligncenter{\tempcount}%
\temp=\wd\Tempwidth %
\divide\temp by 2\relax %
\setbox\Tempwidth=\hbox{\gregorianfont \char 6}%
\else%\ifnum#1<40
\advance\tempcount by -40\relax %
\findsimplenotesaligncenter{\tempcount}%
\temp=\wd\Tempwidth %
\divide\temp by 2\relax %
\setbox\Tempwidth=\hbox{\gregorianfont \char 7}%
\fi %
\advance\temp by \wd\Tempwidth %
\global\notesaligncenter=\temp %
\global\tempcount=0\relax %
\fi %
\relax %
}

% box that we will use to determine the width of the notes, to determine wether we typeset a - or not after the letters
\newbox\Syllablenotes
\def\syllablenotes#1{%
\setbox\Syllablenotes=\hbox{#1}%
\relax%
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% macros for the typesetting of glyphs and notes together
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% a dimen that will contain the difference between the end of the text and the end of the notes for the previous syllable (if we are in the same word) : positive if notes go further than text. We will use it for space adjustment between syllables of the same word

\newdimen\enddifference 

% a dimen that will contain the enddifference of the previous glyph

\newdimen\previousenddifference 

% \begindifference is the difference between the begginning of the text and the beginning of the notes. Warning : it can be negative.

\newdimen\begindifference

\newdimen\temp

% box that will contain the text of the syllable

\newbox\Syllabletext

% count that will be 0 if in the last text there was no dash (or if it is the beginning of a word, and 1 if there was
%\newcount\previousdash

\newcount\firstsyllableofword
\firstsyllableofword=1

\ifluatex
% an attribute we put on the text nodes.
% if it is 1, it means that there may be a dash here if this syllable is at the end of a line
% if it is 2, it means that it's never useful to typeset a dash
% if it is 0, it just means that we are in a score...
\attributedef\gregorioattr=987
\fi

% we specify if it is the last syllable of the score with that value
\newcount\endofscore

%% general macro : it will typeset the syllable : arguments are :
% #1 : the first letters of the syllable, that don't count for the alignment
% #2 : the middle letters of the syllable, we must align in the middle of them
% #3 : the end letters, they don't count
% #4 : end of word : if it is 0 it means it is not an end of word, if it is 1 it is
% TODO: find another system for the end syllable
%% #5 (not used anymore) : beggining of word : if it is 0 it means it is not a beginning of word, if it is 1 it is
% #9 : glyphs : all the notes
% the three next parameters are to put an hyphen if necessary, they can be empty for end of words
% #5 : first letters of the next syllable 
% #6 : middle letters of the next syllabel
% #7 : alignment type of the first next glyph
% #8 : other macros (translation, double text, etc.) that don't fit in the limitation of the number of arguments
%% with a special option for #7 : if it is a bar, we don't put a space at the end
%% at the end we wall \endofword or \endofsyllable with #7, to reduce the space in case of a flat or natural
\def\syllable#1#2#3#4#5#6#7#8#9{%
\ifluatex % by default, gregorioattr will be 2
\gregorioattr=2\relax %
\fi %
\firstglyph=1 %
\findtextaligncenter{#1}{#2}% we first get the width between the alignment point and the end of the syllable
\syllablenotes{#9}% we put the notes in a box, so that we have the width of it
% now we calculate the begin difference, that is to say \notesaligncenter - \textaligncenter
\begindifference=\notesaligncenter %
\advance\begindifference by -\textaligncenter %
% first we check if it is the first syllable of a line. If it is we apply the following algorithm : 
% there must be at least a certain space between the key and the first note. The first letter can be beneath the key, but not to the left
\ifnum\lastoflinecount=2\relax %
\temp=\intersyllablespace %
\advance\temp by \begindifference %
\ifdim\temp <-\clefwidth %
\temp=-\clefwidth %
\fi %
\hbox{\kern\temp}%
\hskip\afterclefnospace %
\else %\ifnum\lastoflinecount=2
% then we do a kind of trick to separate more the notes of two different syllables : we put a space if we are in the same word (enddifference!=0) if necessary
% there are two cases according to the sign of enddifference
% and we do it only if it is not the first syllable of a word
% but we must not do it when there is a bar before... so when there is a bar enddifference = 0
\ifnum\firstsyllableofword=0 %
\ifdim\enddifference>0pt%
\temp=\intersyllablespace %
\advance\temp by \begindifference %
\else %\enddifference<0
\temp=\intersyllablespace %
\advance\temp by \begindifference %
\advance\temp by \enddifference %
\fi % \ifdim\enddifference>0pt
\ifnum\firstisalteration=1\relax %
\advance\temp by \beforealterationspace %
\global\firstisalteration=0\relax %
\fi % \ifnum\firstisalteration=1
\ifdim\temp>0pt %
\hskip\temp %
\fi %
\fi %
\fi %
\setnextbegindifference{#5}{#6}{#7}%
\setbox\Syllabletext=\hbox{\gretextformat{#1#2#3}}%
\setenddifference{\wd\Syllablenotes}{\wd\Syllabletext}{\textaligncenter}{\notesaligncenter}{1}%
\ifcase#4 %
% we enter here if the end of word is 0, so we must determine if we need to type a dash here
%
% we set temp to the additional space that will be needed before the next syllable
%\ifdim\enddifference>0pt%
\temp=\enddifference %
\advance\temp by \intersyllablespace %
\advance\temp by \nextbegindifference %
%
% then we compare it with \maximumspacewithoutdash, if it is larger, we add a dash
%
\ifdim\temp>\maximumspacewithoutdash %
\setbox\Syllabletext=\hbox{\gretextformat{#1#2#3-}}%
\setenddifference{\wd\Syllablenotes}{\wd\Syllabletext}{\textaligncenter}{\notesaligncenter}{0}%
\else %
\ifluatex %
\gregorioattr=1\relax % in this particular case where it is not the end of a word and we haven't put a dash, we set potentital dash to 1
% we rebuild this box, in order it to have the attribute
\setbox\Syllabletext=\hbox{\gretextformat{#1#2#3}}%
\fi %
\fi%
\fi%
% then we reuse temp, we assign to it the \begindifference, but only if it is positive, else it is 0
\ifdim\begindifference > 0 pt%
\kern \begindifference %
\fi%
#8\relax %
\raise\textlower \copy\Syllabletext %
\kern -\wd\Syllabletext %
\kern -\begindifference %
\ifluatex % here we need to unset \gregorioattr for the typesetting of notes
\gregorioattr=0\relax %
\fi %
#9% we do that instead of \unhbox\Syllablnotes, because it would not set the \localrightbox
\ifdim\the\enddifference <0pt%
%% important, else we are not really at the end of the syllable
\kern -\enddifference %
\fi%
\ifnum\lastoflinecount=2\relax %
% we put a space after the initial clefs
%\localleftbox{% I just commented it... I can't really remember why I did that thing...
%\copy\Lines% draws the lines
%\unkern %
%\hbox{\copy\Leftbox\hskip\spaceafterlineclef}%
%}%
\global\lastoflinecount=0\relax %
\fi %
% we call end of syllable
%% then we call end of syllable or end of word, but only if the next syllable is not a bar, that is to say, the number is between 10 and 19. TeX is a shitty language, so we do a dirty workaround to make a and in the if.
\ifnum#7>9\relax %
\ifnum#7<20\relax %
\ifnum\lastoflinecount=1\relax %
\endbeforebar{0}%
\else %
% otherwise we call it with 1 only if there is no letters after (we can see it with nextbegindifference)
\setbox\Tempwidth=\hbox{#5#6}%
% /!\ warning: can be buggy...
\ifdim\wd\Tempwidth=0pt%
\endbeforebar{0}%
\else %
\endbeforebar{1}%
\fi %
\fi %
\global\firstsyllableofword=1\relax %
\else %
\shittytexworkaround{#4}%
\fi %
\else %
\shittytexworkaround{#4}%
\fi%
\global\notesaligncenter=0pt% very important, see flat and natural
\relax%
}

% not a very beautiful name... maybe I should change it... the only reason of this function is that TeX can't have and in if
% #1 is the #4 of syllable
\def\shittytexworkaround#1{%
\ifnum\lastoflinecount=1\relax %
\global\lastoflinecount=2\relax %
\ifcase#1 %
\global\firstsyllableofword=0\relax %
\or%
\endofword{0}%
\global\firstsyllableofword=1\relax %
\fi%
\else %\ifnum\lastoflinecount=1 %
\ifcase#1 %
\endofsyllable%
\global\firstsyllableofword=0\relax %
\or%
\endofword{1}%
\global\firstsyllableofword=1\relax %
\fi%
\fi%
}
%skip needed for the barsyllable macro
\newskip\skipone

%a macro to typeset a syllable with only a bar inside
\def\barsyllable#1#2#3#4#5#6#7#8#9{%
% the algorithm of this function is *extremely* complex, and has been much painful to write... good luck to understand.
% the main goal is, when there is no text under the bar, to put the bar in the middle of the space between the last note of the prefious syllable and the first note of the next syllable. But there are limits : a bar cant go very far above text. For example if there is nuncncncncn with a punctum on the u, the bar can't go above the fourth n, the most far position is the position where the end of the bar is above the end of the word. The same limitation applies for the syllable after the bar.
% there are two different cases that have almost nothing in common : the case where there is something written under the bar, and the case where there is nothing.
% first of all we need to calculate previousenddifference, begindifference, enddifference and nextbegindifference.
\findtextaligncenter{#1}{#2}%
\setbox\Syllabletext=\hbox{\gretextformat{#1#2#3}}%
\syllablenotes{#9}%
\notesaligncenter=\wd\Syllablenotes%
\divide\notesaligncenter by 2\relax %
\begindifference=\notesaligncenter %
\advance\begindifference by -\textaligncenter %
\setenddifference{\wd\Syllablenotes}{\wd\Syllabletext}{\textaligncenter}{\notesaligncenter}{1}%
\setnextbegindifference{#5}{#6}{#7}%
% then we check if there is something to write
\ifdim\wd\Syllabletext = 0 pt\relax %
% the most difficult case : when there is nothing to write
% first we need to determine the real space that there will be between the notes. Here again it is not so simple... let's consider these two kinds of spaces : 
%% 1/ the minimal space between a note and the bar + the width of the bar + the minimal space between the bar and the note (that's the global idea, in fact there are nuances) : we assign skipone to it
%% 2/ enddifference + begindifference + space between notes and word : we assign temp to it
\skipone=\notebarspace %
\advance\skipone by \notebarspace %
\advance\skipone by \wd\Syllablenotes %
% now let's get temp
\ifdim\nextbegindifference < 0 pt%
\temp=-\nextbegindifference %
\else %
\temp=0 pt%
\fi %
\ifdim\previousenddifference < 0 pt%
\advance\temp by -\previousenddifference %
\advance\temp by \interwordspacetext % in fact it is the max between interwordspacetext and interwordspacetextnotes
\else %
\advance\temp by \interwordspacenotestext % in fact it is the max between interwordspacenotestext and interwordspacenotes
\fi%
% we take the max of it, then we divide it by two and we substract half of the width of the bar
\ifdim\skipone <\temp %
\skipone=\temp %
\fi %
\divide\skipone by 2\relax %
\temp=\wd\Syllablenotes %
\divide\temp by 2\relax %
\advance\skipone by -\temp %
% now we have our skipone
\temp=\skipone %
\ifdim\previousenddifference < 0 pt%
\advance\temp by \previousenddifference %
\fi %
\penalty 10001\relax %
\ifdim\temp > -\wd\Syllablenotes %
\kern\temp %
\else %
\kern -\wd\Syllablenotes %
\fi %
\penalty 10001\relax %
#9\relax %
\penalty -1000\relax %
\ifdim\temp < -\wd\Syllablenotes %
\ifdim\nextbegindifference > 0 pt%
\hskip\interwordspacetextnotes %
\else % \ifdim\nextbegindifference > 0 pt
\hskip\interwordspacetext %
\fi %
\else % \ifdim\temp < -\wd\Syllablenotes
%\temp=\wd\Syllablenotes %
%\divide\temp by 2\relax %
%\kern -\temp %
\temp=\skipone %
\ifdim\nextbegindifference < 0 pt%
\advance\temp by \nextbegindifference %
\fi %
\ifdim\temp > -\wd\Syllablenotes %
\kern\temp %
\else % \ifdim\temp > -\wd\Syllablenotes %
\hskip -\wd\Syllablenotes %
\fi %
\fi %
% then the most simple : the case where there is something to write under the bar. We just need to adjust the spaces.
\else %ifdim\wd\hbox{#1#2#3}=0
% I'm a little lazy for now, I won't make the usual mountain of ifs... TODO: use different spaces
\skipone=\textbartextspace %
% same code as in syllable
\temp=\begindifference %
\ifdim\temp > 0 pt %
\advance\skipone by \temp %
\fi%
%\kern\skipone %
#8\relax %
\raise\textlower \copy\Syllabletext %
\kern -\wd\Syllabletext %
\kern -\begindifference %
#9% we do that instead of \unhbox\Syllablnotes, because it would not set the \localrightbox
\ifdim\the\enddifference <0pt%
%% important, else we are not really at the end of the syllable
\kern -\enddifference %
\fi%
% end of same code as syllable
\ifnum\lastoflinecount=1\relax %
\global\lastoflinecount=2\relax %
\endafterbar{0}%
\else %
\global\lastoflinecount=0\relax %
\endafterbar{1}%
\fi %
%and that's it !!
\fi%
\firstsyllableofword=1 %
\global\notesaligncenter= 0 pt\relax % very important, see flat and natural
\relax%
}

%nextbegindifference is the begindifference of the next syllable
\newskip\nextbegindifference
\newskip\tempskip % couldn't we use another existing temp* ? maybe not

% macro to set \nextbegindifference
%% 1 : the first letters of the next syllable
%% 2 : the middle letters of the next syllable
%% 3 : the type of notes alignment
\def\setnextbegindifference#1#2#3{%
%to prevent the pollution of the normal values, we stock them into a temp value
\tempskip=\textaligncenter %
\findtextaligncenter{#1}{#2}%
\global\nextbegindifference=-\textaligncenter %
\global\textaligncenter=\tempskip %
\tempskip=\notesaligncenter %
\findnextnotesaligncenter{#3}% idem
\global\advance\nextbegindifference by \the\notesaligncenter %
\global\notesaligncenter=\tempskip %
\relax %
}

% macro to set \enddifference (defined above) to \wd\Syllablenotes - (\wd\Syllabletext - \textaligncenter) - \notesaligncenter
% \enddifference will be positive if text go further than the notes, and negative in the other case
% arguments are :
% #1: \wd\Syllablenotes : the total width of the notes
% #2: \wd\Syllabletext : the total width of the text
% #3: \textaligncenter (defined above)
% #4: \notesaligncenter (defined above too)
% #5: if we have to set previousenddifference or not
\def\setenddifference#1#2#3#4#5{%
\ifcase#5\or %
\global\previousenddifference=\the\enddifference %
\fi %
\global\enddifference=#1%
\global\advance\enddifference by -#2%
\global\advance\enddifference by #3%
\global\advance\enddifference by -#4%
\relax%
}

%% Finally we don't use it, because syllables never cross, I keep it, just in case...
% macro that will calculate the shift that we apply at the beginning, to combine two syllables of the same note
% arguments are :
% #1: \begindifferrence, defined above
% but the macro also uses \previousenddifference, \previousdash (not yet)
%\def\setsyllableshift#1{%
%\the\previousenddifference %
%\ifdim\previousenddifference >0pt %
%\hskip\intersyllablenotesspace %
%\ifdim-#1<\previousenddifference %
%\kern #1%
%test1 %
%\else%
%\kern -\previousenddifference %
%test2%
%\fi%
%\else%
% we test if begin > end - intersyllablespace
%\temp=\previousenddifference %
%\advance\temp by \intersyllablenotesspace %
%\ifdim#1 >\temp %
%\kern #1 %
%test3%
%\else%
%\kern\temp%
%test4%
%\fi%
%\fi%
%}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% macro for putting text above lines for annotations and the like
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% additional space for the text above lines
\def\abovelinestextstyle#1{\small\itshape #1}
\newdimen\abovelinestextraise % raises the text above the note line
\newdimen\abovelinestextwidth % used for kerning to ``reset'' spacing
\newbox\abovelinestextbox % box for the text above

% set space above the text lines - almost the same as for the translation
\def\addspaceabove{%
\global\abovelinestextraise=60000 sp%
\global\multiply\abovelinestextraise by \the\grefactor %
%\global\advance\spaceabovelines by \abovelinestextraise %
\generatelines %
\calculateconstantglyphraise %
\global\advance\abovelinestextraise by 4\stafflineheight
\global\advance\abovelinestextraise by 4\interstafflinespace
\relax %
}
% we don't need space above any more
\def\removespaceabove{%
\global\abovelinestextraise=0 sp%
\generatelines %
\calculateconstantglyphraise %
\relax %
}
% set the text above the line
\def\abovelinestext#1{%
\setbox\abovelinestextbox\hbox{\abovelinestextstyle{#1}}
\leavevmode\raise\abovelinestextraise\copy\abovelinestextbox%
\global\abovelinestextwidth=\wd\abovelinestextbox%
\kern-\abovelinestextwidth%
}

