diff options
author | Karl Berry <karl@freefriends.org> | 2016-04-16 21:22:41 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-04-16 21:22:41 +0000 |
commit | c9383c25c72dffde2894fd8a164d53269ce828a1 (patch) | |
tree | 0eb3ad41c8855ab9c21b0924ef23a2215b30f06e /Master/texmf-dist/tex/luatex/gregoriotex | |
parent | cb7776b7b205ed1ca821d824dd80f7e6c86dc92e (diff) |
gregoriotex (16apr16)
git-svn-id: svn://tug.org/texlive/trunk@40561 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/gregoriotex')
14 files changed, 10737 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregorio-vowels.dat b/Master/texmf-dist/tex/luatex/gregoriotex/gregorio-vowels.dat new file mode 100644 index 00000000000..f4b82d91715 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregorio-vowels.dat @@ -0,0 +1,108 @@ +# Vowel rule file for Gregorio +# Copyright (C) 2015 The Gregorio Project (see CONTRIBUTORS.md) +# +# This file is part of Gregorio. +# +# 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/>. + +# Comments begin with a hash symbol and end at the end of the line. These two +# lines are comments. + +# In general, Gregorio does no case folding, so upper- and lower-case +# characters and combinations thereof should be listed. + +# The "alias" keyword indicates that a name is an alias for a given language. +# The "alias" keyword must be followed by the name of the alias in square +# brackets, the "to" keyword, the name of the target language in square +# brackets, and a semicolon. For best performance, aliases should precede the +# language they are aliasing. +alias [english] to [English]; + +# The "language" keyword indicates that the rules which follow are for the +# specified language. It must be followed by the language name enclosed in +# square brackets and a semicolon. The language specified applies until the +# next language statement. +language [English]; + +# The "vowel" keyword indicates that the characters which follow, until the +# next semicolon, should be considered vowels. There may be multiple "vowel" +# statements, and the characters following all of them will be considered +# vowels. +vowel aàáâAÀÁÂ; +vowel eèéêëEÈÉÊË; +vowel iìíîIÌÍÎ; +vowel oòóôOÒÓÔ; +vowel uùúûUÙÚÛ; +vowel yỳýYỲÝ; +vowel æǽÆǼ; +vowel œŒ; + +# The "prefix" keyword lists strings of characters which end in a vowel, but +# when followed by a sequence of vowels, SHOULD NOT be considered part of the +# vowel sound. These strings follow the keyword and must be separated by space +# and end with a semicolon. There may be multiple "prefix" statements, and all +# will apply. Examples of prefixes include "i" and "u" in Latin and "qu" in +# English. +prefix qu Qu qU QU; +prefix gu Gu gU GU; +prefix y Y; + +# The "suffix" keyword lists strings of characters which don't start with a +# vowel, but when appearing after a sequence of vowels, SHOULD be considered +# part of the vowel sound. These strings follow the keyword and must be +# separated by space and end with a semicolon. There may be multiple "suffix" +# statements, and all will apply. Examples of suffixes include "w" and "we" in +# English and "y" in Spanish. +suffix w W; +suffix we We wE WE; + +# The "secondary" keyword lists strings of characters which do not contain +# vowels, but for which, when there are no vowels present in a syllable, define +# the center of the syllable. These strings follow the keyword and must be +# separated by space and end with a semicolon. Examples of secondary sequences +# include "w" from Welsh loanwords in English and the syllabic consonants "l" +# and "r" in Czech. +secondary w W; + +alias [polish] to [Polish]; +alias [Polish] to [Slavic]; +alias [czech] to [Czech]; +alias [Czech] to [Slavic]; +alias [slovak] to [Slovak]; +alias [Slovak] to [Slavic]; + +language [Slavic]; + +vowel aàáâąAÀÁÂĄ; +vowel eèéêëěęEÈÉÊËĚĘ; +vowel iìíîIÌÍÎ; +vowel oòóôOÒÓÔ; +vowel uùúûůUÙÚÛŮ; +vowel yỳýYỲÝ; +vowel æǽÆǼ; +vowel œŒ; + +secondary l L ĺ Ĺ; +secondary r R ŕ Ŕ; +secondary m M; + +alias [hungarian] to [Hungarian]; + +language [Hungarian]; + +vowel aáAÁ; +vowel éeëÉEË; +vowel iíIÍ; +vowel oóöőOÓÖŐ; +vowel uúüűUÚÜŰ; diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-chars.tex b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-chars.tex new file mode 100644 index 00000000000..25bbe59a204 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-chars.tex @@ -0,0 +1,201 @@ +%GregorioTeX file. +% +% Copyright (C) 2007-2015 The Gregorio Project (see CONTRIBUTORS.md) +% +% This file is part of Gregorio. +% +% Gregorio 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. +% +% Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +\gre@debugmsg{general}{Loading gregoriotex-chars.tex}% +\gre@declarefileversion{gregoriotex-chars.tex}{4.1.1}% GREGORIO_VERSION + +\def\gre@char@fuse@punctum@one{\GreFuseTwo{\GreCPLeadingPunctumOne}{\GreCPPunctum}}% +\def\gre@char@fuse@quilisma@one{\GreFuseTwo{\GreCPLeadingQuilismaOne}{\GreCPPunctum}}% +\def\gre@char@fuse@oriscus@one{\GreFuseTwo{\GreCPLeadingOriscusOne}{\GreCPPunctum}}% +\def\gre@char@fuse@punctum@two{\GreFuseTwo{\GreCPLeadingPunctumTwo}{\GreCPPunctum}}% +\def\gre@char@fuse@quilisma@two{\GreFuseTwo{\GreCPLeadingQuilismaTwo}{\GreCPPunctum}}% +\def\gre@char@fuse@oriscus@two{\GreFuseTwo{\GreCPLeadingOriscusTwo}{\GreCPPunctum}}% +\def\gre@char@fuse@debilis{\GreFuseTwo{\GreCPLeadingPunctumOneInitioDebilis}{\GreCPPunctum}}% + +% horizontal episema +\newbox\gre@box@hep% +\def\gre@def@char@he#1#2{% + \expandafter\def\csname gre@char@he@#1\endcsname##1{% + \ifx##1f\csname GreCPHEpisema#2\endcsname% + \else% + \setbox\gre@box@hep\hbox{\csname GreCPHEpisema#2\endcsname}% + \hbox to \wd\gre@box@hep{% + \ifx##1l\else\hfil\fi% + \csname GreCPHEpisema#2Reduced\endcsname% + \ifx##1r\else\hfil\fi% + }% + \fi% + }% +}% +\def\gre@def@char@he@porr#1#2{% + \expandafter\def\csname gre@char@he@#1\endcsname##1##2{% + \ifcase##1\gre@char@he@punctum{##2}% + \or\csname GreCPHEpisema#2One\endcsname% + \or\csname GreCPHEpisema#2Two\endcsname% + \or\csname GreCPHEpisema#2Three\endcsname% + \or\csname GreCPHEpisema#2Four\endcsname% + \or\csname GreCPHEpisema#2Five\endcsname% + \fi% + }% +}% +\gre@def@char@he{punctum}{Punctum}% +\gre@def@char@he{punctum@line@br}{PunctumLineBR}% +\gre@def@char@he{punctum@line@tr}{PunctumLineTR}% +\gre@def@char@he{punctum@line@tl}{PunctumLineTL}% +\gre@def@char@he{punctum@line@bl}{PunctumLineBL}% +\gre@def@char@he{punctum@line@blbr}{PunctumLineBLBR}% +\gre@def@char@he{punctumauctus@line@bl}{PunctumAuctusLineBL}% +\gre@def@char@he{salicus@oriscus}{SalicusOriscus}% +\gre@def@char@he{flexus}{FlexusDeminutus}% +\gre@def@char@he{initio}{Debilis}% +\gre@def@char@he{virga}{Virga}% +\gre@def@char@he{virgabase@line@bl}{VirgaBaseLineBL}% +\gre@def@char@he{inclinatum}{Inclinatum}% +\gre@def@char@he{inclinatumdem}{InclinatumDeminutus}% +\gre@def@char@he{stropha}{Stropha}% +\gre@def@char@he@porr{porrectus}{Porrectus}% +\gre@def@char@he@porr{porrectus@amone}{PorrectusAmOne}% +\gre@def@char@he@porr{porrectusfl}{PorrectusFlexus}% +\gre@def@char@he{quilisma}{Quilisma}% +\gre@def@char@he{quilisma@line@tr}{QuilismaLineTR}% +\gre@def@char@he{oriscus}{Oriscus}% +\gre@def@char@he{oriscus@line@tr}{OriscusLineTR}% +\gre@def@char@he{smallpunctum}{HighPes}% "smallpunctum" is the top punctum in a pes +\gre@def@char@he{flat}{Flat}% +\gre@def@char@he{sharp}{Sharp}% +\gre@def@char@he{natural}{Natural}% + +\def\gre@fontchar@flat{\gre@font@music\GreCPFlat}% +\def\gre@fontchar@flathole{\gre@font@music\GreCPFlatHole}% +\def\gre@fontchar@natural{\gre@font@music\GreCPNatural}% +\def\gre@fontchar@naturalhole{\gre@font@music\GreCPNaturalHole}% +\def\gre@fontchar@sharp{\gre@font@music\GreCPSharp}% +\def\gre@fontchar@sharphole{\gre@font@music\GreCPSharpHole}% +\def\gre@fontchar@cclef{\gre@font@music\GreCPCClef}% +\def\gre@fontchar@fclef{\gre@font@music\GreCPFClef}% +\def\gre@fontchar@incclef{\gre@font@music\GreCPCClefChange}% +\def\gre@fontchar@infclef{\gre@font@music\GreCPFClefChange}% +\def\gre@fontchar@punctummora{\gre@font@music\GreCPAuctumMora}% +\def\gre@fontchar@verticalepisema{\gre@font@music\GreCPVEpisema}% +\def\gre@fontchar@custostoplong{\gre@font@music\GreCPCustosUpLong}% +\def\gre@fontchar@custostopshort{\gre@font@music\GreCPCustosUpShort}% +\def\gre@fontchar@custostopmiddle{\gre@font@music\GreCPCustosUpMedium}% +\def\gre@fontchar@custosbottomlong{\gre@font@music\GreCPCustosDownLong}% +\def\gre@fontchar@custosbottomshort{\gre@font@music\GreCPCustosDownShort}% +\def\gre@fontchar@custosbottommiddle{\gre@font@music\GreCPCustosDownMedium}% +\def\gre@fontchar@abovebarbrace{\gre@font@music\GreCPBarBrace}% +\def\gre@fontchar@punctum{\gre@font@music\GreCPPunctum}% + +%%%%%%%%%%%%%%%%% +% macros for the different styles% +%%%%%%%%%%%%%%%%% + +\def\gresetglyphstyle#1{% + \IfStrEqCase{#1}{% + {default}% + {% + \greresetglyph{Flat}% + \greresetglyph{FlatHole}% + \greresetglyph{Natural}% + \greresetglyph{NaturalHole}% + \greresetglyph{Sharp}% + \greresetglyph{SharpHole}% + \greresetglyph{CClef}% + \greresetglyph{FClef}% + \greresetglyph{CClefChange}% + \greresetglyph{FClefChange}% + \greresetglyph{AuctumMora}% + \greresetglyph{VEpisema}% + \greresetglyph{CustosUpLong}% + \greresetglyph{CustosUpShort}% + \greresetglyph{CustosUpMedium}% + \greresetglyph{CustosDownLong}% + \greresetglyph{CustosDownShort}% + \greresetglyph{CustosDownMedium}% + \greresetglyph{BarBrace}% + \greresetglyph{Punctum}% + \relax % + }% + {medicaea}% + {% + \gresetglyphstyle{default}\gre@usestylecommon % + \grechangeglyph{CustosUpLong}{greextra}{MedicaeaCustosUpLong}% + \grechangeglyph{CustosUpShort}{greextra}{MedicaeaCustosUpShort}% + \grechangeglyph{CustosUpMedium}{greextra}{MedicaeaCustosUpMedium}% + \grechangeglyph{CustosDownLong}{greextra}{MedicaeaCustosDownLong}% + \grechangeglyph{CustosDownShort}{greextra}{MedicaeaCustosDownShort}% + \grechangeglyph{CustosDownMedium}{greextra}{MedicaeaCustosDownMedium}% + \grechangeglyph{CClef}{greextra}{MedicaeaCClef}% + \grechangeglyph{FClef}{greextra}{MedicaeaFClef}% + \grechangeglyph{CClefChange}{greextra}{MedicaeaCClefChange}% + \grechangeglyph{FClefChange}{greextra}{MedicaeaFClefChange}% + \grechangeglyph{Flat}{greextra}{MedicaeaFlat}% + \grechangeglyph{FlatHole}{greextra}{MedicaeaFlatHole}% + \relax % + }% + {hufnagel}% + {% + \gresetglyphstyle{default}\gre@usestylecommon % + \grechangeglyph{CustosUpLong}{greextra}{HufnagelCustosUpLong}% + \grechangeglyph{CustosUpShort}{greextra}{HufnagelCustosUpShort}% + \grechangeglyph{CustosUpMedium}{greextra}{HufnagelCustosUpMedium}% + \grechangeglyph{CustosDownLong}{greextra}{HufnagelCustosDownLong}% + \grechangeglyph{CustosDownShort}{greextra}{HufnagelCustosDownShort}% + \grechangeglyph{CustosDownMedium}{greextra}{HufnagelCustosDownMedium}% + \grechangeglyph{CClef}{greextra}{HufnagelCClef}% + \grechangeglyph{FClef}{greextra}{HufnagelFClef}% + \grechangeglyph{CClefChange}{greextra}{HufnagelCClefChange}% + \grechangeglyph{FClefChange}{greextra}{HufnagelFClefChange}% + \grechangeglyph{Flat}{greextra}{HufnagelFlat}% + \grechangeglyph{FlatHole}{greextra}{HufnagelFlatHole}% + \relax % + }% + {mensural}% + {% + \gresetglyphstyle{default}\gre@usestylecommon % + \grechangeglyph{CustosUpLong}{greextra}{MensuralCustosUpLong}% + \grechangeglyph{CustosUpShort}{greextra}{MensuralCustosUpShort}% + \grechangeglyph{CustosUpMedium}{greextra}{MensuralCustosUpMedium}% + \grechangeglyph{CustosDownLong}{greextra}{MensuralCustosDownLong}% + \grechangeglyph{CustosDownShort}{greextra}{MensuralCustosDownShort}% + \grechangeglyph{CustosDownMedium}{greextra}{MensuralCustosDownMedium}% + \grechangeglyph{Flat}{greextra}{MensuralFlat}% + \grechangeglyph{FlatHole}{greextra}{MensuralFlatHole}% + \relax % + }% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetglyphstyle\MessageBreak Possible options are: 'default', 'medicaea', 'hufnagel' and 'mensural'}% + ]% +}% + +\def\greusedefaultstyle{%OBSOLETE + \gre@obsolete{\protect\greusedefaultstyle}{\protect\gresetglyphstyle{default}}% +}% + +\def\greusemedicaeastyle{%OBSOLETE + \gre@obsolete{\protect\greusemedicaeastyle}{\protect\gresetglyphstyle{medicaea}}% +}% + +\def\greusehufnagelstyle{%OBSOLETE + \gre@obsolete{\protect\greusehufnagelstyle}{\protect\gresetglyphstyle{hufnagel}}% +}% + +\def\greusemensuralstyle{%OBSOLETE + \gre@obsolete{\protect\greusemensuralstyle}{\protect\gresetglyphstyle{mensural}}% +}% diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-main.tex b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-main.tex new file mode 100644 index 00000000000..3344a56edcf --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-main.tex @@ -0,0 +1,2030 @@ +%GregorioTeX main file. +% +% Copyright (C) 2007-2015 The Gregorio Project (see CONTRIBUTORS.md) +% +% This file is part of Gregorio. +% +% Gregorio 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. +% +% Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +% this file contains definitions for lines, initial, fonts, etc. + +\ifluatex% + \ifnum\luatexversion<76% + \gre@error{Error: this document must be compiled with LuaTeX (lualatex) 0.76 or later}% + \fi% +\else% + \gre@error{Error: this document must be compiled with LuaTeX (lualatex)}% +\fi% + +\def\gre@debugmsg#1#2{% + \IfStrEq{\gre@debug}{}{}% + %false + {\IfStrEq{#1}{all}% + %true + {\gre@error{Debug error: ‘all’ is not a permitted keyword}}% + %false + {\IfStrEq{\gre@debug}{all}% + %true + {\gre@typeout{GregorioTeX debug: (#1) #2}}% + %false + {\IfSubStr{\gre@debug}{#1}% + %true + {\gre@typeout{GregorioTeX debug: (#1) #2}}% + %false + {\relax}% + }% + }% + }% +}% + +\gre@debugmsg{general}{Loading gregoriotex-main.tex}% + +% Macro to handle deprecated macros. +% #1 - the deprecated macro +% #2 - the correct macro to use +\def\gre@deprecated#1#2{% + \ifgre@allowdeprecated% + \gre@warning{#1\space is deprecated.\MessageBreak Use #2\space instead}% + \else% + \gre@error{#1\space is deprecated.\MessageBreak Use #2\space instead}% + \fi% + \relax% +}% + +\def\gre@obsolete#1#2{% + \gre@error{#1\space is obsolete.\MessageBreak Use #2\space instead}% + \relax% +}% + + +\def\gre@nothing{} + +\AtBeginDocument{\IfStrEq{\gre@debug}{}{}{\directlua{gregoriotex.set_debug_string([[\gre@debug]])}\typeout{GregorioTeX is in debug mode}\typeout{\gre@debug\space messages will be printed to the log.}}}% + +% Depending on version of TeX / LaTeX, some primitives may or may not have a +% luatex prefix, so we need to check and handle either + +\ifdefined\localleftbox% + \let\gre@localleftbox\localleftbox% +\else% + \let\gre@localleftbox\luatexlocalleftbox% +\fi% +\ifdefined\localrightbox% + \let\gre@localrightbox\localrightbox% +\else% + \let\gre@localrightbox\luatexlocalrightbox% +\fi% +% 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... +\newluatexattribute\gre@attr@dash% + +% an attribute used for translation centering +\newluatexattribute\gre@attr@center% + +\newluatexattribute\GreScoreId % + +% attributes for tracking glyph heights +\newluatexattribute\gre@attr@glyph@id % +\newluatexattribute\gre@attr@glyph@top % +\newluatexattribute\gre@attr@glyph@bottom % + +\newluatexcatcodetable\gre@atletter % +\setluatexcatcodetable\gre@atletter{% + \catcode`\@=11 % +}% + +% The version of gregorio. All gregoriotex*.tex files must have the same. +% All gtex files must also have the same version. +\xdef\gre@gregorioversion{4.1.1}% GREGORIO_VERSION - VersionManager.py + +% first some macros to allow checks for version: +% Tests that all gregoriotex files are of the same version. +% #1 is the name of the file +% #2 is the version + +\def\gre@declarefileversion#1#2{% + \IfStrEq*{#2}{\gre@gregorioversion}{}{%else + \gre@error{uncoherent file versions: gregoriotex-main.tex is in version \number\gre@gregorioversion \space\space while #1 is in version \number#2}}% +}% + +% Macro called by scores. +% Tests the major version of gregorio (X.0.0) against the score. Fails +% if the major version (X) does not match. +% #1 is the version of GregorioTeX the score is made for. + +\def\GregorioTeXAPIVersion#1{% + \StrBefore{\gre@gregorioversion}{.}[\gre@gregoriomajorversion]% + \IfBeginWith{#1}{\gre@gregoriomajorversion}{\relax}{%else + \gre@error{GregorioTeX is in version \gre@gregorioversion \space\space while a score you included requires version #1. Please recompile your scores}}% +}% + +\RequireLuaModule{gregoriotex}% +\ifcsname greskipheightcomputation\endcsname % + \directlua{gregoriotex.init(arg, false)}% +\else % + \directlua{gregoriotex.init(arg, true)}% +\fi % + +\xdef\gre@gregoriotexluaversion{\directlua{tex.write(gregoriotex.get_gregorioversion())}}% + +% Test to make sure that gregoriotex.lua is of the same version. +\IfStrEq*{\gre@gregoriotexluaversion}{\gre@gregorioversion}{}{%else + \gre@error{uncoherent file versions: gregoriotex-main.tex is in version \number\gre@gregorioversion \space\space while gregoriotex.lua is in version \gre@gregoriotexluaversion}}% + + +%%%%%%%%%%%%%%%%%%%%%%%% +%% aux file definitions +%%%%%%%%%%%%%%%%%%%%%%%% + +% for now, we only use an aux file with LuaTeX + +\ifluatex% + \newwrite\gre@gaux% +\fi% + +\def\gre@write@gaux#1{% + \write\gre@gaux{#1}% + \relax % +}% + +\def\gre@open@gaux{% + \openout\gre@gaux \jobname .gaux\relax% +}% + +\def\gre@close@gaux{% + \closeout\gre@gaux % +}% + + +%%%%%%%%%%%%%%% +%% basic start +%%%%%%%%%%%%%%% + +\def\gre@pitch@a{3}% +\def\gre@pitch@b{4}% +\def\gre@pitch@c{5}% +\def\gre@pitch@d{6}% +\def\gre@pitch@e{7}% +\def\gre@pitch@f{8}% +\def\gre@pitch@g{9}% +\def\gre@pitch@h{10}% +\def\gre@pitch@i{11}% +\def\gre@pitch@j{12}% +\def\gre@pitch@k{13}% +\def\gre@pitch@l{14}% +\def\gre@pitch@m{15}% +\def\gre@pitch@n{16}% +\def\gre@pitch@p{17}% + +\let\gre@pitch@adjust@bottom\gre@pitch@c % +\let\gre@pitch@belowstaff\gre@pitch@c % +\let\gre@pitch@ledger@below\gre@pitch@b % +\let\gre@pitch@barvepisema\gre@pitch@c % +\let\gre@pitch@underbrace\gre@pitch@b % +\let\gre@pitch@overbraceglyph\gre@pitch@g % +\let\gre@pitch@bar\gre@pitch@g % +\let\gre@pitch@dummy\gre@pitch@g % + +% factor is the factor with which you open you font (the number after the at). It will decide almost everything (spaces, etc.), so it is particularly important. +% it is set to the default value : 17 (the value that makes it look like a standard graduale) +\newcount\gre@factor% +\gre@factor=17% + +%%%%%%%%%%%%%%%%%%% +%% vertical spaces +%%%%%%%%%%%%%%%%%%% + +\input gregoriotex-spaces.tex% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for additionnal vertical spaces +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% macro called to go to the next line +\def\GreNewLine{% + \gre@debugmsg{lineheight}{GreNewLine}% + \gre@newlinecommon{0}{0}% + \relax% +}% + +% basically same as above, but this one does a \hfill, so the lines are not justified +\def\GreNewParLine{% + \gre@debugmsg{lineheight}{GreNewParLine}% + \gre@newlinecommon{1}{0}% + \relax% +}% + +% the macro we call each time we force a changing of line, it automatically sets \gre@knownline, and adjusts left spaces +% #1 is 0 in case of gabc z, 1 for Z +% #2 is 0 in the normal case, 1 after a bar in the new spacing algorithm +\def\gre@newlinecommon#1#2{% + \ifgre@blockeolcustos\ifnum\gre@insidediscretionary=0\relax % + \gre@localrightbox{}% + \fi\fi % + \ifgre@boxing\else% + \ifnum\gre@biginitial=1\relax % + \ifcase\gre@knownline % + % 0: should not happend... + \or % 1 + \gre@adjustsecondline % + \or %2 + \gre@adjustthirdline % + \fi % + \fi % + \global\advance\gre@knownline by 1\relax % + \global\gre@lastoflinecount=2\relax % + \ifnum#2=0\relax % + % we have to repeat the end of syllable shifts here because the manual line breaks will occur before we get to the regular shifting code in \GreSyllable + \ifdim\gre@dimen@enddifference <0pt\relax% + %% important, else we are not really at the end of the syllable + \kern -\gre@dimen@enddifference\relax% + \fi% + \ifgre@eolshiftsenabled% + \GreNoBreak% we want to make sure this shift doesn't get separated from the previous one if both occur + \gre@calculate@eolshift{\gre@dimen@enddifference}% + \gre@debugmsg{eolshift}{Manual end of line shift: \the\gre@dimen@eolshift}% + \kern -\gre@dimen@eolshift\relax% + \fi% + \fi % + \ifnum\gre@insidediscretionary=0\relax % + \gre@updateleftbox % + \fi % + \ifnum#1=1\relax % + \GreNoBreak % + \hfill % + \fi % + \gre@penalty{-10001}% + \fi % + \gre@adjustlineifnecessary\relax % + \gre@reseteolcustos\relax % +}% + +\def\gre@mark@translation{\directlua{gregoriotex.mark_translation()}}% +\def\gre@mark@abovelinestext{\directlua{gregoriotex.mark_abovelinestext()}}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of text +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% macro that sets \gre@dimen@temp@three to the width of its argument + +\newbox\gre@box@temp@width% + +\def\gre@widthof#1{% + \setbox\gre@box@temp@width=\hbox{#1}% + \global\gre@dimen@temp@three=\wd\gre@box@temp@width% + \relax% +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of the initial +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% box containing the initial, and dimen containing its width (and the width of the space after) +\newbox\gre@box@initial% + + +% gre@biginitial means that the inital takes two lines +\newcount\gre@biginitial% + +% gre@knownline is the line we think we are in +\newcount\gre@knownline% + +% macro to call before the call of \initial +\def\gre@setbiginitial{% + \gre@debugmsg{general}{setting BIG initial}% + \global\gre@biginitial=1\relax % + \relax % +}% + +% macro to cancel before the call of \initial +\def\gre@normalinitial{% + \gre@debugmsg{general}{setting normal initial}% + \global\gre@biginitial=0\relax % + \relax % +}% + +% macro to call before the first syllable, but after setinitialclef +\def\gre@adjustsecondline{% + \gre@dimen@additionalleftspace=\gre@dimen@initialwidth\relax% + \gre@updateleftbox % + \relax % +}% + +% macro to call during the second line +\def\gre@adjustthirdline{% + \gre@dimen@additionalleftspace= 0 pt\relax% + \gre@updateleftbox % + \relax % +}% + +\newif\ifgre@thirdlineadjustmentnecessary % +\def\gre@adjustlineifnecessary{% + \ifgre@thirdlineadjustmentnecessary % + \gre@adjustthirdline % + \gre@thirdlineadjustmentnecessaryfalse % + \fi % +}% + +\def\gre@updateleftbox{% + \gre@updatelinewidth % + \gre@updatelinesclef % +}% + +\def\gre@updatelinewidth{% + \gre@debugmsg{ifdim}{ additionalleftspace = 0pt}% + \ifdim\gre@dimen@additionalleftspace=0pt\relax% + \else % + \gre@dimen@temp@five=\gre@dimen@stafflinewidth\relax% + \global\advance\gre@dimen@stafflinewidth by -\gre@dimen@additionalleftspace\relax% + \gre@generatelines % + \global\gre@dimen@stafflinewidth=\gre@dimen@temp@five % + \fi % +}% + +\def\greillumination#1{% + \setbox\gre@box@initial=\hbox{#1}% +}% + +\def\gre@setinitial#1{% + % see comments on this function to see what it does + \gre@debugmsg{commentary}{Time to calculate the true raise.}% + \gre@calculate@commentarytrueraise% + % we start by printing the commentary + % when doing this we place it inside a box as which is linewidth wide with an \hfill before to get it to align to the right of the page + % we then place that box inside one of 0 width so that our cursor doesn't move when we place the commentary + \ifvoid\gre@box@commentary\else% + \gre@debugmsg{commentary}{I am printing a commentary box}% + \raise\gre@dimen@commentarytrueraise\hbox to 0pt{\hbox to \gre@dimen@linewidth{\hfill\box\gre@box@commentary}}% + \fi% + \gre@debugmsg{annotation}{Time to calculate the true raise.}% + \gre@calculate@annotationtrueraise % + % we print the initial always at the same place, and then we print the gre@box@annotation, centered + % first we print the initial + \gre@dimen@temp@five = \dimexpr(\gre@dimen@textlower+\gre@space@dimen@initialraise)\relax% + % if it is a big initial we print it on the second line + \ifnum\gre@biginitial=0\relax % + \ifvoid\gre@box@initial% + \gre@debugmsg{initial}{Fill initial box a}% + \setbox\gre@box@initial=\hbox{\gre@style@initial\gre@fixedtextformat{#1}\endgre@style@initial}% + \fi% + \ifx\gre@empty@initialformat\greinitialformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\greinitialformat}{\protect\grechangestyle{initial}}% OBSOLETE + \fi% OBSOLETE + \gre@debugmsg{ifdim}{ manualinitialwidth = 0pt}% + \ifdim\gre@space@dimen@manualinitialwidth=0 pt\relax% + \global\gre@dimen@initialwidth=\wd\gre@box@initial % + \else% + \gre@style@initial% + \global\gre@dimen@initialwidth=\gre@space@dimen@manualinitialwidth\relax% + \endgre@style@initial% + \ifx\gre@empty@initialformat\greinitialformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\greinitialformat}{\protect\grechangestyle{initial}}% OBSOLETE + \fi% OBSOLETE + \fi% + \gre@debugmsg{ifdim}{ wd(gre@box@annotation) > initialwidth}% + \ifdim\wd\gre@box@annotation>\gre@dimen@initialwidth\relax% + \global\gre@dimen@initialwidth=\wd\gre@box@annotation% + \fi% + \gre@debugmsg{annotation}{Width check completed.}% + \setbox\gre@box@initial=\hbox to \gre@dimen@initialwidth {\hss\raise \gre@dimen@temp@five\box\gre@box@initial\hss}% + \gre@debugmsg{annotation}{Initial set.}% + \gre@style@initial% + \global\gre@dimen@temp@four = \gre@space@dimen@beforeinitialshift\relax% + \endgre@style@initial% + \ifx\gre@empty@initialformat\greinitialformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\greinitialformat}{\protect\grechangestyle{initial}}% OBSOLETE + \fi% OBSOLETE + \else % + \ifgre@allowdeprecated%%% DEPRECATED for removal in 5.0 + \gre@warning{biginitial style is deprecated, but the old\MessageBreak behavior will be used since deprecated usage is\MessageBreak currently enabled. This behavior will disappear\MessageBreak in 5.0, so consider disabling deprecated usage\MessageBreak and switching to the initial style instead. (See\MessageBreak UPGRADE.md for more information)}%%% DEPRECATED for removal in 5.0 + \fi%%% DEPRECATED for removal in 5.0 + \advance\gre@dimen@temp@five by \dimexpr(-\gre@dimen@additionalbottomspace % + - \gre@space@dimen@spacebeneathtext % + - \gre@space@dimen@spacelinestext % + - 4\gre@dimen@interstafflinespace % + - 4\gre@dimen@stafflineheight % + - \gre@dimen@currenttranslationheight % + - \f@size pt % + + \gre@space@dimen@initialraise)\relax% + \ifvoid\gre@box@initial% + \gre@debugmsg{initial}{fill big initial box}% + \ifgre@allowdeprecated%%% DEPRECATED for removal in 5.0 + \setbox\gre@box@initial=\hbox{\gre@style@biginitial\gre@fixedtextformat{#1}\endgre@style@biginitial}% DEPRECATED for removal in 5.0 + \else%%% DEPRECATED for removal in 5.0 + \setbox\gre@box@initial=\hbox{\gre@style@initial\gre@fixedtextformat{#1}\endgre@style@initial}% keep this line + \fi%%% DEPRECATED for removal in 5.0 + \fi% + \ifx\gre@empty@biginitialformat\grebiginitialformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\grebiginitialformat}{\protect\grechangestyle{biginitial}}% OBSOLETE + \fi% OBSOLETE + \gre@debugmsg{ifdim}{ manualinitialwidth = 0pt}% + \ifdim\gre@space@dimen@manualinitialwidth=0 pt\relax% + \global\gre@dimen@initialwidth=\wd\gre@box@initial % + \else% + \ifgre@allowdeprecated%%% DEPRECATED for removal in 5.0 + \gre@style@biginitial%%% DEPRECATED for removal in 5.0 + \global\gre@dimen@initialwidth=\gre@space@dimen@manualinitialwidth\relax%%% DEPRECATED for removal in 5.0 + \endgre@style@biginitial%%% DEPRECATED for removal in 5.0 + \else%%% DEPRECATED for removal in 5.0 + \gre@style@initial% keep this line + \global\gre@dimen@initialwidth=\gre@space@dimen@manualinitialwidth\relax% keep this line + \endgre@style@initial% keep this line + \fi%%% DEPRECATED for removal in 5.0 + \ifx\gre@empty@biginitialformat\grebiginitialformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\grebiginitialformat}{\protect\grechangestyle{biginitial}}% OBSOLETE + \fi% OBSOLETE + \fi% + \gre@debugmsg{ifdim}{ wd(GreAboveinitialfirstbox) > initialwidth}% + \ifdim\wd\gre@box@annotation>\gre@dimen@initialwidth\relax% + \global\gre@dimen@initialwidth=\wd\gre@box@annotation% + \fi% + \setbox\gre@box@initial=\hbox{\vtop to 0pt{\hbox to \gre@dimen@initialwidth {\hss\raise \gre@dimen@temp@five\box\gre@box@initial\hss}\vss}}% + \ifgre@allowdeprecated%%% DEPRECATED for removal in 5.0 + \gre@style@biginitial%%% DEPRECATED for removal in 5.0 + \global\gre@dimen@temp@four = \gre@space@dimen@beforeinitialshift\relax%%% DEPRECATED for removal in 5.0 + \endgre@style@biginitial%%% DEPRECATED for removal in 5.0 + \else%%% DEPRECATED for removal in 5.0 + \gre@style@initial% keep this line + \global\gre@dimen@temp@four = \gre@space@dimen@beforeinitialshift\relax% keep this line + \endgre@style@initial% keep this line + \fi%%% DEPRECATED for removal in 5.0 + \ifx\gre@empty@biginitialformat\grebiginitialformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\grebiginitialformat}{\protect\grechangestyle{biginitial}}% OBSOLETE + \fi% OBSOLETE + \fi % + \hskip\gre@dimen@temp@four % + \global\advance\gre@dimen@initialwidth by \gre@dimen@temp@four % + \gre@debugmsg{annotation}{Ready to place initial.}% + \box\gre@box@initial% + \ifnum\gre@biginitial=0\relax% + \gre@style@initial% + \global\gre@dimen@temp@four = \gre@space@dimen@afterinitialshift\relax% + \endgre@style@initial% + \ifx\gre@empty@initialformat\greinitialformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\greinitialformat}{\protect\grechangestyle{initial}}% OBSOLETE + \fi% OBSOLETE + \else% + \ifgre@allowdeprecated%%% DEPRECATED for removal in 5.0 + \gre@style@biginitial%%% DEPRECATED for removal in 5.0 + \global\gre@dimen@temp@four = \gre@space@dimen@afterinitialshift\relax%%% DEPRECATED for removal in 5.0 + \endgre@style@biginitial%%% DEPRECATED for removal in 5.0 + \else%%% DEPRECATED for removal in 5.0 + \gre@style@initial% keep this line + \global\gre@dimen@temp@four = \gre@space@dimen@afterinitialshift\relax% keep this line + \endgre@style@initial% keep this line + \fi%%% DEPRECATED for removal in 5.0 + \ifx\gre@empty@biginitialformat\grebiginitialformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\grebiginitialformat}{\protect\grechangestyle{biginitial}}% OBSOLETE + \fi% OBSOLETE + \fi% + \hskip\gre@dimen@temp@four % + \global\advance\gre@dimen@initialwidth by \gre@dimen@temp@four% + % then we center the annotation box above the initial, if there is one + \gre@debugmsg{annotation}{Time to set the annotation.}% + \ifvoid\gre@box@annotation\relax% + \gre@debugmsg{annotation}{There is no annotation.}% + \else % + \gre@debugmsg{annotation}{Calculate horizontal position.}% + \gre@dimen@temp@five=\dimexpr((\gre@dimen@initialwidth - \wd\gre@box@annotation) / 2)\relax % + \gre@skip@temp@four = -\gre@dimen@initialwidth\relax% + \hskip\gre@skip@temp@four % + \kern\gre@dimen@temp@five % + \gre@debugmsg{annotation}{And place the annotation.}% + \raise\gre@dimen@annotationtrueraise\box\gre@box@annotation% + \gre@debugmsg{annotation}{Move to beginning of staff.}% + \kern\gre@dimen@temp@five % + \fi % + \relax % +}% + +\def\gre@noinitial{% + \setbox\gre@box@initial=\box\voidb@x% + \global\gre@dimen@initialwidth=0pt\relax% + \relax % +}% + + + +\newbox\gre@box@annotation% +\newbox\gre@box@add% +\newbox\gre@box@old% + +\def\greannotation{\@ifnextchar[{\gre@annotation}{\gre@annotation[c]}}% + +%This flag controls whether the annotation control line is the top line (false) or the bottom line (true) +\newif\ifgre@annotationbottomline% +\gre@annotationbottomlinefalse% + +\def\gresetannotationby#1{% + \IfStrEqCase{#1}{% + {topline}% + {\gre@annotationbottomlinefalse}% + {bottomline}% + {\gre@annotationbottomlinetrue}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetannotationby\MessageBreak Possible options are: 'topline' and 'bottomline'}% + ]% +}% + +% This flag controls whether the top (0), baseline (1), or bottom (2) of the control line is aligned with the top line of the staff before applying annotationraise. +\newcount\gre@count@annotationvalign% +\gre@count@annotationvalign=1% + +\def\gresetannotationvalign#1{% + \IfStrEqCase{#1}{% + {top}% + {\gre@count@annotationvalign=0}% + {baseline}% + {\gre@count@annotationvalign=1}% + {bottom}% + {\gre@count@annotationvalign=2}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetannotationvalign\MessageBreak Possible options are: 'top', 'baseline' and 'bottom'}% + ]% +}% + +\def\gre@annotation[#1]#2{% + \ifx l#1\relax% + \let\gre@rightfill\hfil% + \let\gre@leftfill\relax% + \else\ifx r#1\relax% + \let\gre@rightfill\relax% + \let\gre@leftfill\hfil% + \else\ifx c#1\relax% + \let\gre@rightfill\hfil% + \let\gre@leftfill\hfil% + \else% + \gre@error{Unrecognzied alignment option for \protect\greannotation}% + \fi\fi\fi% + % first we determine the widest box + \gre@widthof{\gre@style@annotation#2\endgre@style@annotation}% + \ifdim\gre@dimen@temp@three < \wd\gre@box@annotation\relax% + \gre@dimen@temp@three = \wd\gre@box@annotation\relax% + \fi% + \ifvoid\gre@box@annotation% + \gre@debugmsg{annotation}{We're on the first line of the annotation.}% + \setbox\gre@box@annotation = \hbox to \gre@dimen@temp@three{\gre@leftfill\gre@style@annotation#2\endgre@style@annotation\gre@rightfill}% + % We set the initial value for annotationtrueraise based on the annotationvalign setting. We always do this because if there is only one line in the annotation, then the topline is the bottomline. + \gre@debugmsg{annnotation}{Initial set point.}% + \ifcase\gre@count@annotationvalign\relax% + %case 0 = top of first line + \global\gre@dimen@annotationtrueraise=-\ht\gre@box@annotation\relax% + \gre@debugmsg{annotation}{Aligning to top of first line: \the\gre@dimen@annotationtrueraise}% + \or %case 1 = baseline of first line + \global\gre@dimen@annotationtrueraise= 0pt\relax% + \gre@debugmsg{annotation}{Aligning to baseline of first line: \the\gre@dimen@annotationtrueraise}% + \or %case 2 = bottom of first line + \global\gre@dimen@annotationtrueraise=\dp\gre@box@annotation\relax% + \gre@debugmsg{annotation}{Aligning to bottom of first line: \the\gre@dimen@annotationtrueraise}% + \else% Bug + \gre@bug{Invalid value for \protect\gre@count@annotationvalign}% + \fi% + \else% + \gre@debugmsg{annotation}{We're not on the first line of the annotation.}% + \setbox\gre@box@old = \hbox to \gre@dimen@temp@three{\gre@leftfill\box\gre@box@annotation\gre@rightfill}% + \setbox\gre@box@add = \hbox to \gre@dimen@temp@three{\gre@leftfill\gre@style@annotation#2\endgre@style@annotation\gre@rightfill}% + % if the user has asked for the bottom line to be the controlling line, then we need to change the value of the annotationtrueraise appropriately + \gre@style@annotation% to make sure that an annotationseparation in font relative units translates correctly + \ifgre@annotationbottomline% + \ifcase\gre@count@annotationvalign\relax% + %case 0 = top of first line + \global\gre@dimen@annotationtrueraise=\dimexpr\ht\gre@box@old+\dp\gre@box@old+\gre@space@dimen@annotationseparation-\ht\gre@box@add\relax% + \gre@debugmsg{annotation}{Aligning to top of last line: \the\gre@dimen@annotationtrueraise}% + \or %case 1 = baseline of first line + \global\gre@dimen@annotationtrueraise=\dimexpr\ht\gre@box@old+\dp\gre@box@old+\gre@space@dimen@annotationseparation\relax% + \gre@debugmsg{annotation}{Aligning to baseline of last line: \the\gre@dimen@annotationtrueraise}% + \or %case 2 = bottom of first line + \global\gre@dimen@annotationtrueraise=\dimexpr\ht\gre@box@old+\dp\gre@box@old+\gre@space@dimen@annotationseparation+\dp\gre@box@add\relax% + \gre@debugmsg{annotation}{Aligning to bottom of last line: \the\gre@dimen@annotationtrueraise}% + \else% Bug + \gre@bug{Invalid value for \protect\gre@count@annotationvalign}% + \fi% + \fi% + \endgre@style@annotation% + \setbox\gre@box@annotation = \vtop spread \gre@space@dimen@annotationseparation\relax {\offinterlineskip\box\gre@box@old\vss\box\gre@box@add}% + \fi% +}% + + +\def\gresetfirstlineaboveinitial#1#2{%OBSOLETE + \gre@obsolete{\protect\gresetfirstlineaboveinitial}{\protect\greannotation}% +}% + +\def\gresetfirstannotation#1{%OBSOLETE + \gre@obsolete{\protect\gresetfirstannotation}{\protect\greannotation}% +}% + +\let\setfirstannotation\gresetfirstannotation%OBSOLETE + +\def\gresetsecondannotation#1{%OBSOLETE + \gre@obsolete{\protect\gresetsecondannotation}{\protect\greannotation}% +}% + +\let\setsecondannotation\gresetsecondannotation%OBSOLETE + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the score reference (unused) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\grescorereference#1{% DEPRECATED by 4.1 + \ifgre@allowdeprecated% + \gre@warning{\protect\grescorereference\space is deprecated.\MessageBreak It does nothing; stop using it.}% + \else% + \gre@error{\protect\grescorereference\space is deprecated.\MessageBreak It does nothing; stop using it.}% + \fi% + \relax % +}% + +\def\GreScoreReference#1{%OBSOLETE + \gre@error{\protect\GreScoreReference\space is obsolete.\MessageBreak It does nothing; stop using it.}% + \relax% +}% + +\def\scorereference#1{%OBSOLETE + \gre@error{\protect\scorereference\space is obsolete.\MessageBreak It does nothing; stop using it.}% +}% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting the things above the initial +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\gre@writemode#1#2#3{% + \greannotation{% + \gre@style@modeline #1\endgre@style@modeline % + \gre@style@modemodifier \directlua{gregoriotex.mode_part("\luatexluaescapestring{#2}")}\endgre@style@modemodifier % + \gre@style@modedifferentia \directlua{gregoriotex.mode_part("\luatexluaescapestring{#3}")}\endgre@style@modedifferentia % + \relax % + }% + \relax % +}% + +\def\GreMode#1#2#3{% + \ifvoid\gre@box@annotation% + \gre@writemode{#1}{#2}{#3}% + \fi% + \relax% +}% + +\def\gre@romannumeral@majuscule#1{\uppercase\expandafter{\romannumeral#1\relax}}% +\def\gre@romannumeral@minuscule#1{\romannumeral#1\relax}% +\def\gresetmodenumbersystem#1{% + \IfStrEqCase{#1}{% + {roman-majuscule}% + {\let\GreModeNumber\gre@romannumeral@majuscule}% + {roman-minuscule}% + {\let\GreModeNumber\gre@romannumeral@minuscule}% + {arabic}% + {\let\GreModeNumber\relax}% + }[% all other cases + \gre@error{Unrecognized option "#1" in \protect\gresetmodenumbersystem\MessageBreak Possible options are: 'roman-majuscule', 'roman-minuscule', and 'arabic'}% + ]% +}% +\gresetmodenumbersystem{roman-minuscule}% + +\def\GreAnnotationLines#1#2{% + \ifvoid\gre@box@annotation% + \greannotation{#1}% + \greannotation{#2}% + \fi% + \relax% +}% + +%% macro that draws the lines : starts by the first and then draws the lines of every line. +%% has to be called before drawing the key, after drawing the initial +\def\gre@beginnotes{% + \gre@drawfirstlines % + %%localeleftbox is a primitive of Omega, it draws the same box at the beginning of new lines (here after the first) + \gre@localleftbox{% + \copy\gre@box@lines % + }% + \relax % +}% + +\newbox\gre@box@commentary + +\def\grecommentary{\@ifnextchar[{\gre@commentary}{\gre@commentary[0pt]}} + +\def\gre@commentary[#1]#2{% + % we initialize commentarytrueraise here, but will only calculate it's final value just before placing the commentary so that we make sure we have the correct values for the distances which go into it + \gre@style@commentary% to make sure font relative units on the argument translate correctly + \global\gre@dimen@commentarytrueraise=#1\relax% + \endgre@style@commentary% + \ifvoid\gre@box@commentary% + \setbox\gre@box@commentary = \hbox{\gre@style@commentary#2\endgre@style@commentary}% + \else% + \gre@widthof{\gre@style@commentary#2\endgre@style@commentary}% + \ifdim\gre@dimen@temp@three < \wd\gre@box@commentary\relax% + \gre@dimen@temp@three = \wd\gre@box@commentary% + \fi% + \setbox\gre@box@old = \hbox to \gre@dimen@temp@three{\hfill\box\gre@box@commentary}% + \setbox\gre@box@add = \hbox to \gre@dimen@temp@three{\hfill\gre@style@commentary#2\endgre@style@commentary}% + \setbox\gre@box@commentary = \vbox spread \gre@space@dimen@commentaryseparation{\offinterlineskip\box\gre@box@old\vss\box\gre@box@add}% + \fi% +} + +\def\commentary#1{%OBSOLETE + \gre@obsolete{\protect\commentary}{\protect\grecommentary}% +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macro for putting text above lines for annotations and the like +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% format for text above the lines +\def\greabovelinestextstyle#1{% OBSOLETE + \relax % +}% +\let\gre@empty@abovelinestextstyle\greabovelinestextstyle% + +% set space above the text lines - almost the same as for the translation +\def\gre@addspaceabove{% + \gre@style@abovelinestext% + \global\gre@dimen@currentabovelinestextheight=\gre@space@dimen@abovelinestextheight\relax% + \gre@generatelines % + \endgre@style@abovelinestext% + \ifx\gre@empty@abovelinestextstyle\greabovelinestextstyle% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\greabovelinestextstyle}{\protect\grechangestyle{abovelinestext}}% OBSOLETE + \fi% OBSOLETE + \relax % +}% + +% we don't need space above any more +\def\gre@removespaceabove{% + \global\gre@dimen@currentabovelinestextheight=0 sp% + \gre@generatelines % + \relax % +}% + +% the code is a bit strange here: we always execute \gre@space@skip@spaceabovelines at the beginning of a glyph. This will: +% - typeset the text above the lines if relevant, and making sure we execute it only once +% - not do anything else + +\xdef\gre@currenttextabovelines{}% + +\def\GreSetTextAboveLines#1{% + \gdef\gre@currenttextabovelines{% + \gre@typesettextabovelines{#1}% + \gdef\gre@currenttextabovelines{}% + \relax % + }% +}% + +% typesets the text above the line +\def\gre@typesettextabovelines#1{% + \gre@style@abovelinestext% + \gre@debugmsg{spacing}{Raise alt text: \gre@space@dimen@abovelinestextraise}% + \endgre@style@abovelinestext% + \ifx\gre@empty@abovelinestextstyle\greabovelinestextstyle% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\greabovelinestextstyle}{\protect\grechangestyle{abovelinestext}}% OBSOLETE + \fi% OBSOLETE + \gre@dimen@temp@five=\dimexpr(4\gre@dimen@stafflineheight % + + 4\gre@dimen@interstafflinespace % + + \gre@space@dimen@spacebeneathtext % + + \gre@dimen@currenttranslationheight % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@additionalbottomspace % + + \gre@dimen@additionaltopspacealt % + + \gre@space@dimen@abovelinestextraise)\relax% + \gre@mark@abovelinestext % + \gre@debugmsg{spacing}{Raise alt text: \the\gre@dimen@temp@five}% + \leavevmode\raise\gre@dimen@temp@five\hbox to 0pt{\gre@style@abovelinestext#1\endgre@style@abovelinestext\hss}% + \ifx\gre@empty@abovelinestextstyle\greabovelinestextstyle% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\greabovelinestextstyle}{\protect\grechangestyle{abovelinestext}}% OBSOLETE + \fi% OBSOLETE + \relax % +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of the lines +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% first a macro to prevent the typesetting of the lines (useful for some people) +\newif\ifgre@showlines% +\gre@showlinestrue + +\def\gresetlines#1{% + \IfStrEqCase{#1}{% + {visible}% + {\gre@showlinestrue}% + {invisible}% + {\gre@showlinesfalse}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetlines\MessageBreak Possible options are: 'visible' and 'invisible'}% + ]% +} + +\def\greremovelines{%OBSOLETE + \gre@obsolete{\protect\greremovelines}{\protect\gresetlines{invisible}}% +}% + +\def\gredonotremovelines{%OBSOLETE + \gre@obsolete{\protect\gredonotremovelines}{\protect\gresetlines{visible}}% +}% + +%% macro that draws the stafflines on the first line, it is different from others due to the initial that can take some place, without lines +\def\gre@drawfirstlines{% + \advance\gre@dimen@stafflinewidth by -\gre@dimen@initialwidth\relax% + %\advance\gre@dimen@stafflinewidth by -\gre@space@dimen@minimalspaceatlinebeginning + %\gre@dimen@initialwidth=0pt + \hbox to 0pt{% + \vbox{% + \gre@style@normalstafflines% + \ifx\gre@empty@normalstafflinesformat\grenormalstafflinesformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\grenormalstafflinesformat}{\protect\grechangestyle{normalstafflines}}% OBSOLETE + \fi% OBSOLETE + \vskip\gre@dimen@currentabovelinestextheight\relax% + \vskip\gre@dimen@additionaltopspace\relax% + \ifgre@showlines % + \hrule height \gre@dimen@stafflineheight width \gre@dimen@stafflinewidth\relax% + \else % + \vskip\gre@dimen@stafflineheight\relax% + \fi % + \gre@skip@temp@four = \gre@dimen@interstafflinespace\relax% + \kern\gre@skip@temp@four % + \ifgre@showlines % + \hrule height \gre@dimen@stafflineheight width \gre@dimen@stafflinewidth\relax% + \else % + \vskip\gre@dimen@stafflineheight\relax% + \fi % + \ifgre@haslinethree % + \gre@skip@temp@four = \gre@dimen@interstafflinespace\relax% + \kern\gre@skip@temp@four % + \ifgre@showlines % + \hrule height \gre@dimen@stafflineheight width \gre@dimen@stafflinewidth\relax% + \else % + \vskip\gre@dimen@stafflineheight\relax% + \fi % + \fi % + \ifgre@haslinefour % + \gre@skip@temp@four = \gre@dimen@interstafflinespace\relax% + \kern\gre@skip@temp@four % + \ifgre@showlines % + \hrule height \gre@dimen@stafflineheight width \gre@dimen@stafflinewidth\relax% + \else % + \vskip\gre@dimen@stafflineheight\relax% + \fi % + \fi % + \ifgre@haslinefive % + \gre@skip@temp@four = \gre@dimen@interstafflinespace\relax% + \kern\gre@skip@temp@four % + \ifgre@showlines % + \hrule height \gre@dimen@stafflineheight width \gre@dimen@stafflinewidth\relax% + \else % + \vskip\gre@dimen@stafflineheight\relax% + \fi % + \fi % + \vskip\gre@space@dimen@spacelinestext\relax% + \vskip\gre@space@dimen@spacebeneathtext\relax% + \vskip\gre@dimen@currenttranslationheight\relax% + \vskip\gre@dimen@additionalbottomspace\relax% + \endgre@style@normalstafflines% + }% + \hss% + }% + \gre@dimen@stafflinewidth=\gre@dimen@linewidth\relax% + \relax% +}% + +%% box containing the stafflines for other lines than the first +\newbox\gre@box@lines% + +% macro that must be called at each change of linewidth and gre@factor +\def\gre@generatelines{% + \setbox\gre@box@lines=\hbox to 0pt{% + \vbox{% + \gre@style@normalstafflines% + \ifx\gre@empty@normalstafflinesformat\grenormalstafflinesformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\grenormalstafflinesformat}{\protect\grechangestyle{normalstafflines}}% OBSOLETE + \fi% OBSOLETE + \vskip\glueexpr(\gre@dimen@additionaltopspace+\gre@space@skip@spaceabovelines+\gre@dimen@currentabovelinestextheight)\relax% + \ifgre@showlines % + \hrule height \gre@dimen@stafflineheight width \gre@dimen@stafflinewidth\relax% + \else % + \vskip\gre@dimen@stafflineheight\relax% + \fi % + \gre@skip@temp@four = \gre@dimen@interstafflinespace\relax% + \kern\gre@skip@temp@four % + \ifgre@showlines % + \hrule height \gre@dimen@stafflineheight width \gre@dimen@stafflinewidth\relax% + \else % + \vskip\gre@dimen@stafflineheight\relax% + \fi % + \ifgre@haslinethree % + \gre@skip@temp@four = \gre@dimen@interstafflinespace\relax% + \kern\gre@skip@temp@four % + \ifgre@showlines % + \hrule height \gre@dimen@stafflineheight width \gre@dimen@stafflinewidth\relax% + \else % + \vskip\gre@dimen@stafflineheight\relax% + \fi % + \fi % + \ifgre@haslinefour % + \gre@skip@temp@four = \gre@dimen@interstafflinespace\relax% + \kern\gre@skip@temp@four % + \ifgre@showlines % + \hrule height \gre@dimen@stafflineheight width \gre@dimen@stafflinewidth\relax% + \else % + \vskip\gre@dimen@stafflineheight\relax% + \fi % + \fi % + \ifgre@haslinefive % + \gre@skip@temp@four = \gre@dimen@interstafflinespace\relax% + \kern\gre@skip@temp@four % + \ifgre@showlines % + \hrule height \gre@dimen@stafflineheight width \gre@dimen@stafflinewidth\relax% + \else % + \vskip\gre@dimen@stafflineheight\relax% + \fi % + \fi % + \kern\dimexpr(\gre@space@dimen@spacelinestext+\gre@dimen@additionalbottomspace+\gre@space@dimen@spacebeneathtext+\gre@dimen@currenttranslationheight)\relax% + \endgre@style@normalstafflines % + }% + \hss% + }% + \relax % +}% + +% Macro for fusion of larger neumes +\def\GreFuseTwo#1#2{% + #1\GreNoBreak #2\relax % +}% + +\def\GreFuse{\GreNoBreak}% + +% Macros for using variant glyphs + +% Changes a gregorio code point to a variant glyph +% #1 = the name of the gregorio code point +% #2 = font name +% #3 = glyph name, glyph variant name (preceded by .), or code point +\def\grechangeglyph#1#2#3{% + \directlua{gregoriotex.init_variant_font([[#2]], true, [[\the\gre@factor]])}% + \directlua{gregoriotex.change_score_glyph([[#1]],[[#2]],[[#3]])}% +}% + +% Resets a gregorio code point to its default setting +% #1 = the name of the gregorio code point +\def\greresetglyph#1{% + \directlua{gregoriotex.reset_score_glyph([[#1]])}% +}% + +{% + \directlua{gregoriotex.init_variant_font('greciliae', true, [[\the\gre@factor]])}% + \directlua{gregoriotex.map_font('greciliae', 'CP')}% +}% + +\input gregoriotex-chars.tex% + +\input gregoriotex-signs.tex% + +\input gregoriotex-syllable.tex% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the translations +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newif\ifgre@translationcentering +\gre@translationcenteringfalse + +\def\gresettranslationcentering#1{% + \IfStrEqCase{#1}{% + {left}% + {\gre@translationcenteringfalse}% + {center}% + {\gre@translationcenteringtrue}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresettranslationcentering\MessageBreak Possible options are: 'left' and 'center'}% + ]% +}% + +\def\setgretranslationcenteringscheme#1{%OBSOLETE + \gre@obsolete{\protect\setgretranslationcenteringscheme}{\protect\gresettranslationcentering}% +}% + + +\newif\ifgre@breakintranslation% +\gre@breakintranslationfalse% + +\def\gresetbreakintranslation#1{% + \IfStrEqCase{#1}{% + {allow}% + {\gre@breakintranslationtrue}% + {prohibit}% + {\gre@breakintranslationfalse}% + }[% all other cases + \gre@error{Unrecognized option "#1" in \protect\gresetbreakintranslation\MessageBreak Possible options are: 'allow' and 'prohibit'}% + ]% +}% + +\def\gresetnlbintranslation#1{%OBSOLETE + \gre@obsolete{\protect\gresetnlbintranslation}{\protect\gresetbreakintranslation}% +}% + +\def\GreWriteTranslation#1{% + \ifgre@translationcentering % + \setbox\gre@box@temp@width=\hbox{#1}% + \gre@dimen@temp@five=\dimexpr((\wd\gre@box@syllabletext - \wd\gre@box@temp@width) / 2)\relax% + \gre@mark@translation % + \kern\gre@dimen@temp@five % + \raise\gre@space@dimen@spacebeneathtext\hbox to 0pt{\vbox to 0pt{\vss\hbox to 0pt{\gre@style@translation#1\endgre@style@translation\hss}}}% + \ifx\gre@empty@translationformat\gretranslationformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\gretranslationformat}{\protect\grechangestyle{translation}}% OBSOLETE + \fi% OBSOLETE + \kern-\gre@dimen@temp@five % + \else % + \gre@mark@translation % + \raise\gre@space@dimen@spacebeneathtext\hbox to 0pt{\vbox to 0pt{\vss\hbox to 0pt{\gre@style@translation#1\endgre@style@translation\hss}}}% + \ifx\gre@empty@translationformat\gretranslationformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\gretranslationformat}{\protect\grechangestyle{translation}}% OBSOLETE + \fi% OBSOLETE + \fi % +}% + +\def\GreWriteTranslationWithCenterBeginning#1{% + \ifgre@breakintranslation\else% + \GreBeginNLBArea{0}{1}% + \fi % + \gre@attr@center=1\relax % + \gre@mark@translation % + \raise\gre@space@dimen@spacebeneathtext\hbox to 0pt{\kern 0pt\vbox to 0pt{\vss\hbox to 0pt{\gre@style@translation#1\endgre@style@translation\hss}}\kern 0pt}% + \ifx\gre@empty@translationformat\gretranslationformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\gretranslationformat}{\protect\grechangestyle{translation}}% OBSOLETE + \fi% OBSOLETE + \unsetluatexattribute{\gre@attr@center}% + \relax % +}% + +\newif\ifgre@mustdotranslationcenterend% +\gre@mustdotranslationcenterendfalse% + +\def\GreTranslationCenterEnd{% + \gre@mustdotranslationcenterendtrue% + \relax % +}% + +\def\gre@dotranslationcenterend{% + \ifgre@breakintranslation\else% + \GreEndNLBArea{0}{1}% + \fi % + \gre@attr@center=2\relax % + \raise\gre@space@dimen@spacebeneathtext\hbox to 0pt{}% + \unsetluatexattribute{\gre@attr@center}% + \relax % +}% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% other macros +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newif\ifgre@justifylastline% +\gre@justifylastlinefalse% + +\def\gresetlastline#1{% + \IfStrEqCase{#1}{% + {justified}% + {\gre@justifylastlinetrue}% + {ragged}% + {\gre@justifylastlinefalse}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetlastline\MessageBreak Possible options are: 'justified' and 'ragged'}% + ]% +}% + +% make this a count so that it can be read more easily in Lua +\newcount\gre@variableheightexpansion\gre@variableheightexpansion=1\relax % +\def\gresetlineheightexpansion#1{% + \IfStrEqCase{#1}{% + {uniform}% + {\gre@variableheightexpansion=0\relax }% + {variable}% + {\gre@variableheightexpansion=1\relax }% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetlineheightexpansion\MessageBreak Possible options are: 'uniform' and 'variable'}% + ]% +}% + +% gre@attr@dash (see its definition in gregorio-syllable) is 0 when we are in a score, and unset when we are not + +\newif\ifgre@beginningofscore% +\newif\ifgre@haslinethree% +\newif\ifgre@haslinefour% +\newif\ifgre@haslinefive% + +\def\gre@setstafflines#1{% + \def\gre@stafflines{#1}% + \ifcase#1% 0 + \gre@error{Invalid number of staff lines}% + \or % 1 + \gre@error{Invalid number of staff lines}% + \or % 2 + \let\gre@pitch@adjust@top\gre@pitch@f % + \let\gre@pitch@abovestaff\gre@pitch@g % + \let\gre@pitch@ledger@above\gre@pitch@h % + \let\gre@pitch@raresign\gre@pitch@g % + \let\gre@pitch@overbrace\gre@pitch@i % + \grechangeglyph{Virgula}{*}{.2}% + \grechangeglyph{Divisio*}{*}{.2}% + \gre@haslinethreefalse % + \gre@haslinefourfalse % + \gre@haslinefivefalse % + \or % 3 + \let\gre@pitch@adjust@top\gre@pitch@h % + \let\gre@pitch@abovestaff\gre@pitch@i % + \let\gre@pitch@ledger@above\gre@pitch@j % + \let\gre@pitch@raresign\gre@pitch@i % + \let\gre@pitch@overbrace\gre@pitch@k % + \grechangeglyph{Virgula}{*}{.3}% + \grechangeglyph{Divisio*}{*}{.3}% + \gre@haslinethreetrue % + \gre@haslinefourfalse % + \gre@haslinefivefalse % + \or % 4 + \let\gre@pitch@adjust@top\gre@pitch@j % + \let\gre@pitch@abovestaff\gre@pitch@k % + \let\gre@pitch@ledger@above\gre@pitch@l % + \let\gre@pitch@raresign\gre@pitch@k % + \let\gre@pitch@overbrace\gre@pitch@m % + \greresetglyph{Virgula}% + \greresetglyph{Divisio*}% + \gre@haslinethreetrue % + \gre@haslinefourtrue % + \gre@haslinefivefalse % + \or % 5 + \let\gre@pitch@adjust@top\gre@pitch@l % + \let\gre@pitch@abovestaff\gre@pitch@m % + \let\gre@pitch@ledger@above\gre@pitch@n % + \let\gre@pitch@raresign\gre@pitch@m % + \let\gre@pitch@overbrace\gre@pitch@p % + \grechangeglyph{Virgula}{*}{.5}% + \grechangeglyph{Divisio*}{*}{.5}% + \gre@haslinethreetrue % + \gre@haslinefourtrue % + \gre@haslinefivetrue % + \else % + \gre@error{Invalid number of staff lines}% + \fi % +}% + +%macro called at the beginning of a score +% #1 is the gabc score id +% #2 is the high height +% #3 is the low height +% #4 is 1 if there is a translation somewhere +% #5 is if 1 if we have space above the staff +% #6 is the point-and-click filename +% #7 is the number of staff lines +\def\GreBeginScore#1#2#3#4#5#6#7{% + % scores must be new paragraphs! + \ifhmode\par\fi % + \gre@beginningofscoretrue% + \global\gre@dimen@morawidth=0pt\relax % + \gre@reseteolcustos% + \gre@resetledgerlineheuristics% + \global\setluatexattribute\gre@attr@glyph@id{0}% + \xdef\gre@gabcname{#6}% + \gre@setstafflines{#7}% + \global\let\gre@save@englishcentering\gre@lyriccentering\relax % OBSOLETE + \global\let\gre@opening@initialstyle\gre@initiallines\relax % DEPRECATED by 4.1 + \ifgre@justifylastline% + \xdef\gre@save@parfillskip{\the\parfillskip}% + \parfillskip=0pt plus 0pt minus 0pt\relax% + \fi % + \ifgre@usestylefont% + \gre@setstylefont % + \fi % + \gre@computespaces% + \gre@cancelpenalties % + \gre@attr@dash=0\relax % + \xdef\gre@exhyphencharsave{\the\exhyphenchar}% + \exhyphenchar=-1\relax % + \gre@generatelines % + \noindent% + \gre@calculate@additionalspaces{#2}{#3}{#4}{#5}% + \directlua{ + gregoriotex.atScoreBeginning([[#1]], #2, #3, #4, #5, + \gre@pitch@adjust@top, \gre@pitch@adjust@bottom) + gregoriotex.adjust_line_height(1) + }% + %TODO do something like LaTeX's AtBeginDocument + \ifdefined\optgabcAtScoreBeginning % + \optgabcAtScoreBeginning % + \fi % + \global\gre@knownline=1\relax % + \global\gre@lastoflinecount=2\relax % + \global\gre@endofscorefalse % + \relax% +}% + +%macro called at the end of a score +\def\GreEndScore{% + \ifnum\gre@biginitial=1\relax% + \ifnum\gre@knownline<3\relax% + \gre@error{Score ended before finding the end\MessageBreak of the second line of a 2-line initial. Make sure\MessageBreak you have at least two manual line breaks in \MessageBreak your gabc}% + \fi% + \fi% + \global\gre@lastoflinecount=0\relax % + \gre@useautoeolcustos% + \GreEndEUOUAE{}% + \ifnum\gre@nlbstate=0\else % + \GreEndNLBArea{2}{0}% + \fi % + \gre@localleftbox{}% + \ifgre@keeprightbox\else % + \gre@localrightbox{}% + \fi % + \hfil % + \par % + \ifgre@keeprightbox% + \global\gre@keeprightboxfalse% + \fi% + % with some versions of LuaTeX, the \localrightbox and \localleftbox must be set empty in an environment with the good attributes set + \gre@localleftbox{}% + \gre@localrightbox{}% + \gre@calculate@additionalspaces{\gre@pitch@dummy}{\gre@pitch@dummy}{0}{0}% + \global\gre@dimen@currentabovelinestextheight=0 sp% + \gre@removetranslationspace % + \gre@normalinitial % + \gre@restorepenalties % + \exhyphenchar=\gre@exhyphencharsave % + \gre@dimen@temp@one=0pt\relax% + \gre@dimen@temp@two=0pt\relax% + \gre@dimen@temp@three=0pt\relax% + \gre@dimen@temp@four=0pt\relax% + \gre@dimen@temp@five=0pt\relax% + \gre@skip@temp@one=0pt\relax% + \gre@skip@temp@two=0pt\relax% + \gre@skip@temp@three=0pt\relax% + \gre@skip@temp@four=0pt\relax% + \setbox\gre@box@annotation=\box\voidb@x% + \setbox\gre@box@commentary=\box\voidb@x% + \directlua{gregoriotex.atScoreEnd()}% + \unsetluatexattribute{\gre@attr@glyph@id}% + \unsetluatexattribute{\gre@attr@glyph@top}% + \unsetluatexattribute{\gre@attr@glyph@bottom}% + \unsetluatexattribute{\gre@attr@dash}% + \ifgre@justifylastline% + \parfillskip=\gre@save@parfillskip\relax% + \fi % + \global\let\gre@lyriccentering\gre@save@englishcentering\relax % OBSOLETE + \global\setluatexattribute\gre@attr@glyph@id{0}% + \relax% +}% + +% macro called at the end of a bar (old bar spacing algorithm only). +\def\gre@endafterbar#1{% + \gre@penalty{\greendafterbarpenalty }\relax % + \ifnum#1=1\relax % + \gre@debugmsg{ifdim}{ enddifference > 0pt}% + \ifdim\gre@dimen@enddifference > 0 pt\relax% + \gre@debugmsg{ifdim}{ nextbegindifference > 0pt}% + \ifdim\gre@skip@nextbegindifference > 0 pt\relax% + \gre@skip@temp@four = \gre@space@skip@notebarspace\relax% + \gre@hskip\gre@skip@temp@four % + \else % (next begin difference >0pt) + \gre@skip@temp@four = \gre@space@skip@textbartextspace\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \else%(enddifference < 0pt) + \gre@debugmsg{ifdim}{ nextbegindifference < 0pt}% + \ifdim\gre@skip@nextbegindifference < 0 pt\relax% + \gre@skip@temp@four = \gre@space@skip@textbartextspace\relax% + \gre@hskip\gre@skip@temp@four % + \else %(next begin difference < 0 pt) + \gre@skip@temp@four = \gre@space@skip@interwordspacetext\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \fi % + \fi % + %\gre@penalty{\greendafterbarpenalty }\relax + %\global\gre@dimen@enddifference=0pt + \relax % +}% + +\newcount\gre@lastoflinecount% + +% called at syllable level. Indicates that the syllable is the last of the line (or score) +% 0 if nothing +% 1 if the syllable is the last of the line +% 2 after it has finished the syllable, so when it is two it means that the syllable is the first of a line +\def\GreLastOfLine{% + \global\gre@lastoflinecount=1\relax% + \gre@debugmsg{eolshift}{set lastoflinecount to 1}% + \relax% +}% + +% Flag to mark the last syllable of the score +\newif\ifgre@endofscore% +\gre@endofscorefalse% + +% called at element level, before the final element +\def\GreLastOfScore{% + %\gre@localleftbox{}% For an unknown reason, if I uncomment this line, the + %blank line removing algorithm (in lua) will let some blank space after the + %last line... (see bug #20953) + \global\gre@endofscoretrue % + \gre@usemanualeolcustos% + \gre@debugmsg{eolshift}{set lastoflinecount to 1}% + \relax% +}% + +% a flag to disable (or reenable) the left shift for first syllables of lines +\newif\ifgre@bolshiftsenabled% +% default state is for them to be enabled +\gre@bolshiftsenabledtrue + +\def\gresetbolshifts#1{% + \IfStrEqCase{#1}{% + {enable}% + {\gre@bolshiftsenabledtrue}% + {disable}% + {\gre@bolshiftsenabledfalse}% + }[% all other cases + \gre@error{Unrecognized option "#1" in \protect\gresetbolshifts\MessageBreak Possible options are: 'enable' and 'disable'}% + ]% +}% + +% a flag to disable (or reenable) the shift for last syllables of lines +% when the shifts are enabled lyrics cannot extend under (or past) the custos at the end of a line +\newif\ifgre@eolshiftsenabled% +% default state is for them to be enabled +\gre@eolshiftsenabledtrue + +\def\greseteolshifts#1{% + \IfStrEqCase{#1}{% + {enable}% + {\gre@eolshiftsenabledtrue}% + {disable}% + {\gre@eolshiftsenabledfalse}% + }[% all other cases + \gre@error{Unrecognized option "#1" in \protect\greseteolshifts\MessageBreak Possible options are: 'enable' and 'diable'}% + ]% +}% + +\def\gredisableeolshifts{%OBSOLETE + \gre@obsolete{\protect\gredisableeolshifts}{\protect\greseteolshifts{disable}}% +}% + +\def\greenableeolshifts{%OBSOLETE + \gre@obsolete{\protect\greenableeolshifts}{\protect\greseteolshifts{enable}}% +}% + +% Flag indicating if we block the custos. We just block custos at the end of a score, to prevent a bug. +\newif\ifgre@blockeolcustos% +\def\gre@usemanualeolcustos{% + \gre@blockeolcustostrue% + \gre@localrightbox{}% +}% +\def\gre@useautoeolcustos{% + \gre@blockeolcustosfalse% +}% +\def\greseteolcustos#1{% + \IfStrEqCase{#1}{% + {manual}% + {\global\let\gre@reseteolcustos\gre@usemanualeolcustos\relax}% + {auto}% + {\global\let\gre@reseteolcustos\gre@useautoeolcustos\relax}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\greseteolcustos\MessageBreak Possible options are: 'manual' and 'auto'}% + ]% +}% +\greseteolcustos{auto}% + +\newif\ifgre@blockeolcustosbeforeeuouae% +\def\greseteolcustosbeforeeuouae#1{% + \IfStrEqCase{#1}{% + {suppressed}% + {\gre@blockeolcustosbeforeeuouaetrue\relax}% + {auto}% + {\gre@blockeolcustosbeforeeuouaefalse\relax}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\greseteolcustosbeforeeuouae\MessageBreak Possible options are: 'suppressed' and 'auto'}% + ]% +}% +\greseteolcustosbeforeeuouae{suppressed}% + +\newif\ifgre@raggedbreakbeforeeuouae% +\def\gresetbreakbeforeeuouae#1{% + \IfStrEqCase{#1}{% + {ragged}% + {\gre@raggedbreakbeforeeuouaetrue\relax}% + {justified}% + {\gre@raggedbreakbeforeeuouaefalse\relax}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\greseteolcustosbeforeeuouae\MessageBreak Possible options are: 'ragged' and 'justified'}% + ]% +}% +\gresetbreakbeforeeuouae{justified}% + +% macro to suppress the custos +\def\greblockcustos{%OBSOLETE + \gre@obsolete{\protect\greblockcustos}{\protect\greseteolcustos{manual}}% +}% + +\def\GreAdHocSpaceEndOfElement#1#2{% + \gre@skip@temp@four = \gre@space@skip@interelementspace\relax % + \directlua{gregoriotex.scale_space(#1)}% + \GreEndOfElement{4}{#2}% +}% + +% macro to end elements, #1 is the type of space, it can be : +%% 0: default space +%% 1: larger space +%% 2: glyph space +%% 3: zero-width space +%% 4: custom space +% #2 is if the space is unbreakable (1) or not (0) +\def\GreEndOfElement#1#2{% + \ifnum #2=0\relax % + \gre@penalty{\greendofelementpenalty}% + \else % + \GreNoBreak % + \fi % + \ifcase#1% + \gre@skip@temp@four = \gre@space@skip@interelementspace\relax% + \gre@hskip\gre@skip@temp@four % + \or% case 1 + \gre@skip@temp@four = \gre@space@skip@largerspace\relax% + \gre@hskip\gre@skip@temp@four % + \or% case 2 + \gre@skip@temp@four = \gre@space@skip@glyphspace\relax% + \gre@hskip\gre@skip@temp@four % + \or% case 3 + \gre@skip@temp@four = \gre@space@skip@zerowidthspace\relax% + \gre@hskip\gre@skip@temp@four % + \or% case 4 + \gre@hskip\gre@skip@temp@four % + \fi% + \ifnum #2=1\relax % + \GreNoBreak % + \fi % +\relax% +}% + +% puts the correct skip value into \gre@skip@temp@four for the desired type of space +%% 0: default space +%% 1: zero width space +%% 2: space between flat or natural and a note +%% 3: space between two puncta inclinata +%% 7: space between a punctum inclinatum and a punctum inclinatum deminutus +%% 8: space between two puncta inclinata deminuti +%% 4: space between bivirga or trivirga +%% 5: space between bistropha or tristropha +%% 6: space after a punctum mora XXX: not used yet, not so sure it is a good idea... +%% 7: space between a punctum inclinatum and a punctum inclinatum debilis +%% 8: space between two puncta inclinata debilis +%% 9: space before a punctum (or something else) and a punctum inclinatum +%% 10: space between puncta inclinata (also debilis for now), larger ambitus (range=3rd). +%% 11: space between puncta inclinata (also debilis for now), larger ambitus (range=4th or 5th) +%% 12: ascending version of 3 +%% 13: ascending version of 7 +%% 14: ascending version of 10 +%% 15: ascending version of 11 +%% 16: space between a punctum inclinatum and a "no-bar" glyph one pitch below +%% 17: space between a punctum inclinatum and a "no-bar" glyph two pitches below +%% 18: space between a punctum inclinatum and a "no-bar" glyph three or four pitches below +%% 19: space between a punctum inclinatum and a "no-bar" glyph one pitch above +%% 20: space between a punctum inclinatum and a "no-bar" glyph two pitches above +%% 21: space between a punctum inclinatum and a "no-bar" glyph three or four pitches above +%% 22: half-space +\def\gre@get@spaceskip#1{% + \ifcase#1% + \gre@skip@temp@four = \gre@space@skip@interglyphspace\relax% + \or% case 1 + \gre@skip@temp@four = \gre@space@dimen@zerowidthspace\relax% + \or% case 2 + \gre@skip@temp@four = \gre@space@dimen@alterationspace\relax% + \or% case 3 + \gre@skip@temp@four = \gre@space@skip@punctuminclinatumshift\relax% + \or% case 4 + \gre@skip@temp@four = \gre@space@skip@bitrivirspace\relax% + \or% case 5 + \gre@skip@temp@four = \gre@space@skip@bitristrospace\relax% + \or% case 6 + \gre@skip@temp@four = \gre@space@skip@spaceaftersigns\relax% + \or% case 7 + \gre@skip@temp@four = \gre@space@skip@punctuminclinatumanddebilisshift\relax% + \or% case 8 + \gre@skip@temp@four = \gre@space@skip@punctuminclinatumdebilisshift\relax% + \or% case 9 + \gre@skip@temp@four = \gre@space@skip@beforepunctainclinatashift\relax% + \or% case 10 + \gre@skip@temp@four = \gre@space@skip@punctuminclinatumbigshift\relax% + \or% case 11 + \gre@skip@temp@four = \gre@space@skip@punctuminclinatummaxshift\relax% + \or% case 12 (ascending version of 3) + \gre@skip@temp@four = \gre@space@skip@ascendingpunctuminclinatumshift\relax% + \or% case 13 (ascending version of 7) + \gre@skip@temp@four = \gre@space@skip@ascendingpunctuminclinatumanddebilisshift\relax% + \or% case 14 (ascending version of 10) + \gre@skip@temp@four = \gre@space@skip@ascendingpunctuminclinatumbigshift\relax% + \or% case 15 (ascending version of 11) + \gre@skip@temp@four = \gre@space@skip@ascendingpunctuminclinatummaxshift\relax% + \or% case 16 + \gre@skip@temp@four = \gre@space@skip@descendinginclinatumtonobarshift\relax% + \or% case 17 + \gre@skip@temp@four = \gre@space@skip@descendinginclinatumtonobarbigshift\relax% + \or% case 18 + \gre@skip@temp@four = \gre@space@skip@descendinginclinatumtonobarmaxshift\relax% + \or% case 19 + \gre@skip@temp@four = \gre@space@skip@ascendinginclinatumtonobarshift\relax% + \or% case 20 + \gre@skip@temp@four = \gre@space@skip@ascendinginclinatumtonobarbigshift\relax% + \or% case 21 + \gre@skip@temp@four = \gre@space@skip@ascendinginclinatumtonobarmaxshift\relax% + \or% case 22 + \gre@skip@temp@four = \gre@space@skip@halfspace\relax% + \fi% +}% + +% macro to end a glyph without ending the element +% see \gre@get@glyphskip for the valus of the argument +\def\GreEndOfGlyph#1{% + \GreNoBreak % + \gre@get@spaceskip{#1}% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \relax% +}% + +% The different states of line break areas: +% 0: not currently in a no line break area +% 1: no line break area due to translation centering +% 2: no line break area due to <nlba> tag +\xdef\gre@nlbstate{0}% + +% first argument is if if the nlba is starting in neumes or not +% second argument is if it is called from translation centering or not +\def\GreBeginNLBArea#1#2{% + \xdef\gre@nlbinitialstate{\gre@nlbstate}% + \ifnum#2=0\relax % + \xdef\gre@nlbstate{2}% + \else % + \ifcase\gre@nlbstate % + \xdef\gre@nlbstate{1}% + \or % + \xdef\gre@nlbstate{1}% + \or % + \xdef\gre@nlbstate{2}% + \fi % + \fi % + \ifnum\gre@nlbinitialstate=0\relax % + \xdef\gre@nobreakpenaltysave{\grenobreakpenalty }% + \xdef\grenobreakpenalty{10001}% + \xdef\gre@endofwordpenaltysave{\greendofwordpenalty }% + \xdef\greendofwordpenalty{10001}% + \xdef\gre@endofsyllablepenaltysave{\greendofsyllablepenalty }% + \xdef\greendofsyllablepenalty{10001}% + \xdef\gre@endafterbarpenaltysave{\greendafterbarpenalty }% + \xdef\greendafterbarpenalty{10001}% + \xdef\gre@endafterbaraltpenaltysave{\greendafterbaraltpenalty }% + \xdef\greendafterbaraltpenalty{10001}% + \xdef\gre@endofelementpenaltysave{\greendofelementpenalty }% + \xdef\greendofelementpenalty{10001}% + \xdef\gre@hyphenpenaltysave{\grehyphenpenalty }% + \xdef\grehyphenpenalty{10001}% + \fi % +}% + +\def\GreEndNLBArea#1#2{% + \xdef\gre@nlbinitialstate{\gre@nlbstate}% + \ifnum#2=0\relax % + \xdef\gre@nlbstate{0}% + \else % + \ifcase\gre@nlbstate % + \xdef\gre@nlbstate{0}% + \or % + \xdef\gre@nlbstate{0}% + \or % + \xdef\gre@nlbstate{2}% + \fi % + \fi % + % if gre@nlbstate is not 0, then nothing should happend + \ifnum\gre@nlbstate=0\relax % + \ifnum\gre@nlbinitialstate=0\else % + \xdef\grenobreakpenalty{\gre@nobreakpenaltysave }% + \xdef\greendofwordpenalty{\gre@endofwordpenaltysave}% + \xdef\greendofsyllablepenalty{\gre@endofsyllablepenaltysave}% + \xdef\greendafterbarpenalty{\gre@endafterbarpenaltysave}% + \xdef\greendafterbaraltpenalty{\gre@endafterbaraltpenaltysave}% + \xdef\greendofelementpenalty{\gre@endofelementpenaltysave}% + \xdef\grehyphenpenalty{\gre@hyphenpenaltysave}% + \ifcase #1\relax % 0 + \gre@penalty{\greendofelementpenalty}% + \or % 1 + \gre@penalty{\greendofsyllablepenalty}% + \or % 2 + % end of score, no penalty needs to be added + \or % 3 + % before bar, no penalty should to be added + \fi % + \fi % + \fi % +}% + +\newif\ifgre@euouae@implies@nlba +\gre@euouae@implies@nlbatrue + +\def\gresetbreakineuouae#1{% + \IfStrEqCase{#1}{% + {allow}% + {\gre@euouae@implies@nlbafalse}% + {prohibit}% + {\gre@euouae@implies@nlbatrue}% + }[% all other cases + \gre@error{Unrecognized option "#1" in \protect\gresetbreakineuouae\MessageBreak Possible options are: 'allow' and 'prohibit'}% + ]% +}% + + +\newif\ifgre@in@euouae +\gre@in@euouaefalse + +\newif\ifgre@firstin@euouae +\gre@firstin@euouaefalse +\newcount\gre@lasteuouaeindex +\gre@lasteuouaeindex=0 + +\def\GreBeginEUOUAE#1{% + \ifgre@euouae@implies@nlba % + \GreBeginNLBArea{0}{0}% + \fi % + \ifgre@raggedbreakbeforeeuouae % + \gre@lasteuouaeindex=#1\relax % + \gre@firstin@euouaetrue % + \fi % + \gre@in@euouaetrue % + % as soon as the EUOUAE starts, we stop blocking the EOL custos that might + % have been blocked on the prior syllable. + \gre@reseteolcustos % +} + +\def\GreEndEUOUAE#1{% + \ifgre@euouae@implies@nlba % + \GreEndNLBArea{#1}{0}% + \fi % + \gre@in@euouaefalse % + \gre@firstin@euouaefalse % +} + +\input gregoriotex-symbols.tex% + +%%%%%%%%% +%% fonts +%%%%%%%%% + +\def\gretilde{% + \ensuremath{\sim}% + \relax % +}% + + +\def\gresetgregoriofont{\@ifnextchar[{\gre@setgregoriofont}{\gre@setgregoriofont[]}}% +\def\gresetgregoriofontscaled{\@ifnextchar[{\gre@setgregoriofontscaled}{\gre@setgregoriofontscaled[]}}% + +\def\gre@setgregoriofont[#1]#2{% + \gre@setgregoriofontscaled[#1]{#2}{100000}% + \relax % +}% + +\def\gre@setgregoriofontscaled[#1]#2#3{% + \if\relax\detokenize{#1}\relax % + \xdef\gre@gregoriofontname{#2}% + \expandafter\xdef\csname gre@fontfactor@#2\endcsname{#3}% + \gre@loadgregoriofont% + \gdef\GreCPVirgaReversaAscendensOnDLine##1{##1}% + \else % + \xdef\gre@gregoriofontname{#2-#1}% + \expandafter\xdef\csname gre@fontfactor@#2-#1\endcsname{#3}% + \gre@loadgregoriofont% + \gdef\GreCPVirgaReversaAscendensOnDLine##1{\GreCPVirgaReversaLongqueueAscendens}% + \fi % + \relax % +}% + +\def\gre@loadgregoriofont{% + \gre@count@temp@three = \the\gre@factor % + \gre@count@temp@two = \expandafter\csname gre@fontfactor@\gre@gregoriofontname\endcsname\relax % + \directlua{gregoriotex.set_font_factor([[\gre@gregoriofontname]], [[\the\gre@count@temp@two]])}% + \multiply\gre@count@temp@three by \gre@count@temp@two % + \global\font\gre@font@music={name:\gre@gregoriofontname} at \the\gre@count@temp@three sp\relax % + {\gre@font@music\directlua{gregoriotex.check_font_version() gregoriotex.scale_score_fonts([[\the\gre@count@temp@three]], [[\the\gre@factor]])}}% + \relax% +}% + +% the default gregorio font +\gresetgregoriofont{greciliae}% + +\newif\ifgre@usestylefont% +\gre@usestylefontfalse% + +% gregoriostylefont is the font used for additional glyphs +\def\gre@setstylefont{% + \gre@count@temp@three = \numexpr(\gre@factor * 100000)\relax % + \global\font\gre@font@style={name:greextra} at \the\gre@count@temp@three sp% + {\gre@font@music\directlua{gregoriotex.check_font_version() gregoriotex.scale_score_fonts([[\the\gre@count@temp@three]], [[\the\gre@factor]])}}% + \relax% +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% The following style functions are defined for backwards compatibility. They will eventually be removed. +\def\greinitialformat#1{% OBSOLETE + \relax % +} +\let\gre@empty@initialformat\greinitialformat + +\def\grebiginitialformat#1{% OBSOLETE + \relax % +} +\let\gre@empty@biginitialformat\grebiginitialformat + +\def\gretranslationformat#1{% OBSOLETE + \relax % +}% +\let\gre@empty@translationformat\gretranslationformat + +\def\grenormalstafflinesformat{% OBSOLETE + \relax % +}% +\let\gre@empty@normalstafflinesformat\grenormalstafflinesformat + +\def\greadditionalstafflinesformat{% OBSOLETE + \relax % +}% +\let\gre@empty@additionalstafflinesformat\greadditionalstafflinesformat + +%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\GreSetStaffLinesFormat#1{%OBSOLETE + \gre@obsolete{\protect\GreSetStaffLinesFormat}{\protect\grechangestyle{normalstafflines}}% +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Master function for changing element formats +%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\grechangestyle#1#2{% + \IfStrEq{#1}{biginitial}{\gre@deprecated{biginitial style}{initial style}}{}%%% DEPRECATED for removal in 5.0 + \@ifnextchar[{\gre@changestyle{#1}{#2}}{\gre@changestyle{#1}{#2}[\relax]}% +}% + +% because the mechanism for the defining the formats differs under LaTeX and PlainTeX the underlying function which does the work is defined in gregoriotex.sty or gregoriotex.tex respectively. + + +%%%%%%%%%%%%%%%%%%% +%% changing staff size +%%%%%%%%%%%%%%%%%%% + +\def\grechangestaffsize#1{% + \ifnum#1<0\relax% + \gre@error{Staff size must be a positive integer.}% + \else% + \gre@changedimenfactor{\gre@factor}{#1}% + \global\gre@factor=#1\relax % + \fi% + \gre@loadgregoriofont% + \relax % +}% + +\def\setgrefactor#1{%OBSOLETE + \gre@obsolete{\protect\setgrefactor}{\protect\grechangestaffsize}% +}% + +%%%%%%%%%%%%%%%%%%% +%% headers +%%%%%%%%%%%%%%%%%%% +\def\gresetheadercapture#1#2#3{% + \directlua{gregoriotex.set_header_capture("#1","#2","#3")}% +}% + +\def\GreHeader#1#2{% + \directlua{gregoriotex.capture_header("#1","#2")}% +}% + +%%%%%%%%%%%%%%%%%%% +%% score including +%%%%%%%%%%%%%%%%%%% + +% Flag to track compilation behavior +% 0 = never compile (default) +% 1 = auto compile (compile outdated scores and those lacking a compiled version) +% 2 = compile all scores +\def\gre@compilegabc{0} + +% User macro to change compilation behavior +\def\gresetcompilegabc#1{% + \IfStrEqCase{#1}{% + {force}{\gdef\gre@compilegabc{2}}% + {auto}{\gdef\gre@compilegabc{1}}% + {never}{\gdef\gre@compilegabc{0}}% + }[% all other cases + \gre@error{Unrecognized argument for \protect\gresetcompilegabc.}% + ]% +}% + + +% User macro to force gregriotex to recompile gabc files. Useful for when there +% are changes to gregoriotex but the GREGORIOTEX API VERSION is not changed. +\def\forcecompilegabc{%OBSOLETE + \gre@obsolete{\protect\forcecompilegabc}{\protect\gresetcompilegabc{force}}% +}% + +% User macro to let gregoriotex auto recompile gabc files as necessary. +% Intended to be used in the main tex file to revert the previous macro. +\def\autocompilegabc{%OBSOLETE + \gre@obsolete{\protect\autocompilegabc}{\protect\gresetcompilegabc{auto}}% +}% + +% User macro to force score inclusion without compilation. +\def\nevercompilegabc{%OBSOLETE + \gre@obsolete{\protect\nevercompilegabc}{\protect\gresetcompilegabc{never}}% +} + + +% Internal marco which includes a score when \gregorioscore is called without the optional argument. Behavior is determined by the value of \gre@compilegabc flag. +% +% If \gre@compilegabc is 0, then we simply try to include the file as it is given to us. This is the old behavior. +% +% If \gre@compilegabc is 1, tell the lua function to check that: +% -- The gtex file exists. +% -- The gtex file is of the correct gregoriotexapi_version. +% -- The gtex file is 'newer' than it's corresponding gabc file. +% If any test fails, the gabc file is (re)compiled. +% +% If \gre@compilegabc is 2, pass true to the lua function. +% This forces gregoriotex to recompile the gabc file. + +\def\gre@gregorioscore#1{% + \ifcase\gre@compilegabc% case 0, never compile + \gre@debugmsg{compile}{Refusing to compile #1}% + \input #1% + \or% case 1, auto compile + \gre@debugmsg{compile}{Auto compile #1}% + \directlua{gregoriotex.include_score([[#1]], nil)}% + \or% case 2, force compile + \gre@debugmsg{compile}{Forced to compile #1}% + \directlua{gregoriotex.include_score([[#1]], true)}% + \fi% + \relax% +}% + +% The internal macro called when \gregorioscore is called with the optional argument. Behavior is determined by the value of the argument: +% n - do not attempt to compile the score. Simply include it as is. +% a - perform the checks to see if the score needs to be recompiled and do so only if necessary +% f - force the compilation of the score before including it +\def\gre@gregorioscore@option[#1]#2{% + \ifx #1n\relax% + \gre@debugmsg{compile}{Override not compiling #2}% + \input #2% + \else% + \ifx #1f\relax% + \gre@debugmsg{compile}{Override force compiling #2}% + \directlua{gregoriotex.include_score([[#2]], true)}% + \else% + \ifx #1a\relax% + \gre@debugmsg{compile}{Override auto compiling #2}% + \directlua{gregoriotex.include_score([[#2]], nil)}% + \else% + \gre@error{Unrecognized option "#1" for \protect\includescore\MessageBreak Possible options are: 'f', 'a', and 'n'}% + \fi% + \fi% + \fi% + \relax% +}% + +% The main macro used by the user to input scores into the document. + +\def\includescore{%OBSOLETE + \gre@obsolete{\protect\includescore}{\protect\gregorioscore}% +}% + +\def\gregorioscore{\@ifnextchar[{\gre@gregorioscore@option}% + {\gre@gregorioscore}% +}% + +% If called without the optional argument: '\gregorioscore{Antiphon}' +% the filename will be passed to the lua function 'include_score' +% which will check: whether the gtex file exists, if the API version +% of the gtex file, or if the gabc file is newer than the gtex +% file. If one of these tests fails, the gabc file will be +% (re)compiled. +% The argument may or may not include a file extension. These are all valid: +% '\gregorioscore{Antiphon}' or '\gregorioscore{Antiphon.gabc}' or +% '\gregorioscore{Antiphon.gtex}' + +% If called with the optional argument: '\gregorioscore[f]{Antiphon.gtex}' +% the gtex file will be forced into the document and will not be +% checked by the lua function 'include_score'. This does not bypass +% the API version test done by '\GregorioTeXAPIVersion'. + +% Macros for compiling short snippets of GABC directly expressed in TeX + +\long\def\gre@gabcsnippet@option[#1]#2{%%% DEPRECATED by 4.1 + \gre@deprecated{\protect\gabcsnippet with initial-style argument}{\protect\gresetinitiallines}% + \directlua{gregoriotex.direct_gabc("\luatexluaescapestring{\unexpanded\expandafter{#2}}", "initial-style: #1;")}% +}% + +\long\def\gre@gabcsnippet#1{% + \directlua{gregoriotex.direct_gabc("\luatexluaescapestring{\unexpanded\expandafter{#1}}")}% +}% + +%%% \gre@gabcsnipper@option is DEPRECATED by 4.1 +\def\gabcsnippet{\@ifnextchar[{\gre@gabcsnippet@option}{\gre@gabcsnippet}}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% some hyphen definitions +%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% a zero-width hyphen, useful for fine tuning line endings. To input in gabc verb for example. +\def\gre@char@zerohyph{% + \hbox to 0pt{% + \char\the\hyphenchar\font % + \hss % + }% +}% + +% a normal hyphen +\def\gre@char@normalhyphen{% + %- + \char\the\hyphenchar\font % +}% + +% the definition that will be always used for end of lines hyphens in gregorio, except if one of the two before is explicitely used +\let\GreHyph\gre@char@normalhyphen % + +% macro to change the definition of the hyphen: +\def\greseteolhyphen#1{% + \IfStrEqCase{#1}{% + {normal}% + {\global\let\GreHyph\gre@char@normalhyphen}% + {zero}% + {\global\let\GreHyph\gre@char@zerohyph}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\greseteolhyphen\MessageBreak Possible options are: 'normal' and 'zero'}% + ]% +}% + +\def\GreUseNormalHyphen{%OBSOLETE + \gre@obsolete{\protect\GreUseNormalHyphen}{\protect\greseteolhyphen{normal}}% +}% + +\def\GreUseZeroHyphen{%OBSOLETE + \gre@obsolete{\protect\GreUseZeroHyphen}{\protect\greseteolhyphen{zero}}% +}% + +% macro to force hyphenation of all syllables. +\newif\ifgre@forcehyphen\gre@forcehyphenfalse% +\def\gresethyphen#1{% + \IfStrEqCase{#1}{% + {force}% + {\gre@forcehyphentrue}% + {auto}% + {\gre@forcehyphenfalse}% + }[% all other cases + \gre@error{Unrecognized option "#1" in \protect\gresethyphen\MessageBreak Possible options are: 'force' and 'auto'}% + ]% +}% + +% macro called before the headers of a given inclusion +\def\GreBeginHeaders{}% +\long\def\grebeforeheaders#1{\def\GreBeginHeaders{#1}}% + +% macro called after the headers of a given inclusion +\def\GreEndHeaders{}% +\long\def\greafterheaders#1{\def\GreEndHeaders{#1}}% + +% We load the default space configuration. +\greloadspaceconf{default}% + +\input gregoriotex-nabc.tex diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-nabc.lua b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-nabc.lua new file mode 100644 index 00000000000..659502e7d63 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-nabc.lua @@ -0,0 +1,425 @@ +--GregorioTeX Nabc Lua file. +-- +--Copyright (C) 2014-2015 The Gregorio Project (see CONTRIBUTORS.md) +-- +--This file is part of Gregorio. +-- +--Gregorio 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. +-- +--Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +-- this file contains lua functions used by GregorioTeX St. Gall ancient +-- neume support when called with LuaTeX. + +-- GREGORIO_VERSION 4.1.1 + +local catcode_at_letter = luatexbase.catcodetables['gre@atletter'] + +local gregallaliases = { + ["ci~"] = "cl>", + ["pe~"] = "ta>", + ["vs~"] = "ta>", + ["pf~"] = "po>", + ["sc~"] = "pe>2", + ["sa~"] = "pe>2", + ["suu1"] = "ta-", + ["ppu1"] = "ta-", + ["pfG"] = "sfM", + ["cl~"] = "vi>", + ["pr~"] = "vs>", + ["visu2"] = "ci", + ["vi-su2"] = "ci-", + ["visu3"] = "ci1", + ["visu1sux1"] = "ci>", + ["clSsut1"] = "ciG", + ["clSsu2"] = "ciG1", + ["visu1suw1"] = "ciM", + ["vi-su1suw1"] = "ciM-", + ["visu1sut1"] = "ciS", + ["visut2"] = "ciS1", + ["visu2lsc3"] = "cilsc3", + ["vipp2"] = "sc", + ["vi-ppt2"] = "sc-", + ["vipp3"] = "sc1", + ["vi>pp2"] = "sc>", + ["peppt1"] = "scG", + ["vippt2"] = "scS", + ["ta>ppt1"] = "sc~", + ["clpp2"] = "sf", + ["cl-ppt2"] = "sf-", + ["cl>pp2"] = "sf>", + ["toppt1"] = "sfG", + ["clMpp2"] = "sfM1", + ["clppt2"] = "sfS", + ["clpp2lsc2"] = "sflsc2", + ["ciSppt1"] = "vippt1su1sut1", + ["cippt1"] = "vippt1su2", + ["cippt1lsc3"] = "vippt1su2lsc3", + ["cippu1"] = "vippu1su2", + ["cippu1lsc3"] = "vippu1su2lsc3", + ["clppt1"] = "toG", + ["pf!cl~"] = "cl!po>", + ["pf!cl~ppt1"] = "cl!po>ppt1" +} + +local function gregallreadfont(font_id) + local tab = {} + local metrics = {} + local fontdata = font.getfont(font_id) + -- The unicodes table may be lazy-loaded, so iterating it may not + -- return everything. Attempting to retrieve the code point of a + -- glyph that has not already been loaded will trigger the __index + -- method in the metatable (implemented by the fontloader) to load + -- the table until the glyph is found. When iterating the + -- unicodes, we want the whole table to be filled, so we try to + -- access a non-existing glyph in order to force load the entire + -- table. + local ignored = fontdata.resources.unicodes['_this_is_hopefully_a_nonexistent_glyph_'] + for key, value in pairs(fontdata.resources.unicodes) do + local g = fontdata.characters[value] + local name = key:gsub("B", ">"):gsub("N", "-"):gsub("E", "!"):gsub("T", "~") + if g and (value >= 0xe400) and (value < 0xf000) then + tab[name] = "\\char" .. value + metrics[name] = { width = g.width, height = g.height, depth = (g.depth and g.depth or 0) } + end + end + for key, value in pairs(gregallaliases) do + if tab[value] and not tab[key] then + tab[key] = tab[value] + metrics[key] = metrics[value] + end + end + return tab, metrics +end + +local gregalltab = {} +local gregallmetrics = {} + +local gregallneumekinds = { vi = 1, pu = 1, ta = 1, gr = 1, cl = 1, un = 1, pv = 1, pe = 1, po = 1, to = 1, ci = 1, sc = 1, pf = 1, sf = 1, tr = 1, + st = 1, ds = 1, ts = 1, tg = 1, bv = 1, tv = 1, pr = 1, pi = 1, vs = 1, ["or"] = 1, sa = 1, pq = 1, qi = 1, ql = 1, pt = 1 } +local gregalllskinds = { c = 1, t = 1, s = 1, l = 1, x = 1, ["+"] = 1, a = 1, al = 1, am = 1, b = 1, cm = 1, co = 1, cw = 1, d = 1, e = 1, eq = 1, + ew = 1, f = 1, fid = 1, fr = 1, g = 1, h = 1, hp = 1, hn = 1, i = 1, im = 1, iv = 1, k = 1, lb = 1, lc = 1, len = 1, + lm = 1, lp = 1, lt = 1, m = 1, md = 1, moll = 1, n = 1, nl = 1, nt = 1, p = 1, par = 1, pfec = 1, pm = 1, q = 1, + sb = 1, sc = 1, sc = 1, simil = 1, simul = 1, sj = 1, sjc = 1, sjcm = 1, sm = 1, st = 1, sta = 1, su = 1, tb = 1, + th = 1, tm = 1, tw = 1, v = 1, ve = 1, vol = 1 } + +-- Parse a single base neume +local gregallparse_base = function (str, idx, len) + local ret = str:sub(idx, idx + 1) + local alt = {} + local height = 5 + local alts = "MSG-><~" + if idx >= len or not gregallneumekinds[ret] then return 1 end + idx = idx + 2 + -- The alternation modifiers can be written in arbitrary order, + -- canonicalize it and remove duplicates. + while idx <= len and alts:find(str:sub(idx, idx)) do + alt[str:sub(idx, idx)] = 1 + idx = idx + 1 + end + for i = 1, 7 do + local c = alts:sub(i, i) + if alt[c] then ret = ret .. c end + end + -- This is followed by a single optional variant digit. + if idx <= len and string.find("123456789", str:sub(idx, idx)) then + ret = ret .. str:sub(idx, idx) + idx = idx + 1 + end + -- Ambitus not handled yet, neither during parsing, nor when + -- typesetting. + -- Optional height, h[a-m]. + if idx < len and str:sub(idx, idx) == "h" then + local p = string.find("abcdefghijklm", str:sub(idx + 1, idx + 1)) + if not p then return 1 end + height = p - 1 + idx = idx + 2 + end + return 0, idx, ret, height +end + +-- Parse one neume, which is one base neume or several base neumes +-- separated with ! characters, and all this followed by arbitrary +-- ls, pp and su modifiers. +local gregallparse_neume = function (str, idx, len) + local err + local bases = {} + local heights = {} + local pp = '' + local su = '' + local ls = {} + local lsidx = 0 + local i = 1 + err, idx, bases[0], heights[0] = gregallparse_base(str, idx, len) + if err == 1 then return 1 end + while idx <= len and str:sub(idx, idx) == "!" do + err, idx, bases[i], heights[i] = gregallparse_base(str, idx + 1, len) + if err == 1 then return 1 end + i = i + 1 + end + while idx < len do + local v = str:sub(idx, idx + 1) + if v == "ls" then + local idx2 = idx + 2 + while idx2 <= len and not string.find("12346789", str:sub(idx2, idx2)) do + idx2 = idx2 + 1 + end + if idx2 > len or not gregalllskinds[str:sub(idx + 2, idx2 - 1)] then return 1 end + ls[lsidx] = str:sub(idx, idx2) + lsidx = lsidx + 1 + idx = idx2 + 1 + elseif v == "su" or v == "pp" then + local mod = '' + idx = idx + 2 + local c = str:sub(idx, idx) + if idx <= len and string.find("tuvwxy", c) then + mod = mod .. c + idx = idx + 1 + c = str:sub(idx, idx) + end + -- Pre/subpuncta with height not supported yet + -- the heights would need to be adjusted relatively to heights[0] + if idx > len or not string.find("123456789", c) then return 1 end + mod = mod .. c + if v == "su" then su = su .. "su" .. mod else pp = pp .. "pp" .. mod end + idx = idx + 1 + else break end + end + return 0, idx, bases, heights, ls, pp, su +end + +local add_ls = function(base, pre, ls, position, glyphbox, lsbox, baseraise, lwidths, curlwidths, scale) + local raise = 0 + if position == 3 or position == 6 or position == 9 then + if position == 3 then + raise = glyphbox.height - (lsbox.height-lsbox.depth)/2 + baseraise + elseif position == 6 then + raise = (glyphbox.height-glyphbox.depth)/2 - (lsbox.height+lsbox.depth)/2 + baseraise + else + raise = -glyphbox.depth - (lsbox.height+lsbox.depth)/2 + baseraise + end + local kern1 = curlwidths[position] - lwidths[12] + curlwidths[position] = curlwidths[position] + lsbox.width + local kern2 = lwidths[12] - curlwidths[position] + if curlwidths[12] == 0 then + curlwidths[12] = 1 + kern1 = 0 + end + kern1 = kern1 * scale + kern2 = kern2 * scale + raise = raise * scale + return base..'\\kern '..string.format("%.3f",kern1)..'sp\\raise '..string.format("%.3f",raise)..'sp\\hbox{'..ls..'}\\kern '..string.format("%.3f",kern2)..'sp', pre + elseif position == 2 or position == 8 then + if position == 2 then + raise = glyphbox.height + lsbox.depth + baseraise + else + raise = -glyphbox.depth - lsbox.height + baseraise + end + local kern1 = -math.max(glyphbox.width, lwidths[11])/2 - lwidths[position]/2 + curlwidths[position] + curlwidths[position] = curlwidths[position] + lsbox.width + local kern2 = - kern1 - lsbox.width + if curlwidths[11] == 0 and glyphbox.width < lwidths[11] then + curlwidths[11] = 1 + base = '\\kern '..string.format("%.3f",(lwidths[11] - glyphbox.width)/2 * scale)..'sp'..base + kern1 = kern1 + (lwidths[11] - glyphbox.width)/2 + end + kern1 = kern1 * scale + kern2 = kern2 * scale + raise = raise * scale + return base..'\\kern '..string.format("%.3f",kern1)..'sp\\raise '..string.format("%.3f",raise)..'sp\\hbox{'..ls..'}\\kern '..string.format("%.3f",kern2)..'sp', pre + else + if position == 1 then + raise = glyphbox.height - (lsbox.height-lsbox.depth)/2 + baseraise + elseif position == 4 then + raise = (glyphbox.height-glyphbox.depth)/2 - (lsbox.height+lsbox.depth)/2 + baseraise + else + raise = -glyphbox.depth - (lsbox.height+lsbox.depth)/2 + baseraise + end + local kern1 = curlwidths[position] - lwidths[position] + curlwidths[position] = curlwidths[position] + lsbox.width + local kern2 = lwidths[position] - curlwidths[position] + if curlwidths[10] == 0 then + curlwidths[10] = 1 + kern1 = lwidths[10] - lwidths[position] + end + kern1 = kern1 * scale + kern2 = kern2 * scale + raise = raise * scale + return base, pre..'\\kern '..string.format("%.3f",kern1)..'sp\\raise '..string.format("%.3f",raise)..'sp\\hbox{'..ls..'}\\kern '..string.format("%.3f",kern2)..'sp' + end +end + +local add_spacing = function(str, len, idx, ret) + while idx <= len and (str:sub(idx, idx) == "/" or str:sub(idx, idx) == "`") do + if idx < len and str:sub(idx, idx + 1) == "//" then + ret = ret .. "\\hskip \\gre@space@skip@nabclargerspace" + idx = idx + 2 + elseif idx < len and str:sub(idx, idx + 1) == "``" then + ret = ret .. "\\hskip -\\gre@space@skip@nabclargerspace" + idx = idx + 2 + elseif str:sub(idx, idx) == "/" then + ret = ret .. "\\hskip \\gre@space@skip@nabcinterelementspace" + idx = idx + 1 + else + ret = ret .. "\\hskip -\\gre@space@skip@nabcinterelementspace" + idx = idx + 1 + end + end + return idx, ret +end + +local gregallparse_neumes = function(str, kind, scale) + local len = str:len() + local idx = 1 + local ret = '' + idx, ret = add_spacing(str, len, idx, ret) + while idx <= len do + local err, bases, heights, ls, pp, su, lscount + err, idx, bases, heights, ls, pp, su = gregallparse_neume (str, idx, len) + if err == 1 then return ret .. "ERR" end + local base = bases[0] + local i = 1 + while bases[i] do + base = base .. "!" .. bases[i] + local h = heights[i] - heights[0] + if h ~= 0 then + h = h + 5 + if h < 0 or h > 12 then + base = "ERR" + break + end + base = base .. string.sub("abcdefghijklm", h + 1, h + 1) + end + i = i + 1 + end + lscount = 0 + while ls[lscount] do + if not gregalltab[kind][ls[lscount]:sub(1, -2)] then base = "ERR" end + lscount = lscount + 1 + end + if base ~= "ERR" then + local l = {} + function l.try (kind, base, parts, pp, su, ls) + if parts == 2 and pp ~= '' and su ~= '' and gregalltab[kind][base .. pp .. su .. ls] then return base .. pp .. su .. ls, '', '' end + -- Prefer subpunctis over prepunctis. + if parts == 1 and su ~= '' and gregalltab[kind][base .. su .. ls] then return base .. su .. ls, pp, '' end + if parts == 1 and pp ~= '' and gregalltab[kind][base .. pp .. ls] then return base .. pp .. ls, '', su end + -- Prefer subpunctis over significative letters. + if parts == 0 and su ~= '' and ls ~= '' and gregalltab[kind][base .. su] then return nil, pp, su end + if parts == 0 and gregalltab[kind][base .. ls] then return base .. ls, pp, su end + return nil, pp, su + end + local r = nil + local ppsuparts = 0 + if pp ~= '' then ppsuparts = 1 end + if su ~= '' then ppsuparts = ppsuparts + 1 end + -- We assume here no character in the font has more than two + -- significative letters. + local allparts = ppsuparts + lscount + if lscount >= 2 then allparts = ppsuparts + 2 end + -- Try to match as many parts (ls sequences, pp string, su string) as possible + -- except that for ls accept any of ls sequences only if we have all of them. + for parts = allparts, 0, -1 do + if lscount == 2 and parts >= 2 and parts <= 2 + ppsuparts then + r, pp, su = l.try(kind, base, parts - 2, pp, su, ls[0] .. ls[1]) + if not r then + r, pp, su = l.try(kind, base, parts - 2, pp, su, ls[1] .. ls[0]) + end + if r then + ls[0] = '' + ls[1] = '' + break + end + if r then break end + end + if lscount == 1 and parts >= 1 and parts <= 1 + ppsuparts then + r, pp, su = l.try(kind, base, parts - 1, pp, su, ls[0]) + if r then + ls[0] = '' + break + end + end + r, pp, su = l.try(kind, base, parts, pp, su, '') + if r then break end + end + if not r or (pp ~= '' and not gregalltab[kind][pp]) or (su ~= '' and not gregalltab[kind][su]) then + base = "ERR" + else + base = gregalltab[kind][r] + local above = '' + local below = '' + local rmetrics = { width = gregallmetrics[kind][r].width, + height = gregallmetrics[kind][r].height, + depth = gregallmetrics[kind][r].depth } + -- Should the pre and subpuncta be somehow specially positioned + -- against the base neume? + if pp ~= '' then + base = gregalltab[kind][pp] .. base + rmetrics.width = rmetrics.width + gregallmetrics[kind][pp].width + rmetrics.height = math.max (rmetrics.height, gregallmetrics[kind][pp].height) + rmetrics.depth = math.max (rmetrics.height, gregallmetrics[kind][pp].depth) + end + if su ~= '' then + base = base .. gregalltab[kind][su] + rmetrics.width = rmetrics.width + gregallmetrics[kind][su].width + rmetrics.height = math.max (rmetrics.height, gregallmetrics[kind][su].height) + rmetrics.depth = math.max (rmetrics.height, gregallmetrics[kind][su].depth) + end + local baseraise = 0 + if heights[0] ~= 5 then + baseraise = (heights[0] - 5) * gregallmetrics[kind].cl.height / 4 + base = '\\raise '..string.format("%.3f",baseraise * scale)..'sp\\hbox{'..base..'}' + end + local lwidths = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + local curlwidths = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + for i = 0, lscount - 1 do + if ls[i] ~= '' then + local p = tonumber(ls[i]:sub(-1, -1)) + local l = ls[i]:sub(1, -2) + lwidths[p] = lwidths[p] + gregallmetrics[kind][l].width + end + end + lwidths[10] = math.max (lwidths[1], lwidths[4], lwidths[7]) + lwidths[11] = math.max (lwidths[2], lwidths[8]) + lwidths[12] = math.max (lwidths[3], lwidths[6], lwidths[9]) + local pre = '' + for i = 0, lscount - 1 do + if ls[i] ~= '' then + local p = tonumber(ls[i]:sub(-1, -1)) + local l = ls[i]:sub(1, -2) + local lstr = gregalltab[kind][l] + base, pre = add_ls(base, pre, lstr, p, rmetrics, gregallmetrics[kind][l], baseraise, lwidths, curlwidths, scale) + end + end + base = pre..base + end + end + ret = ret .. base + idx, ret = add_spacing(str, len, idx, ret) + end + return ret +end + +local function init_font(fontname) + if not gregalltab[fontname] then + gregalltab[fontname], gregallmetrics[fontname] = gregallreadfont(font.current()) + end +end + +local function print_nabc(nabc) + tex.sprint(catcode_at_letter, nabc) +end + +gregoriotex.parse_nabc = gregallparse_neumes +gregoriotex.print_nabc = print_nabc +gregoriotex.init_nabc_font = init_font +gregoriotex.nabc_font_tables = gregalltab diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-nabc.tex b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-nabc.tex new file mode 100644 index 00000000000..25ebe0b847c --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-nabc.tex @@ -0,0 +1,64 @@ +%GregorioTeX file. +% +% Copyright (C) 2014-2015 The Gregorio Project (see CONTRIBUTORS.md) +% +% This file is part of Gregorio. +% +% Gregorio 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. +% +% Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +% this file contains macros for St. Gall ancient neume support + +\gre@debugmsg{general}{Loading gregoriotex-nabc.tex}% +\gre@declarefileversion{gregoriotex-nabc.tex}{4.1.1}% GREGORIO_VERSION + + +\xdef\gre@nabcfontname{gregall} +\xdef\gre@nabcfontsize{8} + +\def\gresetnabcfont#1#2{% + \xdef\gre@nabcfontname{#1}% + \xdef\gre@nabcfontsize{#2}% + \global\font\gre@font@nabc={name:#1} at #2 pt\relax % + {% + \gre@font@nabc % + \directlua{gregoriotex.init_nabc_font("\luatexluaescapestring{#1}")}% + }% + \gre@nabcfontloadedtrue% +} + +\def\grenabccharno#1#2#3{{\directlua{ + gregoriotex.print_nabc(gregoriotex.parse_nabc("#1", "\luatexluaescapestring{#2}", #3)) +}}} + +\def\GreNABCChar#1{{% + %\catcode`\~=12{}% + %\catcode`\@=11{}% + \gre@font@nabc % + \gre@style@nabc % + \grenabccharno{#1}{\gre@nabcfontname}{1}% + \endgre@style@nabc% +}} + +\def\GreNABCNeumes#1#2{% + \GreSetTextAboveLines{\GreNABCChar{#2}}% +} + +\newif\ifgre@nabcfontloaded% +\gre@nabcfontloadedfalse% + +\def\GreScoreNABCLines#1{% + \ifgre@nabcfontloaded\else% + \gresetnabcfont{\gre@nabcfontname}{\gre@nabcfontsize}% + \fi % +} diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-signs.lua b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-signs.lua new file mode 100644 index 00000000000..0acb9789e75 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-signs.lua @@ -0,0 +1,485 @@ +--GregorioTeX Signs Lua support file. +-- +--Copyright (C) 2015 The Gregorio Project (see CONTRIBUTORS.md) +-- +--This file is part of Gregorio. +-- +--Gregorio 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. +-- +--Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +-- this file contains lua functions to support signs used by GregorioTeX. + +-- GREGORIO_VERSION 4.1.1 + +local err = gregoriotex.module.err +local warn = gregoriotex.module.warn +local info = gregoriotex.module.info +local log = gregoriotex.module.log + +-- Note offset cases: +-- here are the common values for both hepisema (and consequently also for +-- additional lines) and vepisema +-- this indicates the note +local offset_cases = { + -- punctum as last note (works with pes) + { + case = 'FinalPunctum', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctum}{1}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPPunctum}{\gre@char@he@punctum{#4}}{2}{#3}]], + }, + -- deminutus as last note + { + case = 'FinalDeminutus', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctumDeminutus}{1}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPPunctumDeminutus}{\gre@char@he@initio{#4}}{2}{#3}]], + }, + -- second-to-last note, disconnected from prior note, with a second ambitus + -- of at least two, when last note is a standard punctum (like the second + -- note of hig) + { + case = 'PenultBeforePunctumWide', + v = [[\gre@vepisemaorrareaux{\GreCPFlexusNobarTwoNothing}{\GreCPPunctum}{2}{0}{#2}{#3}{#4}]], + -- a kind of flexus, it has the good width + h = [[\gre@hepisorlineaux{\GreCPFlexusNobarTwoNothing}{\gre@char@he@punctum{#4}}{2}{#3}]], + }, + -- second-to-last note, when last note is a deminutus + { + case = 'PenultBeforeDeminutus', + v = [[\gre@vepisemaorrareaux{0}{\GreCPFlexusTwoDeminutus}{1}{0}{#2}{#3}{#4}]], + -- in order to go to the good place, we first make a kern of - the glyph + -- before deminutus, which has the same width as a standard flexus deminutus + h = [[\gre@hepisorlineaux{\GreCPFlexusTwoDeminutus}{\gre@char@he@punctum{#4}}{2}{#3}]], + }, + -- third-to-last note, when the last note is a punctum (for porrectus flexus) + { + case = 'AntepenultBeforePunctum', + v = [[\gre@vepisemaorrareaux{\GreCPTorculusOneTwoNothing}{\GreCPPunctum}{2}{0}{#2}{#3}{#4}]], + -- is a torculus, it has the good width + h = [[\gre@hepisorlineaux{\GreCPTorculusOneTwoNothing}{\gre@char@he@punctum{#4}}{2}{#3}]], + }, + -- third-to-last note, when the last notes is a deminutus (for porrectus + -- flexus) + { + case = 'AntepenultBeforeDeminutus', + v = [[\gre@vepisemaorrareaux{\GreCPTorculusTwoTwoDeminutus}{\GreCPPunctum}{2}{0}{#2}{#3}{#4}]], + -- torculus deminutus has the good width + h = [[\gre@hepisorlineaux{\GreCPTorculusTwoTwoDeminutus}{\gre@char@he@punctum{#4}}{2}{#3}]], + }, + -- standard punctum as first note, disconnected from next note + { + case = 'InitialPunctum', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctum}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{0}{\gre@char@he@punctum{#4}}{0}{#3}]], + }, + -- initio debilis (always the first note) + { + case = 'InitioDebilis', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctumDeminutus}{0}{0}{#2}{#3}{#4}]], + -- we assume that the initio-debilis has the same width as a punctum + -- deminutus + h = [[\gre@hepisorlineaux{0}{\gre@char@he@initio{#4}}{0}{#3}]], + }, + -- first note of a non-auctus porrectus with a second ambitus of at least two + { + case = 'PorrNonAuctusInitialWide', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctum}{0}{0}{#2}{#3}{#4}]], + -- we do (for now) the same as case 6 + h = [[\gre@hepisorlineaux{0}{\gre@char@he@porrectus{#2}{#4}}{0}{#3}]], + }, + -- first note of a non-auctus porrectus with a second ambitus of one + { + case = 'PorrNonAuctusInitialOne', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctum}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{0}{\gre@char@he@porrectus@amone{#2}{#4}}{0}{#3}]], + }, + -- first note of an auctus porrectus, regardless of second ambitus + { + case = 'PorrAuctusInitialAny', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctum}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{0}{\gre@char@he@porrectusfl{#2}{#4}}{0}{#3}]], + }, + -- punctum inclinatum as last note + { + case = 'FinalInclinatum', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctumInclinatum}{0}{30\the\gre@factor }{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPPunctumInclinatum}{\gre@char@he@inclinatum{#4}}{2}{#3}]], + }, + -- punctum inclinatum deminutus as last note + { + case = 'FinalInclinatumDeminutus', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctumInclinatumDeminutus}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPPunctumInclinatumDeminutus}{\gre@char@he@inclinatumdem{#4}}{2}{#3}]], + }, + -- stropha as last note + { + case = 'FinalStropha', + v = [[\gre@vepisemaorrareaux{0}{\GreCPStropha}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPStropha}{\gre@char@he@stropha{#4}}{2}{#3}]], + }, + -- quilisma as last note + { + case = 'FinalQuilisma', + v = [[\gre@vepisemaorrareaux{0}{\GreCPQuilisma}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPQuilisma}{\gre@char@he@quilisma{#4}}{2}{#3}]], + }, + -- oriscus as last note + { + case = 'FinalOriscus', + v = [[\gre@vepisemaorrareaux{0}{\GreCPOriscus}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPOriscus}{\gre@char@he@oriscus{#4}}{2}{#3}]], + }, + -- second-to-last note, with a second ambitus of one, when last note is a + -- standard punctum (like the second note of ghg) + { + case = 'PenultBeforePunctumOne', + v = [[\gre@vepisemaorrareaux{\GreCPFlexusNobarOneNothing}{\GreCPPunctum}{2}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPFlexusNobarOneNothing}{\gre@char@he@punctum{#4}}{2}{#3}]], + }, + -- "upper smaller punctum" as last note (concerning simple podatus, podatus, + -- and torculus resupinus) + { + case = 'FinalUpperPunctum', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctumSmall}{1}{-30\the\gre@factor}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPPunctumSmall}{\gre@char@he@smallpunctum{#4}}{2}{#3}]], + }, + -- oriscus as first note, disconnected from next note + { + case = 'InitialOriscus', + v = [[\gre@vepisemaorrareaux{0}{\GreCPOriscusReversus}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{0}{\gre@char@he@oriscus{#4}}{0}{#3}]], + }, + -- quilisma as first note, disconnected from next note + { + case = 'InitialQuilisma', + v = [[\gre@vepisemaorrareaux{0}{\GreCPQuilisma}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{0}{\gre@char@he@quilisma{#4}}{0}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with a punctum, + -- with a first and second ambitus of at least two + { + case = 'TorcResNonAuctusSecondWideWide', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@punctum@two}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingPunctumTwo}{\gre@char@he@porrectus{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with a punctum, + -- with a first ambitus of one and a second ambitus of at least two + { + case = 'TorcResNonAuctusSecondOneWide', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@punctum@one}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingPunctumOne}{\gre@char@he@porrectus{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus initio debilis with any + -- first ambitus and a second ambitus of at least two + { + case = 'TorcResDebilisNonAuctusSecondAnyWide', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@debilis}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingPunctumOneInitioDebilis}{\gre@char@he@porrectus{#2}{#4}}{3}{#3}]], + }, + -- linea punctum (cavum) as last note + { + case = 'FinalLineaPunctum', + v = [[\gre@vepisemaorrareaux{0}{\GreCPLineaPunctum}{1}{0}{#2}{#3}{#4}]], + -- the episema is not quite long enough so I assumed a different width + -- for now... + h = [[\gre@hepisorlineaux{\GreCPPesQuadratumOneInitioDefilisDescendens}{\gre@char@he@punctum{#4}}{2}{#3}]], + }, + -- standard bar + { + case = 'BarStandard', + v = [[\gre@vepisemaorrareaux{0}{\GreCPDivisioMinima}{1}{0}{#2}{#3}{#4}]], + }, + -- virgula + { + case = 'BarVirgula', + v = [[\gre@vepisemaorrareaux{0}{\GreCPVirgula}{1}{0}{#2}{#3}{#4}]], + }, + -- divisio finalis + { + case = 'BarDivisioFinalis', + v = [[\gre@vepisemaorrareaux{0}{\gre@fontchar@divisiofinalis}{1}{0}{#2}{#3}{#4}]], + }, + -- second note of a non-auctus torculus resupinus starting with a quilisma, + -- with a first and second ambitus of at least two + { + case = 'TorcResQuilismaNonAuctusSecondWideWide', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@quilisma@two}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingQuilismaTwo}{\gre@char@he@porrectus{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with an oriscus, + -- with a first and second ambitus of at least two + { + case = 'TorcResOriscusNonAuctusSecondWideWide', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@oriscus@two}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingOriscusTwo}{\gre@char@he@porrectus{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with a quilisma, + -- with a first ambitus of one and and second ambitus of at least two + { + case = 'TorcResQuilismaNonAuctusSecondOneWide', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@quilisma@one}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingQuilismaOne}{\gre@char@he@porrectus{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with an oriscus, + -- with a first ambitus of one and and second ambitus of at least two + { + case = 'TorcResOriscusNonAuctusSecondOneWide', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@oriscus@one}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingOriscusOne}{\gre@char@he@porrectus{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with a punctum, + -- with a first ambitus of at least two and a second ambitus of one + { + case = 'TorcResNonAuctusSecondWideOne', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@punctum@two}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingPunctumTwo}{\gre@char@he@porrectus@amone{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus initio debilis with any + -- first ambitus and a second ambitus of one + { + case = 'TorcResDebilisNonAuctusSecondAnyOne', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@debilis}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingPunctumOneInitioDebilis}{\gre@char@he@porrectus@amone{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with a quilisma, + -- with a first ambitus of at least two and a second ambitus of one + { + case = 'TorcResQuilismaNonAuctusSecondWideOne', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@quilisma@two}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingQuilismaTwo}{\gre@char@he@porrectus@amone{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with an oriscus, + -- with a first ambitus of at least two and a second ambitus of one + { + case = 'TorcResOriscusNonAuctusSecondWideOne', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@oriscus@two}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingOriscusTwo}{\gre@char@he@porrectus@amone{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with a punctum, + -- with a first and second ambitus of one + { + case = 'TorcResNonAuctusSecondOneOne', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@punctum@one}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingPunctumOne}{\gre@char@he@porrectus@amone{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with a quilisma, + -- with a first and second ambitus of one + { + case = 'TorcResQuilismaNonAuctusSecondOneOne', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@quilisma@one}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingQuilismaOne}{\gre@char@he@porrectus@amone{#2}{#4}}{3}{#3}]], + }, + -- second note of a non-auctus torculus resupinus starting with an oriscus, + -- with a first and second ambitus of one + { + case = 'TorcResOriscusNonAuctusSecondOneOne', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@oriscus@one}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingOriscusOne}{\gre@char@he@porrectus@amone{#2}{#4}}{3}{#3}]], + }, + -- second note of an auctus torculus resupinus starting with a punctum, with + -- a first ambitus of at least two and any second ambitus + { + case = 'TorcResAuctusSecondWideAny', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@punctum@two}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingPunctumTwo}{\gre@char@he@porrectusfl{#2}{#4}}{3}{#3}]], + }, + -- second note of an auctus torculus resupinus initio debilis with any first + -- and second ambitus + { + case = 'TorcResDebilisAuctusSecondAnyAny', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@debilis}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingPunctumOneInitioDebilis}{\gre@char@he@porrectusfl{#2}{#4}}{3}{#3}]], + }, + -- second note of an auctus torculus resupinus starting with a quilisma, with + -- a first ambitus of at least two and any second ambitus + { + case = 'TorcResQuilismaAuctusSecondWideAny', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@quilisma@two}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingQuilismaTwo}{\gre@char@he@porrectusfl{#2}{#4}}{3}{#3}]], + }, + -- second note of an auctus torculus resupinus starting with an oriscus, with + -- a first ambitus of at least two and any second ambitus + { + case = 'TorcResOriscusAuctusSecondWideAny', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@oriscus@two}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingOriscusTwo}{\gre@char@he@porrectusfl{#2}{#4}}{3}{#3}]], + }, + -- second note of an auctus torculus resupinus starting with a punctum, with + -- a first ambitus of one and any second ambitus + { + case = 'TorcResAuctusSecondOneAny', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@punctum@one}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingPunctumOne}{\gre@char@he@porrectusfl{#2}{#4}}{3}{#3}]], + }, + -- second note of an auctus torculus resupinus starting with a quilisma, with + -- a first ambitus of one and any second ambitus + { + case = 'TorcResQuilismaAuctusSecondOneAny', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@quilisma@one}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingQuilismaOne}{\gre@char@he@porrectusfl{#2}{#4}}{3}{#3}]], + }, + -- second note of an auctus torculus resupinus starting with an oriscus, with + -- a first ambitus of one and any second ambitus + { + case = 'TorcResOriscusAuctusSecondOneAny', + v = [[\gre@vepisemaorrareaux{\gre@char@fuse@oriscus@one}{\GreCPPunctum}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPLeadingOriscusOne}{\gre@char@he@porrectusfl{#2}{#4}}{3}{#3}]], + }, + -- second-to-last note connected to prior note, with a second ambitus of at + -- least two, when last note is a standard punctum (like the second note of + -- gig) + { + case = 'ConnectedPenultBeforePunctumWide', + v = [[\gre@vepisemaorrareaux{\GreCPFlexusLineBL}{\GreCPPunctumLineBLBR}{2}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPFlexusLineBL}{\gre@char@he@punctum@line@blbr{#4}}{2}{#3}]], + }, + -- second-to-last note connected to prior note, with a second ambitus of one, + -- when last note is a standard punctum (like the second note of gih) + { + case = 'ConnectedPenultBeforePunctumOne', + v = [[\gre@vepisemaorrareaux{\GreCPFlexusAmOneLineBL}{\GreCPPunctumLineBL}{2}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPFlexusAmOneLineBL}{\gre@char@he@punctum@line@bl{#4}}{2}{#3}]], + }, + -- standard punctum as first note, connected to next higher note + { + case = 'InitialConnectedPunctum', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctumLineTR}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{0}{\gre@char@he@punctum@line@tr{#4}}{0}{#3}]], + }, + -- "virga" as first note, connected to next lower note + { + case = 'InitialConnectedVirga', + v = [[\gre@vepisemaorrareaux{0}{\GreCPVirgaBaseLineBL}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{0}{\gre@char@he@virgabase@line@bl{#4}}{0}{#3}]], + }, + -- quilisma as first note, connected to next higher note + { + case = 'InitialConnectedQuilisma', + v = [[\gre@vepisemaorrareaux{0}{\GreCPQuilismaLineTR}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{0}{\gre@char@he@quilisma@line@tr{#4}}{0}{#3}]], + }, + -- oriscus as first note, connected to next higher note + { + case = 'InitialConnectedOriscus', + v = [[\gre@vepisemaorrareaux{0}{\GreCPOriscusLineTR}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{0}{\gre@char@he@oriscus@line@tr{#4}}{0}{#3}]], + }, + -- punctum as last note, connected to prior higher note + { + case = 'FinalConnectedPunctum', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctum}{1}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPPunctumLineTL}{\gre@char@he@punctum@line@tl{#4}}{2}{#3}]], + }, + -- auctus as last note, connected to prior lower note + { + case = 'FinalConnectedAuctus', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctumAuctusLineBL}{1}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPPunctumAuctusLineBL}{\gre@char@he@punctumauctus@line@bl{#4}}{2}{#3}]], + }, + -- virga aucta as last note + { + case = 'FinalVirgaAuctus', + v = [[\gre@vepisemaorrareaux{0}{\GreCPVirgaReversaDescendens}{1}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPVirgaReversaDescendens}{\gre@char@he@punctumauctus@line@bl{#4}}{2}{#3}]], + }, + -- "virga" as last note, connected to prior lower note + { + case = 'FinalConnectedVirga', + v = [[\gre@vepisemaorrareaux{0}{\GreCPVirga}{1}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPVirga}{\gre@char@he@virga{#4}}{2}{#3}]], + }, + -- "virga" as first note, disconnected from next note + { + case = 'InitialVirga', + v = [[\gre@vepisemaorrareaux{0}{\GreCPVirga}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{0}{\gre@char@he@virga{#4}}{0}{#3}]], + }, + -- "oriscus" as the middle note of a salicus with a second ambitus of at + -- least two + { + case = 'SalicusOriscusWide', + v = [[\gre@vepisemaorrareaux{\GreCPVirgaStrataThreeNothing}{\GreCPSalicusOriscus}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPVirgaStrataThreeNothing}{\gre@char@he@salicus@oriscus{#4}}{4}{#3}]], + }, + -- "oriscus" as the middle note of a salicus with a second ambitus of one + { + case = 'SalicusOriscusOne', + v = [[\gre@vepisemaorrareaux{\GreCPVirgaStrataOneNothing}{\GreCPOriscus}{3}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPVirgaStrataOneNothing}{\gre@char@he@salicus@oriscus{#4}}{4}{#3}]], + }, + -- punctum fused to the next note + { + case = 'LeadingPunctum', + v = [[\gre@vepisemaorrareaux{0}{\GreCPPunctum}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPPunctumTwoUp}{\gre@char@he@punctum{#4}}{2}{#3}]], + }, + -- qulisma fused to the next note + { + case = 'LeadingQuilisma', + v = [[\gre@vepisemaorrareaux{0}{\GreCPQuilisma}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPQuilismaTwoUp}{\gre@char@he@quilisma{#4}}{2}{#3}]], + }, + -- oriscus fused to the next note + { + case = 'LeadingOriscus', + v = [[\gre@vepisemaorrareaux{0}{\GreCPOriscus}{0}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPOriscusTwoUp}{\gre@char@he@oriscus{#4}}{2}{#3}]], + }, + -- flat + { + case = 'Flat', + v = [[\gre@vepisemaorrareaux{0}{\GreCPFlat}{1}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPFlat}{\gre@char@he@flat{#4}}{2}{#3}]], + }, + -- sharp + { + case = 'Sharp', + v = [[\gre@vepisemaorrareaux{0}{\GreCPSharp}{1}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPSharp}{\gre@char@he@sharp{#4}}{2}{#3}]], + }, + -- natural + { + case = 'Natural', + v = [[\gre@vepisemaorrareaux{0}{\GreCPNatual}{1}{0}{#2}{#3}{#4}]], + h = [[\gre@hepisorlineaux{\GreCPNatural}{\gre@char@he@natural{#4}}{2}{#3}]], + }, +} + +local function emit_offset_macros() + local i, item + for i, item in ipairs(offset_cases) do + log([[\def\GreOCase%s{%d}]], item.case, i) + tex.sprint(string.format([[\def\GreOCase%s{%d}]], item.case, i)) + end + tex.sprint([[\def\gre@v@case#1#2#3#4{]]) + tex.sprint([[\ifcase#1\gre@bug{Invalid note offset case: \string#1}]]) + for i, item in ipairs(offset_cases) do + tex.sprint([[\or]]) + if item.v then + tex.sprint(item.v) + end + end + tex.sprint([[\else\gre@bug{Invalid note 2 offset case: \string#1}]]) + tex.sprint([[\fi}]]) + tex.sprint([[\def\gre@h@case#1#2#3#4{]]) + tex.sprint([[\ifcase#1\gre@bug{Invalid note offset case: \string#1}]]) + for i, item in ipairs(offset_cases) do + tex.sprint([[\or]]) + if item.h then + tex.sprint(item.h) + end + end + tex.sprint([[\else\gre@bug{Invalid note offset case: \string#1}]]) + tex.sprint([[\fi}]]) +end + +gregoriotex.emit_offset_macros = emit_offset_macros diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-signs.tex b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-signs.tex new file mode 100644 index 00000000000..36ffb0a23ac --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-signs.tex @@ -0,0 +1,2282 @@ +%GregorioTeX file. +% +% Copyright (C) 2007-2015 The Gregorio Project (see CONTRIBUTORS.md) +% +% This file is part of Gregorio. +% +% Gregorio 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. +% +% Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + + +% this file contains definitions of signs (bar, episema, punctum, alterations) + +\def\grebarbracewidth{.58879}% + +\gre@debugmsg{general}{Loading gregoriotex-signs.tex}% +\gre@declarefileversion{gregoriotex-signs.tex}{4.1.1}% GREGORIO_VERSION + +\def\gre@usestylecommon{% + \ifgre@usestylefont\else % + \gre@usestylefonttrue% + \gre@setstylefont % + \fi % + \relax % +}% + +\gresetglyphstyle{default}% + +% Possibility to disable some signs: +\newif\ifgre@disablevepisema +\gre@disablevepisemafalse +\newif\ifgre@disablehepisema +\gre@disablehepisemafalse +\newif\ifgre@disablemora +\gre@disablemorafalse + +\def\greprintsigns#1#2{% + \IfStrEqCase{#2}{% + {enable}% + {% + \IfStrEqCase{#1}{% + {vepisema}% + {\global\gre@disablevepisemafalse}% + {hepisema}% + {\global\gre@disablehepisemafalse}% + {mora}% + {\global\gre@disablemorafalse}% + {all}% + {\global\gre@disablemorafalse\global\gre@disablevepisemafalse\global\gre@disablehepisemafalse}% + }[% all other cases + \gre@error{Unrecognized first argument for \protect\greprintsigns}% + ]% + }% + {disable}% + {% + \IfStrEqCase{#1}{% + {vepisema}% + {\global\gre@disablevepisematrue}% + {hepisema}% + {\global\gre@disablehepisematrue}% + {mora}% + {\global\gre@disablemoratrue}% + {all}% + {\global\gre@disablemoratrue\global\gre@disablevepisematrue\global\gre@disablehepisematrue}% + }[% all other cases + \gre@error{Unrecognized first argument for \protect\greprintsigns}% + ]% + }% + }[% all other cases + \gre@error{Unrecognized second argument for \protect\greprintsigns}% + ]% +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for discretionaries +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% In order to avoid clef change at beginning or end of line, we use discretionaries +% for clef change, or even with more complex data (z0::c3 for instance). The problem +% with discretionaries is that: +% - you cannot use \hskip (but you can use kern) +% - you cannot use \penalty (which is useless indeed) +% +% To remedy that, we define \gre@hskip to be \hskip outside a discretionary, and +% \kern inside a discretionary. This is what these macros do: + +\def\gre@falsepenalty#1{}% +\def\gre@truepenalty#1{\penalty#1}% + +\let\gre@hskip\hskip% +\let\gre@penalty\gre@truepenalty% +\xdef\gre@insidediscretionary{\number 0}% + +% #1 is the type of discretionary, for penalty assignment. Recognized types: +% - 0: clef change +\def\GreDiscretionary#1#2#3{% + \global\let\gre@hskip\kern % + \global\let\gre@penalty\gre@falsepenalty % + \global\xdef\gre@insidediscretionary{\number 1}% + \discretionary{% + \global\gre@lastoflinecount=1\relax % (a good magic trick) + \gre@debugmsg{bolshift}{discretionary pre lastoflinecount: \the\gre@lastoflinecount}% + #2% + }{% + \global\gre@lastoflinecount=2\relax % (a good magic trick) + \gre@debugmsg{bolshift}{discretionary post lastoflinecount: \the\gre@lastoflinecount}% + }{% + \gre@debugmsg{bolshift}{discretionary no lastoflinecount: \the\gre@lastoflinecount}% + #3% + }% + \global\xdef\gre@insidediscretionary{\number 0}% + \global\let\gre@hskip\hskip % + \global\let\gre@penalty\gre@truepenalty % + \relax % +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of the clefs of the beginning of lines and custos +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% flag for showing the clef +\newif\ifgre@showclef% +\gre@showcleftrue + +\def\gresetclef#1{% + \IfStrEqCase{#1}{% + {visible}% + {\gre@showcleftrue}% + {invisible}% + {\gre@showcleffalse}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetclef\MessageBreak Possible options are: 'visible' and 'invisible'}% + ]% +}% + + +\def\greremoveclef{% OBSOLETE + \gre@obsolete{\protect\greremoveclef}{\protect\gresetclef{invisible}}% +}% + +\def\grenormalclef{% OBSOLETE + \gre@obsolete{\protect\grenormalclef}{\protect\gresetclef{visible}}% +}% + +%% marcro to define the clef that will appear at the beginning of the lines +% the first argument is the type : f or c, and the second is the height +% the third argument is whether we must type a space after or not (0 if not, 1 if yes) +% if the fourth argument is 3, it means that we must not put a flat after the key, otherwise it's the height of the flat +\def\GreSetLinesClef#1#2#3#4#5#6#7{% + \gre@localleftbox{% + \gre@skip@temp@four = \gre@dimen@additionalleftspace\relax% + \kern\gre@skip@temp@four % + \copy\gre@box@lines% draws the lines + \unkern % + \ifgre@showclef% + \gre@skip@temp@four = \gre@space@skip@afterclefnospace\relax% + \hbox{\gre@typeclef{#1}{#2}{0}{#3}{#4}{#5}{#6}{#7}\hskip\gre@skip@temp@four}% + \else % + \gre@skip@temp@four = \gre@space@dimen@noclefspace\relax% + \hbox{\kern\gre@skip@temp@four}% + \fi % + }% + \xdef\gre@clefflatheight{#4}% + \xdef\gre@cleftwoflatheight{#7}% + \relax% +}% + +\def\gre@save@clef#1#2#3#4#5#6{% + \global\let\gre@clef=#1\relax% + \xdef\gre@clefheight{#2}% + \xdef\gre@clefflatheight{#3}% + \global\let\gre@cleftwo=#4\relax% + \xdef\gre@cleftwoheight{#5}% + \xdef\gre@cleftwoflatheight{#6}% +}% + +%% macro redrawing a key from clefnum, useful for vertical space changes +\def\gre@updatelinesclef{% + \GreSetLinesClef{\gre@clef}{\gre@clefheight}{1}{\gre@clefflatheight}% + {\gre@cleftwo}{\gre@cleftwoheight}{\gre@cleftwoflatheight}\relax % +}% + +\newbox\gre@box@temp@clef% +\newbox\gre@box@temp@cleftwo% +% macro that typesets the clef +% arguments are : +%% #1: the type of the clef : c or f +%% #2: the line of the clef (1 is the lowest) +%% #3: if we must use small clef characters (inside a line) or not 0: if not inside, 1 if inside +%% #4: if we must type a space after or not +%% #5: if 3, it means that we must not put a flat after the clef, otherwise it's the height of the flat +%% #6: the type of the secondary clef : c or f +%% #7: the line of the secondary clef (1 is the lowest) +%% #8: if 3, it means that we must not put a flat after the secondary clef, otherwise it's the height of the flat +\def\gre@typeclef#1#2#3#4#5#6#7#8{% + \setbox\gre@box@temp@width=\hbox{% + \ifcase#7% + \gre@typesingleclef{#1}{#2}{#3}{#5}% + \else % + \ifnum\numexpr (#7 - #2) * (#7 - #2) > 1 \relax % + \setbox\gre@box@temp@clef=\hbox{\gre@typesingleclef{#1}{#2}{#3}{#5}}% + \setbox\gre@box@temp@cleftwo=\hbox{\gre@typesingleclef{#6}{#7}{#3}{#8}}% + \ifdim\wd\gre@box@temp@clef>\wd\gre@box@temp@cleftwo% + \hbox to 0pt{\copy\gre@box@temp@cleftwo}\copy\gre@box@temp@clef% + \else % + \hbox to 0pt{\copy\gre@box@temp@clef}\copy\gre@box@temp@cleftwo% + \fi % + \else % + \gre@typesingleclef{#1}{#2}{#3}{#5}% + \gre@skip@temp@two=\gre@space@skip@clefflatspace\relax% + \gre@hskip\gre@skip@temp@two % + \gre@typesingleclef{#6}{#7}{#3}{#8}% + \fi % + \fi % + }% + \ifcase#3% + \global\gre@dimen@clefwidth=\wd\gre@box@temp@width % + \fi % + \copy\gre@box@temp@width % + \gre@skip@temp@two=\gre@space@skip@spaceafterlineclef\relax% + \ifnum#4=0\relax % + \gre@skip@temp@two=\gre@space@skip@afterclefnospace\relax% + \fi % + \gre@hskip\gre@skip@temp@two % +}% + +% macro that typesets one clef +% arguments are : +%% #1: the type of the key : c or f +%% #2: the line of the key (1 is the lowest) +%% #3: if we must use small key characters (inside a line) or not 0: if not inside, 1 if inside +%% #4: if 3, it means that we must not put a flat after the key, otherwise it's the height of the flat +\def\gre@typesingleclef#1#2#3#4{% + \ifcase#2 % + \or% + \gre@calculate@glyphraisevalue{\gre@pitch@c}{0}{}% + \or% + \gre@calculate@glyphraisevalue{\gre@pitch@e}{0}{}% + \or% + \gre@calculate@glyphraisevalue{\gre@pitch@g}{0}{}% + \or% + \gre@calculate@glyphraisevalue{\gre@pitch@i}{0}{}% + \or% + \gre@calculate@glyphraisevalue{\gre@pitch@k}{0}{}% + \fi% + \ifx c#1% we check if it is a c key + \ifcase#3% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@fontchar@cclef}{}{}% + \or% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@fontchar@incclef}{}{}% + \fi% + \else % we consider that it is a f key + \ifcase#3% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@fontchar@fclef}{}{}% + \or% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@fontchar@infclef}{}{}% + \fi% + \fi% + \ifnum#4=3% + \else % + \gre@skip@temp@four = \gre@space@skip@clefflatspace\relax% + \gre@hskip\gre@skip@temp@four % + \GreFlat{#4}{1}{}{}{}% + \fi % + \relax % +}% + +% macro that writes the initial key, and sets the next keys to the same value +% if #3 is 3, it means that we must not put a flat after the key, otherwise it's the height +% of the flat +\def\GreSetInitialClef#1#2#3#4#5#6{% + \gre@save@clef{#1}{#2}{#3}{#4}{#5}{#6}% + \ifgre@showclef% + \gre@typeclef{#1}{#2}{0}{1}{#3}{#4}{#5}{#6}% + \else% + \gre@skip@temp@four = \gre@space@dimen@noclefspace\relax% + \hbox{\kern\gre@skip@temp@four}% + \fi % + \GreSetLinesClef{#1}{#2}{1}{#3}{#4}{#5}{#6}% + % if the initial is big, then we adjust the second line + \ifnum\gre@biginitial=0\relax % + \else % + \gre@adjustsecondline % + \fi % + \relax% +}% + +% macro called when the key changes +% #1 and #2 are the type and line of the clef +% #3 is 1 or 0 according to the need of a space before the clef. Useful for clefs after bars for example +% if #4 is 3, it means that we must not put a flat after the key, otherwise it's the height +% of the flat +\def\GreChangeClef#1#2#3#4#5#6#7{% + % it makes no sense to change the clef when there is no clef... + \gresetclef{visible}% + \gre@save@clef{#1}{#2}{#4}{#5}{#6}{#7}% + \ifnum\gre@insidediscretionary=0\relax % + \GreSetLinesClef{#1}{#2}{1}{#4}{#5}{#6}{#7}% + \fi % + \ifnum#3=1\relax % + \gre@skip@temp@four = \gre@space@skip@clefchangespace\relax% + \gre@hskip\gre@skip@temp@four % + \else % + % here it means that there is a bar before the clef, so we skip the difference between the normal space and the space around bars with clef changes + \gre@skip@temp@four = -\gre@space@skip@spacearoundclefbars\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \gre@typeclef{#1}{#2}{1}{0}{#4}{#5}{#6}{#7}% + \gre@skip@temp@four = \gre@space@skip@clefchangespace\relax% + \gre@hskip\gre@skip@temp@four % + \relax% +}% + +% custos just typesets a custos, useful for before the key changes for example +% #1 is the height +% #2 is indicating if the custo ends the line +\def\GreCustos#1{% + \ifdim\gre@skip@bar@lastskip=0pt\else % we're after a bar: + \kern-\gre@skip@bar@lastskip % + \fi % + \gre@skip@temp@four = \gre@space@skip@spacebeforeinlinecustos\relax% + \kern\gre@skip@temp@four% + \gre@calculate@glyphraisevalue{#1}{0}{}% + %here we need some tricks to draw the line before the custos (for the color) + \setbox\gre@box@temp@width=\hbox{\gre@pickcustos{#1}}% + \gre@dimen@temp@three=\wd\gre@box@temp@width % + \ifgre@showlines % + \ifnum#1<\gre@pitch@belowstaff\relax % + \gre@additionalbottomcustoslinemiddle % + \else\ifnum#1>\gre@pitch@abovestaff\relax % + \gre@additionaltopcustoslinemiddle % + \fi\fi % + \fi % + \raise \gre@dimen@glyphraisevalue\relax% + \copy\gre@box@temp@width % + \ifdim\gre@skip@bar@lastskip=0pt\relax % + % for now we consider we always have a bar after the custos + % we don't want to end the line here + \GreNoBreak % + \gre@skip@temp@four = -\gre@space@skip@spacearoundclefbars\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \else % + \GreNoBreak % + \kern\gre@skip@bar@lastskip % + \GreNoBreak % + \fi % + \relax % +}% + +% typesets a custos for the end of the score +\def\GreFinalCustos#1{% + \GreNoBreak% + \gre@dimen@temp@four = \glueexpr(\gre@space@skip@spacebeforeeolcustos)\relax% + \kern\gre@dimen@temp@four % + \GreNoBreak% + \GreCustos{#1}% + \gre@endofglyphcommon % +} + +% the argument is the height +\edef\gre@nextcustos{\gre@pitch@dummy}% +\def\GreNextCustos#1{% + \gre@debugmsg{custos}{nextcustos = #1}% + \ifnum\gre@insidediscretionary=0\relax % + \gre@debugmsg{custos}{not discretionary}% + \edef\gre@nextcustos{#1}% + \ifgre@blockeolcustos\else% + \gre@debugmsg{custos}{not blocked}% + \gre@calculate@glyphraisevalue{#1}{0}{}% + %here we need some tricks to draw the line before the custos (for the color) + \setbox\gre@box@temp@width=\hbox{% + % we type a hskip and the we type the custos + \gre@hskip\gre@space@skip@spacebeforeeolcustos\relax % + \gre@pickcustos{#1}\relax % + }% + \gre@dimen@temp@three=\wd\gre@box@temp@width % + % we make \wd\gre@box@temp@sign contain the width of a custos + \setbox\gre@box@temp@sign=\hbox{% + \gre@pickcustos{#1}\relax % + }% + \gre@localrightbox{% + \ifgre@showlines % + \ifnum#1<\gre@pitch@belowstaff\relax % + \gre@additionalbottomcustoslineend % + \else\ifnum#1>\gre@pitch@abovestaff\relax % + \gre@additionaltopcustoslineend % + \fi\fi % + \fi % + \raise \gre@dimen@glyphraisevalue\relax% + \copy\gre@box@temp@width % + }% + \fi % + \fi % + \relax% +}% + +% macro that typesets an additional line at the top for custos at end of line + +\def\gre@additionaltopcustoslineend{% + \gre@dimen@temp@five=\dimexpr(\gre@dimen@staffheight % + + \gre@space@dimen@spacebeneathtext % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@interstafflinespace % + + \gre@dimen@additionalbottomspace % + + \gre@dimen@currenttranslationheight)\relax % + \raise\gre@dimen@temp@five % + \hbox to 0pt{% + \gre@style@additionalstafflines % + \ifx\gre@empty@additionalstafflinesformat\greadditionalstafflinesformat% OBSOLETE + \else % OBSOLETE + \gre@obsolete{\protect\greadditionalstafflinesformat}{\protect\grechangestyle{additionalstafflinesformat}}% OBSOLETE + \fi% OBSOLETE + \kern\gre@dimen@temp@three % + \gre@dimen@temp@five=\dimexpr(\wd\gre@box@temp@sign + \gre@space@dimen@additionalcustoslineswidth)\relax% + \kern-\gre@dimen@temp@five % + \vrule width \gre@dimen@temp@five height \gre@dimen@stafflineheight\relax% + \hss % + \endgre@style@additionalstafflines% + }% + \relax % +}% + +\def\gre@additionalbottomcustoslineend{% + \gre@dimen@temp@five=\dimexpr(\gre@space@dimen@spacebeneathtext % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@additionalbottomspace % + + \gre@dimen@currenttranslationheight % + - \gre@dimen@interstafflinespace % + - \gre@dimen@stafflineheight)\relax % + \raise\gre@dimen@temp@five % + \hbox to 0pt{% + \gre@style@additionalstafflines % + \ifx\gre@empty@additionalstafflinesformat\greadditionalstafflinesformat% OBSOLETE + \else % OBSOLETE + \gre@obsolete{\protect\greadditionalstafflinesformat}{\protect\grechangestyle{additionalstafflinesformat}}% OBSOLETE + \fi% OBSOLETE + \kern\gre@dimen@temp@three % + \gre@dimen@temp@five=\dimexpr(\wd\gre@box@temp@sign+\gre@space@dimen@additionalcustoslineswidth)\relax% + \kern-\gre@dimen@temp@five % + \vrule width \gre@dimen@temp@five height \gre@dimen@stafflineheight\relax% + \hss % + \endgre@style@additionalstafflines% + }% + \relax % +}% + +% same macros, but for a custos in the middle + +\def\gre@additionaltopcustoslinemiddle{% + \gre@dimen@temp@five=\dimexpr(\gre@dimen@staffheight % + + \gre@space@dimen@spacebeneathtext % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@interstafflinespace % + + \gre@dimen@additionalbottomspace % + + \gre@dimen@currenttranslationheight)\relax% + \raise\gre@dimen@temp@five % + \hbox to 0pt{% + \gre@style@additionalstafflines % + \ifx\gre@empty@additionalstafflinesformat\greadditionalstafflinesformat% OBSOLETE + \else % OBSOLETE + \gre@obsolete{\protect\greadditionalstafflinesformat}{\protect\grechangestyle{additionalstafflinesformat}}% OBSOLETE + \fi% OBSOLETE + \hss % + \kern\gre@dimen@temp@three % + \gre@dimen@temp@five=\dimexpr((\gre@space@dimen@additionalcustoslineswidth*2)+\wd\gre@box@temp@sign)\relax % + \vrule width \gre@dimen@temp@five height \gre@dimen@stafflineheight\relax% + \hss % + \endgre@style@additionalstafflines% + }% + \relax % +}% + +\def\gre@additionalbottomcustoslinemiddle{% + \gre@dimen@temp@five=\dimexpr(\gre@space@dimen@spacebeneathtext % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@additionalbottomspace % + + \gre@dimen@currenttranslationheight % + - \gre@dimen@interstafflinespace % + - \gre@dimen@stafflineheight)\relax% + \raise\gre@dimen@temp@five % + \hbox to 0pt{% + \gre@style@additionalstafflines % + \ifx\gre@empty@additionalstafflinesformat\greadditionalstafflinesformat% OBSOLETE + \else % OBSOLETE + \gre@obsolete{\protect\greadditionalstafflinesformat}{\protect\grechangestyle{additionalstafflinesformat}}% OBSOLETE + \fi% OBSOLETE + \hss % + \kern\gre@dimen@temp@three % + \gre@dimen@temp@five=\dimexpr((\gre@space@dimen@additionalcustoslineswidth*2)+\wd\gre@box@temp@sign)\relax % + \vrule width \gre@dimen@temp@five height \gre@dimen@stafflineheight\relax% + \hss % + \endgre@style@additionalstafflines% + }% + \relax % +}% + +\def\gre@pickcustos#1{% + \ifcase#1% + \or\or% + \or\gre@fontchar@custostopmiddle % + \or\gre@fontchar@custostoplong % + \or\gre@fontchar@custostopshort % + \or\gre@fontchar@custostoplong % + \or\gre@fontchar@custostopshort % + \or % + \ifgre@haslinethree % + \gre@fontchar@custostoplong % + \else % + \gre@fontchar@custosbottomlong % + \fi % + \or % + \ifgre@haslinethree % + \gre@fontchar@custostopshort % + \else % + \gre@fontchar@custosbottomshort % + \fi % + \or % + \ifgre@haslinefour % + \gre@fontchar@custostoplong % + \else % + \gre@fontchar@custosbottomlong % + \fi % + \or % + \ifgre@haslinefour % + \gre@fontchar@custostopshort % + \else % + \ifgre@haslinethree % + \gre@fontchar@custosbottomshort % + \else % + \gre@fontchar@custosbottommiddle % + \fi % + \fi % + \or % + \ifgre@haslinefive % + \gre@fontchar@custostoplong % + \else % + \gre@fontchar@custosbottomlong % + \fi % + \or % + \ifgre@haslinefive % + \gre@fontchar@custostopshort % + \else % + \ifgre@haslinefour % + \gre@fontchar@custosbottomshort % + \else % + \gre@fontchar@custosbottommiddle % + \fi % + \fi % + \or\gre@fontchar@custosbottomlong % + \or % + \ifgre@haslinefive % + \gre@fontchar@custosbottomshort % + \else % + \gre@fontchar@custosbottommiddle % + \fi % + \or\gre@fontchar@custosbottomlong % + \or\gre@fontchar@custosbottommiddle % + \fi% +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of braces and other things above the score +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newif\ifgre@metapost@brace\gre@metapost@bracetrue % +\newif\ifgre@metapost@underbrace\gre@metapost@underbracetrue % +\newif\ifgre@metapost@curlybrace\gre@metapost@curlybracetrue % +\newif\ifgre@metapost@barbrace\gre@metapost@barbracetrue % +\def\gresetbracerendering{% + \@ifnextchar[{\gre@setbracerendering}{\gre@setallbracerendering}% +}% +\def\gre@setallbracerendering#1{% + \gre@@setbracerendering{brace}{#1}% + \gre@@setbracerendering{underbrace}{#1}% + \gre@@setbracerendering{curlybrace}{#1}% + \gre@@setbracerendering{barbrace}{#1}% +}% +\def\gre@setbracerendering[#1]#2{% + \IfStrEqCase{#1}{% + {brace}{\gre@@setbracerendering{#1}{#2}}% + {underbrace}{\gre@@setbracerendering{#1}{#2}}% + {curlybrace}{\gre@@setbracerendering{#1}{#2}}% + {barbrace}{\gre@@setbracerendering{#1}{#2}}% + }[\gre@error{Unrecognized option "#1" for \protect\gresetbracerendering\MessageBreak Possible options are: 'brace', 'underbrace', 'curlybrace', and 'barbrace'}]% +}% +\def\gre@@setbracerendering#1#2{% + \IfStrEqCase{#2}{% + {font}{\csname gre@metapost@#1false\endcsname}% + {metapost}{\csname gre@metapost@#1true\endcsname}% + }[\gre@error{Unrecognized option "#2" for \protect\gresetbracerendering\MessageBreak Possible options are: 'font' and 'metapost'}]% +}% + +\gdef\gre@fontchar@curlybrace{\gre@font@music\GreCPCurlyBrace}% +\gdef\gre@fontchar@brace{\gre@font@music\GreCPRoundBrace}% +\gdef\gre@fontchar@underbrace{\gre@font@music\GreCPRoundBraceDown}% + +% the command to resize a box, \resizebox is provided by graphicx +\global\let\gre@resizebox\resizebox % + +% #1: the width +% #2: a vertical shift +% #3: a horizontal shift +% #4: 1 if we shift to the beginning of the last glyph, 0 otherwise +% #5: 1 if we put an accentus above or not +\def\GreOverCurlyBrace#1#2#3#4#5{% + \ifgre@boxing\else % + \gre@brace@common{#1}{#2}{#3}{#4}{#5}{\gre@pitch@overbraceglyph}{\gre@fontchar@curlybrace}% + \fi % +}% + +% #1: the width +% #2: a vertical shift +% #3: a horizontal shift +% #4: 1 if we shift to the beginning of the last glyph, 0 otherwise +\def\GreOverBrace#1#2#3#4{% + \ifgre@boxing\else % + \gre@brace@common{#1}{#2}{#3}{#4}{0}{\gre@pitch@overbraceglyph}{\gre@fontchar@brace}% + \fi % +}% + +% #1: the width +% #2: a vertical shift +% #3: a horizontal shift +% #4: 1 if we shift to the beginning of the last glyph, 0 otherwise +\def\GreUnderBrace#1#2#3#4{% + \ifgre@boxing\else % + \gre@brace@common{#1}{#2}{#3}{#4}{0}{\gre@pitch@underbrace}{\gre@fontchar@underbrace}% + \fi % +}% + +% #1: the width +% #2: a vertical shift +% #3: a horizontal shift +% #4: 1 if we shift to the beginning of the last glyph, 0 otherwise +% #5: 1 if we put an accentus above, 0 if not +% #6: the pitch at which to compute the height +% #7: the brace character +\def\gre@brace@common#1#2#3#4#5#6#7{% + \ifnum#4=1\relax % + \setbox\gre@box@temp@sign=\hbox{\gre@fontchar@punctum}% + \gre@dimen@temp@five=\wd\gre@box@temp@sign % + \kern-\gre@dimen@temp@five % + \fi % + \gre@calculate@glyphraisevalue{#6}{13}{}% + \advance\gre@dimen@glyphraisevalue by #2\relax % + \hbox to 0pt{% + \gre@skip@temp@four = #3\relax % + \kern\gre@skip@temp@four % + \raise\gre@dimen@glyphraisevalue\hbox{% + \ifx#7\gre@fontchar@curlybrace % + \ifgre@metapost@curlybrace % + \gre@draw@curlybrace{#1}% + \else % + \gre@draw@fontbrace{#1}{#7}% + \fi % + \else % + \ifx#7\gre@fontchar@brace % + \ifgre@metapost@brace % + \gre@draw@brace{#1}% + \else % + \gre@draw@fontbrace{#1}{#7}% + \fi % + \else % + \ifx#7\gre@fontchar@underbrace % + \ifgre@metapost@underbrace % + \gre@draw@underbrace{#1}% + \else % + \gre@draw@fontbrace{#1}{#7}% + \fi % + \fi % + \fi % + \fi % + }% + \hss % + \ifnum#5=1\relax % + \gre@calculate@glyphraisevalue{\gre@pitch@overbrace}{13}{}% + \advance\gre@dimen@glyphraisevalue by \gre@space@dimen@curlybraceaccentusshift\relax% + \raise\gre@dimen@glyphraisevalue\hbox{% + \gre@font@music\GreCPAccentus\relax % + }% + \hss % + \fi % + }% + \ifnum#4=1\relax % + \kern\gre@dimen@temp@five % + \fi % + \relax % +}% +% #1 : the width +% #2 : the brace character +\def\gre@draw@fontbrace#1#2{% + \setbox\gre@box@temp@sign=\hbox{#2}% + \gre@resizebox{#1}{\ht\gre@box@temp@sign}{#2}% +}% + +% #1: the width, or * for the bar brace width +% this can't have @ in the name because of the metapost catcode settings +\def\grebracemetapostpreamble#1{% + % multiplier to convert gre@factor to em-size in bp + % (100000 sp) * (72 bp/in) / (65536 sp/pt) / 72.27 (pt/in) + factor = 1.5201782378; + scale = \the\gre@factor * factor; + % assuming #1 is in bp, we convert it back into the internal unit of the + % calculation, ems + width = \directlua{gregoriotex.width_to_bp([[#1]], "\grebarbracewidth * scale")} / scale; +}% + +% #1: the width +\def\gre@draw@curlybrace#1{% + \gre@debugmsg{general}{curly brace width = #1}% + \gre@metapost{ + \grebracemetapostpreamble{#1} + transform t; + t = identity scaled scale; + p := (width - 0.1416) / 2; + q := (width - 0.08626) / 2; + if (p < 0.1005) or (q < 0.12817): + t := t xscaled (width / 0.34261); + p := 0.1005; + q := 0.12817; + fi; + f := 1 + (p / 4); + beginfig(0); + fill + ( (0,0) + -- (0.00651,0) + .. controls (((0.03239**f)*p)+0.00651,0.01763) and (((0.08502**f)*p)+0.00651,0.03065) .. (((0.15789**f)*p)+0.00651,0.03906) + .. controls (((0.23347**f)*p)+0.00651,0.04801) and (((0.32659**f)*p)+0.00651,0.05249) .. (((0.43725**f)*p)+0.00651,0.05249) + .. controls (((0.49663**f)*p)+0.00651,0.05249) and (((0.59109**f)*p)+0.00651,0.05086) .. (((0.72065**f)*p)+0.00651,0.04761) + .. controls (((0.82861**f)*p)+0.00651,0.04408) and (((0.92173**f)*p)+0.00651,0.04232) .. (p+0.00651,0.04232) + .. controls (p+0.0198,0.04232) and (p+0.03242,0.04842) .. (p+0.04435,0.06063) + .. controls (p+0.05602,0.07365) and (p+0.06483,0.0906) .. (p+0.0708,0.11149) + .. controls (p+0.07677,0.0906) and (p+0.08558,0.07365) .. (p+0.09725,0.06063) + .. controls (p+0.10918,0.04842) and (p+0.1218,0.04232) .. (p+0.13509,0.04232) + .. controls (p+((1-(0.92173**f))*p)+0.13509,0.04232) and (p+((1-(0.82861**f))*p)+0.13509,0.04408) .. (p+((1-(0.72065**f))*p)+0.13509,0.04761) + .. controls (p+((1-(0.59109**f))*p)+0.13509,0.05086) and (p+((1-(0.49663**f))*p)+0.13509,0.05249) .. (p+((1-(0.43725**f))*p)+0.13509,0.05249) + .. controls (p+((1-(0.32659**f))*p)+0.13509,0.05249) and (p+((1-(0.23347**f))*p)+0.13509,0.04801) .. (p+((1-(0.15789**f))*p)+0.13509,0.03906) + .. controls (p+((1-(0.08502**f))*p)+0.13509,0.03065) and (p+((1-(0.03239**f))*p)+0.13509,0.01763) .. (p+p+0.13509,0) + -- (p+p+0.13509,0) -- (q+q+0.08626,0) -- (q+q+0.08626,0) + .. controls (q+((1-(0.02117**f))*q)+0.08626,0.02658) and (q+((1-(0.08466**f))*q)+0.08626,0.04774) .. (q+((1-(0.19048**f))*q)+0.08626,0.06348) + .. controls (q+((1-(0.29418**f))*q)+0.08626,0.07975) and (q+((1-(0.42434**f))*q)+0.08626,0.08789) .. (q+((1-(0.58095**f))*q)+0.08626,0.08789) + .. controls (q+((1-(0.63386**f))*q)+0.08626,0.08789) and (q+((1-(0.70159**f))*q)+0.08626,0.08626) .. (q+((1-(0.78413**f))*q)+0.08626,0.08301) + .. controls (q+((1-(0.87937**f))*q)+0.08626,0.07894) and (q+((1-(0.95132**f))*q)+0.08626,0.0769) .. (q+0.08626,0.0769) + .. controls (q+0.06219,0.0769) and (q+0.05013,0.10644) .. (q+0.04679,0.13102) + -- (q+0.04679,0.13102) -- (q+0.03947,0.13102) -- (q+0.03947,0.13102) + .. controls (q+0.03614,0.10644) and (q+0.02407,0.0769) .. (q+0,0.0769) + .. controls (((0.95132**f)*q)+0,0.0769) and (((0.87937**f)*q)+0,0.07894) .. (((0.78413**f)*q)+0,0.08301) + .. controls (((0.70159**f)*q)+0,0.08626) and (((0.63386**f)*q)+0,0.08789) .. (((0.58095**f)*q)+0,0.08789) + .. controls (((0.42434**f)*q)+0,0.08789) and (((0.29418**f)*q)+0,0.07975) .. (((0.19048**f)*q)+0,0.06348) + .. controls (((0.08466**f)*q)+0,0.04774) and (((0.02117**f)*q)+0,0.02658) .. (0,0) + -- cycle + ) transformed t; + setbounds currentpicture to + ( (0,-0.67980) -- (q+q+0.08626,-0.67980) -- (q+q+0.08626,0.13102) -- (0,0.13102) -- cycle ) + transformed t; + endfig; + }% +}% + +% #1: the width +\def\gre@draw@brace#1{% + \gre@draw@roundbrace{#1}{.89500}{ + (-.00192,.70347) % start the top + .. controls (-.00192,.70525) and (-.00134,.70740) + .. (.00000,.71000) -- (.00000,.71000){curl c} + .. (p/2,.89500) % top of the center + .. {curl c}(p,.71000) -- (p,.71000) + .. controls (p+.00134,.70740) and (p+.00192,.70525) + .. (p+.00192,.70347) % end the top + .. controls (p+.00192,.69508) and (p-.01103,.69500) + .. (p-.01856,.69500) % start the bottom + .. controls (p-.01856,.69500) and (p-.01900,.69500) + .. (p-.01900,.69500) -- (p-.01900,.69500){curl c} + .. (p/2,.86400) % bottom of the center + .. {curl c}(.01900,.69500) -- (.01900,.69500) + .. controls (.01900,.69500) and (.01856,.69500) + .. (.01856,.69500) % end the bottom + .. controls (.01103,.69500) and (-.00192,.69508) + .. (-.00192,.70347) -- cycle + }% +}% + +% #1: the width +\def\gre@draw@underbrace#1{% + \gre@draw@roundbrace{#1}{.25500}{ + (-.00192,.24653) % start the bottom + .. controls (-.00192,.24475) and (-.00134,.24260) + .. (.00000,.24000) -- (.00000,.24000){curl c} + .. (p/2,.05500) % bottom of the center + .. {curl c}(p,.24000) -- (p,.24000) + .. controls (p+.00134,.24260) and (p+.00192,.24475) + .. (p+.00192,.24653) % end the bottom + .. controls (p+.00192,.25492) and (p-.01103,.25500) + .. (p-.01856,.25500) % start the top + .. controls (p-.01856,.25500) and (p-.01900,.25500) + .. (p-.01900,.25500) -- (p-.01900,.25500){curl c} + .. (p/2,.08600) % top to the center + .. {curl c}(.01900,.25500) -- (.01900,.25500) + .. controls (.01900,.25500) and (.01856,.25500) + .. (.01856,.25500) % end the top + .. controls (.01103,.25500) and (-.00192,.25492) + .. (-.00192,.24653) -- cycle + }% +}% + +% #1: the width +% #2: height of the bounding box +% #3: metapost commands to draw the outline +\def\gre@draw@roundbrace#1#2#3{% + \gre@debugmsg{general}{round brace width = #1}% + \gre@metapost{ + \grebracemetapostpreamble{#1} + p = width; + transform t; + t = identity scaled scale; + c = 1; + if p < 0.200: + c := 0; + t := t xscaled (p/0.200); + p := 0.200; + elseif p < 0.350: + c := (p - 0.200) / 0.350; + fi; + beginfig(0); + fill ( #3 ) transformed t; + setbounds currentpicture to + ( (0,0) -- (p,0) -- (p,#2) -- (0,#2) -- cycle ) + transformed t; + endfig; + }% +}% + +% #1 : x-distance +% #2 : y-distance +% #3 : -1 for below, 1 for above +\def\gre@draw@slur#1#2#3{% + \gre@metapost{ + \grebracemetapostpreamble{\directlua{gregoriotex.hypotenuse([[#1]],[[#2]])}} + transform t; + t = identity scaled scale; + t := t xscaled width; + t := t rotated \directlua{gregoriotex.rotation([[#1]],[[#2]])}; + beginfig(0); + fill + ( (0,0) + .. controls (0.3,#3*0.20) and (0.7,#3*0.20) + .. (1,0) + -- (1,0) + .. controls (0.7,#3*0.22) and (0.3,#3*0.22) + .. (0,0) + -- cycle + ) transformed t withpen pencircle scaled 0.3; + endfig; + }% +}% + +\newdimen\greslurheight +% #1 : height +% #2 : -1 for below, 1 for above +% #3 : 0 = no left-shift, 1 = left-shift 1 punctum, 2 = left shift 1/2 punctum +% #4 : x-distance +% #5 : y-distance +% #6 : end height if #6 not given +\def\GreSlur#1#2#3#4#5#6{% + \ifgre@boxing\else % + \ifnum\number#2 > 0\relax % + \gre@calculate@glyphraisevalue{#1}{15}{}% + \else % + \gre@calculate@glyphraisevalue{#1}{16}{}% + \fi % + \hbox to 0pt{\raise\gre@dimen@glyphraisevalue\hbox{% + \ifcase#3 % 0 + \or % 1 + \setbox\gre@box@temp@sign=\hbox{\gre@fontchar@punctum}% + \kern-\wd\gre@box@temp@sign % + \or % 2 + \setbox\gre@box@temp@sign=\hbox{\gre@fontchar@punctum}% + \kern-.5\wd\gre@box@temp@sign % + \fi % + \if\relax\detokenize{#5}\relax % + \gre@dimen@temp@five=\gre@dimen@glyphraisevalue\relax % + \ifnum\number#2 > 0\relax % + \gre@calculate@glyphraisevalue{#6}{15}{}% + \else % + \gre@calculate@glyphraisevalue{#6}{16}{}% + \fi % + \greslurheight = \dimexpr(\gre@dimen@glyphraisevalue - \gre@dimen@temp@five)\relax % + \else % + \greslurheight = #5\relax % + \fi % + \gre@draw@slur{#4}{\the\greslurheight}{#2}% + }}% + \fi % + \relax % +}% + +% #1: id of the variable length brace within the score +\def\GreVarBraceLength#1{% + \ifgre@boxing\else % + \directlua{gregoriotex.var_brace_len(#1)}% + \fi % +}% + +% #1: id of the variable length brace within the score +% #2: 0 = no left-shift, 1 = left-shift 1 punctum, 2 = left shift 1/2 punctum +% #3: 1 if the start, 2 if the end +\def\GreVarBraceSavePos#1#2#3{% + \ifgre@boxing\else % + \ifcase#2 % 0 + \gre@debugmsg{general}{save case 0}% + \pdfsavepos % + \or % 1 + \setbox\gre@box@temp@sign=\hbox{\gre@fontchar@punctum}% + \kern-\wd\gre@box@temp@sign % + \pdfsavepos % + \kern\wd\gre@box@temp@sign % + \or % 2 + \gre@debugmsg{general}{save case 2}% + \setbox\gre@box@temp@sign=\hbox{\gre@fontchar@punctum}% + \gre@dimen@temp@five=\wd\gre@box@temp@sign % + \kern-.5\wd\gre@box@temp@sign % + \pdfsavepos % + \kern.5\wd\gre@box@temp@sign % + \fi % + \directlua{gregoriotex.var_brace_note_pos(#1, #3)}% + \fi % + \relax % +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of punctum mora, auctum duplex and choral signs +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% a function to typeset a punctum mora, +% #1 is the letter of the height of the punctum mora +% #2 is +% - 0 in the general case +% - 1 if we make the punctum mora 0-width (e.g!hv) +% - 2 if we shift the width of one punctum to the left (g.e) +% - 3 same as 2 but with ambitus of one (g.f) +% #3 is 1 in case of a punctommora in the note before the last note of a podatus, porrectus or torculus resupinus, 0 otherwise. +% #4 is 1 if we are at a punctum inclinatum, 0 otherwise +\def\gre@punctum@mora#1#2#3#4{% + \GreNoBreak % + \ifcase#2\relax % + \gre@skip@temp@four = \gre@space@skip@spacebeforesigns\relax% + \hskip\gre@skip@temp@four% + \or % + \gre@skip@temp@four = \gre@space@skip@spacebeforesigns\relax% + \kern\gre@skip@temp@four % + \or % + % to get the widht of a punctum minus a line, we calculate the width of a flexus (with ambitus of two) minus the width of a punctum + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPPesQuadratumLongqueueThreeNothing}% + \gre@dimen@temp@five=\wd\gre@box@temp@width % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPPunctum}% + \advance\gre@dimen@temp@five by -\wd\gre@box@temp@width % + \kern-\gre@dimen@temp@five % + \gre@skip@temp@four = \gre@space@skip@spacebeforesigns\relax% + \kern\gre@skip@temp@four % + \or % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPPunctum}% + \gre@dimen@temp@five=\wd\gre@box@temp@width % + \kern-\gre@dimen@temp@five % + \gre@skip@temp@four = \gre@space@skip@spacebeforesigns\relax% + \kern\gre@skip@temp@four % + \fi % + \ifnum#2=0\relax % + \global\gre@lastendswithmoratrue% + \fi % + \ifcase#3\relax % 0 + \gre@calculate@glyphraisevalue{#1}{4}{}% + \or% 1 + \gre@calculate@glyphraisevalue{#1}{8}{}% + \or% 2 + \gre@calculate@glyphraisevalue{#1}{14}{}% + \fi % + % here we shift a bit left in the case where we have a punctum inclinatum on a line + \ifnum#4=1\relax % + \ifgre@isonaline % + \gre@dimen@temp@three=\dimexpr(3700sp * \gre@factor)\relax % + \kern-\gre@dimen@temp@three % + \gre@dimen@temp@three=\dimexpr(4500sp * \gre@factor)\relax% + \advance\gre@dimen@glyphraisevalue by -\gre@dimen@temp@three % + \else % + \gre@dimen@temp@three=\dimexpr(2500sp * \gre@factor)\relax % + \advance\gre@dimen@glyphraisevalue by -\gre@dimen@temp@three % + \fi % + \fi % + \GreNoBreak % + \raise \gre@dimen@glyphraisevalue \hbox{\gre@fontchar@punctummora}% + \GreNoBreak % + \ifcase#2\relax\or % + \setbox\gre@box@temp@width=\hbox{\gre@fontchar@punctummora}% + \gre@skip@temp@four = -\wd\gre@box@temp@width % + \kern\gre@skip@temp@four% + \gre@skip@temp@four = -\gre@space@skip@spacebeforesigns\relax% + \kern\gre@skip@temp@four % + \or % + \setbox\gre@box@temp@width=\hbox{\gre@fontchar@punctummora}% + \gre@skip@temp@four = -\wd\gre@box@temp@width % + \kern\gre@skip@temp@four% + \gre@skip@temp@four = -\gre@space@skip@spacebeforesigns\relax% + \kern\gre@skip@temp@four % + \kern\gre@dimen@temp@five % + \or % + \setbox\gre@box@temp@width=\hbox{\gre@fontchar@punctummora}% + \gre@skip@temp@four = -\wd\gre@box@temp@width % + \kern\gre@skip@temp@four% + \gre@skip@temp@four = -\gre@space@skip@spacebeforesigns\relax% + \kern\gre@skip@temp@four % + \kern\gre@dimen@temp@five % + \fi % + \GreNoBreak % + \relax% +}% + +\def\GrePunctumMora#1#2#3#4{% + \ifgre@disablemora\else % + \gre@punctum@mora{#1}{#2}{#3}{#4}% + \fi % + \relax % +} + +% a function to typeset an augmentum duplex, easy enough to be understood... +\def\GreAugmentumDuplex#1#2#3{% + \ifgre@boxing\else % + \GrePunctumMora{#1}{1}{#3}{0}% + \fi % + \GrePunctumMora{#2}{0}{0}{0}% + \relax % +}% + +\gdef\grelowchoralsignstyle#1{\relax}% OBSOLETE +\let\gre@empty@lowchoralsignstyle\grelowchoralsignstyle% +\gdef\grehighchoralsignstyle#1{\relax}% OBSOLETE +\let\gre@empty@highchoralsignstyle\grehighchoralsignstyle% + +% quite simple function: #1 is the height, #2 is the string, #3 is #2 of punctum mora, #4 is #3 of punctum mora +% #3 is 1 if it must be a bit higher +\def\GreLowChoralSign#1#2#3{% + \GreNoBreak % + \gre@skip@temp@four = \gre@space@skip@beforelowchoralsignspace\relax% + \hskip\gre@skip@temp@four % + \GreNoBreak % + \ifnum#3=1\relax % + \gre@calculate@glyphraisevalue{#1}{12}{}% + \else % + \gre@calculate@glyphraisevalue{#1}{10}{}% + \fi % + \raise\gre@dimen@glyphraisevalue\hbox{\gre@style@lowchoralsign#2\endgre@style@lowchoralsign}% + \ifx\gre@empty@lowchoralsignstyle\grelowchoralsignstyle% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\grelowchoralsignstyle}{\protect\grechangestyle{lowchoralsign}}% OBSOLETE + \fi% OBSOLETE + \relax % +}% + +\def\GreHighChoralSign#1#2#3{% + \GreNoBreak % + \gre@vepisemaorrare{#1}{#3}{}{3}{\gre@style@highchoralsign#2\endgre@style@highchoralsign}% + \ifx\gre@empty@highchoralsignstyle\grehighchoralsignstyle% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\grehighchoralsignstyle}{\protect\grechangestyle{highchoralsign}}% OBSOLETE + \fi% OBSOLETE + \relax % +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of linea +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\GreLinea#1#2#3#4#5#6{% + \GreGlyph{\GreCPLinea}{#1}{#2}{#3}{#4}{#5}{#6}% + \relax % +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of vertical episema +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newbox\gre@box@temp@sign% + +% a macro to help typesetting vertical episema. +% #1 is an offset glyph (see #3 below) +% #2 represents the glyph upon which the sign is to be centered +% #3 is a case number +% 0 : go back to the beginning of the previous glyph and then forward half +% the width of #2; this puts the sign at the beginning of the previous +% glyph, whose first note is the size of #2 +% 1 : go back half the width of #2; this puts the sign at the end of the +% previous glyph, whose last note is the size of #2 +% 2 : go back the width of #1 and then foward half the width of #2; this +% puts the sign at the glyph from the end that starts at #1's width from +% the end +% 3 : go back to the beginning of the previous glyph and then forward the +% width of #1 and then back half the width of #2; this puts the sign at +% the glyph from the start that ends at #1's width from the start +% #4 is a shift that we want to get applied, useful for punctum inclinatum for example +% #5 is the glyph number. +% #6 is the type of sign (1: vertical episema, 2: rare sign, 3: choral sign) +% #7 is the choral sign if relevant +\def\gre@vepisemaorrareaux#1#2#3#4#5#6#7{% + % first we set \gre@dimen@temp@three to the width of the last glyph + \gre@dimen@temp@three=\gre@dimen@lastglyphwidth\relax% + \setbox\gre@box@temp@sign=\hbox{\gre@font@music #2}% + \gre@dimen@temp@two=\dimexpr(\wd\gre@box@temp@sign / 2)\relax % + \ifcase#3% + % tempwidth is the width of the last glyph + \advance\gre@dimen@temp@three by -\gre@dimen@temp@two % + \or% + \gre@dimen@temp@three=\gre@dimen@temp@two % + \or% + \setbox\gre@box@temp@sign=\hbox{\gre@font@music #1}% + \gre@dimen@temp@three=\dimexpr(\wd\gre@box@temp@sign - \gre@dimen@temp@two)\relax % + \or % + \setbox\gre@box@temp@sign=\hbox{\gre@font@music #1}% + \advance\gre@dimen@temp@three by \dimexpr(-\wd\gre@box@temp@sign + \gre@dimen@temp@two)\relax % + \fi% + \kern-\gre@dimen@temp@three % we do it here because of the now-removed ictus (chironomy) + % then we draw the sign + \ifcase#6\or % + % vertical episema + \setbox\gre@box@temp@sign=\hbox{\gre@fontchar@verticalepisema}% + \or % rare sign + \setbox\gre@box@temp@sign=\hbox{\gre@font@music#5}% + \or % choral sign + \setbox\gre@box@temp@sign=\hbox{#7}% + \or % brace above bar + \setbox\gre@box@temp@sign=\hbox{\gre@render@barbrace}% + \fi % + % we set tempwidth to half a punctum malus half the sign width, so that the centers are aligned + \gre@dimen@temp@two=\dimexpr(\wd\gre@box@temp@sign / 2)\relax % + \advance\gre@dimen@temp@three by \gre@dimen@temp@two % + \kern-\gre@dimen@temp@two% + \gre@skip@temp@four = #4sp% + \kern \gre@skip@temp@four% + \raise \gre@dimen@glyphraisevalue \copy\gre@box@temp@sign % + \kern -\gre@skip@temp@four% + % and finally we go back to the end of the glyph, where we were first + \advance\gre@dimen@temp@three by -2\gre@dimen@temp@two % + \kern\gre@dimen@temp@three% + \relax% +}% + +\directlua{gregoriotex.emit_offset_macros()}% + +% a function to typeset a vertical episema or a rare accent (like accentus, +% circulus, etc.). This function must be called after a call to \GreGlyph. +% #1 is the letter of the height of the episema (not the height of the note +% it corresponds to. +% #2 is note position case as in the table above +% #3 is the sign glyph +% #4 is type (1: vertical episema, 2: rare sign, 3: choral sign, 4: brace above the bar) +% #5 is the choral sign if relevant +\def\gre@vepisemaorrare#1#2#3#4#5{% + \ifgre@boxing\else % + \ifcase#4\or % + % if it is a vertical episema, we call the normal calculateglyphvalue + \gre@calculate@glyphraisevalue{#1}{3}{}% + \or % + % if it is not, we call it with 6 as second argument, it will give us the height of the rare signs (accentus, etc.) the first argument is m if the pitch is < k, otherwise it's n. + \ifnum#1<\gre@pitch@raresign\relax % + \gre@calculate@glyphraisevalue{\gre@pitch@raresign}{6}{}% + \else % + {% + \gre@count@temp@three=\numexpr(#1 + 1)\relax % + \gre@calculate@glyphraisevalue{\gre@count@temp@three}{6}{}% + }% + \fi % + \or % if it's a choral sign + \gre@calculate@glyphraisevalue{#1}{11}{}% + \or % if it's the brace above the bar + \gre@calculate@glyphraisevalue{#1}{13}{}% + \fi % + \gre@v@case{#2}{#3}{#4}{#5}% + \fi % + \relax% +}% + +\def\GreVEpisema#1#2{% + \ifgre@disablevepisema\else % + \gre@vepisemaorrare{#1}{#2}{\GreCPVEpisema}{1}{}% + \fi % + \relax % +}% + +\def\GreBarBrace#1{% + \gre@vepisemaorrare{\gre@pitch@overbraceglyph}{#1}{% + \gre@render@barbrace% + }{4}{}% + \relax % +}% +\def\gre@render@barbrace{% + \hbox{% + \ifgre@metapost@barbrace % + \gre@draw@brace{*}% + \else % + \gre@fontchar@abovebarbrace % + \fi % + }% +}% + +\def\GreBarVEpisema#1{% + \gre@vepisemaorrare{\gre@pitch@barvepisema}{#1}{\GreCPVEpisema}{1}{}% + \relax % +}% + +\def\GreAccentus#1#2{% + \gre@vepisemaorrare{#1}{#2}{\GreCPAccentus}{2}{}% + \relax % +}% + +\def\GreSemicirculus#1#2{% + \gre@vepisemaorrare{#1}{#2}{\GreCPSemicirculus}{2}{}% + \relax % +}% + +\def\GreCirculus#1#2{% + \gre@vepisemaorrare{#1}{#2}{\GreCPCirculus}{2}{}% + \relax % +}% + +\def\GreReversedAccentus#1#2{% + \gre@vepisemaorrare{#1}{#2}{\GreCPAccentusReversus}{2}{}% + \relax % +}% + +\def\GreReversedSemicirculus#1#2{% + \gre@vepisemaorrare{#1}{#2}{\GreCPSemicirculusReversus}{2}{}% + \relax % +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting horizontal episema +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +% a macro that will help in the typesetting of a horizontal episema and additional lines, +% #1 is an offset glyph (see #3, below) +% #2 is the episema glyph +% #3 is a case number, similar in nature to #3 in gre@vepisemaorrareaux +% 0 : go back to the beginning of the previous glyph; this starts the +% episema at the beginning of the previous glyph +% 1 : stay at the end of the glyph; doesn't make much sense to use this +% 2 : go back the width of #1; this starts the episema at the glyph from +% the end that starts at #1's width from the end +% 3 : go back to the beginning of the previous glyph and then forward the +% width of #1; this starts the episema at the glyph from the start that +% starts just after #1's width from the start +% 4 : go back to the beginning of the previous glyph and then forward the +% width of #1, then back the width of #2; this ends the episema at the +% end of #1 +% #4 argument is the same as in hepisorline +\def\gre@hepisorlineaux#1#2#3#4{% + \ifcase#3% case 0 + % first we set \gre@dimen@temp@three to the width of the last glyph + \gre@dimen@temp@three=\gre@dimen@lastglyphwidth\relax% + \or % case 1 + \gre@dimen@temp@three=0 pt\relax % + \or % case 2 + \setbox\gre@box@temp@sign=\hbox{\gre@font@music #1}% + \gre@dimen@temp@three=\wd\gre@box@temp@sign% + \or % case 3 + \setbox\gre@box@temp@sign=\hbox{\gre@font@music #1}% + \gre@dimen@temp@three=\dimexpr(\gre@dimen@lastglyphwidth - \wd\gre@box@temp@sign)\relax % + \or % case 4 + \setbox\gre@box@temp@sign=\hbox{\gre@font@music #1}% + \gre@dimen@temp@three=\dimexpr(\gre@dimen@lastglyphwidth - \wd\gre@box@temp@sign)\relax % + \setbox\gre@box@temp@sign=\hbox{\gre@font@music #2}% + \advance\gre@dimen@temp@three by \wd\gre@box@temp@sign % + \fi% + \kern-\gre@dimen@temp@three % + % then we draw the sign, and go back to the beginning of the sign + \setbox\gre@box@temp@sign=\hbox{\gre@font@music#2}% + % we set tempwidth to half a punctum malus half the sign width, so that the centers are aligned + \gre@dimen@temp@two=\wd\gre@box@temp@sign % + \ifcase#4% + %case of hepisema + \raise \gre@dimen@glyphraisevalue \copy\gre@box@temp@sign % + \or % + %case of hepisema at the bottom + \raise \gre@dimen@glyphraisevalue \copy\gre@box@temp@sign % + \or % case of a line at the top + \ifnum\gre@count@lastglyphiscavum=2\relax % + \gre@drawadditionalline{0}{\gre@dimen@temp@two}{0}{}{1}{}% + \else % + \gre@drawadditionalline{0}{\gre@dimen@temp@two}{1}{}{1}{}% + \fi % + \gre@dimen@temp@two=0pt\relax % + \or % case of a line at the bottom + \ifnum\gre@count@lastglyphiscavum=2\relax % + \gre@drawadditionalline{1}{\gre@dimen@temp@two}{0}{}{1}{}% + \else % + \gre@drawadditionalline{1}{\gre@dimen@temp@two}{1}{}{1}{}% + \fi % + \gre@dimen@temp@two=0pt\relax % + \or % + %case of choral sign + \raise \gre@dimen@glyphraisevalue \copy\gre@box@temp@sign % + \or % + \fi % + % and finally we go back to the end of the glyph, where we were first + \advance\gre@dimen@temp@three by -\gre@dimen@temp@two % + \kern\gre@dimen@temp@three % + \relax% +}% + +% another dumb top function +\def\GreAdditionalLine#1#2#3{% + \ifgre@showlines % + \ifgre@boxing\else % + \xdef\gre@dimen@savedglyphraise{\the\gre@dimen@glyphraisevalue}% + \gre@style@additionalstafflines % + \ifx\gre@empty@additionalstafflinesformat\greadditionalstafflinesformat% OBSOLETE + \else % OBSOLETE + \gre@obsolete{\protect\greadditionalstafflinesformat}{\protect\grechangestyle{additionalstafflinesformat}}% OBSOLETE + \fi% OBSOLETE + \gre@hepisorline{\gre@pitch@dummy}{#1}{#2}{#3}{f}{}{}% + \endgre@style@additionalstafflines% + \gre@dimen@glyphraisevalue=\gre@dimen@savedglyphraise\relax% + \fi % + \fi % + \relax % +}% + +% #1 0 for over staff, +% 1 for under staff +% #2 length of line +% #3 0 for no space before, +% 1 for \gre@space@dimen@additionallineswidth before, +% 2 for #4 space before +% #4 custom space before, used if #2 is 2 +% #5 0 for no space after, +% 1 for \gre@space@dimen@additionallineswidth after, +% 2 for #6 space after +% #6 custom space after, used if #4 is 2 +\def\GreDrawAdditionalLine#1#2#3#4#5#6{% + \ifgre@showlines % + \xdef\gre@dimen@savedglyphraise{\the\gre@dimen@glyphraisevalue}% + \gre@style@additionalstafflines % + \ifx\gre@empty@additionalstafflinesformat\greadditionalstafflinesformat% OBSOLETE + \else % OBSOLETE + \gre@obsolete{\protect\greadditionalstafflinesformat}{\protect\grechangestyle{additionalstafflinesformat}}% OBSOLETE + \fi% OBSOLETE + \gre@drawadditionalline{#1}{#2}{#3}{#4}{#5}{#6}% + \endgre@style@additionalstafflines% + \gre@dimen@glyphraisevalue=\gre@dimen@savedglyphraise\relax% + \fi % + \relax % +} +\def\gre@drawadditionalline#1#2#3#4#5#6{% + \ifcase#3 % 0 + \gre@dimen@temp@five=0pt\relax % + \or % 1 + \gre@dimen@temp@five=\gre@space@dimen@additionallineswidth\relax % + \or % 2 + \gre@dimen@temp@five=#4\relax % + \fi % + \ifcase#5 % 0 + \gre@dimen@temp@four=0pt\relax % + \or % 1 + \gre@dimen@temp@four=\gre@space@dimen@additionallineswidth\relax % + \or % 2 + \gre@dimen@temp@four=#6\relax % + \fi % + \gre@dimen@temp@two=% + \dimexpr(#2 % + + \gre@dimen@temp@five % + + \gre@dimen@temp@four)\relax % + \ifcase#1 % 0 + \gre@dimen@glyphraisevalue=% + \dimexpr(\gre@dimen@additionalbottomspace % + + \gre@space@dimen@spacebeneathtext % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@currenttranslationheight % + + \gre@stafflines\gre@dimen@interstafflinespace % + + \gre@stafflines\gre@dimen@stafflineheight)\relax% + \or % 1 + \gre@dimen@glyphraisevalue=% + \dimexpr(\gre@dimen@additionalbottomspace % + + \gre@space@dimen@spacebeneathtext % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@currenttranslationheight % + - \gre@dimen@interstafflinespace % + - \gre@dimen@stafflineheight)\relax% + \fi % + \raise\gre@dimen@glyphraisevalue\hbox to 0pt{% + \kern-\gre@dimen@temp@five % + \vrule height \gre@dimen@stafflineheight % + width \gre@dimen@temp@two % + }% +} + +% a function to typeset a horizontal line (additional line or episema). +% This function must be called after a call to \GreGlyph. +% #1 is the letter of the height of the episema (not the height of the note +% it corresponds to. +% #2 is note position case as in the table above +% #3 is the ambitus for a two note episema at the diagonal stroke of a +% porrectus, porrectus flexus, orculus resupinus, or torculus resupinus +% flexus +% #4 is 0 for an horizontal episema, 1 for an horizontal episema under a +% note, 3 for a line at the bottom, 2 for a line at the top +% #5 is f for a normal episema, l for a small episema aligned left, +% c for a small episema aligned center, or r for a small episema +% aligned right +% #6 is the vertical nudge +% #7 is horizontal episema interline position case +%% 0 : auto +%% 1 : middle +%% 2 : low in space above note +%% 3 : high in space above note +%% 4 : low in space below note +%% 5 : high in space below note +\def\gre@hepisorline#1#2#3#4#5#6#7{{% + \ifcase#4 % 0 + \gre@calculate@glyphraisevalue{#1}{9}{#7}% + \or % 1 + \gre@calculate@glyphraisevalue{#1}{5}{#7}% + \or % 2 + % the glyphraisevalue is ignored anyway... but it's just in case... + \gre@calculate@glyphraisevalue{\gre@pitch@ledger@above}{0}{}% + \or % 3 + \gre@calculate@glyphraisevalue{\gre@pitch@ledger@below}{0}{}% + \fi % + \global\gre@dimen@glyphraisevalue=\dimexpr\gre@dimen@glyphraisevalue#6\relax % + \gre@h@case{#2}{#3}{#4}{#5}% + \relax% +}}% + +% dumb top function +% #6 is a trick for bridges: if we must use a different height because of a +% bridge, use #6, otherwise use #1 +% #7 is used for setting heuristics +% #8 is the vertical nudge +% #9 is horizontal episema interline position case +%% 0 : auto +%% 1 : middle +%% 2 : low in space above note +%% 3 : high in space above note +%% 4 : low in space below note +%% 5 : high in space below note +\def\GreHEpisema#1#2#3#4#5#6#7#8#9{% + \ifgre@boxing\else\ifgre@disablehepisema\else % + \gre@prephepisemaledgerlineheuristics% + #7% + \ifgre@hepisemabridge% + \gre@hepisorline{#6}{#2}{#3}{#4}{#5}{#8}{#9}% + \else % + \gre@hepisorline{#1}{#2}{#3}{#4}{#5}{#8}{#9}% + \fi % + \gre@resetledgerlineheuristics% + \fi\fi % + \relax % +}% + +\newif\ifgre@hepisemabridge +\gre@hepisemabridgetrue + +\def\AddHEpisemusBridges{%OBSOLETE + \gre@obsolete{\protect\AddHEpisemusBridges}{\protect\gresethepisema{bridge}}% +}% + +\def\RemoveHEpisemusBridges{%OBSOLETE + \gre@obsolete{\protect\RemoveHEpisemusBridges}{\protect\gresethepisema{break}}% +}% + +\def\gresethepisema#1{% + \IfStrEqCase{#1}{% + {bridge}% + {\gre@hepisemabridgetrue}% + {break}% + {\gre@hepisemabridgefalse}% + }[% all other cases + \gre@error{Unrecognized option, #1, for \protect\gresethepisema\MessageBreak Possible options are: 'bridge' and 'break'}% + ]% +}% + +% same but for a "bridge episema" after the last note of a glyph (element, syllable) if the next episema is at the same height +% #1 is the height +% #2 is 0 for episema above, 1 for episema below +% #3 is the "space case" for the following note, if a punctum inclinatum +% #4 is for setting heuristics +% #5 is the vertical nudge +% #6 is horizontal episema interline position case +%% 0 : auto +%% 1 : middle +%% 2 : low in space above note +%% 3 : high in space above note +%% 4 : low in space below note +%% 5 : high in space below note +\def\GreHEpisemaBridge#1#2#3#4#5#6{% + \ifgre@hepisemabridge% + \ifgre@boxing\else % + \gre@prephepisemaledgerlineheuristics% + #4% + \ifcase#2 % + \gre@calculate@glyphraisevalue{#1}{9}{#6}% + \or % + \gre@calculate@glyphraisevalue{#1}{5}{#6}% + \fi % + \global\gre@dimen@glyphraisevalue=\dimexpr\gre@dimen@glyphraisevalue#5\relax % + \IfStrEq{-1}{#3}{% + \raise\gre@dimen@glyphraisevalue\hbox to 0pt{\gre@font@music\gre@char@he@punctum{f}\hss}% + }{% + % special handling for punctum inclinatum + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPHEpisemaPunctumReduced}% + \gre@dimen@temp@four = \wd\gre@box@temp@width\relax % + \gre@get@spaceskip{#3}% + % convert rubber length to dimension... not perfect but works in the usual case + \gre@dimen@temp@three = 1\gre@skip@temp@four\relax % + \raise\gre@dimen@glyphraisevalue\hbox to 0pt{% + \loop\ifdim\gre@dimen@temp@three > 0pt\relax% + \advance\gre@dimen@temp@three by -\gre@dimen@temp@four\relax % + {\gre@font@music\GreCPHEpisemaPunctumReduced}% + \repeat % + \kern\gre@dimen@temp@three{\gre@font@music\GreCPHEpisemaPunctumReduced}% + \hss % + }% + }% + \gre@resetledgerlineheuristics% + \fi % + \fi % + \relax % +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of bars +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% we define two types of macro for each four bar : when it is inside a syllable, and when it is not + +\def\GreInVirgula#1#2{% + \gre@writebar{0}{1}{#1}{#2}% + \relax% +}% + +\def\GreVirgula#1#2{% + \gre@writebar{0}{0}{#1}{#2}% + \relax% +}% + +\def\GreInDivisioMinima#1#2{% + \gre@writebar{1}{1}{#1}{#2}% + \relax% +}% + +\def\GreDivisioMinima#1#2{% + \gre@writebar{1}{0}{#1}{#2}% + \relax% +}% + +\def\GreInDivisioMinor#1#2{% + \gre@writebar{2}{1}{#1}{#2}% + \relax% +}% + +\def\GreDivisioMinor#1#2{% + \gre@writebar{2}{0}{#1}{#2}% + \relax% +}% + +\def\GreInDivisioMaior#1#2{% + \gre@writebar{3}{1}{#1}{#2}% + \relax% +}% + +\def\GreDivisioMaior#1#2{% + \gre@writebar{3}{0}{#1}{#2}% + \relax% +}% + +\def\GreDominica#1#2#3{% + \ifcase#1\or % + \gre@writebar{6}{0}{#2}{#3}% + \or % + \gre@writebar{7}{0}{#2}{#3}% + \or % + \gre@writebar{8}{0}{#2}{#3}% + \or % + \gre@writebar{9}{0}{#2}{#3}% + \or % + \gre@writebar{10}{0}{#2}{#3}% + \or % + \gre@writebar{11}{0}{#2}{#3}% + \or % + \gre@writebar{12}{0}{#2}{#3}% + \or % + \gre@writebar{13}{0}{#2}{#3}% + \fi % + \relax% +}% + +\def\GreInDominica#1#2#3{% + \ifcase#1\or % + \gre@writebar{6}{1}{#2}{#3}% + \or % + \gre@writebar{7}{1}{#2}{#3}% + \or % + \gre@writebar{8}{1}{#2}{#3}% + \or % + \gre@writebar{9}{1}{#2}{#3}% + \or % + \gre@writebar{10}{1}{#2}{#3}% + \or % + \gre@writebar{11}{1}{#2}{#3}% + \or % + \gre@writebar{12}{1}{#2}{#3}% + \or % + \gre@writebar{13}{1}{#2}{#3}% + \fi % + \relax% +}% + +\def\GreInDivisioFinalis#1#2{% + \ifgre@endofscore % + \gre@writebar{5}{1}{#1}{#2}% + \else % + \gre@writebar{4}{1}{#1}{#2}% + \fi % + \relax% +}% + +\def\GreDivisioFinalis#1#2{% + \ifgre@endofscore % + \gre@writebar{5}{0}{#1}{#2}% + \else % + \gre@writebar{4}{0}{#1}{#2}% + \fi % + \relax% +}% + +% #1 is #2 of gre@writebar +% #2 is #3 of gre@writebar +% emits the suffix of the space +\def\gre@bar@space@suffix#1#2{% + \ifcase#1\ifgre@newbarspacing % + \ifcase#2 @standalone@notext\or @standalone@text\fi % + \fi\fi % +}% + +\newcount\gre@count@shiftaftermora +\gre@count@shiftaftermora=5 + +\def\gresetshiftaftermora#1{% + \IfStrEqCase{#1}{% + {always}% + {\gre@count@shiftaftermora=5}% + {notesonly}% + {\gre@count@shiftaftermora=4}% + {barsonly}% + {\gre@count@shiftaftermora=3}% + {barsnotextonly}% + {\gre@count@shiftaftermora=2}% + {barsinsideonly}% + {\gre@count@shiftaftermora=1}% + {never}% + {\gre@count@shiftaftermora=0}% + }[% all other cases + \gre@error{Unrecognized option "#1" in gresetshiftaftermora\MessageBreak Possible options are: 'always', 'barsonly', 'notesonly', 'barsnotextonly', 'barsinsideonly' and 'never'}% + ]% +}% + +% width of a punctum mora, reinitalized at each score +\newdimen\gre@dimen@morawidth + +% sets gre@skip@punctummorashift to the (usually negative) shift to apply before +% a syllable following a punctum mora, to cancel its taking into account into +% horizontal placement. +% First argument is: +% - 1 for the general case +% - 2 when the punctum mora is before a bar +\def\gre@get@unkern@aftermora#1{% + \ifdim\gre@dimen@morawidth=0pt\relax % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\gre@fontchar@punctummora}% + \global\gre@dimen@morawidth=\wd\gre@box@temp@width % + \fi % + \ifnum #1=1% + \global\gre@skip@punctummorashift=\glueexpr - \gre@dimen@morawidth - \gre@space@skip@spacebeforesigns + \gre@space@skip@moraadjustment\relax % + \else % + \global\gre@skip@punctummorashift=\glueexpr - \gre@dimen@morawidth - \gre@space@skip@spacebeforesigns + \gre@space@skip@moraadjustmentbar\relax % + \fi % + \relax % +} + +\def\gre@unkern@bar@aftermora{% + \ifgre@newbarspacing% + % don't apply a negative kern on the first glyph + % while boxing, otherwise the box width will be wrong + \ifgre@firstglyph % + \ifgre@boxing\else % + \gre@get@unkern@aftermora{2}% + \kern\gre@skip@punctummorashift % + \fi % + \else % + \gre@get@unkern@aftermora{2}% + \kern\gre@skip@punctummorashift % + \fi % + \else% + \gre@get@unkern@aftermora{2}% + \kern\gre@skip@punctummorashift % + \fi% + \relax % +} + +\newskip\gre@skip@bar@lastskip% skip after last bar + +%a macro to write a bar +%% 1: the type of the bar : 0 for virgula, 1 for minima 2 for minor, 3 for major, 4 for finalis and 5 for the last finalis, 6 to 13 for dominican bars +%% 2: is 0 if it is in a syllable containing only this bar, 1 otherwise +%% 3: is 0 if there's no text under the bar or 1 if there is text under the bar +%% 4: macros that may happen before the skip after the bar (typically GreVEpisema) +\def\gre@writebar#1#2#3#4{% + % first, for the bar to be really centered, if the last glyph has a punctum + % mora, we kern of the corresponding space. We do it only in the case + % of a bar in the middle of other notes. + \ifgre@lastendswithmora % + \ifgre@newbarspacing % + \ifnum\gre@count@shiftaftermora=0\else\ifnum\gre@count@shiftaftermora=4\else % + % new bar spacing takes care of punctum mora on its own, but only when + % bar has its own syllable + \ifcase #2\or % + \gre@unkern@bar@aftermora % + \fi % + \fi\fi % + \else % + \ifcase\gre@count@shiftaftermora\or % + % barsinsideonly + \ifcase #2\or % + \gre@unkern@bar@aftermora % + \fi % + \or % + % barsnotextonly + \ifcase #3\relax % + \gre@unkern@bar@aftermora % + \fi % + \or % + % barsonly + \gre@unkern@bar@aftermora % + \or\or % + % always + \gre@unkern@bar@aftermora % + \fi % + \fi % + \fi % + \gre@newglyphcommon % + \gre@calculate@glyphraisevalue{\gre@pitch@bar}{0}{}% bar glyphs are made to be at this height + \GreNoBreak % + % count indicating if we have to output space or not: + \gre@count@temp@one=0\relax % + \ifnum#2=1\relax % + \gre@count@temp@one=1\relax % + \else % + \ifgre@newbarspacing % + \gre@count@temp@one=1\relax % + \fi % + \fi % + \gre@skip@temp@four=0pt\relax % + \ifcase#1 % 0 : virgula + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@virgula\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPVirgula}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPVirgula}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@virgula\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 1 : minima + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@minima\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioMinima}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioMinima}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@minima\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 2 : minor + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@minor\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioMinor}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioMinor}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@minor\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 3 : maior + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@maior\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioMaior}% + \gre@fontchar@divisiomaior % + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@maior\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 4 : finalis + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@finalis\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@fontchar@divisiofinalis}% + #4\relax % + \gre@fontchar@divisiofinalis% + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@finalis\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 5 : final finalis + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@finalfinalis\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@fontchar@divisiofinalis}% + #4\relax % + \gre@fontchar@divisiofinalis% + \ifgre@newbarspacing % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@finalfinalis\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \or % 6 : dominican bar 1 + \gre@calculate@glyphraisevalue{\gre@pitch@e}{0}{}% + % we need to adjust the height of the bar a little so that it is perfectly aligned with the bottom (or the top for some bars) of the staff line, which is not the case by default if \gre@stafflinefactor is not 10. + \advance\gre@dimen@glyphraisevalue by -\gre@dimen@stafflinediff\relax% + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioDominican}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioDominican}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 7 : dominican bar 2 + \gre@calculate@glyphraisevalue{\gre@pitch@e}{0}{}% + \advance\gre@dimen@glyphraisevalue by \gre@dimen@stafflinediff\relax% + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioDominicanAlt}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioDominicanAlt}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 8 : dominican bar 3 + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \advance\gre@dimen@glyphraisevalue by -\gre@dimen@stafflinediff\relax% + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioDominican}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioDominican}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 9 : dominican bar 4 + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \advance\gre@dimen@glyphraisevalue by \gre@dimen@stafflinediff\relax% + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioDominicanAlt}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioDominicanAlt}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 10 : dominican bar 5 + \gre@calculate@glyphraisevalue{\gre@pitch@i}{0}{}% + \advance\gre@dimen@glyphraisevalue by -\gre@dimen@stafflinediff\relax% + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioDominican}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioDominican}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 11 : dominican bar 6 + \gre@calculate@glyphraisevalue{\gre@pitch@i}{0}{}% + \advance\gre@dimen@glyphraisevalue by \gre@dimen@stafflinediff\relax% + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioDominicanAlt}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioDominicanAlt}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 12 : dominican bar 7 + \gre@calculate@glyphraisevalue{\gre@pitch@k}{0}{}% + \advance\gre@dimen@glyphraisevalue by -\gre@dimen@stafflinediff\relax% + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioDominican}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioDominican}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \or % 13 : dominican bar 8 + \gre@calculate@glyphraisevalue{\gre@pitch@k}{0}{}% + \advance\gre@dimen@glyphraisevalue by \gre@dimen@stafflinediff\relax% + \ifnum\gre@count@temp@one=1\relax % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \GreNoBreak % + \fi % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioDominicanAlt}% + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioDominicanAlt}% + #4\relax % + \ifnum\gre@count@temp@one=1\relax % + \GreNoBreak % + \gre@skip@temp@four = \csname gre@space@skip@bar@dominican\gre@bar@space@suffix{#2}{#3}\endcsname\relax% + \gre@hskip\gre@skip@temp@four % + \fi % + \fi % + \global\gre@skip@bar@lastskip=\gre@skip@temp@four % + \gre@debugmsg{spacing}{Width of bar just printed: \the\wd\gre@box@temp@width}% + \gre@debugmsg{spacing}{Last bar space: \the\gre@skip@temp@four}% + \global\gre@dimen@lastglyphwidth=\wd\gre@box@temp@width % + \directlua{gregoriotex.adjust_line_height(\gre@insidediscretionary)}% + \relax% +}% + +\def\gre@fontchar@divisiomaior{% + \ifnum\gre@stafflinefactor=17\relax % + %\gre@calculate@glyphraisevalue{\gre@pitch@bar}{0}{}% bar glyphs are made to be at this height + \raise\gre@dimen@glyphraisevalue\hbox{\gre@font@music\GreCPDivisioMaior}% + \else % + \setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioMaior}% + % we calculate the raise of the bar + \gre@dimen@temp@five=\dimexpr(\gre@dimen@additionalbottomspace % + + \gre@space@dimen@spacebeneathtext % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@currenttranslationheight)\relax% + % we calculate the height of the bar + \raise\gre@dimen@temp@five\hbox{\vrule height \gre@dimen@staffheight width \wd\gre@box@temp@width}% + \fi % + \relax % +}% + +\def\gre@fontchar@divisiofinalis{% + \gre@calculate@glyphraisevalue{\gre@pitch@bar}{0}{}% bar glyphs are made to be at this height + \gre@fontchar@divisiomaior % + \kern\gre@space@dimen@divisiofinalissep % + \GreNoBreak % + \gre@fontchar@divisiomaior % +}% + +% Flag to tell if we have to keep the localrightbox until the end +\newif\ifgre@keeprightbox% + +%macro to end a line with a divisio finalis +\def\GreFinalDivisioFinalis#1{% + \GreBarSyllable{\GreSetThisSyllable{}{}{}{}{}}{}{}{1}{\GreSetNextSyllable{}{}{}{}{}\GreLastOfLine}{}{16}{}{% + \ifgre@newbarspacing\else % + \gre@hskip\gre@space@skip@bar@finalfinalis % + \GreNoBreak % + \fi % + \GreLastOfScore % + \GreDivisioFinalis{0}{}% + #1% + }% + \relax% +}% + +%macro to end a line with a divisio maior +\def\GreFinalDivisioMaior#1{% + \GreBarSyllable{\GreSetThisSyllable{}{}{}{}{}}{}{}{1}{\GreSetNextSyllable{}{}{}{}{}\GreLastOfLine}{}{16}{}{% + \GreLastOfScore % + \GreDivisioMaior{0}{}% + #1% + }% + \relax% +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for filling holes of empty notes +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% flag to indicate that lines behind a punctum cavum should be hidden +\newif\ifgre@hidepclines +% default state is to not hide them +\gre@hidepclinesfalse + +% macro for manipulating above flag +\def\gresetlinesbehindpunctumcavum#1{% + \IfStrEqCase{#1}{% + {visible}% + {\gre@hidepclinesfalse}% + {invisible}% + {\gre@hidepclinestrue}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetlinesbehindpunctumcavum\MessageBreak Possible options are: 'visible' and 'invisible'}% + ]% +}% + +\def\GreHidePCLines{%OBSOLETE + \gre@obsolete{\protect\GreHidePCLines}{\protect\gresetlinesbehindpunctumcavum{invisible}}% +}% + +\def\GreDontHidePCLines{%OBSOLETE + \gre@obsolete{\protect\GreDontHidePCLines}{\protect\gresetlinesbehindpunctumcavum{visible}}% +}% + +% flag to indicate that lines behind an alteration should be hidden +\newif\ifgre@hidealtlines +% default state is to not hide them +\gre@hidealtlinesfalse + +% macro for manipulating above flag +\def\gresetlinesbehindalteration#1{% + \IfStrEqCase{#1}{% + {visible}% + {\gre@hidealtlinesfalse}% + {invisible}% + {\gre@hidealtlinestrue}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetlinesbehindalteration\MessageBreak Possible options are: 'visible' and 'invisible'}% + ]% +}% + +\def\GreHideAltLines{%OBSOLETE + \gre@obsolete{\protect\GreHideAltLines}{\protect\gresetlinesbehindalteration{invisible}}% +}% + +\def\GreDontHideAltLines{%OBSOLETE + \gre@obsolete{\protect\GreDontHideAltLines}{\protect\gresetlinesbehindalteration{visible}}% +}% + +% is last glyph a cavum? +\newcount\gre@count@lastglyphiscavum +% 0 if no +% 1 if current glyph is a cavum (set once the cavum is filled) +% 2 if previous glyph is a cavum (which is the most interesting information) +\gre@count@lastglyphiscavum=0 + +% the argument is the character with which we fill the hole, and we suppose that +% isonaline and glyphraisevalue are correctly set. +\def\gre@fillhole#1{% + \ifgre@boxing\else % + \global\gre@count@lastglyphiscavum=1\relax % + \setbox\gre@box@temp@sign=\hbox{#1}% + \hbox to 0pt{% + {% + \color{grebackgroundcolor}% + \raise \gre@dimen@glyphraisevalue\relax% + \copy\gre@box@temp@sign % + }% + %\pdfliteral{}% this is a ugly hack for old versions of LuaTeX to work + \hss % + }% + \GreNoBreak % + \fi % + \relax % +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for typesetting alterations +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% the top level macro: +% #1 is the height +% #2 is the char of the alteration +% #3 is the char of the alteration hole +% #4 is 1 if the alteration is the flat in a clef +% #5 are the signs to typeset before the glyph (typically additional bars, as they must be "behind" the glyph) +% #6 are the signs to typeset after the glyph (almost all signs) +% #7 is the line:char:column for a textedit link +\def\gre@alteration#1#2#3#4#5#6#7{% + \setbox\gre@box@temp@width=\hbox{\gre@pointandclick{#2}{#7}}% + \ifnum#4=0\relax % + \gre@newglyphcommon % + \fi % + \global\gre@dimen@lastglyphwidth=\wd\gre@box@temp@width % + % the three next lines are a trick to get the additional lines below the glyphs + \gre@skip@temp@one = \gre@dimen@lastglyphwidth\relax% + \kern\gre@skip@temp@one % + #5\relax % + \kern-\gre@skip@temp@one % + \gre@calculate@glyphraisevalue{#1}{0}{}% + \ifgre@hidealtlines % + \gre@fillhole{#3}% + \fi % + \raise \gre@dimen@glyphraisevalue\relax% + \copy\gre@box@temp@width% + #6\relax % + \ifnum#4=0\relax % + % we try to avoid line breaking after a flat or a natural + \GreNoBreak % + \gre@skip@temp@four = \gre@space@dimen@alterationspace\relax% + \ifgre@firstglyph% + \gre@debugmsg{bolshift}{making adjustments for leading alteration}% + \global\advance\gre@dimen@notesaligncenter by % + \dimexpr(\wd\gre@box@temp@width + \dimexpr\gre@skip@temp@four)\relax % + \kern\gre@skip@temp@four % + \global\gre@dimen@bolextra = \dimexpr(\wd\gre@box@temp@width + \dimexpr\gre@skip@temp@four)\relax% + \gre@debugmsg{bolshift}{bolextra: \the\gre@dimen@bolextra}% + \else % + \gre@hskip\gre@skip@temp@four % + \fi % + \GreNoBreak % + \directlua{gregoriotex.adjust_line_height(\gre@insidediscretionary)}% + \fi % + \relax % +}% + +% This macro typesets a flat on the height provided by #1. +% #2 is 1 if the flat is part of a clef. + +\def\GreFlat#1#2#3#4#5{% + \gre@alteration{#1}{\gre@fontchar@flat}{\gre@fontchar@flathole}{#2}{#3}{#4}{#5}% + \relax% +}% + +% Same as the one before, but for naturals. + +\def\GreNatural#1#2#3#4#5{% + \gre@alteration{#1}{\gre@fontchar@natural}{\gre@fontchar@naturalhole}{#2}{#3}{#4}{#5}% + \relax% +}% + +% Same as the one before, but for sharps. + +\def\GreSharp#1#2#3#4#5{% + \gre@alteration{#1}{\gre@fontchar@sharp}{\gre@fontchar@sharphole}{#2}{#3}{#4}{#5}% + \relax% +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for typesetting punctum cavum +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\gre@fontchar@punctumcavum{\gre@font@music\GreCPPunctumCavum}% +\def\gre@fontchar@lineapunctumcavum{\gre@font@music\GreCPLineaPunctumCavum}% +\def\gre@fontchar@punctumcavumhole{\gre@font@music\GreCPPunctumCavumHole}% +\def\gre@fontchar@lineapunctumcavumhole{\gre@font@music\GreCPLineaPunctumCavumHole}% + +\def\gresetpunctumcavum#1{% + \IfStrEqCase{#1}{% + {alternate}% + {% + \grechangeglyph{PunctumCavum}{greciliae}{.caeciliae}% + \grechangeglyph{LineaPunctumCavum}{greciliae}{.caeciliae}% + \grechangeglyph{PunctumCavumHole}{greciliae}{.caeciliae}% + \grechangeglyph{LineaPunctumCavumHole}{greciliae}{.caeciliae}% + }% + {normal}% + {% + \greresetglyph{PunctumCavum}% + \greresetglyph{LineaPunctumCavum}% + \greresetglyph{PunctumCavumHole}% + \greresetglyph{LineaPunctumCavumHole}% + }% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetpunctumcavum\MessageBreak Possible options are: 'alternate' and 'normal'}% + ]% +}% + + +\def\UseAlternatePunctumCavum{%OBSOLETE + \gre@obsolete{\protect\UseAlternatePunctumCavum}{\protect\gresetpunctumcavum{alternate}}% +}% + +\def\UseNormalPunctumCavum{%OBSOLETE + \gre@obsolete{\protect\UseNormalPunctumCavum}{\protect\gresetpunctumcavum{normal}}% +}% + +\def\gre@char@cavum#1#2#3#4#5#6#7#8{% + \setbox\gre@box@temp@width=\hbox{#7}% + \global\gre@dimen@lastglyphwidth=\wd\gre@box@temp@width % + \gre@skip@temp@four = \gre@dimen@lastglyphwidth\relax% + \kern\gre@skip@temp@four % + #4\relax % + \kern-\gre@skip@temp@four % + \gre@calculate@glyphraisevalue{#1}{0}{}% + \ifgre@hidepclines% + \gre@fillhole{#8}% + \fi % + \GreGlyph{#7}{#1}{#2}{#3}{}{#5}{#6}% + %\relax % +}% + +\def\GrePunctumCavum#1#2#3#4#5#6{% + \gre@char@cavum{#1}{#2}{#3}{#4}{#5}{#6}% + {\gre@fontchar@punctumcavum}{\gre@fontchar@punctumcavumhole}% +}% + +\def\GreLineaPunctumCavum#1#2#3#4#5#6{% + \gre@char@cavum{#1}{#2}{#3}{#4}{#5}{#6}% + {\gre@fontchar@lineapunctumcavum}{\gre@fontchar@lineapunctumcavumhole}% +}% + +\def\GrePunctumCavumInclinatum#1#2#3#4#5#6{% + \gre@char@cavum{#1}{#2}{#3}{#4}{#5}{#6}% + {\gre@font@music\GreCPPunctumCavumInclinatum}{\gre@font@music\GreCPPunctumCavumInclinatumHole}% +}% + +\def\GrePunctumCavumInclinatumAuctus#1#2#3#4#5#6{% + \gre@char@cavum{#1}{#2}{#3}{#4}{#5}{#6}% + {\gre@font@music\GreCPPunctumCavumInclinatumAuctus}{\gre@font@music\GreCPPunctumCavumInclinatumAuctusHole}% +}% + +\def\GreOriscusCavum#1#2#3#4#5#6{% + \gre@char@cavum{#1}{#2}{#3}{#4}{#5}{#6}% + {\gre@font@music\GreCPOriscusCavum}{\gre@font@music\GreCPOriscusCavumHole}% +}% + +\def\GreOriscusCavumAuctus#1#2#3#4#5#6{% + \gre@char@cavum{#1}{#2}{#3}{#4}{#5}{#6}% + {\gre@font@music\GreCPOriscusCavumReversus}{\gre@font@music\GreCPOriscusCavumReversusHole}% +}% + +\def\GreOriscusCavumDeminutus#1#2#3#4#5#6{% + \gre@char@cavum{#1}{#2}{#3}{#4}{#5}{#6}% + {\gre@font@music\GreCPOriscusCavumDeminutus}{\gre@font@music\GreCPOriscusCavumDeminutusHole}% +}% diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-spaces.tex b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-spaces.tex new file mode 100644 index 00000000000..dab25f2208e --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-spaces.tex @@ -0,0 +1,1824 @@ +%GregorioTeX file. +% +% Copyright (C) 2007-2015 The Gregorio Project (see CONTRIBUTORS.md) +% +% This file is part of Gregorio. +% +% Gregorio 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. +% +% Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +% this file contains definitions of spaces + +\gre@debugmsg{general}{Loading gregoriotex-spaces.tex}% +\gre@declarefileversion{gregoriotex-spaces.tex}{4.1.1}% GREGORIO_VERSION + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for tuning penalties +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% The following macros enable users to tune penalties used in Gregorio + +% macro to force a break on a new line +\def\GreForceBreak{\gre@penalty{\grenewlinepenalty}}% + +% macro to prevent a line break +\def\GreNoBreak{\gre@penalty{\grenobreakpenalty}}% + + +%% The following macros cancel some useless penalties, and reinstates them +%% at the end of a score + +\def\gre@cancelpenalties{% + \xdef\gre@hyphenpenaltysave{\the\hyphenpenalty }% + \xdef\gre@exhyphenpenaltysave{\the\exhyphenpenalty }% + \xdef\gre@doublehyphendemeritssave{\the\doublehyphendemerits }% + \xdef\gre@finalhyphendemeritssave{\the\finalhyphendemerits }% + \xdef\gre@brokenpenaltysave{\the\brokenpenalty }% + \hyphenpenalty=\grehyphenpenalty\relax % + \exhyphenpenalty=\grehyphenpenalty\relax % + \doublehyphendemerits=0\relax % + \finalhyphendemerits=0\relax % + \brokenpenalty=\grebrokenpenalty\relax % + \xdef\gre@loosenesssave{\the\looseness}% + \xdef\gre@tolerancesave{\the\tolerance}% + \xdef\gre@pretolerancesave{\the\pretolerance}% + \xdef\gre@emergencystretchsave{\the\emergencystretch}% + \xdef\gre@widowpenaltysave{\the\widowpenalty}% + \xdef\gre@clubpenaltysave{\the\clubpenalty}% + \looseness=\grelooseness % + \tolerance=\gretolerance % + \pretolerance=\grepretolerance % + \emergencystretch=\greemergencystretch % + \widowpenalty=\grewidowpenalty % + \clubpenalty=\greclubpenalty % +}% + +\def\gre@restorepenalties{% + \hyphenpenalty=\gre@hyphenpenaltysave % + \exhyphenpenalty=\gre@exhyphenpenaltysave % + \doublehyphendemerits=\gre@doublehyphendemeritssave % + \finalhyphendemerits=\gre@finalhyphendemeritssave % + \brokenpenalty=\gre@brokenpenaltysave % + \looseness=\gre@loosenesssave % + \tolerance=\gre@tolerancesave % + \pretolerance=\gre@pretolerancesave % + \emergencystretch=\gre@emergencystretchsave % + \widowpenalty=\gre@widowpenaltysave % + \clubpenalty=\gre@clubpenaltysave % +}% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of spaces +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Independent default distances are defined in gsp-default.tex. The distances defined here are calculated from those distances. + +%%%%%%%%%%%%%%%%% +%% Global distances +%%%%%%%%%%%%%%%%% + +% textlower is the height of the separation between the bottom line (which is invisible : for the notes which are very low) and the bottom of the text +\newdimen\gre@dimen@textlower\relax% +\def\gre@calculate@textlower{% + \gre@dimen@textlower=\gre@space@dimen@spacebeneathtext\relax% + %\advance\gre@dimen@textlower by \translationheight +}% + +% stafflinewidth is the width of a line of staff, this can vary, for example at the first line +\newdimen\gre@dimen@stafflinewidth\relax% +\def\gre@calculate@stafflinewidth{% + \gre@dimen@stafflinewidth=\gre@dimen@linewidth\relax% +}% + + +% linewidth is the width of a line of a score (including the initial) +\newdimen\gre@dimen@linewidth\relax% +\def\gre@calculate@linewidth{% + \gre@dimen@linewidth=\hsize % +}% + +% Messing with the staff line thickness directly is messy, so we provide the following interface to make life easier on the user: +% stafflineheight is the height of a staff line +% = 1500 * stafflinefactor +\newdimen\gre@dimen@stafflineheight\relax% +\def\gre@calculate@stafflineheight{% + \global\gre@dimen@stafflineheight=\dimexpr(1500 sp * \gre@stafflinefactor)\relax % +}% + +% interstafflinespace is the space between two lines of staff +% = (30000 - (stafflineheight/gre@factor - 1500)) * gre@factor = 31500 * gre@factor - stafflineheight +\newdimen\gre@dimen@interstafflinespace\relax% +\def\gre@calculate@interstafflinespace{% + \global\gre@dimen@interstafflinespace=\dimexpr((31500sp * \gre@factor) % + - \gre@dimen@stafflineheight)\relax% +}% + +% a distance to help place glyphs when the lines are not their default thickness +% = (stafflineheight/gre@factor - 1500sp)/2 * gre@factor +\newdimen\gre@dimen@stafflinediff\relax% +\def\gre@calculate@stafflinediff{% + \global\gre@dimen@stafflinediff = \dimexpr(% + ( ( ( \gre@dimen@stafflineheight % + / \gre@factor)% + - 1500sp)% + / 2)% + * \gre@factor)\relax% +}% + +% the default factor +% the stafflinefactor follows the same scale as the gre@factor, i.e. a stafflinefactor corresponds to the default staff line thickness for gre@factor 17, stafflinefactor 34 corresponds to the default staff line thickness for gre@factor 34, etc. +\xdef\gre@stafflinefactor{17}% +% flag for whether the stafflinefactor should scale with changes of the gre@factor +\newif\ifgre@scale@stafflinefactor% +\gre@scale@stafflinefactortrue + +% a macro for setting the thickness of the staff lines. This changes the stafflinefactor and then adjusts the spaces that are affected by the thicker staff lines. +\def\grechangestafflinethickness#1{% + \xdef\gre@stafflinefactor{#1}% + \relax % +}% + +\def\setstafflinethickness{%OBSOLETE + \gre@obsolete{\protect\setstafflinethickness}{\protect\grechangestafflinethickness}% +}% + +%constantglyphraise is the space between the 0 of the gregorian fonts and the effective 0 of the TeX score +\newdimen\gre@dimen@constantglyphraise\relax% +% to calculate that, we take the bottom of the third line : it is at 200 in the fonts, and it must be at grespacelinestext + grespacebeneathtext + 2*greinterstafflinespace + 2*grestafflineheight + translationheight +\def\gre@calculate@constantglyphraise{% + \global\gre@dimen@constantglyphraise = \dimexpr((-22000 sp * \gre@factor) % + + \gre@dimen@additionalbottomspace % + + \gre@space@dimen@spacebeneathtext % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@interstafflinespace % + + \gre@dimen@interstafflinespace % + + \gre@dimen@stafflineheight % + + \gre@dimen@stafflineheight % + + \gre@dimen@currenttranslationheight % + % an adjustment in the case of big lines + + \gre@dimen@stafflinediff)\relax% + \relax % +}% + +%% Here is the function to compute some more vertical spaces from the basic values +\newdimen\gre@dimen@staffheight\relax% +\def\gre@calculate@staffheight{% + \global\gre@dimen@staffheight = \dimexpr % + \gre@stafflines\gre@dimen@stafflineheight % + + \gre@stafflines\gre@dimen@interstafflinespace % + - \gre@dimen@interstafflinespace\relax% + \relax % +}% + +% A routine that simply aggregates the above global space calculating routines so we can easily update all when needed. +%% Note: It used to be that some distance calculating functions called others. Since this can create problems with circularity if one is not careful, this is no longer the case. Now all distance calculating functions simply calculate their respective distance. This means that dependent distances are not necessarily recalculated when an individual distance is recalculated. This function updates all global calculated distances and in the order needed for the dependencies. +%% Dependencies: +%% textlower: spacebeneathtext +%% linewidth: hsize +%% stafflinewidth: linewidth +%% stafflineheight: stafflinefactor & gre@factor +%% interstafflinespace: stafflineheight & gre@factor +%% stafflinediff: stafflineheight & gre@factor +%% staffheight: stafflineheight & interstafflinespace +%% constantglyphraise: gre@factor, additionalbottomspace, spacebeneathtext, spacelinestext, interstafflinespace, stafflineheight, currenttranslationheight, stafflinediff +\def\gre@computespaces{% + \gre@calculate@textlower% + \gre@calculate@linewidth% + \gre@calculate@stafflinewidth% + \gre@calculate@stafflineheight% + \gre@calculate@interstafflinespace% + \gre@calculate@stafflinediff% + \gre@calculate@staffheight% + \gre@calculate@constantglyphraise% +}% + +\newskip\gre@skip@syllablefinalskip +\newskip\gre@skip@minTextDistance% +\newskip\gre@skip@minNotesDistance% +\newdimen\gre@dimen@curTextDistance% +\newdimen\gre@dimen@curNotesDistance% +\newskip\gre@skip@minShiftText% +\newskip\gre@skip@minShiftNotes% + +%% @desc Macro computing the skip at the end of the syllable +%% @arg#1 0 if end of syllable, 1 if end of word +%% @arg#2 0 if next syllable is normal, 1 if it's a bar, 2 if it starts with +%% an alteration +%% +%% @uses \gre@dimen@enddifference +%% @uses \gre@skip@nextbegindifference +%% +%% Pseudo-code: +%% min_text_dist = same_word ? 0 : space_inter_words +%% if (no_txt_under_prev) : +%% tmp = cur_end_diff > 0 ? 0 : -cur_end_diff +%% min_text_dist = max(min_text_dist, tmp) +%% min_notes_dist = space_between_notes +%% if (barres sur cur ou barres sur next): +%% min_notes_dist = space_between_bars +%% % space between end of syllable and current point for previous note +%% cur_dist_notes = cur_dist_text = 0 +%% if (cur_end_diff < 0): +%% cur_dist_text += -cur_end_diff +%% else: +%% cur_dist_notes += cur_end_diff +%% if (next_begin_diff < 0): +%% cur_dist_notes += -next_begin_diff +%% else: +%% cur_dist_text += next_begin_diff +%% min_shift_text = min_dist_text - cur_dist_text +%% min_shift_notes = min_dist_notes - cur_dist_notes +%% shift = max(min_shift_text, min_shift_notes) +\def\gre@calculate@syllablefinalskip#1#2{% +%% min_text_dist = prev_cur_word ? 0 : space_inter_words + \ifnum#1=1\relax % + \ifgre@in@euouae % + \ifgre@newbarspacing% + \ifnum#2=1\relax % + \gre@skip@minTextDistance=\gre@space@dimen@interwordspacetext@bars@euouae\relax% + \else % + \gre@skip@minTextDistance=\gre@space@skip@interwordspacetext@euouae\relax% + \fi % + \else% + \gre@skip@minTextDistance=\gre@space@skip@interwordspacetext@euouae\relax% + \fi% + \else % + \ifgre@newbarspacing% + \ifnum#2=1\relax % + \gre@skip@minTextDistance=\gre@space@dimen@interwordspacetext@bars\relax% + \else % + \gre@skip@minTextDistance=\gre@space@skip@interwordspacetext\relax% + \fi % + \else% + \gre@skip@minTextDistance=\gre@space@skip@interwordspacetext\relax% + \fi% + \fi % + \else % + \gre@skip@minTextDistance=0pt\relax% + \fi % + \gre@debugmsg{syllablespacing}{ minTextDistance = \the\gre@skip@minTextDistance}% + % setting minNotesDistance (quite simple) + \ifcase#2\relax % + \ifnum#1=1\relax % + \ifgre@in@euouae % + \gre@skip@minNotesDistance=\gre@space@skip@interwordspacenotes@euouae\relax% + \else % + \gre@skip@minNotesDistance=\gre@space@skip@interwordspacenotes\relax% + \fi % + \else % + \gre@skip@minNotesDistance=\gre@space@dimen@intersyllablespacenotes\relax% + \fi % + \ifnum\gre@count@shiftaftermora>3\relax % + \ifgre@thisendswithmora % + % last syllable ends by a punctum mora, we want to ignore it. + % this sets the distance to shift into \gre@skip@temp@four: + \gre@get@unkern@aftermora{1}% + \advance\gre@skip@minNotesDistance by \gre@skip@punctummorashift % + \fi % + \fi % + \or % + \ifgre@newbarspacing % + \gre@skip@minNotesDistance=0pt\relax% + \else % + \gre@skip@minNotesDistance=\gre@space@skip@notebarspace\relax% + \fi % + \or % + \ifnum#1=1\relax % + \gre@skip@minNotesDistance=\gre@space@skip@interwordspacenotes@alteration\relax % + \else % + \gre@skip@minNotesDistance=\gre@space@dimen@intersyllablespacenotes@alteration\relax% + \fi % + \fi % + \gre@debugmsg{syllablespacing}{ minNotesDistance = \the\gre@skip@minNotesDistance}% + % determining current distance between notes and + % next notes, and current distance between text and next text + \gre@dimen@curTextDistance=0pt\relax% + \gre@dimen@curNotesDistance=0pt\relax% +%% cur_dist_notes = cur_dist_text = 0 +%% if (cur_end_diff < 0): +%% cur_dist_notes += -cur_end_diff +%% else: +%% cur_dist_text += cur_end_diff +%% if (next_begin_diff < 0): +%% cur_dist_notes += -next_begin_diff +%% else: +%% cur_dist_text += next_begin_diff + \gre@debugmsg{syllablespacing}{ enddifference = \the\gre@dimen@enddifference}% + \gre@debugmsg{syllablespacing}{ nextbegindifference = \the\gre@skip@nextbegindifference}% + \ifdim\gre@dimen@enddifference < 0 pt\relax% + \gre@dimen@curNotesDistance = -\gre@dimen@enddifference\relax% + \else % + \gre@dimen@curTextDistance = \gre@dimen@enddifference\relax% + \fi % + \ifdim\gre@skip@nextbegindifference < 0 pt\relax% + \advance\gre@dimen@curNotesDistance by -\gre@skip@nextbegindifference\relax% + \else % + \advance\gre@dimen@curTextDistance by \gre@skip@nextbegindifference\relax% + \fi % + \gre@debugmsg{syllablespacing}{ curNotesDistance = \the\gre@dimen@curNotesDistance}% + \gre@debugmsg{syllablespacing}{ curTextDistance = \the\gre@dimen@curTextDistance}% +%% min_shift_text = min_dist_text - cur_dist_text +%% min_shift_notes = min_dist_notes - cur_dist_notes +%% shift = max(min_shift_text, min_shift_notes) + \gre@skip@minShiftText = \glueexpr(\gre@skip@minTextDistance - \gre@dimen@curTextDistance)\relax % + \gre@skip@minShiftNotes = \glueexpr(\gre@skip@minNotesDistance - \gre@dimen@curNotesDistance)\relax % + \gre@debugmsg{syllablespacing}{ minShiftNotes = \the\gre@skip@minShiftNotes}% + \gre@debugmsg{syllablespacing}{ minShiftText = \the\gre@skip@minShiftText}% + \ifdim\gre@skip@minShiftNotes < \gre@skip@minShiftText % + \global\gre@skip@syllablefinalskip = \gre@skip@minShiftText % + \else % + \global\gre@skip@syllablefinalskip = \gre@skip@minShiftNotes % + \fi % + \ifgre@showhyphenafterthissyllable % + \gre@debugmsg{syllablespacing}{ add intersyllablespacestretchhyphen (\gre@space@skip@intersyllablespacestretchhyphen)}% + \advance\gre@skip@syllablefinalskip by \gre@space@skip@intersyllablespacestretchhyphen\relax% + \fi % + \gre@debugmsg{syllablespacing}{ syllablefinalskip = \the\gre@skip@syllablefinalskip}% + \relax % +} + +% dimen keeping the shift computed with next function +\newdimen\gre@dimen@bolshift +% dimen which is used to add a bit extra to the previous one in the case where the first glyph is a flat or a natural +\newdimen\gre@dimen@bolextra + +%% @desc Macro used in \GreSyllable. Sets \gre@skip@bolshift to the left kern that +%% should appear at the beginning of a line in case of a linebreak. +%% The goal of this left kern is to have all lines aligned on notes. See +%% TODO for details. +%% +%% @arg#1 \gre@dimen@begindifference of the first syllable of the line +\def\gre@calculate@bolshift#1{% + \gre@skip@temp@three = 0pt\relax% + % bolextra is the space taken up by a leading alteration (it's 0 if there is no leading alteration) + % it's allowed to invade spaceafterlineclef, so long as it leaves at least beforealterationspace between itself and the clef + % and minimalspaceatlinebeginning between the lyrics and the beginning of the line + \gre@skip@temp@one = \glueexpr(\gre@space@skip@spaceafterlineclef-\gre@space@dimen@beforealterationspace)\relax% + \ifdim\gre@dimen@bolextra>\gre@skip@temp@one\relax% + \global\advance\gre@skip@temp@three by \gre@skip@temp@one\relax% + \else% + \global\advance\gre@skip@temp@three by \gre@dimen@bolextra\relax% + \fi% + \ifdim#1>0pt\relax% + % no additional shift is needed if the notes start before the text + \global\gre@dimen@bolshift = \gre@skip@temp@three\relax% + \else% + % as the \gre@dimen@bolshift is computed from skips, we compute it in + % a skip temp registry, and then "cast" it into a dimen + % basic value for bolshift needs to incorporate -begindifference + \advance\gre@skip@temp@three by -#1\relax% + % we don't want to kern more than clefwidth + spaceafterlineclef - minimalspaceatlinebeginning + % violating this would mean that either the notes are closer than (clefwidth + spaceafterlineclef) + % or that the lyrics are closer than minimalspaceatlinebeginning + \gre@skip@temp@one = \glueexpr(\gre@dimen@clefwidth % + + \gre@space@skip@spaceafterlineclef % + - \gre@space@dimen@minimalspaceatlinebeginning)\relax % + \ifdim\gre@skip@temp@three < \gre@skip@temp@one % + \global\gre@dimen@bolshift = \dimexpr\gre@skip@temp@three\relax % + \else% + \global\gre@dimen@bolshift = \dimexpr\gre@skip@temp@one\relax % + \fi % + \fi% + \gre@debugmsg{bolshift}{ bolshift = \the\gre@dimen@bolshift}% + \relax % +} + +% dimen keeping the shift computed with next function +\newdimen\gre@dimen@eolshift +\newcount\gre@count@protrusion@hyphen@eol % + +% protrusion for hyphens inerted by Lua +\gre@count@protrusion@hyphen@eol = 50\relax + +\def\gresethyphenprotrusion#1{% + \gre@count@protrusion@hyphen@eol = #1\relax % + \relax % +} + +%% @desc Macro used in \GreSyllable. Sets \gre@dimen@eolshift to the right kern +%% that should appear before an end of line. When active this prevents +%% text from going under the custos. +%% +%% @arg#1 The \gre@dimen@enddifference of the corresponding syllable +\def\gre@calculate@eolshift#1{% + \gre@skip@temp@two=0pt\relax% + % we only need a shift if the lyrics are longer than the notes + \gre@debugmsg{eolshift}{eolshift called with enddifference: \the #1}% + \ifdim#1 <0pt\relax% + % we only need to shift if there is a custos being printed + \ifgre@blockeolcustos% + \gre@dimen@eolshift=0pt\relax% + \else% + % The basic value for the eol shift is -enddifference + \gre@skip@temp@two=-#1\relax% + % if there is a possible hyphen (added afterwards in lua), we keep some room for it + \ifgre@possibleluahyphenafterthissyllable % + \setbox\gre@box@temp@width=\hbox{\GreHyph}% + \advance\gre@skip@temp@two by -\dimexpr(\wd\gre@box@temp@width * ((100 - \gre@count@protrusion@hyphen@eol) / 100))\relax% + \gre@debugmsg{eolshift}{adjusted enddifference for protrusion: \the\gre@skip@temp@two}% + \fi % + % The maximum value is wd(custos) + spacebeforeeolcustos + % Were the eolshift larger than this the lyrics would stick out + % into the margin + \setbox\gre@box@temp@width=\hbox{\gre@pickcustos{\gre@pitch@g}}% + \gre@skip@temp@three = \glueexpr(\wd\gre@box@temp@width+\gre@space@skip@spacebeforeeolcustos)\relax% + \gre@debugmsg{eolshift}{custos + space before custos = \the\gre@skip@temp@three}% + % pick the smaller of the two values calculated above + \ifdim\gre@skip@temp@two>\gre@skip@temp@three% + \gre@debugmsg{eolshift}{imposing limit}% + \global\gre@dimen@eolshift = \gre@skip@temp@three% + \else% + \global\gre@dimen@eolshift = \gre@skip@temp@two% + \fi% + \fi % + \else% + \global\gre@dimen@eolshift=0pt\relax% + \fi % + \gre@debugmsg{eolshift}{eolshift: \the\gre@dimen@eolshift}% + \relax % +} + +%%%%%%%%%%%%%%%%%%% +%% Local Distances (computed as needed) +%%%%%%%%%%%%%%%%%%% + +% glyphraisevalue is the value of which we must raise one glyph (that will vary with every glyph) +\newdimen\gre@dimen@glyphraisevalue\relax% + +\newif\ifgre@useledgerlineheuristic% +\gre@useledgerlineheuristictrue% +\def\gresetledgerlineheuristic#1{% + \IfStrEqCase{#1}{% + {enable}% + {\gre@useledgerlineheuristictrue}% + {disable}% + {\gre@useledgerlineheuristicfalse}% + }[% all other cases + \gre@error{Unrecognized option "#1" in \protect\gresetledgerlineheuristic\MessageBreak Possible options are: 'enable' and 'disable'}% + ]% +}% +% for backwards compatibility, we set these to true by default, and the +% system will set them appropriately if the heuristics determine a ledger +% line probably doesn't exist at that point +\newif\ifgre@ledgerline@above% +\newif\ifgre@ledgerline@below% +\def\GreSupposeHighLedgerLine{% + \ifgre@useledgerlineheuristic\gre@ledgerline@abovetrue\fi % +}% +\def\GreSupposeLowLedgerLine{% + \ifgre@useledgerlineheuristic\gre@ledgerline@belowtrue\fi % +}% +\def\gre@resetledgerlineheuristics{% + \gre@ledgerline@abovetrue\gre@ledgerline@belowtrue % +}% +\def\gre@prephepisemaledgerlineheuristics{% + \ifgre@useledgerlineheuristic % + \gre@ledgerline@abovefalse\gre@ledgerline@belowfalse % + \else % + \gre@ledgerline@abovetrue\gre@ledgerline@belowtrue % + \fi % +}% + +% 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 episema, 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 episema 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.) +%% 8: case of the punctum mora of the first note of a podatus or the 2nd note of a porrectus, etc. +%% 9: case of the horizontal episema, that must be placed a bit lower if the note is on a line +%% 10: low choral sign not below the note +%% 11: high choral sign +%% 12: low choral sign below the note +%% 13: brace above the bars +%% 14: punctum mora in a space with a note on the line below it +%% 15: over slur +%% 16: under slur +% #3, for horizontal episemata, is the interline position: +%% 0: auto +%% 1: middle +%% 2: low in space above note +%% 3: high in space above note +%% 4: low in space below note +%% 5: high in space below note +\def\gre@calculate@glyphraisevalue#1#2#3{% + \global\gre@isonalinefalse% + \ifcase#1% + % the first two cases are special cases for episemae on the lowest note + \or\gre@count@temp@three=\number 0% + \or\gre@count@temp@three=\number 1% + \or\gre@count@temp@three=\number 2% + \or\gre@count@temp@three=\number 3% + \ifgre@ledgerline@below % + \ifnum#2=3\relax % + \else % + % if it is a vertical episema, we don't care if it is on a line or + % not... which may cause some problems... + \global\gre@isonalinetrue % + \fi % + \fi % + \or\gre@count@temp@three=\number 4% + \or\gre@count@temp@three=\number 5% + \global\gre@isonalinetrue% + \or\gre@count@temp@three=\number 6% + \or\gre@count@temp@three=\number 7% + \global\gre@isonalinetrue% + \or\gre@count@temp@three=\number 8% + \or\gre@count@temp@three=\number 9% + \ifgre@haslinethree % + \global\gre@isonalinetrue% + \else % + \ifgre@ledgerline@above % + \global\gre@isonalinetrue% + \fi % + \fi % + \or\gre@count@temp@three=\number 10% + \or\gre@count@temp@three=\number 11% + \ifgre@haslinefour % + \global\gre@isonalinetrue% + \else % + \ifgre@haslinethree % + \ifgre@ledgerline@above % + \global\gre@isonalinetrue% + \fi % + \fi % + \fi % + \or\gre@count@temp@three=\number 12% + \or\gre@count@temp@three=\number 13% + \ifgre@haslinefive % + \global\gre@isonalinetrue% + \else % + \ifgre@haslinefour % + \ifgre@ledgerline@above % + \global\gre@isonalinetrue% + \fi % + \fi % + \fi % + \or\gre@count@temp@three=\number 14% + \or\gre@count@temp@three=\number 15% + \ifgre@haslinefive % + \ifgre@ledgerline@above % + \global\gre@isonalinetrue% + \fi % + \fi % + \or\gre@count@temp@three=\number 16% + \or\gre@count@temp@three=\number 17% + \or\gre@count@temp@three=\number 18% + \or\gre@count@temp@three=\number 19% + \or\gre@count@temp@three=\number 20% + \fi% + % if there is not line... we don't consider notes are on lines + \ifgre@showlines\else % + \global\gre@isonalinefalse % + \fi % + % if the note is on a line, we change its height if necessary + \ifgre@isonaline% + \ifcase#2 % + \or% 1 + \global\advance\gre@count@temp@three by 1% + \or% 2 + \global\advance\gre@count@temp@three by -1% + \or% 3 + \global\advance\gre@count@temp@three by -1% + \or% 4 + \global\advance\gre@count@temp@three by 1% + \or% 5 + \global\advance\gre@count@temp@three by -1% + \or\or\or% 8 + \global\advance\gre@count@temp@three by -1% + \or% 9 + \global\advance\gre@count@temp@three by 1% + \or% 10 + \global\advance\gre@count@temp@three by 1% + \or% 11 + \global\advance\gre@count@temp@three by 1% + \or% 12 + \global\advance\gre@count@temp@three by -1% + \fi% + \fi% + \global\advance\gre@count@temp@three by -8 % + \global\gre@dimen@glyphraisevalue = \dimexpr(15750 sp * \gre@factor * \gre@count@temp@three)\relax % + \ifcase#2 % + \or\or\or%3: if it is a vertical episema on a line, we shift it a bit higher, so that it's more beautiful + \ifgre@isonaline% + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@vepisemahighshift\relax % + \else % if it is not on a line, we shift it a bit lower + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@vepisemalowshift\relax % + \fi % + \or% 4: if it is a punctum mora on a line, we shift it a bit lower, for the same reason + \ifgre@isonaline% + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@linepunctummorashift\relax % + \else % + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@spacepunctummorashift\relax % + \fi% + \or% 5: if it is a horizontal episema under a note which is on a line, we shift it lower + \ifcase#3\relax % 0 - auto + \ifgre@isonaline% if it is under a note between two lines, we shift it higher + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@underhepisemahighshift\relax % + \else % + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@underhepisemalowshift\relax % + \fi % + \or % 1 - middle + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@hepisemamiddleshift\relax % + \or % 2 - over-low + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@overhepisemalowshift\relax % + \or % 3 - over-high + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@overhepisemahighshift\relax % + \or % 4 - under-low + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@underhepisemalowshift\relax % + \or % 5 - under-high + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@underhepisemahighshift\relax % + \fi % + \or% 6: if it is a sign, we put it at an arbitrary height + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@raresignshift\relax % + \or\or% 8: if it is a punctum mora on a line, we shift it a bit lower, for the same reason + \ifgre@isonaline% + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@lineporrectuspunctummorashift\relax % + \else % + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@spaceporrectuspunctummorashift\relax % + \fi % + \or% 9: if it is an horizontal episema not on a line, we put it a bit lower + \ifcase#3\relax % 0 - auto + \ifgre@isonaline% + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@overhepisemalowshift\relax % + \else % + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@overhepisemahighshift\relax % + \fi % + \or % 1 - middle + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@hepisemamiddleshift\relax % + \or % 2 - over-low + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@overhepisemalowshift\relax % + \or % 3 - over-high + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@overhepisemahighshift\relax % + \or % 4 - under-low + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@underhepisemalowshift\relax % + \or % 5 - under-high + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@underhepisemahighshift\relax % + \fi % + \or% 10: low choral sign that is not lower than the note + \global\advance\gre@dimen@glyphraisevalue by -\gre@space@dimen@choralsigndownshift\relax% + \or% 11: high choral sign + \ifgre@isonaline% + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@choralsignupshift\relax% + \else % + \global\advance\gre@dimen@glyphraisevalue by -\gre@space@dimen@choralsigndownshift\relax% + \fi % + \or% 12: low choral sign that is lower than the note + \ifgre@isonaline% + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@choralsignupshift\relax% + \else % + \global\advance\gre@dimen@glyphraisevalue by -\gre@space@dimen@choralsigndownshift\relax% + \fi % + \or% 13: if it is the brace above the bars, we shift it to a user-defined value + \global\advance\gre@dimen@glyphraisevalue by -\gre@space@dimen@braceshift\relax% + \or% 14: raise the punctum mora in a space a bit higher than case 4 + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@spaceamonepespunctummorashift\relax% + \or% 15: over slur + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@overslurshift\relax% + \or% 16: under slur + \global\advance\gre@dimen@glyphraisevalue by \gre@space@dimen@underslurshift\relax% + \fi% + \global\advance\gre@dimen@glyphraisevalue by \the\gre@dimen@constantglyphraise\relax% +}% + +% two dimensions for the additionalspaces +\newdimen\gre@dimen@additionalbottomspace\relax% +% the one taken into account to adjust space between lines +\newdimen\gre@dimen@additionaltopspace\relax% +% the one taken into account for above lines text height +\newdimen\gre@dimen@additionaltopspacealt\relax% + +\newcount\gre@space@count@additionaltopspacethreshold\relax% +\gre@space@count@additionaltopspacethreshold=2 + +\newcount\gre@space@count@additionaltopspacealtthreshold\relax% +\gre@space@count@additionaltopspacethreshold=0 + +% #1 is the high height +% #2 is the low height +% #3 is 1 if there is a translation somewhere +% #4 is if 1 if we have space above the staff +\def\gre@calculate@additionalspaces#1#2#3#4{% + \gre@debugmsg{lineheight}{gre@calculate@additional@spaces called with #1 #2 #3 #4}% + \gre@count@temp@one=\numexpr(#1 - \gre@pitch@adjust@top - \gre@space@count@additionaltopspacethreshold)\relax % + \ifnum\gre@count@temp@one>0\relax % + \global\gre@dimen@additionaltopspace=\dimexpr(15750 sp * \gre@count@temp@one * \gre@factor)\relax % + \else % + \global\gre@dimen@additionaltopspace=0 sp% + \fi % + \gre@count@temp@one=\numexpr(#1 - \gre@pitch@adjust@top - \gre@space@count@additionaltopspacealtthreshold)\relax % + \ifnum\gre@count@temp@one>0\relax % + \global\gre@dimen@additionaltopspacealt=\dimexpr(15750 sp * \gre@count@temp@one * \gre@factor)\relax % + \else % + \global\gre@dimen@additionaltopspacealt=0 sp% + \fi % + \gre@count@temp@one=\numexpr((#2 - \gre@pitch@adjust@bottom) * -1)\relax % + \ifnum\gre@count@temp@one>0\relax % + \global\gre@dimen@additionalbottomspace=\dimexpr(15750 sp * \gre@count@temp@one * \gre@factor)\relax % + \else % + \global\gre@dimen@additionalbottomspace=0 sp% + \fi % + \ifnum#3 = 1\relax % + \gre@addtranslationspace % + \else % + \gre@removetranslationspace % + \fi % + \ifnum#4 = 1\relax % + \gre@addspaceabove % + \else % + \gre@removespaceabove % + \fi % + \gre@generatelines % + \gre@calculate@constantglyphraise % + \relax % +}% + +%% macro that typesets the text of the syllable, and sets textaligncenter to the middle of the middle letters, it is needed because we align the note (often the middle of the note) with the middle of the middle letters +%% third argument is 0 if it's the current syllable, 1 if it's the alignment of the following one +%% warning: gretextaligncenter is the width from the beginning of the letters to the middle of the middle letters +%% warning: value is approximative when a ligature appears + +\newdimen\gre@dimen@textaligncenter\relax% + +\def\gre@calculate@textaligncenter#1#2#3{% + \ifnum#3=0\relax% + \gre@widthof{\gre@fixedtextformat{#1#2}}% + \else % + \gre@widthof{\gre@fixednexttextformat{#1#2}}% + \fi % + \global\gre@dimen@textaligncenter=\the\gre@dimen@temp@three % + \ifnum#3=0\relax% + \gre@widthof{\gre@fixedtextformat{#2}}% + \else % + \gre@widthof{\gre@fixednexttextformat{#2}}% + \fi % + \divide\gre@dimen@temp@three by 2 % + \global\advance\gre@dimen@textaligncenter by -\the\gre@dimen@temp@three% + \relax% +}% + +% 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\gre@dimen@enddifference\relax% + +% a dimen that will contain the enddifference of the previous glyph +\newdimen\gre@dimen@previousenddifference\relax% + +% macro to set enddifference (defined above) to \wd\gre@box@syllablenotes - (\wd\gre@box@syllabletext - textaligncenter) - notesaligncenter +% enddifference will be positive if text go further than the notes, and negative in the other case +% arguments are : +% #1: \wd\gre@box@syllablenotes : the total width of the notes +% #2: \wd\gre@box@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\gre@calculate@enddifference#1#2#3#4#5{% + \ifcase#5\or % + \global\gre@dimen@previousenddifference=\the\gre@dimen@enddifference\relax% + \fi % + \global\gre@dimen@enddifference=\dimexpr(#1 - #2 + #3 - #4)\relax% + \relax% +}% + +% temporary value for space for the translation, beneath the text +\newdimen\gre@dimen@currenttranslationheight\relax% + +% macro to tell gregorio to set space for the translation +\def\gre@addtranslationspace{% + \gre@style@translation% + \global\gre@dimen@currenttranslationheight=\gre@space@dimen@translationheight\relax% + \global\gre@dimen@textlower=\dimexpr(\gre@space@dimen@spacebeneathtext % + + \gre@space@dimen@translationheight)\relax% + \gre@generatelines % + \gre@calculate@constantglyphraise % + \endgre@style@translation% + \ifx\gre@empty@translationformat\gretranslationformat% OBSOLETE + \else% OBSOLETE + \gre@obsolete{\protect\gretranslationformat}{\protect\grechangestyle{translation}}% OBSOLETE + \fi% OBSOLETE + \relax % +}% + +\def\gre@removetranslationspace{% + \global\gre@dimen@currenttranslationheight=0 sp% + \global\gre@dimen@textlower=\gre@space@dimen@spacebeneathtext\relax% + \gre@generatelines % + \gre@calculate@constantglyphraise % + \relax % +}% + +%nextbegindifference is the begindifference of the next syllable +\newskip\gre@skip@nextbegindifference\relax% + +% macro to set nextbegindifference +%% 1 : the first letters of the next syllable +%% 2 : the middle letters of the next syllable +%% 3 : the end letters of the next syllable +%% 4 : the type of notes alignment +\def\gre@calculate@nextbegindifference#1#2#3#4{% + \ifnum\gre@lastoflinecount=1\relax % + \global\gre@skip@nextbegindifference=0pt\relax% + \else % + %to prevent the pollution of the normal values, we stock them into a temp value + \gre@dimen@temp@two=\gre@dimen@textaligncenter\relax% + \gre@calculate@textaligncenter{#1}{#2}{1}% + \global\gre@skip@nextbegindifference=-\gre@dimen@textaligncenter\relax% + \global\gre@dimen@textaligncenter=\gre@dimen@temp@two % + \gre@dimen@temp@two=\gre@dimen@notesaligncenter\relax% + \gre@calculate@nextnotesaligncenter{#4}% idem + \global\advance\gre@skip@nextbegindifference by \the\gre@dimen@notesaligncenter\relax% + \global\gre@dimen@notesaligncenter=\gre@dimen@temp@two % + \fi % + \relax % +}% + +%The distance from the baseline of the line to the baseline of the annotations +\newdimen\gre@dimen@annotationtrueraise\relax% +% When text is placed in the annotation boxes these dimensions are initialized with values based on the contents and the user parameters +%This function sets the true raises of the two lines above the initial (it has to be called just as the boxes are placed in order to make sure that the values are all correct) +\def\gre@calculate@annotationtrueraise{% + \gre@debugmsg{annotation}{Calculating the raise.}% + \global\advance\gre@dimen@annotationtrueraise by % + \dimexpr(\gre@dimen@staffheight % + + \gre@space@dimen@spacebeneathtext % + + \gre@dimen@currenttranslationheight % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@additionalbottomspace)\relax% + \gre@style@annotation% + \global\advance\gre@dimen@annotationtrueraise by \gre@space@dimen@annotationraise\relax% + \gre@debugmsg{annnotation}{Added user raise.}% + \endgre@style@annotation% + \relax % +}% + +%The distance from the baseline of the line to the baseline of the commentary +\newdimen\gre@dimen@commentarytrueraise\relax% +%This function sets the true raises of the commentary (it has to be called just as the boxes are placed in order to make sure that the values are all correct) +\def\gre@calculate@commentarytrueraise{% + \gre@style@commentary% + \gre@debugmsg{commentary}{Calculating the raise.}% + \global\advance\gre@dimen@commentarytrueraise by % + \dimexpr(\gre@dimen@staffheight % + + \gre@space@dimen@spacebeneathtext % + + \gre@dimen@currenttranslationheight % + + \gre@space@dimen@spacelinestext % + + \gre@dimen@additionalbottomspace % + + \gre@space@dimen@commentaryraise)\relax% + \endgre@style@commentary% +}% + +% spaces for new bar positioning algorithm +\newskip\gre@skip@bar@requirement% amount of space required by bar (including skips before and after) +\newskip\gre@skip@bar@allocation% amount of space allocated to the bar +\newdimen\gre@dimen@bar@shift% displacement from center of the bar’s position +\newskip\gre@skip@text@requirement% amount of space required by the text (including skips before and after) +\newskip\gre@skip@text@allocation% amount of space allocated to the text +\newdimen\gre@dimen@text@shift% displacement from center of the text’s position +\newdimen\gre@dimen@adjustedpreviousenddifference% previousenddifference adjusted to account for the presence of a punctum mora at the end of the pervious syllable +\newskip\gre@skip@punctummorashift% displacement of whole syllable to account for the presence of a punctum mora at the end of the previous syllable + +% +% New bar spacing algorithm +% +%In the new algorithm the bar and the text are set independently of each other based purely on the positions of the corresponding element in the previous and next syllable +% #1 is #4 from \GreBarSyllable (1 if bar is end of word, 0 if not) +% #2 is #7 from \GreBarSyllable (alignment type of first next glyph) +\def\gre@calculate@barposition#1#2{% + % we start by finding the distance between the text and notes of the previous and the next syllable (as if this syllable didn't exist, for the moment) + \gre@debugmsg{barspacing}{calculate available space}% + % first, recomputing \gre@dimen@previousenddifference into \gre@dimen@adjustedpreviousenddifference + % taking into account the punctum mora shift + \gre@dimen@adjustedpreviousenddifference=\gre@dimen@previousenddifference % + % gre@skip@punctummorashift is 0 or the punctum mora shift + \gre@skip@punctummorashift=0pt\relax % + \ifgre@lastendswithmora % + \ifcase\gre@count@shiftaftermora\or\or % + \ifdim\wd\gre@box@syllabletext=0pt\relax % + % punctum mora adjustment should occur only for bars with no text + \gre@get@unkern@aftermora{2}% + \advance\gre@dimen@adjustedpreviousenddifference by \gre@skip@punctummorashift % + \fi % + \or % + % punctum mora adjustment only before bars + \gre@get@unkern@aftermora{2}% + \advance\gre@dimen@adjustedpreviousenddifference by \gre@skip@punctummorashift % + \or\or % + % punctum mora adjustment always occurs + \gre@get@unkern@aftermora{2}% + \advance\gre@dimen@adjustedpreviousenddifference by \gre@skip@punctummorashift % + \fi % + \fi % + % now something a bit tricky: as we changed previousenddifference, + % we must kern of the difference we created, but no more than + % the end of the text: + \ifdim\gre@skip@punctummorashift=0pt\else % + \gre@debugmsg{barspacing}{adjustment for punctum mora: \the\gre@skip@punctummorashift}% + \gre@debugmsg{barspacing}{adjusted previous enddifference (for punctum mora): \the\gre@dimen@adjustedpreviousenddifference}% + \ifdim -\gre@skip@punctummorashift < \gre@dimen@previousenddifference % + \gre@debugmsg{barspacing}{kern \the\gre@skip@punctummorashift for punctum mora adjustment}% + \kern\gre@skip@punctummorashift % + \else % + \ifdim\gre@dimen@previousenddifference > 0pt\relax % + \gre@debugmsg{barspacing}{kern \the\gre@dimen@previousenddifference for punctum mora adjustment}% + \kern-\gre@dimen@previousenddifference % + \fi % + \fi % + \fi % + \ifdim\gre@dimen@adjustedpreviousenddifference > 0pt\relax% + % the notes ended after the text in the previous syllable + \gre@skip@text@allocation = \gre@dimen@adjustedpreviousenddifference\relax% + \gre@skip@bar@allocation = 0pt\relax% + \else% + % the text ended after the notes in the previous syllable + \gre@skip@text@allocation = 0pt\relax% + \gre@skip@bar@allocation = -\gre@dimen@adjustedpreviousenddifference\relax% + \fi% + \ifdim\gre@skip@nextbegindifference > 0pt\relax% + % the text began after the notes in the next syllable + \advance\gre@skip@text@allocation by \gre@skip@nextbegindifference\relax% + \advance\gre@skip@bar@allocation by 0pt\relax% + \else% + % the notes begin after the text in the next syllable + \advance\gre@skip@text@allocation by 0pt\relax% + \advance\gre@skip@bar@allocation by -\gre@skip@nextbegindifference\relax% + \fi% + \gre@debugmsg{barspacing}{space available to text: \the\gre@skip@text@allocation}% + \gre@debugmsg{barspacing}{spacing available to notes: \the\gre@skip@bar@allocation}% + % now we need to check these widths against the width the current syllable needs for each element and increase them as necessary + % if they aren't wide enough, then we need to increase *both* widths + \gre@debugmsg{barspacing}{calculate required widths}% + % first we check the text width + % we have to account for the spacing around the text as well as the text itself + \ifdim\wd\gre@box@syllabletext > 0pt\relax% + % first we account for the spacing which is needed after the previous syllable text (by using the minTextDistance left over from the previous syllablefinalskip calculation) + \gre@debugmsg{barspacing}{text width: \the\wd\gre@box@syllabletext}% + \gre@debugmsg{barspacing}{previous syllable skip after text: \the\gre@skip@minTextDistance}% + \gre@skip@text@requirement = \glueexpr\wd\gre@box@syllabletext + \gre@skip@minTextDistance\relax% + %now we need to account for the spacing which goes after this syllable (if there is text to this syllable) + %this calculation is similar to what is done in \gre@calculate@syllablefinalskip, but is only for the text, so we'll use \gre@skip@syllablefinalskip to hold this value for now + \ifnum#1=1\relax % + \ifgre@in@euouae % + \gre@skip@syllablefinalskip=\gre@space@dimen@interwordspacetext@bars@euouae\relax% + \else % + \gre@skip@syllablefinalskip=\gre@space@dimen@interwordspacetext@bars\relax% + \fi % + \else % + \gre@skip@syllablefinalskip=0pt\relax% + \fi % + \gre@debugmsg{barspacing}{this syllable skip after text: \the\gre@skip@syllablefinalskip}% + \advance\gre@skip@text@requirement by \gre@skip@syllablefinalskip\relax% + \else% + \ifnum#1=1\relax% + \ifgre@in@euouae% + \gre@skip@text@requirement=\gre@space@dimen@interwordspacetext@bars@notext@euouae\relax% + \else% + \gre@skip@text@requirement=\gre@space@dimen@interwordspacetext@bars@notext\relax% + \fi% + \else% + \gre@skip@text@requirement=0pt\relax% + \fi% + \fi% + \ifdim\gre@skip@text@allocation < \gre@skip@text@requirement\relax% + \advance\gre@skip@bar@allocation by \glueexpr(\gre@skip@text@requirement - \gre@skip@text@allocation)\relax% + \gre@skip@text@allocation = \gre@skip@text@requirement\relax% + \fi% + \gre@debugmsg{barspacing}{space required by text: \the\gre@skip@text@requirement}% + \gre@debugmsg{barspacing}{allocated text space: \the\gre@skip@text@allocation}% + \gre@debugmsg{barspacing}{allocated notes space: \the\gre@skip@bar@allocation}% + % now we check the bar width + \gre@debugmsg{barspacing}{bar width: \the\wd\gre@box@syllablenotes}% + \gre@skip@bar@requirement = \wd\gre@box@syllablenotes\relax% + \ifdim\gre@skip@bar@allocation < \gre@skip@bar@requirement\relax% + \advance\gre@skip@text@allocation by \glueexpr(\gre@skip@bar@requirement - \gre@skip@bar@allocation)\relax% + \gre@skip@bar@allocation = \gre@skip@bar@requirement\relax% + \fi% + \gre@debugmsg{barspacing}{required space for notes: \the\gre@skip@bar@requirement}% + \gre@debugmsg{barspacing}{allocated text space: \the\gre@skip@text@allocation}% + \gre@debugmsg{barspacing}{allocated notes space: \the\gre@skip@bar@allocation}% + % our final position calculation is to make sure that the centers of the text and the bar are not too far from each other + % this isn't really the begindifference (it doesn't account for the width of the text and the bar), but it's close enough that we'll use that register for this calculation + % to be consistent with the normal begin difference, this value should take us from the middle of the notes to the middle of the text. + \gre@dimen@begindifference=\dimexpr(-\gre@skip@bar@allocation/2% going to the left by the bar@allocation/2 (an always positive value, so we lead with a minus sign to go left) + -\gre@dimen@adjustedpreviousenddifference% moving from the end of the notes in the previous syllable to the end of the text there (opposite the sense of enddifference so we lead with a minus sign) + +\gre@skip@text@allocation/2)\relax% going to the right by the text@allocation/2 (an always positive value, so lead with positive to go right) + \gre@debugmsg{barspacing}{new begindifference approximation: \the\gre@dimen@begindifference}% + % in order to avoid code duplication, we check whether or not there is a bar line now and set temp variables to the appropriate offset limits. We’ll then use those temp variables in the code below. + \ifdim\wd\gre@box@syllablenotes = 0pt\relax% + \gre@debugmsg{barspacing}{no bar offset limits}% + \gre@dimen@temp@three=\gre@space@dimen@maxbaroffsettextleft@nobar\relax% + \gre@dimen@temp@two=\gre@space@dimen@maxbaroffsettextright@nobar\relax% + \else% + \gre@debugmsg{barspacing}{normal offset limits}% + \gre@dimen@temp@three=\gre@space@dimen@maxbaroffsettextleft\relax% + \gre@dimen@temp@two=\gre@space@dimen@maxbaroffsettextright\relax% + \fi% + % in the event that the bar is occurring at the end of the line, we use different offset limits + % for now this only works for explicit end of lines which occur in the same syllable as the bar line (e.g. `test(::z)`) + \ifnum\gre@newlinearg=-1\relax\else% + \gre@debugmsg{barspacing}{end of line override on offset limits}% + \gre@dimen@temp@three=\gre@space@dimen@maxbaroffsettextleft@eol\relax% + \gre@dimen@temp@two=\gre@space@dimen@maxbaroffsettextright@eol\relax% + \fi% + \gre@debugmsg{barspacing}{left offset limit: \the\gre@dimen@temp@three}% + \gre@debugmsg{barspacing}{right offset limit: \the\gre@dimen@temp@two}% + % All this worry about shifts is superfluous if the text isn’t present, + % so now we check for that and set them to 0 if it is missing + \ifdim\wd\gre@box@syllabletext = 0pt\relax% + \gre@debugmsg{barspacing}{no text, shifts set to 0}% + \gre@dimen@text@shift = 0pt\relax% + \gre@dimen@bar@shift = 0pt\relax% + \else% + \ifdim\gre@dimen@begindifference > \gre@dimen@temp@two\relax% + %the two elements are too far apart and the text is to the right of the bar + \gre@debugmsg{barspacing}{shifts for text right of bar}% + % first we shift text to the left so that it has the correct offset + \gre@dimen@bar@shift = 0pt\relax% + \gre@dimen@text@shift = \dimexpr(0pt - (\gre@dimen@begindifference - \gre@dimen@temp@two))\relax% + % is the text too far to the left? + \ifdim-\gre@dimen@text@shift > \dimexpr(\gre@skip@text@allocation/2-\gre@skip@text@requirement/2)\relax% + % it is, so push both bar and text right to prevent a collision + \gre@debugmsg{barspacing}{text collision detected}% + \gre@dimen@bar@shift = \dimexpr(-\gre@dimen@text@shift-(\gre@skip@text@allocation/2-\gre@skip@text@requirement/2))\relax % + \gre@dimen@text@shift = \dimexpr(0pt - (\gre@skip@text@allocation/2 - \gre@skip@text@requirement/2))\relax % + % is the bar too far to the right? + % \gre@dimen@temp@one is excess shift + \gre@dimen@temp@one = \dimexpr\gre@dimen@bar@shift - (\gre@skip@bar@allocation/2 - \gre@skip@bar@requirement/2)\relax% + \ifdim\gre@dimen@temp@one>0pt\relax % + \gre@debugmsg{barspacing}{bar collision detected}% + % it is, so allocate more space to prevent the collision + \advance\gre@skip@bar@allocation by \gre@dimen@temp@one\relax % + % since the additional allocation will be split evenly on both sides of the bar, we also need to shift both elements left so that all of it will appear on the right hand side + \advance\gre@dimen@bar@shift by -0.5\gre@dimen@temp@one\relax% + \advance\gre@dimen@text@shift by -0.5\gre@dimen@temp@one\relax% + \fi % + \fi% + \else\ifdim-\gre@dimen@begindifference > \gre@dimen@temp@three\relax% + %the two elements are too far apart and the text is to the left of the bar + \gre@debugmsg{barspacing}{shifts for text to left of bar}% + % first we shift text to the right so that it has the correct offset + \gre@dimen@bar@shift = 0pt\relax % + \gre@dimen@text@shift = \dimexpr((-\gre@dimen@begindifference) - \gre@dimen@temp@three)\relax % + % is the text too far to the right? + \ifdim\gre@dimen@text@shift > \dimexpr(\gre@skip@text@allocation/2-\gre@skip@text@requirement/2)\relax % + \gre@debugmsg{barspacing}{text collision detected}% + % it is so push both bar and text left to prevent a collision + \gre@dimen@bar@shift = \dimexpr(-\gre@dimen@text@shift+\gre@skip@text@allocation/2-\gre@skip@text@requirement/2)\relax % + \gre@dimen@text@shift = \dimexpr(\gre@skip@text@allocation/2-\gre@skip@text@requirement/2)\relax % + % is the bar too far to the left? + % gre@dimen@temp@one is the excess of bar@shift: + \gre@dimen@temp@one=\dimexpr(-\gre@dimen@bar@shift -(\gre@skip@bar@allocation/2-\gre@skip@bar@requirement/2))\relax % + \ifdim\gre@dimen@temp@one>0pt\relax % + \gre@debugmsg{barspacing}{bar collision detected}% + % it is, so allocate more space to prevent the collision + \advance\gre@skip@bar@allocation by \gre@dimen@temp@one\relax % + % since the allocation will be split evenly on either side of the bar, we also need to shift both bar an text right by half of the increase so all of it appears on the left side + \advance\gre@dimen@bar@shift by 0.5\gre@dimen@temp@one\relax% + \advance\gre@dimen@text@shift by 0.5\gre@dimen@temp@one\relax% + \fi % + \fi % + \else% + %the two elements are sufficiently close together + \gre@debugmsg{barspacing}{zero shifts}% + \gre@dimen@text@shift = 0pt\relax% + \gre@dimen@bar@shift = 0pt\relax% + \fi\fi% + \fi% + \gre@debugmsg{barspacing}{text shift: \the\gre@dimen@text@shift}% + \gre@debugmsg{barspacing}{bar shift: \the\gre@dimen@bar@shift}% + %at this point we're going to correct the values of enddifference and begindifference so that they are right for calculations which reference them in the next syllable + \gre@debugmsg{barspacing}{bar width: \the\wd\gre@box@syllablenotes}% + \gre@debugmsg{barspacing}{text width: \the\wd\gre@box@syllabletext}% + \gre@debugmsg{barspacing}{Correcting begindifference}% + %same as before but now we need to account for the widths of the elements and the shifts + \gre@dimen@begindifference = \dimexpr(\wd\gre@box@syllablenotes/2% go right to the middle of the bar syllable (width is always positive so lead with plus to go right) + -\gre@dimen@bar@shift% go from actual middle of bar to nominal middle of bar (bar@shift represents going the other way, so lead with minus) + +\gre@dimen@begindifference% go from nominal middle of bar line to nominal middle of text (this is what begindifference currently holds, so lead with positive) + +\gre@dimen@text@shift% go from nominal middle of text to actual middle of text (text@shift represents this move, so lead with positive) + -\wd\gre@box@syllabletext/2)\relax% go left from middle to beginning of text (width is always positive, so lead with negative to go left + \gre@debugmsg{barspacing}{begindifference: \the\gre@dimen@begindifference}% + \gre@debugmsg{barspacing}{Correcting enddifference}% + \gre@dimen@enddifference = \dimexpr-\wd\gre@box@syllabletext% go from end of text to beginning of text (width is always positive, so lead with negative to go left) + -\gre@dimen@begindifference% go from beginning of text to beginning of notes (opposite sense of begindifference so lead with negative) + +\wd\gre@box@syllablenotes\relax% go from beginning of notes to end of notes (width is always positive so lead with positive to go right + \gre@debugmsg{barspacing}{enddifference: \the\gre@dimen@enddifference}% + %we also need to correct syllablefinalskip to make sure it’s accurate because it depends on enddifference + \gre@debugmsg{barspacing}{Correcting syllablefinalskip}% + \gre@calculate@syllablefinalskip{#1}{\gre@count@temp@one}% + \gre@debugmsg{barspacing}{syllablefinalskip: \the\gre@skip@syllablefinalskip}% +}% + +%%%%%%%%%%%%%%%%%%% +%% other spaces calculated elsewhere +%%%%%%%%%%%%%%%%%%% + +% These distances don't have independent functions which calculate their value, generally because their calculation is distributed over multiple events. + +% begindifference is the difference between the beginning of the text and the beginning of the notes. Warning : it can be negative. +\newdimen\gre@dimen@begindifference\relax% + +% the width of the clef +\newdimen\gre@dimen@clefwidth\relax% + +% the width of the last glyph +\newdimen\gre@dimen@lastglyphwidth\relax% + +% notes align center is the point of alignment for the notes +\newdimen\gre@dimen@notesaligncenter\relax% + +%this dimension is the additional space that we have to add to the localleftbox sometimes. For now it is used only for the initials on two lines +\newdimen\gre@dimen@additionalleftspace\relax% + +% the calculated width of the initial (may be actual width of letter or be forced wider under certain conditions) +\newdimen\gre@dimen@initialwidth\relax% +\gre@dimen@initialwidth= 0 pt\relax% + +\newdimen\gre@dimen@currentabovelinestextheight\relax% +\gre@dimen@currentabovelinestextheight = 0pt\relax% + +%% TODO: perhaps create a pair of functions which “reserve” and “release” the temporary registers in order to keep track of which ones are in use when. There would also need to be a list of the registers currently in use. The reserve function would then check the list to make sure the requested register isn’t already in use, throwing an error if it is and adding its name to the list if it isn’t. It might also provide for an alias (via \let). The release function would simply remove the register from the list of those in use. +% Register allocation is an inherently global process in TeX. Below are the registers used within calculations on a temporary basis. +\newdimen\gre@dimen@temp@one% +\newdimen\gre@dimen@temp@two% +\newdimen\gre@dimen@temp@three% +\newdimen\gre@dimen@temp@four% +\newdimen\gre@dimen@temp@five% + +\newskip\gre@skip@temp@one% +\newskip\gre@skip@temp@two % +\newskip\gre@skip@temp@three% +\newskip\gre@skip@temp@four% + +\newcount\gre@count@temp@one% +\newcount\gre@count@temp@two% +\newcount\gre@count@temp@three% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% dimension changing macros +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% This macro creates one dim (#1), setting its value to #2 and sets whether it should scale when the \gre@factor changes (#3, scalable or fixed). Checks that #1 can accept the kind of distance given in #2. +%% Note: the distances created by this function are stored as strings, not skip or dimension registers. This allows the user to specify a distance in em or ex units even though the font parameters may not be the same at the time the distance is specified and the time the distance is used. +\newif\ifgre@checklength% +\def\grecreatedim#1#2#3{% + \gre@dimension{#1}{#2}% + \csname newif\expandafter\endcsname\csname ifgre@scale@#1\endcsname% + \IfStrEqCase{#3}{% + {1}% + {\gre@obsolete{A numerical (1) last argument for \protect\grecreatedim}{'scalable'}}% + {0}% + {\gre@obsolete{A numerical (0) last argument for \protect\grecreatedim}{'fixed'}}% + {scalable}% + {\grescaledim{#1}{true}}% + {fixed}% + {\grescaledim{#1}{false}}% + }[% all other cases + \gre@error{Unrecognized option "#3" for \protect\grecreatedim\MessageBreak Possible options are: 'scalable' and 'fixed'}% + ]% +}% + +\def\gresetdim{%OBSOLETE + \gre@obsolete{\protect\gresetdim}{\protect\grecreatedim}% +}% + +% a macro for changing a dimension. Unlike \grecreatedim, this function won’t create a new distance, just change an existing one. +\def\grechangedim#1#2#3{% + \gre@rubberpermit{#1}% + % figure out our prefix + \ifgre@rubber% + \gre@debugmsg{spacing}{Changing a skip.}% + \def\gre@prefix{skip}% + \else% + \gre@debugmsg{spacing}{Changing a dimen.}% + \def\gre@prefix{dimen}% + \fi% + \ifcsname gre@space@\gre@prefix @#1\endcsname% + \gre@debugmsg{spacing}{It does exist.}% + \gre@dimension{#1}{#2}% + \IfStrEqCase{#3}{% + {1}% + {\gre@obsolete{A numerical (1) last argument for \protect\grechangedim}{'scalable'}}% + {0}% + {\gre@obsolete{A numerical (0) last argument for \protect\grechangedim}{'fixed'}}% + {scalable}% + {\grescaledim{#1}{true}}% + {fixed}% + {\grescaledim{#1}{false}}% + % all other cases + }[\gre@error{Unrecognized option "#3" for \protect\grechangedim\MessageBreak Possible options are: 'scalable' and 'fixed'}]% + \else% + \IfStrEqCase{#1}{% DEPRECATED + {spacearoundsmallbars}% DEPRECATED + {% DEPRECATED + \gre@deprecated{spacearoundsmallbars}{bar@virgula or bar@minima}% DEPRECATED + \grechangedim{bar@virgula}{#2}{#3}% DEPRECATED + \grechangedim{bar@minima}{#2}{#3}% DEPRECATED + }% DEPRECATED + {spacearoundminor}% DEPRECATED + {% DEPRECATED + \gre@deprecated{spacearoundminor}{bar@minor}% DEPRECATED + \grechangedim{bar@minor}{#2}{#3}% DEPRECATED + }% DEPRECATED + {spacearoundmaior}% DEPRECATED + {% DEPRECATED + \gre@deprecated{spacearoundmaior}{bar@maior}% DEPRECATED + \grechangedim{bar@maior}{#2}{#3}% DEPRECATED + }% DEPRECATED + {spacearoundfinalis}% DEPRECATED + {% DEPRECATED + \gre@deprecated{spacearoundfinalis}{bar@finalis}% DEPRECATED + \grechangedim{bar@finalis}{#2}{#3}% DEPRECATED + }% DEPRECATED + {spacebeforefinalfinalis}% DEPRECATED + {% DEPRECATED + \gre@deprecated{spacebeforfinalfinalis}{bar@finalfinalis}% DEPRECATED + \grechangedim{bar@finalfinalis}{#2}{#3}% DEPRECATED + }% DEPRECATED + }[% DEPRECATED + \gre@error{#1 is not a recognized distance.}% keep this line + ]% DEPRECATED + \fi% +}% + +\def\grechangecount#1#2{% + \expandafter\csname gre@space@count@#1\endcsname=#2% + \relax % +} + +% The common internals for \grecreatedim and \grechangedim. +\def\gre@dimension#1#2{% + \gre@checklengthfalse% + %check if #2 is a rubber length (contains plus and/or minus) + \IfSubStr{#2}{plus}{\gre@checklengthtrue}{\relax}% + \IfSubStr{#2}{minus}{\gre@checklengthtrue}{\relax}% + %if #1 is one of the distances which cannot be rubber. + \gre@rubberpermit{#1}% + % do we try to assign a rubber to one where it's not permitted? + \ifgre@rubber% + \def\gre@prefix{skip}% + \else% + \ifgre@checklength% + \gre@error{#1 cannot be a rubber length.}% + \else% + \def\gre@prefix{dimen}% + \fi% + \fi% + % special check for bar@rubber + \IfStrEq*{#1}{bar@rubber}% + {% + \gre@skip@temp@one = #2\relax% + \ifdim\gre@skip@temp@one=0pt\relax\else% + \gre@error{bar@rubber cannot have a non-zero base}% + \fi% + }{}% + \expandafter\edef\csname gre@space@\gre@prefix @#1\endcsname{#2}% + \relax % +} + +%a macro to use if all you want to do is turn on or off the scaling for a particular distance +\def\grescaledim#1#2{% + \IfStrEqCase{#2}{% + {true}% + {\csname gre@scale@#1true\endcsname}% + {yes}% + {\grescaledim{true}}% + {on}% + {\grescaledim{true}}% + {scalable}% + {\grescaledim{true}}% + }[% all other cases + \csname gre@scale@#1false\endcsname% + ]% +} + +\def\grenoscaledim#1{%OBSOLETE + \gre@obsolete{\protect\grenoscaledim}{\protect\grescaledim{...}{no}}% +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% space configuration loading +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\GreLoadSpaceConf#1{%OBSOLETE + \gre@obsolete{\protect\GreLoadSpaceConf}{\protect\greloadspaceconf}% +}% + +\newcount\greconffactor% +\def\greloadspaceconf#1{% + \input gsp-#1.tex\relax % + \ifnum\greconffactor=0\relax% + \gre@error{gsp-#1.tex does not have an assigned staff size.\MessageBreak Please edit it to define \protect\greconffactor}% + \fi % + \ifnum\the\gre@factor=\greconffactor\else %If the space configuration file is designed for a \gre@factor other than the current one, then we need to rescale the distances. + \gre@changedimenfactor{\greconffactor}{\gre@factor} % + \fi% + \greconffactor=0% + \relax % +}% + + +% For everything to work fine the default configuration has to loaded after the gregoriotex package is completely loaded (so that all functions are well defined). As a result you'll find that as the last line in gregoriotex-main.tex + + +%%%%%%%%%%%%%% +%% Rescaling dimensions (for when \gre@factor changes) +%%%%%%%%%%%%%% + +% This function checks to see if the length is one of the ones which cannot be a rubber length. The assumption is that any length not listed here is allowed to be rubber. +\newif\ifgre@rubber% +\def\gre@rubberpermit#1{% + % is length one that cannot be rubber? + \IfStrEqCase*{#1}{% + {additionallineswidth}{\gre@rubberfalse}% + {additionalcustoslineswidth}{\gre@rubberfalse}% + {zerowidthspace}{\gre@rubberfalse}% + {maximumspacewithoutdash}{\gre@rubberfalse}% + {afterinitialshift}{\gre@rubberfalse}% + {beforeinitialshift}{\gre@rubberfalse}% + {minimalspaceatlinebeginning}{\gre@rubberfalse}% + {manualinitialwidth}{\gre@rubberfalse}% + {annotationseparation}{\gre@rubberfalse}% + {intersyllablespacenotes}{\gre@rubberfalse}% + {intersyllablespacenotes@alteration}{\gre@rubberfalse}% + {annotationraise}{\gre@rubberfalse}% + {commentaryseparation}{\gre@rubberfalse}% + {commentaryraise}{\gre@rubberfalse}% + {noclefspace}{\gre@rubberfalse}% + {clivisalignmentmin}{\gre@rubberfalse}% + {choralsigndownshift}{\gre@rubberfalse}% + {choralsignupshift}{\gre@rubberfalse}% + {translationheight}{\gre@rubberfalse}% + {spacelinestext}{\gre@rubberfalse}% + {spacebeneathtext}{\gre@rubberfalse}% + {abovelinestextraise}{\gre@rubberfalse}% + {abovelinestextheight}{\gre@rubberfalse}% + {braceshift}{\gre@rubberfalse}% + {curlybraceaccentusshift}{\gre@rubberfalse}% + {initialraise}{\gre@rubberfalse}% + {beforealterationspace}{\gre@rubberfalse}% + {alterationspace}{\gre@rubberfalse}% + {overslurshift}{\gre@rubberfalse}% + {underslurshift}{\gre@rubberfalse}% + {maxbaroffsettextleft}{\gre@rubberfalse}% + {maxbaroffsettextright}{\gre@rubberfalse}% + {maxbaroffsettextleft@nobar}{\gre@rubberfalse}% + {maxbaroffsettextright@nobar}{\gre@rubberfalse}% + {maxbaroffsettextleft@eol}{\gre@rubberfalse}% + {maxbaroffsettextright@eol}{\gre@rubberfalse}% + {interwordspacetext@bars@euouae}{\gre@rubberfalse}% + {interwordspacetext@bars}{\gre@rubberfalse}% + {interwordspacetext@bars@notext@euouae}{\gre@rubberfalse}% + {interwordspacetext@bars@notext}{\gre@rubberfalse}% + {overhepisemalowshift}{\gre@rubberfalse}% + {overhepisemahighshift}{\gre@rubberfalse}% + {underhepisemalowshift}{\gre@rubberfalse}% + {underhepisemahighshift}{\gre@rubberfalse}% + {hepisemamiddleshift}{\gre@rubberfalse}% + {vepisemalowshift}{\gre@rubberfalse}% + {vepisemahighshift}{\gre@rubberfalse}% + {linepunctummorashift}{\gre@rubberfalse}% + {spacepunctummorashift}{\gre@rubberfalse}% + {spaceamonepespunctummorashift}{\gre@rubberfalse}% + {lineporrectuspunctummorashift}{\gre@rubberfalse}% + {spaceporrectuspunctummorashift}{\gre@rubberfalse}% + {raresignshift}{\gre@rubberfalse}% + {divisiofinalissep}{\gre@rubberfalse}% + }[\gre@rubbertrue]% +}% + +%% an aux function adapting the value #1 from the factor #2 to the factor #3 +\def\gre@changeonedimenfactor#1#2#3{% + % Math + \gre@rubberpermit{#1}% + \ifgre@rubber% + % if we have a rubber allowed length we create a temporary skip + \let\gre@scaledist\gre@skip@temp@one% + \edef\gre@convert{\csname gre@space@skip@#1\endcsname}% + \gre@scaledist=\glueexpr(\gre@convert * \number#3 / \number#2)\relax % + \else% + % otherwise we create a temporary dimen + \let\gre@scaledist\gre@dimen@temp@one% + \edef\gre@convert{\csname gre@space@dimen@#1\endcsname}% + \gre@scaledist=\dimexpr(\gre@convert * \number#3 / \number#2)\relax % + \fi% + \gre@consistentunits{\gre@convert}{\gre@scaledist}% + \gre@dimension{#1}{\gre@stringdist}% + \relax % +}% + + +% This function converts a distance to the units indicated in #1 and returns it as a string. +\def\gre@convertto#1#2{% + \gre@debugmsg{general}{convertto (#1) (#2)}% + % \p@ is equal to 1pt and is used here for a more accurate computation + \edef\gre@converted{\gre@strip@pt\dimexpr#2*\p@/\dimexpr 1#1\relax\relax #1}% + \gre@debugmsg{general}{converted value is \gre@converted}% +}% + +% This function takes a distance (#2) and formats it as a string so that its units conform to the pattern set by a string representation of a distance (#1) +\newif\ifgre@stretch% +\newif\ifgre@shrink% +\def\gre@consistentunits#1#2{% + \gre@stretchfalse% + \gre@shrinkfalse% + \IfSubStr{#1}{plus}{\gre@stretchtrue}{\relax}% + \IfSubStr{#1}{minus}{\gre@shrinktrue}{\relax}% + \ifgre@stretch% + \ifgre@shrink% + %rubber with both stretch and shrink + \StrBefore{#1}{plus}[\gre@baseunit]% + \StrBetween{#1}{plus}{minus}[\gre@stretchunit]% + \StrBehind{#1}{minus}[\gre@shrinkunit]% + \else% + %rubber with stretch only + \StrBefore{#1}{plus}[\gre@baseunit]% + \StrBehind{#1}{plus}[\gre@stretchunit]% + \def\gre@shrinkunit{\relax}% + \fi% + \else% + \ifgre@shrink% + %rubber with shrink only + \StrBefore{#1}{minus}[\gre@baseunit]% + \def\gre@stretchunit{\relax}% + \StrBehind{#1}{minus}[\gre@shrinkunit]% + \else% + %non-rubber + \def\gre@baseunit{#1}% + \def\gre@stretchunit{\relax}% + \def\gre@shrinkunit{\relax}% + \fi% + \fi% + \StrDel{\gre@baseunit}{ }[\gre@baseunit]% + \StrRight{\gre@baseunit}{2}[\gre@baseunit]% + \StrDel{\gre@stretchunit}{ }[\gre@stretchunit]% + \StrRight{\gre@stretchunit}{2}[\gre@stretchunit]% + \StrDel{\gre@shrinkunit}{ }[\gre@shrinkunit]% + \StrRight{\gre@shrinkunit}{2}[\gre@shrinkunit]% + \gre@convertto{\gre@baseunit}{\dimexpr#2\relax}% + \edef\gre@stringdist{\gre@converted}% + \if\relax\gre@stretchunit\else% + \gre@convertto{\gre@stretchunit}{\gluestretch#2}% + \edef\gre@stringdist{\gre@stringdist plus \gre@converted}% + \fi% + \if\relax\gre@shrinkunit\else% + \gre@convertto{\gre@shrinkunit}{\glueshrink#2}% + \edef\gre@stringdist{\gre@stringdist minus \gre@converted}% + \fi% +}% + + +%% this function changes all the values of the spaces (vertical and horizontal) from one factor to another +%% simply by dividing them by the old factor, and multiplying them by the new one. +% #1 is the old gre@factor, #2 is the new one +\def\gre@changedimenfactor#1#2{% + \ifgre@scale@additionallineswidth% + \gre@changeonedimenfactor{additionallineswidth}{#1}{#2}% + \fi% + \ifgre@scale@additionalcustoslineswidth% + \gre@changeonedimenfactor{additionalcustoslineswidth}{#1}{#2}% + \fi% + \ifgre@scale@zerowidthspace% + \gre@changeonedimenfactor{zerowidthspace}{#1}{#2}% + \fi% + \ifgre@scale@interglyphspace% + \gre@changeonedimenfactor{interglyphspace}{#1}{#2}% + \fi% + \ifgre@scale@alterationspace% + \gre@changeonedimenfactor{alterationspace}{#1}{#2}% + \fi% + \ifgre@scale@clefflatspace% + \gre@changeonedimenfactor{clefflatspace}{#1}{#2}% + \fi% + \ifgre@scale@beforelowchoralsignspace% + \gre@changeonedimenfactor{beforelowchoralsignspace}{#1}{#2}% + \fi% + \ifgre@scale@beforealterationspace% + \gre@changeonedimenfactor{beforealterationspace}{#1}{#2}% + \fi% + \ifgre@scale@halfspace% + \gre@changeonedimenfactor{halfspace}{#1}{#2}% + \fi% + \ifgre@scale@interelementspace% + \gre@changeonedimenfactor{interelementspace}{#1}{#2}% + \fi% + \ifgre@scale@largerspace% + \gre@changeonedimenfactor{largerspace}{#1}{#2}% + \fi% + \ifgre@scale@nabcinterelementspace% + \gre@changeonedimenfactor{nabcinterelementspace}{#1}{#2}% + \fi% + \ifgre@scale@nabclargerspace% + \gre@changeonedimenfactor{nabclargerspace}{#1}{#2}% + \fi% + \ifgre@scale@glyphspace% + \gre@changeonedimenfactor{glyphspace}{#1}{#2}% + \fi% + \ifgre@scale@spacebeforeinlinecustos% + \gre@changeonedimenfactor{spacebeforeinlinecustos}{#1}{#2}% + \fi% + \ifgre@scale@spacebeforeeolcustos% + \gre@changeonedimenfactor{spacebeforeeolcustos}{#1}{#2}% + \fi% + \ifgre@scale@spacebeforesigns% + \gre@changeonedimenfactor{spacebeforesigns}{#1}{#2}% + \fi% + \ifgre@scale@spaceaftersigns% + \gre@changeonedimenfactor{spaceaftersigns}{#1}{#2}% + \fi% + \ifgre@scale@spaceafterlineclef% + \gre@changeonedimenfactor{spaceafterlineclef}{#1}{#2}% + \fi% + \ifgre@scale@interwordspacenotes% + \gre@changeonedimenfactor{interwordspacenotes}{#1}{#2}% + \fi% + \ifgre@scale@intersyllablespacenotes% + \gre@changeonedimenfactor{intersyllablespacenotes}{#1}{#2}% + \fi% + \ifgre@scale@interwordspacenotes@alteration% + \gre@changeonedimenfactor{interwordspacenotes@alteration}{#1}{#2}% + \fi% + \ifgre@scale@intersyllablespacenotes@alteration% + \gre@changeonedimenfactor{intersyllablespacenotes@alteration}{#1}{#2}% + \fi% + \ifgre@scale@intersyllablespacestretchhyphen% + \gre@changeonedimenfactor{intersyllablespacestretchhyphen}{#1}{#2}% + \fi% + \ifgre@scale@interwordspacetext% + \gre@changeonedimenfactor{interwordspacetext}{#1}{#2}% + \fi% + \ifgre@scale@interwordspacetext@bars% + \gre@changeonedimenfactor{interwordspacetext@bars}{#1}{#2}% + \fi% + \ifgre@scale@interwordspacetext@bars@notext% + \gre@changeonedimenfactor{interwordspacetext@bars@notext}{#1}{#2}% + \fi% + \ifgre@scale@interwordspacenotes@euouae% + \gre@changeonedimenfactor{interwordspacenotes@euouae}{#1}{#2}% + \fi% + \ifgre@scale@interwordspacetext@euouae% + \gre@changeonedimenfactor{interwordspacetext@euouae}{#1}{#2}% + \fi% + \ifgre@scale@interwordspacetext@bars@euouae% + \gre@changeonedimenfactor{interwordspacetext@bars@euouae}{#1}{#2}% + \fi% + \ifgre@scale@interwordspacetext@bars@notext@euouae% + \gre@changeonedimenfactor{interwordspacetext@bars@notext@euouae}{#1}{#2}% + \fi% + \ifgre@scale@bitrivirspace% + \gre@changeonedimenfactor{bitrivirspace}{#1}{#2}% + \fi% + \ifgre@scale@bitristrospace% + \gre@changeonedimenfactor{bitristrospace}{#1}{#2}% + \fi% + \ifgre@scale@punctuminclinatumshift% + \gre@changeonedimenfactor{punctuminclinatumshift}{#1}{#2}% + \fi% + \ifgre@scale@ascendingpunctuminclinatumshift% + \gre@changeonedimenfactor{ascendingpunctuminclinatumshift}{#1}{#2}% + \fi% + \ifgre@scale@beforepunctainclinatashift% + \gre@changeonedimenfactor{beforepunctainclinatashift}{#1}{#2}% + \fi% + \ifgre@scale@punctuminclinatumanddebilisshift% + \gre@changeonedimenfactor{punctuminclinatumanddebilisshift}{#1}{#2}% + \fi% + \ifgre@scale@ascendingpunctuminclinatumanddebilisshift% + \gre@changeonedimenfactor{ascendingpunctuminclinatumanddebilisshift}{#1}{#2}% + \fi% + \ifgre@scale@punctuminclinatumdebilisshift% + \gre@changeonedimenfactor{punctuminclinatumdebilisshift}{#1}{#2}% + \fi% + \ifgre@scale@punctuminclinatumbigshift% + \gre@changeonedimenfactor{punctuminclinatumbigshift}{#1}{#2}% + \fi% + \ifgre@scale@ascendingpunctuminclinatumbigshift% + \gre@changeonedimenfactor{ascendingpunctuminclinatumbigshift}{#1}{#2}% + \fi% + \ifgre@scale@punctuminclinatummaxshift% + \gre@changeonedimenfactor{punctuminclinatummaxshift}{#1}{#2}% + \fi% + \ifgre@scale@ascendingpunctuminclinatummaxshift% + \gre@changeonedimenfactor{ascendingpunctuminclinatummaxshift}{#1}{#2}% + \fi% + \ifgre@scale@descendinginclinatumtonobarshift% + \gre@changeonedimenfactor{descendinginclinatumtonobarshift}{#1}{#2}% + \fi% + \ifgre@scale@descendinginclinatumtonobarbigshift% + \gre@changeonedimenfactor{descendinginclinatumtonobarbigshift}{#1}{#2}% + \fi% + \ifgre@scale@descendinginclinatumtonobarmaxshift% + \gre@changeonedimenfactor{descendinginclinatumtonobarmaxshift}{#1}{#2}% + \fi% + \ifgre@scale@ascendinginclinatumtonobarshift% + \gre@changeonedimenfactor{ascendinginclinatumtonobarshift}{#1}{#2}% + \fi% + \ifgre@scale@ascendinginclinatumtonobarbigshift% + \gre@changeonedimenfactor{ascendinginclinatumtonobarbigshift}{#1}{#2}% + \fi% + \ifgre@scale@ascendinginclinatumtonobarmaxshift% + \gre@changeonedimenfactor{ascendinginclinatumtonobarmaxshift}{#1}{#2}% + \fi% + \ifgre@scale@bar@virgula% + \gre@changeonedimenfactor{bar@virgula}{#1}{#2}% + \fi% + \ifgre@scale@bar@minima% + \gre@changeonedimenfactor{bar@minima}{#1}{#2}% + \fi% + \ifgre@scale@bar@minor% + \gre@changeonedimenfactor{bar@minor}{#1}{#2}% + \fi% + \ifgre@scale@bar@minor% + \gre@changeonedimenfactor{bar@dominican}{#1}{#2}% + \fi% + \ifgre@scale@bar@maior% + \gre@changeonedimenfactor{bar@maior}{#1}{#2}% + \fi% + \ifgre@scale@bar@finalis% + \gre@changeonedimenfactor{bar@finalis}{#1}{#2}% + \fi% + \ifgre@scale@bar@finalfinalis% + \gre@changeonedimenfactor{bar@finalfinalis}{#1}{#2}% + \fi% + \ifgre@scale@bar@virgula@standalone@text% + \gre@changeonedimenfactor{bar@virgula@standalone@text}{#1}{#2}% + \fi% + \ifgre@scale@bar@minima@standalone@text% + \gre@changeonedimenfactor{bar@minima@standalone@text}{#1}{#2}% + \fi% + \ifgre@scale@bar@minor@standalone@text% + \gre@changeonedimenfactor{bar@minor@standalone@text}{#1}{#2}% + \fi% + \ifgre@scale@bar@minor@standalone@text% + \gre@changeonedimenfactor{bar@dominican@standalone@text}{#1}{#2}% + \fi% + \ifgre@scale@bar@maior@standalone@text% + \gre@changeonedimenfactor{bar@maior@standalone@text}{#1}{#2}% + \fi% + \ifgre@scale@bar@finalis@standalone@text% + \gre@changeonedimenfactor{bar@finalis@standalone@text}{#1}{#2}% + \fi% + \ifgre@scale@bar@virgula@standalone@notext% + \gre@changeonedimenfactor{bar@virgula@standalone@notext}{#1}{#2}% + \fi% + \ifgre@scale@bar@minima@standalone@notext% + \gre@changeonedimenfactor{bar@minima@standalone@notext}{#1}{#2}% + \fi% + \ifgre@scale@bar@minor@standalone@notext% + \gre@changeonedimenfactor{bar@minor@standalone@notext}{#1}{#2}% + \fi% + \ifgre@scale@bar@minor@standalone@notext% + \gre@changeonedimenfactor{bar@dominican@standalone@notext}{#1}{#2}% + \fi% + \ifgre@scale@bar@maior@standalone@notext% + \gre@changeonedimenfactor{bar@maior@standalone@notext}{#1}{#2}% + \fi% + \ifgre@scale@bar@finalis@standalone@notext% + \gre@changeonedimenfactor{bar@finalis@standalone@notext}{#1}{#2}% + \fi% + \ifgre@scale@spacearoundclefbars% + \gre@changeonedimenfactor{spacearoundclefbars}{#1}{#2}% + \fi% + \ifgre@scale@textbartextspace% + \gre@changeonedimenfactor{textbartextspace}{#1}{#2}% + \fi% + \ifgre@scale@notebarspace% + \gre@changeonedimenfactor{notebarspace}{#1}{#2}% + \fi% + \ifgre@scale@maximumspacewithoutdash% + \gre@changeonedimenfactor{maximumspacewithoutdash}{#1}{#2}% + \fi% + \ifgre@scale@afterclefnospace% + \gre@changeonedimenfactor{afterclefnospace}{#1}{#2}% + \fi% + \ifgre@scale@afterinitialshift% + \gre@changeonedimenfactor{afterinitialshift}{#1}{#2}% + \fi% + \ifgre@scale@beforeinitialshift% + \gre@changeonedimenfactor{beforeinitialshift}{#1}{#2}% + \fi% + \ifgre@scale@minimalspaceatlinebeginning% + \gre@changeonedimenfactor{minimalspaceatlinebeginning}{#1}{#2}% + \fi% + \ifgre@scale@manualinitialwidth% + \gre@changeonedimenfactor{manualinitialwidth}{#1}{#2}% + \fi% + \ifgre@scale@annotationseparation% + \gre@changeonedimenfactor{annotationseparation}{#1}{#2}% + \fi% + \ifgre@scale@annotationraise% + \gre@changeonedimenfactor{annotationraise}{#1}{#2}% + \fi% + \ifgre@scale@noclefspace% + \gre@changeonedimenfactor{noclefspace}{#1}{#2}% + \fi% + \ifgre@scale@clefchangespace% + \gre@changeonedimenfactor{clefchangespace}{#1}{#2}% + \fi% + \ifgre@scale@clivisalignmentmin% + \gre@changeonedimenfactor{clivisalignmentmin}{#1}{#2}% + \fi% + \ifgre@scale@choralsigndownshift% + \gre@changeonedimenfactor{choralsigndownshift}{#1}{#2}% + \fi% + \ifgre@scale@choralsignupshift% + \gre@changeonedimenfactor{choralsignupshift}{#1}{#2}% + \fi% + \ifgre@scale@translationheight% + \gre@changeonedimenfactor{translationheight}{#1}{#2}% + \fi% + \ifgre@scale@spaceabovelines% + \gre@changeonedimenfactor{spaceabovelines}{#1}{#2}% + \fi% + \ifgre@scale@spacelinestext% + \gre@changeonedimenfactor{spacelinestext}{#1}{#2}% + \fi% + \ifgre@scale@spacebeneathtext% + \gre@changeonedimenfactor{spacebeneathtext}{#1}{#2}% + \fi% + \ifgre@scale@abovelinestextraise% + \gre@changeonedimenfactor{abovelinestextraise}{#1}{#2}% + \fi% + \ifgre@scale@abovelinestextheight% + \gre@changeonedimenfactor{abovelinestextheight}{#1}{#2}% + \fi% + \ifgre@scale@braceshift% + \gre@changeonedimenfactor{braceshift}{#1}{#2}% + \fi% + \ifgre@scale@curlybraceaccentusshift% + \gre@changeonedimenfactor{curlybraceaccentusshift}{#1}{#2}% + \fi% + \ifgre@scale@maxbaroffsettextright% + \gre@changeonedimenfactor{maxbaroffsettextright}{#1}{#2}% + \fi% + \ifgre@scale@maxbaroffsettextleft% + \gre@changeonedimenfactor{maxbaroffsettextleft}{#1}{#2}% + \fi% + \ifgre@scale@maxbaroffsettextright@nobar% + \gre@changeonedimenfactor{maxbaroffsettextright@nobar}{#1}{#2}% + \fi% + \ifgre@scale@maxbaroffsettextleft@nobar% + \gre@changeonedimenfactor{maxbaroffsettextleft@nobar}{#1}{#2}% + \fi% + \ifgre@scale@maxbaroffsettextleft@eol% + \gre@changeonedimenfactor{maxbaroffsettextleft@eol}{#1}{#2}% + \fi% + \ifgre@scale@maxbaroffsettextright@eol% + \gre@changeonedimenfactor{maxbaroffsettextright@eol}{#1}{#2}% + \fi% + \ifgre@scale@bar@rubber% + \gre@changeonedimenfactor{bar@rubber}{#1}{#2}% + \fi% + \ifgre@scale@divisiofinalissep% + \gre@changeonedimenfactor{divisiofinalissep}{#1}{#2}% + \fi% + \ifgre@scale@stafflinefactor% + \gre@count@temp@two = \numexpr((\gre@stafflinefactor * #2) / #1)\relax% + \xdef\gre@stafflinefactor{\the\gre@count@temp@two}% + \fi% + \relax % +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Some Macros for changing the spacing around the initial +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%Seeing as these are the distances that people will want to change the most often, +%we give them their own set of macros to make that easier. + +% To change the spacing between annotations. +%First argument is distance, second is whether it should scale when \gre@factor changes. +\def\setaboveinitialseparation#1#2{%OBSOLETE + \gre@obsolete{\protect\setaboveinitialseparation}{\protect\grechangedim\{annotationseparation\}}% +}% + + +%To change the space after the initial +%First argument is distance, second is whether it should scale when \gre@factor changes. +\def\setspaceafterinitial#1#2{%OBSOLETE + \gre@obsolete{\protect\setspaceafterinitial}{\protect\grechangedim{afterinitialshift}}% +} + +%To change the space before the initial +%First argument is distance, second is whether it should scale when \gre@factor changes. +\def\setspacebeforeinitial#1#2{%OBSOLETE + \gre@obsolete{\protect\setspacebeforeinitial}{\protect\grechangedim{beforeinitialshift}}% +}% + + +%To change all the distances associated with the initial. +%First three arguments are distances, last is whether they should scale when \gre@factor changes. +\def\setinitialspacing#1#2#3#4{%OBSOLETE + \gre@obsolete{\protect\setinitialspacing}{\protect\grechangedim{beforeinitialshift}, \protect\grechangedim{manualinitialwidth}, and \protect\grechangedim{afterinitialshift}}% +}% diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-syllable.tex b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-syllable.tex new file mode 100644 index 00000000000..2c3a9e08f83 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-syllable.tex @@ -0,0 +1,1321 @@ +%GregorioTeX file. +% +% Copyright (C) 2007-2015 The Gregorio Project (see CONTRIBUTORS.md) +% +% This file is part of Gregorio. +% +% Gregorio 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. +% +% Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +% this file contains definitions of the glyphs and the syllables + +\gre@debugmsg{general}{Loading gregoriotex-syllable.tex}% +\gre@declarefileversion{gregoriotex-syllable.tex}{4.1.1}% GREGORIO_VERSION + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of the different glyphs +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Flag to indicate if the note is on a line or not +\newif\ifgre@isonaline% + +% if previous syllable ends with a punctum mora +\newif\ifgre@lastendswithmora % +\gre@lastendswithmorafalse % + +% if this syllable ends with a punctum mora +\newif\ifgre@thisendswithmora % +\gre@thisendswithmorafalse % + +% a macro called each time we start something looking like a glyph, but not mandatorily called through the \GreGlyph macro, for example bars, flats, etc. + +\newcount\gre@generate@pointandclick\gre@generate@pointandclick=0\relax % + +\def\gresetpointandclick#1{% + \IfStrEqCase{#1}{% + {on}% + {% + \ifx\pdfoutput\undefined % + \gre@warning{Unable to enable point-and-click because \protect\pdfoutput \MessageBreak is not defined}% + \gre@generate@pointandclick=0\relax % + \else % + \ifnum\pdfoutput=1\relax % + \gre@generate@pointandclick=1\relax % + \else % + \gre@warning{Unable to enable point-and-click when not\MessageBreak generating a PDF}% + \gre@generate@pointandclick=0\relax % + \fi % + \fi % + }% + {off}% + {\gre@generate@pointandclick=0\relax}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetpointandclick\MessageBreak Possible options are: 'on' and 'off'}% + ]% +}% + +\def\gre@pointandclick#1#2{% + \def\gre@@arg{#2}% + \ifx\gre@@arg\gre@nothing % + #1% + \else % + \def\gre@@arg{\gre@gabcname}% + \ifx\gre@@arg\gre@nothing % + #1% + \else % + \ifnum\gre@generate@pointandclick=1\relax % + \pdfstartlink user{% + /Subtype/Link/Border[0 0 0]% + /A<</Type/Action/S/URI/URI(textedit://\gre@gabcname:#2)>>% + }% + #1% + \pdfendlink % + \else % + #1% + \fi % + \fi % + \fi % +}% + +\def\gre@newglyphcommon{% + \global\advance\gre@attr@glyph@id by 1\relax % + % first there is something we must do: setting \gre@lastoflinecount to 0 if its value is 2. The reason of this is that in ab(abzcd), we cannot let \grelastoflinecount set to 2 after the end of line... the only way I found to achieve it is to reset \grelastoflinecount to 0 after each glyph or bar. + \ifnum\gre@lastoflinecount=2\relax % + \global\gre@lastoflinecount=0\relax % + \fi % + \global\gre@skip@bar@lastskip=0pt\relax % + \gre@currenttextabovelines % + \ifcase\gre@count@lastglyphiscavum\or % + \global\gre@count@lastglyphiscavum=2\relax % + \or % + \global\gre@count@lastglyphiscavum=0\relax % + \fi % + \global\gre@lastendswithmorafalse % + \ifgre@boxing\else\ifgre@firstin@euouae % + \ifgre@raggedbreakbeforeeuouae % + \directlua{gregoriotex.save_pos(\the\gre@lasteuouaeindex,2)}% + \fi % + \gre@firstin@euouaefalse % + \fi\fi % + \relax % +}% + +\def\gre@endofglyphcommon{% + \ifgre@endofscore % + \gre@penalty{\grefinalpenalty}% + \gre@localleftbox{}% + \gre@localrightbox{}% + \fi % +} + +% passes the glyph height limits: +% #1: the high height +% #2: the low height +\def\GreGlyphHeights#1#2{% + \global\setluatexattribute\gre@attr@glyph@top{#1}% + \global\setluatexattribute\gre@attr@glyph@bottom{#2}% +}% + +% Flag that tells us if the current glyph is the first glyph or not. +\newif\ifgre@firstglyph% + +% 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 custos 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 +% #5 are the signs to typeset before the glyph (typically additional bars, as they must be "behind" the glyph) +% #6 are the signs to typeset after the glyph (almost all signs) +% #7 is the line:char:column for a textedit link +\def\GreGlyph#1#2#3#4#5#6#7{% + \gre@newglyphcommon % + \setbox\gre@box@temp@width=\hbox{\gre@pointandclick{\gre@font@music #1}{#7}}% + \global\gre@dimen@lastglyphwidth=\wd\gre@box@temp@width % + % the three next lines are a trick to get the additional lines below the glyphs + \gre@skip@temp@one = \gre@dimen@lastglyphwidth\relax% + \kern\gre@skip@temp@one % + #5\relax % + \kern-\gre@skip@temp@one % + \gre@calculate@glyphraisevalue{#2}{0}{}% + \raise\gre@dimen@glyphraisevalue\relax% + \copy\gre@box@temp@width% + \ifgre@endofscore\else\ifgre@boxing\else % + \GreNextCustos{#3}% + \fi\fi % + \ifgre@firstglyph% we check if it is the first glyph + \gre@calculate@notesaligncenter{#4}% + \global\gre@firstglyphfalse% + \fi% + #6\relax % + \directlua{gregoriotex.adjust_line_height(\gre@insidediscretionary)}% + \gre@endofglyphcommon % + \relax% +}% + +% this function is quite simple, it just sets \gre@box@temp@width 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 +%% 12: divisio minor +%% 13: divisio maior +%% 14: dominican bar +%% 15 : divisio finalis +%% 16 : no note +% there is a tricky here : if notesaligncenter is not 0, it means that there is a flat before, so we simply add notes aligncenter +% #2 is 0 if we are in the context of current syllable, 1 if we are in the context of next syllable +\def\gre@calculate@simplenotesaligncenter#1#2{% + \ifcase#1% + %case of punctum + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPPunctum}% + \or% + %case of flexus + \gre@handleclivisspecialalignment{\gre@font@music\GreCPPesQuadratumLongqueueThreeNothing}{\gre@font@music\GreCPPunctum}{#2}% + \or% + %case of porrectus (we consider it to have the same alignment as punctum) + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPPunctum}% + \or% + %case of a initio debilis + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPPunctumDeminutus}% + \or % + %case of a quilisma + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPQuilisma}% + \or % + %case of an oriscus + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPOriscus}% + \or % + %case of a punctum inclinatum + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPPunctumInclinatum}% + \or % + %case of a stropha + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPStropha}% + \or % + % case of flexus with ambitus of one + \gre@handleclivisspecialalignment{\gre@font@music\GreCPPesQuadratumLongqueueOneNothing}{\gre@font@music\GreCPPunctum}{#2}% + \or % + % case of flexus deminutus + \gre@handleclivisspecialalignment{\gre@font@music\GreCPFlexusTwoDeminutus}{\gre@font@music\GreCPPunctum}{#2}% + \or % + % case of virgula + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPVirgula}% + \or % + % case of divisio minima + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioMinima}% + \or % + % case of divisio minor + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioMinor}% + \or % + % case of divisio maior + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioMaior}% + \or % + % case of dominican bar + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPDivisioDominican}% + \or % + % case of divisiofinalis + \global\setbox\gre@box@temp@width=\hbox{\gre@fontchar@divisiofinalis}% + \or % + % case of no note + \ifgre@newbarspacing% + \global\setbox\gre@box@temp@width=\hbox{}% + \else% + % under the old algorithm, syllables with no notes triggered a 0 in this function, so we duplicate the first case here + \global\setbox\gre@box@temp@width=\hbox{\gre@font@music\GreCPPunctum}% + \fi% + \fi% + \relax% +}% + +% aux function to previous one: sets \gre@box@temp@width to \hbox{#1} or \hbox{#2} +% according to special clivis alignemt scheme. See comments of +% \gre@clivisalignment for more. +% #1 is the glyph in case we align the clivis in the "clivis" way, +% #2 is the glyph in case we align the clivis in the normal way +% Conditionals can be summed up this way: +% if wd(#1/2) > \gre@dimen@textaligncenter then #2 +% else +% if lyrics are centered on syllables : +% if (\gre@dimen@textaligncenter) > \gre@space@dimen@clivisalignmentmin -> #2 else #1 +% else: +% if wd(\gre@endsyllablepart) > \gre@space@dimen@clivisalignmentmin -> #2 else #1 +% +% #3 is the same as #2 of previous function +\def\gre@handleclivisspecialalignment#1#2#3{% + \ifcase\gre@clivisalignment% + \global\setbox\gre@box@temp@width=\hbox{#1}% + \or% + \global\setbox\gre@box@temp@width=\hbox{#2}% + \or% + \gre@widthof{#1}% + \divide\gre@dimen@temp@three by 2\relax % + \gre@debugmsg{ifdim}{ temp@three > textaligncenter}% + \ifdim\gre@dimen@temp@three >\gre@dimen@textaligncenter\relax% + \global\setbox\gre@box@temp@width=\hbox{#2}% + \else% + \ifcase\gre@lyriccentering% 0 == syllable centering + \gre@debugmsg{ifdim}{ textaligncenter > clivisalignmentmin}% + \ifdim\gre@dimen@textaligncenter >\gre@space@dimen@clivisalignmentmin\relax% + \global\setbox\gre@box@temp@width=\hbox{#2}% + \else% + \global\setbox\gre@box@temp@width=\hbox{#1}% + \fi% + \else% vowel or first-letter centering + \ifcase#3% + \gre@widthof{\gre@endsyllablepart}% + \else% + \gre@widthof{\gre@nextendsyllablepart}% + \fi% + \gre@debugmsg{ifdim}{ temp@three > clivisalignmentmin}% + \ifdim\gre@dimen@temp@three >\gre@space@dimen@clivisalignmentmin\relax% + \global\setbox\gre@box@temp@width=\hbox{#2}% + \else% + \global\setbox\gre@box@temp@width=\hbox{#1}% + \fi% + \fi% + \fi% + \fi% +}% + +% 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\gre@calculate@notesaligncenter#1{% + \gre@calculate@simplenotesaligncenter{#1}{0}% + \global\advance\gre@dimen@notesaligncenter by \dimexpr(\wd\gre@box@temp@width / 2)\relax % + \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, +60 with a sharp +\def\gre@calculate@nextnotesaligncenter#1{% + \ifnum#1<20\relax % + \gre@calculate@simplenotesaligncenter{#1}{1}% + \gre@dimen@temp@five=\dimexpr(\wd\gre@box@temp@width / 2)\relax % + \global\gre@dimen@notesaligncenter=\gre@dimen@temp@five % + \else %\ifnum#1<20 + \gre@count@temp@three=#1 % + \ifnum#1<40\relax% + \advance\gre@count@temp@three by -20\relax % + \gre@calculate@simplenotesaligncenter{\gre@count@temp@three}{1}% + \gre@dimen@temp@five=\dimexpr(\wd\gre@box@temp@width / 2)\relax % + \setbox\gre@box@temp@width=\hbox{\gre@fontchar@flat}% + \else%\ifnum#1<40 + \ifnum#1<60\relax% + \advance\gre@count@temp@three by -40\relax % + \gre@calculate@simplenotesaligncenter{\gre@count@temp@three}{1}% + \gre@dimen@temp@five=\dimexpr(\wd\gre@box@temp@width / 2)\relax % + \setbox\gre@box@temp@width=\hbox{\gre@fontchar@natural}% + \else%\ifnum#1<60 + \advance\gre@count@temp@three by -60\relax % + \gre@calculate@simplenotesaligncenter{\gre@count@temp@three}{1}% + \gre@dimen@temp@five=\dimexpr(\wd\gre@box@temp@width / 2)\relax % + \setbox\gre@box@temp@width=\hbox{\gre@fontchar@sharp}% + \fi% + \fi % + \advance\gre@dimen@temp@five by \dimexpr(\wd\gre@box@temp@width+\gre@space@dimen@alterationspace)\relax % + \global\gre@dimen@notesaligncenter=\gre@dimen@temp@five % + \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\gre@box@syllablenotes% + +% Macro used to fill \gre@box@syllablenotes with everything contained in #1. This +% saves and restores a few values so that when really typesetting #1 in \GreSyllable, +% the result is identical. +\def\gre@syllablenotes#1{% + % \gre@count@lastglyphiscavum is reinitialized at each syllable... + % so there's a bug on g(bx)g(b) + \global\gre@count@lastglyphiscavum=0\relax % + \global\gre@firstglyphtrue% + \global\gre@boxingtrue% + \let\ifgre@lastendswithmorasave\ifgre@lastendswithmora% + \xdef\gre@savedlastoflinecount{\number\gre@lastoflinecount\relax }% + \setbox\gre@box@syllablenotes=\hbox{#1}% + \gre@debugmsg{spacing}{Width of notes: \the\wd\gre@box@syllablenotes}% + \global\gre@boxingfalse% + \global\gre@lastoflinecount=\gre@savedlastoflinecount\relax % + \global\gre@firstglyphtrue% + % now gre@lastendswithmora is true if this syllable ends with a + % punctum mora, but we still want to keep gre@lastendswithmora if we + % are on a bar, so: + % - we set gre@thisendswithmora to gre@lastendswithmora + % - when syllables will be really typeset, they will set gre@lastendswithmora + % again + \ifgre@lastendswithmora % + \gre@thisendswithmoratrue % + \else % + \gre@thisendswithmorafalse % + \fi % + \let\ifgre@lastendswithmora\ifgre@lastendswithmorasave % + \global\gre@count@lastglyphiscavum=0\relax % + \global\gre@skip@bar@lastskip=0pt\relax % + \global\gre@endofscorefalse % + \relax % +}% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% macros for the typesetting of glyphs and notes together +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\GreFirstWord#1{\gre@style@firstword#1\endgre@style@firstword}% +\def\GreFirstSyllable#1{\gre@style@firstsyllable#1\endgre@style@firstsyllable}% +\def\GreFirstSyllableInitial#1{\gre@style@firstsyllableinitial#1\endgre@style@firstsyllableinitial}% +\def\GreElision#1{\gre@style@elision#1\endgre@style@elision}% + +% box that will contain the text of the syllable +\newbox\gre@box@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 + +% Flag to track if we are boxing the syllable notes or printing them +\newif\ifgre@boxing% +\gre@boxingfalse% + +% +% Helper macros for fixing text in rare cases +% + +% the macro we call with all normal text +\def\gre@textnormal#1{% + #1\relax % +}% + +% macro to specify a text which is different from #1#2#3 (of \GreSyllable). It is useful for +% styles, for instance with +% +% <i>ffj</i>(gh) +% +% , we will have +% +% #1 = \textit{f} +% #2 = \textit{f} +% #3 = \textit{j} +% +% and thus #1#2#3 will be \textit{f}\textit{f}\textit{j}, which won't typeset +% ligatures. In this example we should call \grefixedtext{\textit{ffj}}. +% +% for the argument, we have: +% 0: nothing +% 1: italic +% 2: bold +% 3: small caps +% 4: tt +% 5: ul +\def\GreSetFixedTextFormat#1{% + \ifcase#1\relax% + \global\let\gre@fixedtextformat\gre@textnormal % + \or % + \global\let\gre@fixedtextformat\GreItalic % + \or % + \global\let\gre@fixedtextformat\GreBold % + \or % + \global\let\gre@fixedtextformat\GreSmallCaps % + \or % + \global\let\gre@fixedtextformat\GreTypewriter % + \or % + \global\let\gre@fixedtextformat\GreUnderline % + \or % + \global\let\gre@fixedtextformat\GreColored % + \fi % +}% + +% a function to cancel the previous one +\def\gre@unsetfixedtextformat{% + \global\let\gre@fixedtextformat\gre@textnormal % +}% + +\let\gre@fixedtextformat\gre@textnormal % + +% The same but for the next syllable + +\def\GreSetFixedNextTextFormat#1{% + \ifcase#1\relax% + \global\let\gre@fixednexttextformat\gre@textnormal % + \or % + \global\let\gre@fixednexttextformat\GreItalic % + \or % + \global\let\gre@fixednexttextformat\GreBold % + \or % + \global\let\gre@fixednexttextformat\GreSmallCaps % + \or % + \global\let\gre@fixednexttextformat\GreTypewriter % + \or % + \global\let\gre@fixednexttextformat\GreUnderline % + \or % + \global\let\gre@fixednexttextformat\GreColored % + \fi % +}% + +% a function to cancel the previous one +\def\gre@unsetfixednexttextformat{% + \global\let\gre@fixednexttextformat\gre@textnormal % +}% + +\let\gre@fixednexttextformat\gre@textnormal % + +\def\GreUnstyled#1{#1}% + +\newif\ifgre@forcedcentering% +\gre@forcedcenteringfalse% +\newif\ifgre@nextforcedcentering% +\gre@nextforcedcenteringfalse% + +\def\GreGABCForceCenters{% + \ifgre@gabcforcecenters% + \gre@forcedcenteringtrue% + \else% + \gre@forcedcenteringfalse% + \fi% +}% + +\def\GreGABCNextForceCenters{% + \ifgre@gabcforcecenters% + \gre@nextforcedcenteringtrue% + \else% + \gre@nextforcedcenteringfalse% + \fi% +}% + +\newif\ifgre@gabcforcecenters% +\gre@gabcforcecenterstrue% + +\def\gresetgabcforcecenters#1{% + \ifcase\gre@lyriccentering\or + \gre@warning{\protect\gresetgabcforcecenters\space has no effect when lyrics are centered on the vowels}% + \fi% + \IfStrEqCase{#1}{% + {allow}% + {\gre@gabcforcecenterstrue}% + {prohibit}% + {\gre@gabcforcecentersfalse}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetgabcforcecenters\MessageBreak Possible options are: 'allow' and 'prohibit'}% + ]% +}% + +% #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 : the very first letter +% #5 : all the letters after the first letter +\def\GreSetThisSyllable#1#2#3#4#5{% + \ifgre@forcedcentering% + \gdef\gre@firstsyllablepart{#1}% + \gdef\gre@middlesyllablepart{#2}% + \gdef\gre@endsyllablepart{#3}% + \else% + \ifcase\gre@lyriccentering% 0 - syllable centering + \gdef\gre@firstsyllablepart{}% + \gdef\gre@middlesyllablepart{#1#2#3}% + \gdef\gre@endsyllablepart{}% + \or % 1 - vowel centering + \gdef\gre@firstsyllablepart{#1}% + \gdef\gre@middlesyllablepart{#2}% + \gdef\gre@endsyllablepart{#3}% + \or % 2 - first-letter centering + \gdef\gre@firstsyllablepart{}% + \gdef\gre@middlesyllablepart{#4}% + \gdef\gre@endsyllablepart{#5}% + \fi % + \fi% + \gre@forcedcenteringfalse% +}% + +\def\GreSetNextSyllable#1#2#3#4#5{% + \ifgre@nextforcedcentering% + \gdef\gre@nextfirstsyllablepart{#1}% + \gdef\gre@nextmiddlesyllablepart{#2}% + \gdef\gre@nextendsyllablepart{#3}% + \else% + \ifcase\gre@lyriccentering% 0 - syllable centering + \gdef\gre@nextfirstsyllablepart{}% + \gdef\gre@nextmiddlesyllablepart{#1#2#3}% + \gdef\gre@nextendsyllablepart{}% + \or % 1 - vowel centering + \gdef\gre@nextfirstsyllablepart{#1}% + \gdef\gre@nextmiddlesyllablepart{#2}% + \gdef\gre@nextendsyllablepart{#3}% + \or % 2 - first-letter centering + \gdef\gre@nextfirstsyllablepart{}% + \gdef\gre@nextmiddlesyllablepart{#4}% + \gdef\gre@nextendsyllablepart{#5}% + \fi % + \fi% + \gre@nextforcedcenteringfalse% +}% + +%%%%%%%%%%%%%%% +%% Lyric centering +%%%%%%%%%%%%%%% + +\def\gresetlyriccentering#1{% + \IfStrEqCase{#1}{% + {vowel}% + {\xdef\gre@lyriccentering{1}}% + {syllable}% + {\xdef\gre@lyriccentering{0}}% + {firstletter}% + {\xdef\gre@lyriccentering{2}}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetlyriccentering\MessageBreak Possible options are: 'vowel', 'syllable' and 'firstletter'}% + ]% +}% + +\xdef\gre@lyriccentering{1}% + +\def\englishcentering{%OBSOLETE + \gre@obsolete{\protect\englishcentering}{\protect\gresetlyriccentering{syllable}}% +}% + +\def\defaultcentering{%OBSOLETE + \gre@obsolete{\protect\defaultcentering}{\protect\gresetlyriccentering{vowel} }% +}% + +%% options about clivis centering scheme. Clivis are usually aligned by their +%% center, which is different from most neumes. Gregorio has three modes: +%% 0. always align clivis this way +%% 1. never align clivis this way, align on first punctum +%% 2. align clivis this way, except if: +%% - notes would go left of text +%% - consonants after vowels are larger than \gre@space@dimen@clivisalignmentmin +\newcount\gre@clivisalignment% +%% by default we use the mode 2, it seems closest to Solesmes books +\gre@clivisalignment=2% + + +\def\gresetclivisalignment#1{% + \IfStrEqCase{#1}{% + {always}% + {\global\gre@clivisalignment=0\relax}% + {never}% + {\global\gre@clivisalignment=1\relax}% + {special}% + {\global\gre@clivisalignment=2\relax}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetclivisalignment\MessageBreak Possible options are 'always', 'never', and 'special'}% + ]% +}% + +\def\clivisalignmentalways{%OBSOLETE + \gre@obsolete{\protect\clivisalignmentalways}{\protect\gresetclivisalignment{always}}% +}% + +\def\clivisalignmentnever{%OBSOLETE + \gre@obsolete{\protect\clivisalignmentnever}{\protect\gresetclivisalignment{never}}% +}% + +\def\clivisalignmentspecial{%OBSOLETE + \gre@obsolete{\protect\clivisalignmentspecial}{\protect\gresetclivisalignment{special}}% +}% + +\newif\ifgre@forceemptyfirstsyllablehyphen% +\gre@forceemptyfirstsyllablehyphentrue% +\def\gresetemptyfirstsyllablehyphen#1{% + \IfStrEqCase{#1}{% + {auto}% + {\gre@forceemptyfirstsyllablehyphenfalse}% + {force}% + {\gre@forceemptyfirstsyllablehyphentrue}% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetlyriccentering\MessageBreak Possible options are 'auto' and 'force'}% + ]% +}% + +\newif\ifgre@showhyphenafterthissyllable% +\def\GreForceHyphen{\global\gre@showhyphenafterthissyllabletrue\gre@debugmsg{hyphen}{Forcing hyphen in gabc}} +\def\GreEmptyFirstSyllableHyphen{\ifgre@forceemptyfirstsyllablehyphen\GreForceHyphen\fi}% + +% if an hyphen maybe be added by lua for this syllable. When syllable is not end of word and +% no hyphen is added by TeX. +\newif\ifgre@possibleluahyphenafterthissyllable +\gre@possibleluahyphenafterthissyllablefalse + +%% general macro : it will typeset the syllable : arguments are : +% #1 : macro setting the letters of this syllable +% #2 : reserved (unused) +% #3 : control sequence for styling the hyphen +% #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 +% #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 : macros setting next syllable letters of the next syllable +% #6 : the line:char:column for a textedit link +% #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 \greendofword or \gre@endofsyllable with #7, to reduce the space in case of a flat or natural +\def\GreSyllable#1#2#3#4#5#6#7#8#9{% + \gre@debugmsg{general}{}% + \gre@debugmsg{general}{New syllable: \expandafter\unexpanded{#1}}% + \gre@debugmsg{general}{}% + \global\gre@possibleluahyphenafterthissyllablefalse % + \gre@showhyphenafterthissyllablefalse% + \ifcase#4\ifgre@forcehyphen% + \gre@debugmsg{hyphen}{Forcing hyphen}% + \gre@showhyphenafterthissyllabletrue% + \fi\fi% + #1% + \gre@firstglyphtrue% + \gre@dimen@bolextra = 0pt\relax% + \gre@calculate@textaligncenter{\gre@firstsyllablepart}{\gre@middlesyllablepart}{0}% we first get the width between the alignment point and the end of the syllable + \gre@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 \gre@dimen@notesaligncenter - \gre@dimen@textaligncenter + \gre@dimen@begindifference=\dimexpr(\gre@dimen@notesaligncenter - \gre@dimen@textaligncenter)\relax % + % Now, let's go for something I took years to figure out: we want to align + % scores on the notes (see https://github.com/gregorio-project/gregorio/issues/221) + % but it means we have to shift lines starting by text by \gre@dimen@bolshift + % sadly, we cannot do that in TeX, we can't just say that. But, the way TeX + % handles this with usual spaces, is that it ignores all spaces at beginning + % of lines. To use this, we just \kern\gre@dimen@bolshift right, this will be + % ignored at beginning of line, then \hbox{} that will break the "ignorance" + % of spaces, then \kern\gre@dimen@bolshift left, which will not be ignored. + % So, at beginning of lines, we will have shifted left, and in middle of lines + % we will have shifted right and left, thus cancelling... Very easy trick, but + % took me years to find it! + \gre@debugmsg{bolshift}{Current glyph: \the\gre@attr@glyph@id}% + % we only want to execute these shifts if the clef is being shown + % if no clef is being shown, then there is no space under the clef for the + % lyrics to invade + \ifgre@showclef% + \ifgre@bolshiftsenabled% + \gre@calculate@bolshift{\gre@dimen@begindifference}% + % we don't want to shift right on the first syllable of the score + % because the printing of the initial clef, initial, and/or the staff lines + % will have already broken TeX's ignorance of spaces. + \ifgre@beginningofscore% + \gre@beginningofscorefalse% + \else% + % we don't want to shift right inside a discretionary + \ifnum\gre@insidediscretionary=0\relax% + \kern\gre@dimen@bolshift\relax% + \fi% + \fi% + \GreNoBreak % + \hbox to 0pt{}% + \GreNoBreak % + \kern-\gre@dimen@bolshift\relax% + \fi% + \else% + % if there is no clef, we still need to break TeX's ignorance of spaces at + % the beginning of a line so that the alterations, which would otherwise be + % ignored in positioning the syllable, don't stick out into margin + \GreNoBreak % + \hbox to 0pt{}% + \GreNoBreak % + \fi % + % by default, gre@attr@dash will be 2 + \gre@attr@dash=2\relax % + #5% + \gre@calculate@nextbegindifference{\gre@nextfirstsyllablepart}{\gre@nextmiddlesyllablepart}{\gre@nextendsyllablepart}{#7}% + \gre@unsetfixednexttextformat % + \setbox\gre@box@syllabletext=\hbox{\gre@fixedtextformat{\gre@pointandclick{\gre@firstsyllablepart\gre@middlesyllablepart\gre@endsyllablepart}{#6}}}% + \gre@calculate@enddifference{\wd\gre@box@syllablenotes}{\wd\gre@box@syllabletext}{\gre@dimen@textaligncenter}{\gre@dimen@notesaligncenter}{1}% + % gre@count@temp@one holds 0 if next is a not bar, 1 if it is + \gre@count@temp@one=0% + \ifnum#7>9\relax % + \ifnum#7<20\relax % + \gre@count@temp@one=1\relax % + \else % + \gre@count@temp@one=2\relax % + \fi % + \fi % + \gre@calculate@syllablefinalskip{#4}{\gre@count@temp@one}% + \ifcase#4 % + % we enter here if the end of word is 0, so we must determine if we need to type a dash here + \gre@skip@temp@one = \gre@skip@syllablefinalskip\relax% + \gre@debugmsg{ifdim}{ enddifference > 0pt}% + \ifdim\gre@dimen@enddifference >0pt\relax% + \advance\gre@skip@temp@one by \gre@dimen@enddifference\relax% + \fi % + \gre@debugmsg{ifdim}{ nextbegindifference > 0pt}% + \ifdim\gre@skip@nextbegindifference >0pt\relax% + \advance\gre@skip@temp@one by \gre@skip@nextbegindifference\relax% + \fi % + % + % then we compare it with \gre@space@dimen@maximumspacewithoutdash, if it is larger, we add a dash + % + \gre@debugmsg{ifdim}{ temp@skip@one > maximumspacewithoutdash}% + \ifdim\gre@skip@temp@one > \gre@space@dimen@maximumspacewithoutdash\relax% + \gre@debugmsg{hyphen}{spacing requires hyphen}% + \gre@showhyphenafterthissyllabletrue% + \fi % + \fi% ficase#4 + \ifgre@showhyphenafterthissyllable\relax% + \gre@debugmsg{hyphen}{Showing the hyphen}% + % if it's the last syllable of line, the hyphen will be \GreHyph + \ifnum\gre@lastoflinecount=1\relax % + \setbox\gre@box@syllabletext=\hbox{\gre@fixedtextformat{\gre@pointandclick{\gre@firstsyllablepart\gre@middlesyllablepart\gre@endsyllablepart#3{\GreHyph}\relax}{#6}}}% + \else % + \setbox\gre@box@syllabletext=\hbox{\gre@fixedtextformat{\gre@pointandclick{\gre@firstsyllablepart\gre@middlesyllablepart\gre@endsyllablepart#3{-}}{#6}}}% + \fi % + % recomputing end difference and final skip with the final hyphen + \gre@calculate@enddifference{\wd\gre@box@syllablenotes}{\wd\gre@box@syllabletext}{\gre@dimen@textaligncenter}{\gre@dimen@notesaligncenter}{0}% + \gre@calculate@syllablefinalskip{#4}{\gre@count@temp@one}% + \else % + \ifcase#4 % + \gre@debugmsg{hyphen}{No hyphen}% + \gre@attr@dash=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\gre@box@syllabletext=\hbox{\gre@fixedtextformat{\gre@pointandclick{\gre@firstsyllablepart\gre@middlesyllablepart\gre@endsyllablepart}{#6}}}% + \global\gre@possibleluahyphenafterthissyllabletrue % + \fi % + \fi% + % then we reuse temp, we assign to it the \gre@dimen@begindifference, but only if it is positive, else it is 0 + \gre@debugmsg{ifdim}{ begindifference > 0pt}% + \ifdim\gre@dimen@begindifference > 0 pt\relax% + \gre@skip@temp@one = \gre@dimen@begindifference\relax% + \kern\gre@skip@temp@one % + \fi% + #8\relax % + \raise\gre@dimen@textlower\relax% + \copy\gre@box@syllabletext % + \ifgre@mustdotranslationcenterend% + % case of end of translation centering, we do it after the typesetting of the text + \gre@dotranslationcenterend % + \gre@mustdotranslationcenterendfalse% + \fi % + \gre@skip@temp@one = -\wd\gre@box@syllabletext % + \kern\gre@skip@temp@one% + \gre@skip@temp@one = -\gre@dimen@begindifference\relax% + \kern\gre@skip@temp@one % + % here we need to unset \gre@attr@dash for the typesetting of notes + \gre@attr@dash=0\relax % + \GreNoBreak % no line breaks between text and notes + #9% we do that instead of \unhbox\Syllablnotes, because it would not set the \localrightbox + \GreNoBreak % no line breaks between notes and end of syllable skips + \gre@debugmsg{ifdim}{ enddifference < 0pt}% + \ifdim\gre@dimen@enddifference <0pt\relax% + %% important, else we are not really at the end of the syllable + \kern -\gre@dimen@enddifference\relax% + \GreNoBreak % + \fi% + % we call end of syllable + \gre@syllable@end{#7}{\gre@nextfirstsyllablepart\gre@nextmiddlesyllablepart\gre@nextendsyllablepart}{#4}% + \global\gre@dimen@notesaligncenter=0pt\relax% very important, see flat and natural + \gre@unsetfixedtextformat % + \ifgre@blockeolcustos\ifnum\gre@insidediscretionary=0\relax % + \gre@localrightbox{}% + \fi\fi % + \relax % +}% + +% #1 is the id of the euouae block (assigned by the C code) +% #2 is whether there is a line break between here and the actuall beginning of +% the euouae block. 1 if there is a linebreak, 0 in the general case. +\def\GreNextSyllableBeginsEUOUAE#1#2{% + \GreNoBreak % + \ifgre@blockeolcustosbeforeeuouae % + \gre@usemanualeolcustos % + \fi % + \ifgre@raggedbreakbeforeeuouae % + \directlua{gregoriotex.save_pos(#1,1)}% + \ifcase#2\ifcase\directlua{gregoriotex.is_ypos_different(#1)}\relax% + \gre@newlinecommon{1}{1}% + \fi\fi % + \fi % + \relax % +}% + +% #1 is the id of the euouae block (assigned by the C code) +% #2 is whether there is a line break between here and the actuall beginning of +% the euouae block. 1 if there is a linebreak, 0 in the general case. +\def\GreLastSyllableBeforeEUOUAE#1#2{% + \ifcase#2\ifcase\directlua{gregoriotex.is_ypos_different(#1)}\relax% + \GreLastOfLine% + \fi\fi % +}% + +%% @desc Macro to make a few checks and call the right macros between +%% \endbeforebar, \endofword, \endofsyllable +%% @arg#1 next syllable type (#7 of \GreSyllable) +%% @arg#2 next syllable text +%% @arg#3 end of word or not (#4 of \GreSyllable) +\def\gre@syllable@end#1#2#3{% + \gre@debugmsg{syllablespacing}{ syllable@end with #1}% + % gre@count@temp@one holds 0 if next is a not bar, 1 if it is + \gre@count@temp@one=0% + \ifnum#1>9\relax % + \ifnum#1<20\relax % + \gre@count@temp@one=1% + \fi % + \fi % + \gre@debugmsg{syllablespacing}{ gre@count@temp@one = \the\gre@count@temp@one}% + \ifnum\gre@count@temp@one=1\relax % + \ifnum\gre@lastoflinecount=1\relax % + \gre@endofsyllable{0}{1}{1}% + \else % + % otherwise we call it with 1 only if there is no letters after (we can see it with nextbegindifference) + \setbox\gre@box@temp@width=\hbox{#2}% + \ifdim\wd\gre@box@temp@width=0pt\relax% + \gre@endofsyllable{0}{1}{1}% + \else % + \gre@endofsyllable{1}{1}{1}% + \fi % + \fi % + \else % + \ifnum\gre@lastoflinecount=1\relax % + \global\gre@lastoflinecount=2\relax % + \fi % + \gre@debugmsg{syllablespacing}{ calling endofsyllable with #3}% + \gre@endofsyllable{1}{#3}{0}% + \fi % +} + +%% @desc Macro called at end of a syllable, adds a penalty and a space +%% @arg#1 0 to only add the penalty, 1 otherwise +%% @arg#2 0 if end of syllable, 1 if end of word +%% @arg#3 1 if next syllable is a bar, 0 otherwise +%% +\def\gre@endofsyllable#1#2#3{% + \gre@debugmsg{syllablespacing}{ endofsyllable with #2}% + \ifgre@eolshiftsenabled% + %this shift will shorten the line somewhat to allow the lyrics to extend under the custos should TeX decide to insert a line break after the syllable being ended + \GreNoBreak% + \gre@calculate@eolshift{\gre@dimen@enddifference}% + \gre@debugmsg{eolshift}{End of line shift: \the\gre@dimen@eolshift}% + \kern -\gre@dimen@eolshift\relax% + \fi% + \ifnum#3=1\relax % + \GreNoBreak % + \gre@debugmsg{syllablespacing}{ set penalty \grenobreakpenalty}% + \else % + \ifnum#2=1\relax % + \gre@penalty{\greendofwordpenalty}% + \gre@debugmsg{syllablespacing}{ set penalty \greendofwordpenalty}% + \else % + \gre@penalty{\greendofsyllablepenalty}% + \gre@debugmsg{syllablespacing}{ set penalty \greendofsyllablepenalty}% + \fi % + \fi % + \ifgre@eolshiftsenabled% + %If the above penalties don't result in a line break, then we need to undo the eolshift to prevent the next syllable from overlapping with this one. If the line break did occur, then this shift will occur at the beginning of a line and thus will be ignored automatically by TeX. + \kern \gre@dimen@eolshift\relax% + \GreNoBreak% + \fi% + \ifnum#1=1\relax % + \ifgre@newbarspacing% + %the new bar spacing algorithms take care of this for us when the next syllable is a bar + \relax% + \else% + \gre@hskip\gre@skip@syllablefinalskip\relax% + \fi% + \ifnum#3=1\relax % + \GreNoBreak % + \else% + \ifgre@newbarspacing% + %the new bar spacing algorithm still needs the syllablefinalskip when the next syllable is not a bar + \gre@hskip\gre@skip@syllablefinalskip\relax% + \fi% + \fi % + \fi % + \relax% +}% + +\def\gresetbarspacing#1{% + \IfStrEqCase{#1}{% + {new}% + {% + \gre@newbarspacingtrue% + \let\GreNoNoteSyllable\GreBarSyllable% + }% + {old}% + {% + \gre@newbarspacingfalse% + \let\GreNoNoteSyllable\GreSyllable% + }% + }[% all other cases + \gre@error{Unrecognized option "#1" for \protect\gresetbarspacing\MessageBreak Possible options are: 'new' and 'old'}% + ]% +}% + +% macro to save new lines in bar syllables. With the new bar spacing algorithm, we +% cannot allow (::z) to end the line right after the bar, so we just save the +% end of line for later. +\xdef\gre@newlinearg{-1} +\gdef\gre@newlinecommondelayed#1#2{% + \xdef\gre@newlinearg{#1}% +} + +%a macro to typeset a syllable with only a bar inside +\def\GreBarSyllable#1#2#3#4#5#6#7#8#9{% + \gre@debugmsg{general}{New bar syllable}% + \gre@possibleluahyphenafterthissyllablefalse % + \gre@showhyphenafterthissyllablefalse % + % 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 previous syllable and the first note of the next syllable. But there are limits : a bar can't 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. + #1% + \gre@calculate@textaligncenter{\gre@firstsyllablepart}{\gre@middlesyllablepart}{0}% + \setbox\gre@box@syllabletext=\hbox{\gre@fixedtextformat{\gre@pointandclick{\gre@firstsyllablepart\gre@middlesyllablepart\gre@endsyllablepart}{#6}}}% + \gre@debugmsg{barspacing}{Width of bar text: \the\wd\gre@box@syllabletext}% + \global\let\gre@newlinecommonsaved\gre@newlinecommon % + \global\let\gre@newlinecommon\gre@newlinecommondelayed % + \xdef\gre@newlinearg{-1}% + \gre@syllablenotes{#9}% + \gre@debugmsg{barspacing}{Width of bar line: \the\wd\gre@box@syllablenotes}% + \gre@dimen@notesaligncenter=\dimexpr(\wd\gre@box@syllablenotes / 2)\relax % + \gre@dimen@begindifference=\dimexpr(\gre@dimen@notesaligncenter - \gre@dimen@textaligncenter)\relax% + \gre@calculate@enddifference{\wd\gre@box@syllablenotes}{\wd\gre@box@syllabletext}{\gre@dimen@textaligncenter}{\gre@dimen@notesaligncenter}{1}% + #5% + \gre@calculate@nextbegindifference{\gre@nextfirstsyllablepart}{\gre@nextmiddlesyllablepart}{\gre@nextendsyllablepart}{#7}% + \gre@unsetfixednexttextformat % + \gre@debugmsg{barspacing}{previousenddifference: \the\gre@dimen@previousenddifference}% + \gre@debugmsg{barspacing}{begindifference: \the\gre@dimen@begindifference}% + \gre@debugmsg{barspacing}{enddifference: \the\gre@dimen@enddifference}% + \gre@debugmsg{barspacing}{nextbegindifference: \the\gre@skip@nextbegindifference}% + \ifgre@newbarspacing% + % + % New bar spacing algorithm + % + \gre@calculate@barposition{#4}{#7}% + %now we can place the text and bar + %we're going to use the bar line to control positioning, so we need to start by getting to the end of the notes of the previous syllable + \ifdim\gre@dimen@adjustedpreviousenddifference < 0pt\relax% + %we need to move back to where the previous notes ended + \kern\gre@dimen@adjustedpreviousenddifference\relax% + \GreNoBreak % + \fi% + %move to the beginning of the text + \gre@hskip\glueexpr(\gre@skip@bar@allocation/2% right from end of previous notes to nominal middle of bar line + +\gre@dimen@bar@shift% from nominal middle of bar line to actual middle + -\wd\gre@box@syllablenotes/2% back up to beginning of bar line + +\gre@dimen@begindifference% from beginning of bar line to beginning of text + +\gre@space@skip@bar@rubber)\relax % the rubber component + \GreNoBreak % + % all that extra stuff (translations and the like) + #8% + \GreNoBreak % + %print the text, the raise is in case of a translation + \raise\gre@dimen@textlower \copy\gre@box@syllabletext% + %and the code which handles translation centering + \ifgre@mustdotranslationcenterend% + % case of end of translation centering, we do it after the typesetting of the text + \gre@dotranslationcenterend % + \gre@mustdotranslationcenterendfalse% + \fi % + %move back to the beginning of the bar line + \kern\dimexpr(\gre@dimen@enddifference% move from end of text to end of bar line + -\wd\gre@box@syllablenotes)\relax % back up from end of bar line to beginning + \GreNoBreak% + #9% + \global\let\gre@newlinecommon\gre@newlinecommonsaved % + \GreNoBreak% + % get into position to place the penalty + \ifdim\gre@dimen@enddifference < 0pt\relax% + % the text extends past the notes, so we need to get to the end of the text + \kern-\gre@dimen@enddifference% + \GreNoBreak% + \fi% + \ifgre@eolshiftsenabled% + %this shift will shorten the line somewhat to allow the lyrics to extend under the custos should TeX decide to insert a line break after the syllable being ended + \gre@calculate@eolshift{\dimexpr(\gre@dimen@enddifference-\gre@skip@bar@lastskip)\relax }% + \gre@debugmsg{barspacing}{End of line shift: \the\gre@dimen@eolshift}% + \ifdim\gre@dimen@eolshift<\gre@skip@bar@lastskip % + \gre@dimen@eolshift=\gre@skip@bar@lastskip\relax % + \fi % + \kern\glueexpr(-\gre@dimen@eolshift)\relax% + \fi% + % gre@count@temp@one is "forced end of line or last of score" + \gre@count@temp@one=0\relax % + \ifnum\gre@newlinearg=-1\else % + \gre@count@temp@one=1\relax % + \fi % + \ifgre@endofscore % + \gre@count@temp@one=1\relax % + \fi % + % if no end of line or end of score + \ifnum\gre@count@temp@one=0\relax % + % add the penalty + \gre@debugmsg{barspacing}{after bar penalty: \greendafterbarpenalty}% + \gre@penalty{\greendafterbarpenalty}% + \ifgre@eolshiftsenabled% + %If the above penalties don't result in a line break, then we need to undo the eolshift to prevent the next syllable from overlapping with this one. If the line break did occur, then this shift will occur at the beginning of a line and thus will be ignored automatically by TeX. + \kern \dimexpr(\gre@dimen@eolshift)\relax% + \GreNoBreak% + \fi% + \ifdim\gre@dimen@enddifference < 0pt\relax% + %undo the earlier shift + \kern\gre@dimen@enddifference% + \GreNoBreak% + \fi% + %move to the beginning of the notes of the next syllable + \gre@hskip\glueexpr(-\wd\gre@box@syllablenotes/2% back up to middle of notes + -\gre@dimen@bar@shift% go back from actual middle to nominal middle of bar line + +\gre@skip@bar@allocation/2% go from nominal middle to the start of the next notes + +\gre@space@skip@bar@rubber)\relax % the rubber component + \ifdim\gre@skip@nextbegindifference < 0pt\relax% + %we need to move back to where the text for the next syllable should start + \GreNoBreak % + \kern\gre@skip@nextbegindifference\relax% + \fi% + \else % + \ifgre@endofscore % + \gre@localleftbox{}% + \gre@debugmsg{barspacing}{after bar penalty: \greendafterbarpenalty}% + \gre@penalty{\grefinalpenalty}% + \else % + \gre@debugmsg{barspacing}{calling new line with argument: \gre@newlinearg}% + \gre@newlinecommon{\gre@newlinearg}{1}% + \fi % + \fi% + \else% + % + % Old spacing algorithm + % + %This is the old algorithm. I've kept it in case people still want to use it. + % then we check if there is something to write + \global\let\gre@newlinecommon\gre@newlinecommonsaved % + \gre@debugmsg{ifdim}{ wd(gre@box@syllabletext) = 0pt}% + \ifdim\wd\gre@box@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 skip@temp@three to it + %% 2/ enddifference + begindifference + space between notes and word : we assign skip@temp@two to it + \gre@skip@temp@three=\glueexpr(\gre@space@skip@notebarspace % + + \gre@space@skip@notebarspace % + + \wd\gre@box@syllablenotes)\relax % + % now let's get skip@temp@two + \gre@debugmsg{ifdim}{ nextbegindifference < 0pt}% + \ifdim\gre@skip@nextbegindifference < 0 pt\relax% + \gre@skip@temp@two=-\gre@skip@nextbegindifference\relax% + \else % + \gre@skip@temp@two=0 pt\relax% + \fi % + \gre@debugmsg{ifdim}{ previousenddifference < 0pt}% + \ifdim\gre@dimen@previousenddifference < 0 pt\relax% + \advance\gre@skip@temp@two by % + \glueexpr(-\gre@dimen@previousenddifference % + + \gre@space@skip@interwordspacetext)\relax% + \else % + \advance\gre@skip@temp@two by \gre@space@skip@interwordspacenotes\relax% + \fi% + % we take the max of it, then we divide it by two and we substract half of the width of the bar + \gre@debugmsg{ifdim}{ temp@skip@three < temp@skip@two}% + \ifdim\gre@skip@temp@three <\gre@skip@temp@two % + \gre@skip@temp@three=\gre@skip@temp@two % + \fi % + \divide\gre@skip@temp@three by 2\relax % + \advance\gre@skip@temp@three by \dimexpr(\wd\gre@box@syllablenotes / -2)\relax % + % now we have our skipone + \gre@skip@temp@two=\gre@skip@temp@three % + \gre@debugmsg{ifdim}{ previousenddifference < 0pt}% + \ifdim\gre@dimen@previousenddifference < 0 pt\relax% + \advance\gre@skip@temp@two by \gre@dimen@previousenddifference\relax% + \fi % + \GreNoBreak % + \gre@debugmsg{ifdim}{ temp@skip@two > -wd(gre@box@syllablenotes)}% + \ifdim\gre@skip@temp@two > -\wd\gre@box@syllablenotes % + \kern\gre@skip@temp@two % + \else % + \gre@skip@temp@one = -\wd\gre@box@syllablenotes % + \kern\gre@skip@temp@one% + \fi % + \GreNoBreak % + #8\relax % + \ifgre@mustdotranslationcenterend% + % case of end of translation centering, we do it after the typesetting of the text + \gre@dotranslationcenterend % + \gre@mustdotranslationcenterendfalse% + \fi % + #9\relax % + \gre@penalty{\greendafterbaraltpenalty }% TODO: isn't it a bit buggy? + % end of same code as syllable + \ifnum\gre@lastoflinecount=1\relax % + \global\gre@lastoflinecount=2\relax % + \else % + \gre@debugmsg{ifdim}{ temp@skip@two < -wd(gre@box@syllablenotes)}% + \ifdim\gre@skip@temp@two < -\wd\gre@box@syllablenotes % + \gre@debugmsg{ifdim}{ nextbegindifference > 0pt}% + \ifdim\gre@skip@nextbegindifference > 0 pt\relax% + \gre@skip@temp@one = \gre@space@skip@interwordspacetext\relax% + \gre@hskip\gre@skip@temp@one % + \else % \ifdim\gre@skip@nextbegindifference > 0 pt + \gre@skip@temp@one = \gre@space@skip@interwordspacetext\relax% + \gre@hskip\gre@skip@temp@one % + \fi % + \else % + \gre@skip@temp@two=\gre@skip@temp@three % + \gre@debugmsg{ifdim}{ nextbegindifference < 0pt}% + \ifdim\gre@skip@nextbegindifference < 0 pt\relax% + \advance\gre@skip@temp@two by \gre@skip@nextbegindifference\relax% + \fi % + \gre@debugmsg{ifdim}{ temp@skip@two > -wd(gre@box@syllablenotes)}% + \ifdim\gre@skip@temp@two > -\wd\gre@box@syllablenotes % + \kern\gre@skip@temp@two % + \else % \ifdim\gre@dimen@temp@five > -\wd\gre@box@syllablenotes + \gre@skip@temp@one = -\wd\gre@box@syllablenotes % + \gre@hskip\gre@skip@temp@one % + \fi % + \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\gre@box@syllabletext = 0 pt + #8\relax % + \raise\gre@dimen@textlower \copy\gre@box@syllabletext % + \ifgre@mustdotranslationcenterend% + % case of end of translation centering, we do it after the typesetting of the text + \gre@dotranslationcenterend % + \gre@mustdotranslationcenterendfalse% + \fi % + \gre@skip@temp@one = -\wd\gre@box@syllabletext % + \kern\gre@skip@temp@one % + \gre@skip@temp@one = -\gre@dimen@begindifference\relax% + \kern\gre@skip@temp@one % + #9% + \gre@debugmsg{ifdim}{ enddifference < 0pt}% + \ifdim\gre@dimen@enddifference <0pt\relax% + %% important, else we are not really at the end of the syllable + \gre@skip@temp@one = -\gre@dimen@enddifference\relax% + \kern\gre@skip@temp@one % + \fi% + % end of same code as syllable + \ifnum\gre@lastoflinecount=1\relax % + \global\gre@lastoflinecount=2\relax % + \gre@endafterbar{0}% + \else % + \global\gre@lastoflinecount=0\relax % + \gre@endafterbar{1}% + \fi % + %and that's it !! + \fi % + \fi% + \global\gre@dimen@notesaligncenter= 0 pt\relax % very important, see flat and natural + \gre@unsetfixedtextformat % + \ifgre@blockeolcustos\ifnum\gre@insidediscretionary=0\relax % + \gre@localrightbox{}% + \fi\fi % + \relax% +} + +\newif\ifgre@newbarspacing% +\gre@newbarspacingtrue% +% the new bar spacing algorithm treats no note syllables as BarSyllables, while the old algorithm treated them as regular syllables. In order to allow for this variant, we define NoNoteSyllable which aliases to the appropriate function +\let\GreNoNoteSyllable\GreBarSyllable% + +%% internal macro to set the first syllable text after all parts are known +%% #1 - First part of the syllable (before the vowel) +%% #2 - Middle part of the syllable (the vowel) +%% #3 - Last part of the syllable (after the vowel) +%% #4 - First letter of the syllable +%% #5 - Everything after the first letter of the syllable +%% #6 - Macros to run after the text is emitted +\def\gre@setfirstsyllabletext#1#2#3#4#5#6{% + \def\gre@opening@syllabletext{% + \GreSetThisSyllable{#1}{#2}{#3}% + {\GreFirstWord{\GreFirstSyllable{\GreFirstSyllableInitial{#4}}}}% + {\GreFirstWord{\GreFirstSyllable{#5}}}% + #6\relax % + }% +}% + +\def\gresetinitiallines#1{% + \IfInteger{#1}% + {% + \ifnum#1>-1\relax% + \ifnum#1<3\relax% + \def\gre@initiallines{#1}% + \else% + \gre@error{The argument for \protect\gresetinitiallines\space must be 0, 1, or 2}% + \fi% + \else% + \gre@error{The argument for \protect\gresetinitiallines\space must be positive}% + \fi% + }% + {\gre@error{\protect\gresetinitiallines\space takes a positive integer argument}}% +}% +\gresetinitiallines{1}% default to one-line initials + +\def\GreSetInitialStyle#1{%%% DEPRECATED by 4.1 + \gre@deprecated{initial-style gabc header}{\protect\gresetinitiallines}%%% DEPRECATED by 4.1 + \def\gre@opening@initialstyle{#1}%%% DEPRECATED by 4.1 +}%%% DEPRECATED by 4.1 + +%% sets the first syllable text +%% #1 - Initial +%% #2 - First letter after the initial +%% #3 - everything else in the syllable +%% #4 - Three syllable parts when there is a separated initial +%% #5 - Three syllable parts where there is no separated initial +%% #6 - Extra macros to run if there is an initial +\def\GreSetFirstSyllableText#1#2#3#4#5#6{% + %%% DEPRECATED by 4.1: When \gre@opening@initialstyle is removed, use \gre@initiallines directly in the following line + \ifcase\gre@opening@initialstyle\relax % no initial + \gre@noinitial % + \gre@setfirstsyllabletext#5{#1}{#2#3}{}% + \or % regular intiial + \gre@setinitial{#1}% + \gre@setfirstsyllabletext#4{#2}{#3}{#6}% + \or % big initial + \gre@setbiginitial\gre@setinitial{#1}% + \gre@setfirstsyllabletext#4{#2}{#3}{#6}% + \fi % +}% + +\def\GreSetNoFirstSyllableText{% + \gre@noinitial % + \gre@setfirstsyllabletext{}{}{}{}{}{}% +}% + +\def\GreUpcomingNewLineForcesCustos#1{% + \ifcase#1\relax % 0 - forced off + \gre@usemanualeolcustos % + \or % 1 - forced on + \gre@useautoeolcustos % + \GreNextCustos{\gre@nextcustos}% + \fi % +}% + +%% opens a score +%% #1 - macros rendering the things after the initial but before the notes +%% #2 - macros rendering the things after starting notes but before the syllable +%% #3 - macros rendering the things before the initial +%% #4 - control sequence for the syllable +%% #5 - macros rendering the first syllable; should emit the initial and +%% populate \gre@opening@syllabletext (even if that should be empty) +\def\GreScoreOpening#1#2#3#4#5{% + #3\relax % fixed styles, etc. + #5\relax % should emit the initial + \ifnum\gre@biginitial=1\relax % + \gre@debugmsg{general}{making adjustment NECESSARY}% + \gre@thirdlineadjustmentnecessarytrue % + \else % + \gre@debugmsg{general}{making adjustment unnecessary}% + \gre@thirdlineadjustmentnecessaryfalse % + \fi % + #1\relax % score reference, voice info, etc. + \gre@beginnotes\relax % + #2\relax % initial clef, etc. + #4{\gre@opening@syllabletext}% +}% diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-symbols.lua b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-symbols.lua new file mode 100644 index 00000000000..bf8bbe404a8 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-symbols.lua @@ -0,0 +1,61 @@ +--GregorioTeX Symbols Lua support file. +-- +--Copyright (C) 2016 The Gregorio Project (see CONTRIBUTORS.md) +-- +--This file is part of Gregorio. +-- +--Gregorio 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. +-- +--Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +-- this file contains lua functions to support signs used by GregorioTeX. + +-- GREGORIO_VERSION 4.1.1 + +local err = gregoriotex.module.err +local warn = gregoriotex.module.warn +local info = gregoriotex.module.info +local log = gregoriotex.module.log + +local catcode_at_letter = luatexbase.catcodetables['gre@atletter'] +local number_to_letter = gregoriotex.number_to_letter +local special_characters = {} +local next_special = 0 + +function gregoriotex.define_special_character(sequence) + local substitution = special_characters[sequence] + if substitution == nil then + substitution = string.gsub(tostring(next_special), '[0-9]', number_to_letter) + special_characters[sequence] = substitution + next_special = next_special + 1 + end + tex.print(catcode_at_letter, + string.format([[\gdef\gre@special@%s]], substitution)) +end + +function gregoriotex.undefine_special_character(sequence) + local substitution = special_characters[sequence] + if substitution ~= nil then + special_characters[sequence] = nil + tex.print(catcode_at_letter, + string.format([[\let\gre@special@%s\undefined\relax ]], substitution)) + end +end + +function gregoriotex.special_character(sequence) + local substitution = special_characters[sequence] + if substitution ~= nil then + tex.print(catcode_at_letter, string.format([[\gre@special@%s\relax ]], substitution)) + else + tex.print(sequence) + end +end diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-symbols.tex b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-symbols.tex new file mode 100644 index 00000000000..79edaf7ad73 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex-symbols.tex @@ -0,0 +1,237 @@ +%GregorioTeX file. +% +% Copyright (C) 2007-2015 The Gregorio Project (see CONTRIBUTORS.md) +% +% This file is part of Gregorio. +% +% Gregorio 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. +% +% Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +% this file contains definitions of the symbols + +\ifcsname gregoriotex@symbols@loaded\endcsname\endinput\fi% +\def\gregoriotex@symbols@loaded{}% + +\gre@debugmsg{general}{Loading gregoriotex-symbols.tex}% +\gre@declarefileversion{gregoriotex-symbols.tex}{4.1.1}% GREGORIO_VERSION + +\RequireLuaModule{gregoriotex}% + +\def\gre@symbolfontsize{\f@size}% + +% Defines a symbol which automatically scales with \f@size +% #1 = control sequence name +% #2 = font name +% #3 = glyph name or code point +\def\gredefsymbol#1#2#3{% + \directlua{gregoriotex.init_variant_font([[#2]],false)}% + \directlua{gregoriotex.def_symbol([[#1]],[[#2]],[[#3]],false)}% +}% + +% Defines a symbol which takes a point size as argument +% #1 = control sequence name +% #2 = font name +% #3 = glyph name or code point +\def\gredefsizedsymbol#1#2#3{% + \directlua{gregoriotex.init_variant_font([[#2]],false)}% + \directlua{gregoriotex.def_symbol([[#1]],[[#2]],[[#3]],true)}% +}% + +%%%%%%%%%%%%% +%% symbols %% +%%%%%%%%%%%%% + +\gredefsizedsymbol{greABar}{greextra}{ABar} +\gredefsizedsymbol{greRBar}{greextra}{RBar} +\gredefsizedsymbol{greVBar}{greextra}{VBar} +\gredefsizedsymbol{greABarSlant}{greextra}{ABarSlant} +\gredefsizedsymbol{greRBarSlant}{greextra}{RBarSlant} +\gredefsizedsymbol{greVBarSlant}{greextra}{VBarSlant} +\gredefsizedsymbol{greABarSC}{greextra}{ABarSC} +\gredefsizedsymbol{greRBarSC}{greextra}{RBarSC} +\gredefsizedsymbol{greVBarSC}{greextra}{VBarSC} +\gredefsizedsymbol{greABarSmall}{greextra}{ABarSmall} +\gredefsizedsymbol{greRBarSmall}{greextra}{RBarSmall} +\gredefsizedsymbol{greVBarSmall}{greextra}{VBarSmall} +\gredefsizedsymbol{greABarSmallSlant}{greextra}{ABarSmallSlant} +\gredefsizedsymbol{greRBarSmallSlant}{greextra}{RBarSmallSlant} +\gredefsizedsymbol{greVBarSmallSlant}{greextra}{VBarSmallSlant} +\gredefsizedsymbol{greABarSmallSC}{greextra}{ABarSmallSC} +\gredefsizedsymbol{greRBarSmallSC}{greextra}{RBarSmallSC} +\gredefsizedsymbol{greVBarSmallSC}{greextra}{VBarSmallSC} +\gredefsizedsymbol{greABarCaption}{greextra}{ABarCaption} +\gredefsizedsymbol{greRBarCaption}{greextra}{RBarCaption} +\gredefsizedsymbol{greVBarCaption}{greextra}{VBarCaption} +\gredefsizedsymbol{greABarCaptionSlant}{greextra}{ABarCaptionSlant} +\gredefsizedsymbol{greRBarCaptionSlant}{greextra}{RBarCaptionSlant} +\gredefsizedsymbol{greVBarCaptionSlant}{greextra}{VBarCaptionSlant} +\gredefsizedsymbol{greABarCaptionSC}{greextra}{ABarCaptionSC} +\gredefsizedsymbol{greRBarCaptionSC}{greextra}{RBarCaptionSC} +\gredefsizedsymbol{greVBarCaptionSC}{greextra}{VBarCaptionSC} +\gredefsizedsymbol{greABarAlt}{greextra}{RBar.alt} +\gredefsizedsymbol{greRBarAlt}{greextra}{RBar.alt} +\gredefsizedsymbol{greVBarAlt}{greextra}{VBar.alt} + +\def\grebarredsymbol#1#2#3#4#5{% + \leavevmode\hbox to 0pt{}\kern #4\lower#5% + \hbox{\csname #2\endcsname{#3}}\kern -#4\relax #1% +}% + +%% Intermediate version or barred glyph definition +%% #1: the csname you want to define +%% #2: the letter you'll typeset (you can use bold, italic, etc.) +%% #3: the symbol corresponding to the glyph in greextra. Must be defined with \gredefsizedsymbol +%% #4: the size of greextra +%% #5: the kern of the bar from the beggining of the glyph +%% #6: greextra glyph lowering +\def\gredefbarredsymbol#1#2#3#4#5#6{% + \expandafter\gdef\csname #1\endcsname {% + \grebarredsymbol{#2}{#3}{#4}{#5}{#6}% + }% +}% + +%% Most simple version or barred glyph definition +%% #1: A, R or V +%% #2: the negative kern +\def\gresimpledefbarredsymbol#1#2{% + \gredefbarredsymbol{#1bar}{#1}{gre#1Bar}{\f@size}{#2}{0pt}% +}% + +% defining \ABar, \VBar and \RBar for libertine font, define yours for your font +\gresimpledefbarredsymbol{A}{.30em}% +\gresimpledefbarredsymbol{R}{.35em}% +\gresimpledefbarredsymbol{V}{.10em}% + +\gre@iflatex{% + \def\gre@latex@barredsymbol#1#2#3#4{% + \IfStrEq{\f@series/\f@shape}{#1}{\grebarredsymbol{#2}{#3}{\f@size}{#4}{0pt}}% + }% + + %% define a barred symbol that handles italic, slanted, and small cap shapes + %% simply (LaTeX-only) + %% Most simple version or barred glyph definition + %% #1: A, R or V + %% #2: the negative kern for upright shape + %% #3: idem, for italic/slanted shape + %% #4: idem, for bold shape + %% #5: idem, for bold and italic/slanted shape + \def\grelatexsimpledefbarredsymbol#1#2#3#4#5{% + \expandafter\gdef\csname #1bar\endcsname {% + \gre@latex@barredsymbol{m/n}{#1}{gre#1Bar}{#2}{% + \gre@latex@barredsymbol{m/it}{#1}{gre#1BarSlant}{#3}{% + \gre@latex@barredsymbol{m/sl}{#1}{gre#1BarSlant}{#3}{% + \gre@latex@barredsymbol{bx/n}{#1}{gre#1Bar}{#4}{% + \gre@latex@barredsymbol{bx/it}{#1}{gre#1BarSlant}{#5}{% + \gre@latex@barredsymbol{bx/sl}{#1}{gre#1BarSlant}{#5}{% + \gre@latex@barredsymbol{b/n}{#1}{gre#1Bar}{#4}{% + \gre@latex@barredsymbol{b/it}{#1}{gre#1BarSlant}{#5}{% + \gre@latex@barredsymbol{b/sl}{#1}{gre#1BarSlant}{#5}{% + }% + }% + }% + }% + }% + }% + }% + }% + }% + }% + }% + + \grelatexsimpledefbarredsymbol{A}{.30em}{.35em}{.30em}{.33em}% + \grelatexsimpledefbarredsymbol{R}{.35em}{.38em}{.45em}{.48em}% + \grelatexsimpledefbarredsymbol{V}{.10em}{.12em}{.14em}{.18em}% +}% + +% the gothic R and V +\gredefsymbol{gothRbar}{greextra}{RWithBarGoth}% +\gredefsymbol{gothVbar}{greextra}{VWithBarGoth}% + +% the macro to typeset a dagger +\gredefsymbol{GreDagger}{greextra}{Dagger}% + +% macro to typeset a (malt) cross +\gredefsymbol{grecross}{greextra}{Cross}% +\gredefsymbol{grealtcross}{greextra}{Cross.alt}% + +%stars +\gredefsymbol{greheightstar}{greextra}{StarHeight}% +\gredefsymbol{gresixstar}{greextra}{StarSix}% +\let\GreStar\gresixstar% + +%%%%%%%%%%%% +%% Lines %% +%%%%%%%%%%%% +%Unlike the character symbols above, we require that the font size be specified when using the lines. + +\gredefsizedsymbol{greLineOne}{greextra}{Line1}% +\gredefsizedsymbol{greLineTwo}{greextra}{Line2}% +\gredefsizedsymbol{greLineThree}{greextra}{Line3}% +\gredefsizedsymbol{greLineFour}{greextra}{Line4}% +\gredefsizedsymbol{greLineFive}{greextra}{Line5}% + +%lines +%#1 is the type of line (1-5) +%#2 is the number of pt of the font it will use +\def\greseparator#1#2{% + \ifcase#1\relax % + \or\greLineOne{#2}% + \or\greLineTwo{#2}% + \or\greLineThree{#2}% + \or\greLineFour{#2}% + \or\greLineFive{#2}% + \fi% +}% + +\def\gresep#1#2{%OBSOLETE + \gre@obsolete{\protect\gresep}{\protect\greseparator}% +} + +%%%%%%%%%%% +%% Ornamentation +%%%%%%%%%%% + +\gredefsizedsymbol{greOrnamentOne}{greextra}{Drawing1}% +\gredefsizedsymbol{greOrnamentTwo}{greextra}{Drawing2}% + +\def\greornamentation#1#2{% + \ifcase#1\relax% + \or\greOrnamentOne{#2}% + \or\greOrnamentTwo{#2}% + \fi% +}% + +%% Specials + +\def\gresetspecial#1{\directlua{gregoriotex.define_special_character("#1")}}% +\def\greunsetspecial#1{\directlua{gregoriotex.undefine_special_character("#1")}}% +\def\GreSpecial#1{\directlua{gregoriotex.special_character("#1")}}% + +\gresetspecial{A/}{\Abar{}}% +\gresetspecial{\string\037}{\%{}}% +\gresetspecial{R/}{\Rbar{}}% +\gresetspecial{V/}{\Vbar{}}% +\gresetspecial{'æ}{\'\ae{}}% +\gresetspecial{'ae}{\'\ae{}}% +\gresetspecial{'œ}{\'\oe{}}% +\gresetspecial{'oe}{\'\oe{}}% +\gresetspecial{ae}{\ae{}}% +\gresetspecial{oe}{\oe{}}% +\gresetspecial{*}{\GreStar{}}% +\gresetspecial{+}{\GreDagger{}}% +\gresetspecial{-}{\gre@char@zerohyph{}}% +\gresetspecial{\string\092}{\textbackslash{}}% +\gresetspecial{\string\038}{\&{}}% +\gresetspecial{\string\035}{\#{}}% +\gresetspecial{\string\095}{\_{}}% +\gresetspecial{\string\126}{\gretilde{}}% diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex.lua b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex.lua new file mode 100644 index 00000000000..4f94d1a1f9b --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex.lua @@ -0,0 +1,1052 @@ +--GregorioTeX Lua file. +-- +--Copyright (C) 2008-2015 The Gregorio Project (see CONTRIBUTORS.md) +-- +--This file is part of Gregorio. +-- +--Gregorio 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. +-- +--Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +-- this file contains lua functions used by GregorioTeX when called with LuaTeX. + +local hpack, traverse, traverse_id, has_attribute, count, remove, insert_after, copy = node.hpack, node.traverse, node.traverse_id, node.has_attribute, node.count, node.remove, node.insert_after, node.copy + +gregoriotex = gregoriotex or {} +local gregoriotex = gregoriotex + +local internalversion = '4.1.1' -- GREGORIO_VERSION (comment used by VersionManager.py) + +local err, warn, info, log = luatexbase.provides_module({ + name = "gregoriotex", + version = '4.1.1', -- GREGORIO_VERSION + greinternalversion = internalversion, + date = "2016/03/10", -- GREGORIO_DATE_LTX + description = "GregorioTeX module.", + author = "The Gregorio Project (see CONTRIBUTORS.md)", + copyright = "2008-2015 - The Gregorio Project", + license = "GPLv3+", +}) + +gregoriotex.module = { err = err, warn = warn, info = info, log = log } + +local format = string.format + +local hlist = node.id('hlist') +local vlist = node.id('vlist') +local glyph = node.id('glyph') +local glue = node.id('glue') +local whatsit = node.id('whatsit') + +local hyphen = tex.defaulthyphenchar or 45 + +local dash_attr = luatexbase.attributes['gre@attr@dash'] +local potentialdashvalue = 1 +local nopotentialdashvalue = 2 + +local center_attr = luatexbase.attributes['gre@attr@center'] +local startcenter = 1 +local endcenter = 2 + +local glyph_id_attr = luatexbase.attributes['gre@attr@glyph@id'] +local glyph_top_attr = luatexbase.attributes['gre@attr@glyph@top'] +local glyph_bottom_attr = luatexbase.attributes['gre@attr@glyph@bottom'] +local prev_line_id = nil + +local cur_score_id = nil +local score_inclusion = {} +local line_heights = nil +local new_line_heights = nil +local score_heights = nil +local new_score_heights = nil +local var_brace_positions = nil +local new_var_brace_positions = nil +local pos_saves = nil +local new_pos_saves = nil +local auxname = nil + +local space_below_staff = 5 +local space_above_staff = 13 + +local score_fonts = {} +local symbol_fonts = {} +local loaded_font_sizes = {} +local font_factors = {} +local font_indexed = {} +local next_variant = 0 +local variant_prefix = 'gre@font@variant@' +local number_to_letter = { + ['0'] = 'A', ['1'] = 'B', ['2'] = 'C', ['3'] = 'D', ['4'] = 'E', + ['5'] = 'F', ['6'] = 'G', ['7'] = 'H', ['8'] = 'I', ['9'] = 'J', +} + +local capture_header_macro = {} + +local catcode_at_letter = luatexbase.catcodetables['gre@atletter'] + +local user_defined_subtype = node.subtype('user_defined') +local create_marker = luatexbase.new_user_whatsit('marker', 'gregoriotex') +local marker_whatsit_id = luatexbase.get_user_whatsit_id('marker', 'gregoriotex') +local translation_mark = 1 +local abovelinestext_mark = 2 + +log("marker whatsit id is %d", marker_whatsit_id) + +local function mark(value) + local marker = create_marker() + marker.type = 100 + marker.value = value + marker.attr = node.current_attr() + node.write(marker) +end + +local function mark_translation() + mark(translation_mark) +end + +local function mark_abovelinestext() + mark(abovelinestext_mark) +end + +local function is_mark(node, value) + return node.id == whatsit and node.subtype == user_defined_subtype and + node.user_id == marker_whatsit_id and node.value == value +end + +local function keys_changed(tab1, tab2) + if tab2 == nil then return true end + local id,_ + for id,_ in pairs(tab1) do + if tab2[id] == nil then return true end + end + for id,_ in pairs(tab2) do + if tab1[id] == nil then return true end + end + return false +end + +local function heights_changed() + local id, tab + for id, tab in pairs(new_line_heights) do + if keys_changed(tab, line_heights[id]) then return true end + end + for id, tab in pairs(line_heights) do + if keys_changed(tab, new_line_heights[id]) then return true end + end + for id, tab in pairs(new_var_brace_positions) do + if keys_changed(tab, var_brace_positions[id]) then return true end + end + for id, tab in pairs(var_brace_positions) do + if keys_changed(tab, new_var_brace_positions[id]) then return true end + end + for id, tab in pairs(new_pos_saves) do + if keys_changed(tab, pos_saves[id]) then return true end + end + for id, tab in pairs(pos_saves) do + if keys_changed(tab, new_pos_saves[id]) then return true end + end + return false +end + +local function write_greaux() + if heights_changed() then + -- only write this if heights change; since table ordering is not + -- predictable, this ensures a steady state if the heights are unchanged. + local aux = io.open(auxname, 'w') + if aux then + log("Writing %s", auxname) + aux:write('return {\n ["line_heights"]={\n') + local id, tab, id2, line + for id, tab in pairs(new_line_heights) do + aux:write(string.format(' ["%s"]={\n', id)) + for id2, line in pairs(tab) do + aux:write(string.format(' [%d]={%d,%d,%d,%d},\n', id2, line[1], + line[2], line[3], line[4])) + end + aux:write(' },\n') + end + aux:write(' },\n ["var_brace_positions"]={\n') + for id, tab in pairs(new_var_brace_positions) do + aux:write(string.format(' ["%s"]={\n', id)) + for id2, line in pairs(tab) do + if line[1] ~= nil and line[2] ~= nil then + aux:write(string.format(' [%d]={%d,%d},\n', id2, line[1], + line[2])) + end + end + aux:write(' },\n') + end + aux:write(' },\n ["pos_saves"]={\n') + for id, tab in pairs(new_pos_saves) do + aux:write(string.format(' ["%s"]={\n', id)) + for id2, line in pairs(tab) do + if line[1] ~= nil and line[2] ~= nil and line[3] ~= nil and + line[4] ~= nil then + aux:write(string.format(' [%d]={%d,%d,%d,%d},\n', id2, line[1], + line[2], line[3], line[4])) + end + end + aux:write(' },\n') + end + aux:write(' },\n}\n') + aux:close() + else + err("\n Unable to open %s", auxname) + end + + warn("Line heights or variable brace lengths may have changed. Rerun to fix.") + end +end + +local function init(arg, enable_height_computation) + -- is there a better way to get the output directory? + local outputdir = nil + for k,v in pairs(arg) do + if v:find('%-output%-directory') then + if v:find('%-output%-directory=') then + outputdir=string.explode(v, '=')[2] + else + outputdir=arg[tonumber(k)+1] + end + end + end + if outputdir and lfs.isdir(outputdir) then + auxname = outputdir..'/'..tex.jobname..'.gaux' + else + auxname = tex.jobname..'.gaux' + end + + -- to get latexmk to realize the aux file is a dependency + texio.write_nl('('..auxname..')') + if lfs.isfile(auxname) then + log("Reading %s", auxname) + local score_info = dofile(auxname) + line_heights = score_info.line_heights or {} + var_brace_positions = score_info.var_brace_positions or {} + pos_saves = score_info.pos_saves or {} + else + line_heights = {} + var_brace_positions = {} + pos_saves = {} + end + + if enable_height_computation then + new_line_heights = {} + + local mcb_version = luatexbase.get_module_version and + luatexbase.get_module_version('luatexbase-mcb') or 9999 + if mcb_version and mcb_version > 0.6 then + luatexbase.add_to_callback('finish_pdffile', write_greaux, + 'gregoriotex.write_greaux') + else + -- The version of luatexbase in TeX Live 2014 does not support it, and + -- luatexbase prevents a direct call to callback.register. Because of + -- this, we lose the LuaTeX statistics and "output written to" messages, + -- but I know of no other workaround. + + luatexbase.add_to_callback('stop_run', write_greaux, + 'gregoriotex.write_greaux') + end + else + warn('Height computation has been skipped. Gregorio will use '.. + 'previously computed values if available but will not recompute '.. + 'line heights. Remove or undefine \\greskipheightcomputation to '.. + 'resume height computation.') + end + new_var_brace_positions = {} + new_pos_saves = {} +end + +-- node factory +local tmpnode = node.new(glyph, 0) +tmpnode.font = 0 +tmpnode.char = hyphen +local function gethyphennode() + return copy(tmpnode) +end + +local function getdashnnode() + local hyphnode = gethyphennode() + local dashnode = hpack(hyphnode) + dashnode.shift = 0 + return dashnode,hyphnode +end + +-- a simple (for now) function to dump nodes for debugging +local function dump_nodes(head) + local n, m + for n in traverse(head) do + if node.type(n.id) == 'penalty' then + log("%s=%d {%d}", node.type(n.id), n.penalty, has_attribute(n, glyph_id_attr)) + elseif n.id == whatsit and n.subtype == user_defined_subtype and n.user_id == marker_whatsit_id then + log("marker-whatsit %s", n.value) + else + log("node %s [%d] {%d}", node.type(n.id), n.subtype, has_attribute(n, glyph_id_attr)) + end + if n.id == hlist then + for m in traverse(n.head) do + if node.type(m.id) == 'penalty' then + log("..%s=%d {%d}", node.type(m.id), m.penalty, has_attribute(n, glyph_id_attr)) + elseif m.id == whatsit and m.subtype == user_defined_subtype and m.user_id == marker_whatsit_id then + log("..marker-whatsit %s", m.value) + else + log("..node %s [%d] {%d}", node.type(m.id), m.subtype, has_attribute(n, glyph_id_attr)) + end + end + end + end + log('--end dump--') +end + +local function center_translation(startnode, endnode, ratio, sign, order) + -- total width between beginning the two centering points + local total_width = node.dimensions(ratio, sign, order, startnode, endnode) + -- definition of translation with a beginning is: + -- \hbox to 0pt{ + -- \kern 0pt + -- \vbox to 0pt{ + -- \vss\hbox to 0pt{ + -- translation\hss + -- } + -- } + -- \kern 0pt + -- } + -- + -- hence translation width is: + local trans_width = node.dimensions(startnode.head.next.head.next.head) + -- now we must transform the kern 0pt into kern Xpt and kern -Xpt where X is: + local X = (total_width - trans_width) / 2 + startnode.head.kern = X + startnode.head.next.next.kern = -X +end + +local debug_types_activated = {['linesglues'] = false} + +local function set_debug_string(debugstring) + for debugtype in string.gmatch(debugstring, "[^,]+") do + debug_types_activated[debugtype] = true + end +end + +local glue_sign_name = {[0] = 'normal', [1] = 'stretching', [2] = 'shrinking'} + +local function debugmessage(type, message) + if (debug_types_activated[type] or debug_types_activated['all']) then + texio.write_nl('GregorioTeX debug: ('..type..'): '..message) + end +end + +-- in each function we check if we really are inside a score, +-- which we can see with the dash_attr being set or not +local function process (h, groupcode, glyphes) + -- TODO: to be changed according to the font + local lastseennode = nil + local adddash = false + local currentfont = 0 + local currentshift = 0 + local centerstartnode = nil + local line_id = nil + local line_top = nil + local line_bottom = nil + local line_has_translation = false + local line_has_abovelinestext = false + local linenum = 0 + -- we explore the lines + for line in traverse(h) do + if line.id == glue then + if line.next ~= nil and line.next.id == hlist + and has_attribute(line.next, dash_attr) + and count(hlist, line.next.head) <= 2 then + --log("eating glue") + h, line = remove(h, line) + end + elseif line.id == hlist and has_attribute(line, dash_attr) then + -- the next two lines are to remove the dumb lines + if count(hlist, line.head) <= 2 then + --log("eating line") + h, line = remove(h, line) + else + linenum = linenum + 1 + debugmessage('linesglues', format('line %d: %s factor %d%%', linenum, glue_sign_name[line.glue_sign], line.glue_set*100)) + centerstartnode = nil + line_id = nil + line_top = nil + line_bottom = nil + line_has_translation = false + line_has_abovelinestext = false + for n in traverse_id(hlist, line.head) do + if has_attribute(n, center_attr, startcenter) then + centerstartnode = n + elseif has_attribute(n, center_attr, endcenter) then + if not centerstartnode then + warn("End of a translation centering area encountered on a\nline without translation centering beginning,\nskipping translation...") + else + center_translation(centerstartnode, n, line.glue_set, line.glue_sign, line.glue_order) + end + elseif has_attribute(n, dash_attr, potentialdashvalue) then + adddash=true + lastseennode=n + currentfont = 0 + -- we traverse the list, to detect the font to use, + -- and also not to add an hyphen if there is already one + for g in node.traverse_id(glyph, n.head) do + if currentfont == 0 then + currentfont = g.font + end + if g.char == hyphen or g.char == 45 then + adddash = false + end + end + if currentshift == 0 then + currentshift = n.shift + end + -- if we encounter a text that doesn't need a dash, we acknowledge it + elseif has_attribute(n, dash_attr, nopotentialdashvalue) then + adddash=false + end + + if new_score_heights then + local glyph_id = has_attribute(n, glyph_id_attr) + local glyph_top = has_attribute(n, glyph_top_attr) or 9 -- 'g' + local glyph_bottom = has_attribute(n, glyph_bottom_attr) or 9 -- 'g' + if glyph_id and glyph_id > prev_line_id then + if not line_id or glyph_id > line_id then + line_id = glyph_id + end + if not line_top or glyph_top > line_top then + line_top = glyph_top + end + if not line_bottom or glyph_bottom < line_bottom then + line_bottom = glyph_bottom + end + end + end + end + -- look for marks + if new_score_heights then + for n in traverse_id(whatsit, line.head) do + line_has_translation = line_has_translation or + is_mark(n, translation_mark) + line_has_abovelinestext = line_has_abovelinestext or + is_mark(n, abovelinestext_mark) + end + end + if adddash==true then + local dashnode, hyphnode = getdashnnode() + dashnode.shift = currentshift + hyphnode.font = currentfont + insert_after(line.head, lastseennode, dashnode) + addash=false + end + if line_id then + new_score_heights[prev_line_id] = { line_top, line_bottom, + line_has_translation and 1 or 0, + line_has_abovelinestext and 1 or 0 } + prev_line_id = line_id + end + end + -- we reinitialize the shift value, because it may change according to the line + currentshift=0 + end + end + --dump_nodes(h) + -- due to special cases, we don't return h here (see comments in bug #20974) + return true +end + +-- In gregoriotex, hyphenation is made by the process function, so TeX hyphenation +-- is just a waste of time. This function will be registered in the hyphenate +-- callback to skip this step and thus gain a little time. +local function disable_hyphenation() + return false +end + +local function atScoreBeginning (score_id, top_height, bottom_height, + has_translation, has_above_lines_text, top_height_adj, bottom_height_adj) + local inclusion = score_inclusion[score_id] or 1 + score_inclusion[score_id] = inclusion + 1 + score_id = score_id..'.'..inclusion + cur_score_id = score_id + if (top_height > top_height_adj or bottom_height < bottom_height_adj + or has_translation ~= 0 or has_above_lines_text ~= 0) + and tex.count['gre@variableheightexpansion'] == 1 then + score_heights = line_heights[score_id] or {} + if new_line_heights then + new_score_heights = {} + new_line_heights[score_id] = new_score_heights + end + prev_line_id = tex.getattribute(glyph_id_attr) + else + score_heights = nil + new_score_heights = nil + end + + luatexbase.add_to_callback('post_linebreak_filter', process, 'gregoriotex.callback', 1) + luatexbase.add_to_callback("hyphenate", disable_hyphenation, "gregoriotex.disable_hyphenation", 1) +end + +local function atScoreEnd () + luatexbase.remove_from_callback('post_linebreak_filter', 'gregoriotex.callback') + luatexbase.remove_from_callback("hyphenate", "gregoriotex.disable_hyphenation") +end + +local function clean_old_gtex_files(file_withdir) + local filename = "" + local dirpath = "" + local sep = "" + local onwindows = os.type == "windows" or + string.find(os.getenv("PATH"),";",1,true) + if onwindows then + sep = "\\" + dirpath = string.match(file_withdir, "(.*)"..sep) + else + sep = "/" + dirpath = string.match(file_withdir, "(.*)"..sep) + end + if dirpath then -- dirpath is nil if current directory + filename = "^"..file_withdir:match(".*/".."(.*)").."%-%d+_%d+_%d+[-%a%d]*%.gtex$" + for a in lfs.dir(dirpath) do + if a:match(filename) then + os.remove(dirpath..sep..a) + end + end + else + filename = "^"..file_withdir.."%-%d+_%d+_%d+[-%a%d]*%.gtex$" + for a in lfs.dir(lfs.currentdir()) do + if a:match(filename) then os.remove(a) end + end + end +end + +local function compile_gabc(gabc_file, gtex_file) + info("compiling the score %s...", gabc_file) + local extra_args = '' + if tex.count['gre@generate@pointandclick'] == 1 then + extra_args = ' -p' + end + + res = os.execute(string.format("gregorio %s -o %s %s", extra_args, gtex_file, gabc_file)) + if res == nil then + err("\nSomething went wrong when executing\n 'gregorio -o %s %s'.\n" + .."shell-escape mode may not be activated. Try\n\n%s --shell-escape %s.tex\n\nSee the documentation of gregorio or your TeX\ndistribution to automatize it.", gtex_file, gabc_file, tex.formatname, tex.jobname) + elseif res ~= 0 then + err("\nAn error occured when compiling the score file\n'%s' with gregorio.\nPlease check your score file.", gabc_file) + else + -- open the gtex file for writing so that LuaTeX records output to it + -- when the -recorder option is used + local gtex = io.open(gtex_file, 'a') + if gtex == nil then + err("\n Unable to open %s", gtex_file) + else + gtex:close() + end + end +end + +local function include_score(input_file, force_gabccompile) + local file_root + if string.match(input_file:sub(-5), '%.gtex') then + file_root = input_file:sub(1,-6) + elseif string.match(input_file:sub(-4), '%.tex') then + file_root = input_file:sub(1,-5) + elseif string.match(input_file:sub(-5), '%.gabc') then + file_root = input_file:sub(1,-6) + elseif not file_root then + file_root = input_file + end + local gtex_file = file_root.."-"..internalversion:gsub("%.", "_")..".gtex" + local gabc_file = file_root..".gabc" + if not lfs.isfile(gtex_file) then + clean_old_gtex_files(file_root) + log("The file %s does not exist. Searching for a gabc file", gtex_file) + if lfs.isfile(gabc_file) then + local gabc = io.open(gabc_file, 'r') + if gabc == nil then + err("\n Unable to open %s", gabc_file) + return + else + gabc:close() + end + compile_gabc(gabc_file, gtex_file) + tex.print(string.format([[\input %s\relax]], gtex_file)) + return + else + err("The file %s does not exist.", gabc_file) + return + end + end + local gtex_timestamp = lfs.attributes(gtex_file).modification + local gabc_timestamp = lfs.attributes(gabc_file).modification + -- open the gabc file for reading so that LuaTeX records input from it + -- when the -recorder option is used; do this here so that this happens + -- on every run + local gabc = io.open(gabc_file, 'r') + if gabc == nil then + err("\n Unable to open %s", gabc_file) + else + gabc:close() + end + if gtex_timestamp < gabc_timestamp then + log("%s has been modified and %s needs to be updated. Recompiling the gabc file.", gabc_file, gtex_file) + compile_gabc(gabc_file, gtex_file) + elseif force_gabccompile then + compile_gabc(gabc_file, gtex_file) + end + tex.print(string.format([[\input %s\relax]], gtex_file)) + return +end + +local function direct_gabc(gabc, header) + tmpname = os.tmpname() + local f = io.open(tmpname, 'w') + -- trims spaces on both ends (trim6 from http://lua-users.org/wiki/StringTrim) + gabc = gabc:match('^()%s*$') and '' or gabc:match('^%s*(.*%S)') + f:write('name:direct-gabc;\n'..(header or '')..'\n%%\n'..gabc:gsub('\\par ', '\n')) + f:close() + local p = io.popen('gregorio -S '..tmpname, 'r') + if p == nil then + err("\nSomething went wrong when executing\n gregorio -S "..tmpname..".\n" + .."shell-escape mode may not be activated. Try\n\n%s --shell-escape %s.tex\n\nSee the documentation of gregorio or your TeX\ndistribution to automatize it.", tex.formatname, tex.jobname) + end + tex.print(p:read("*a"):explode('\n')) + p:close() + os.remove(tmpname) +end + +local function get_gregorioversion() + return internalversion +end + +local get_font_by_id = font.getfont --- cached, indexes fonts.hashes.identifiers +local font_id = font.id + +-- an "unsafe" version of get_font_by_id that can see all fonts +-- LuaTeX can see, which is needed when we need the font size of +-- the user-selected current font +local function unsafe_get_font_by_id(id) + return get_font_by_id(id) or font.fonts[id] +end + +-- get_font_by_name(name) -- Look up a font identifier in the +-- ``score_fonts`` table. Returns the id of the font if found, -1 +-- otherwise. +local function get_font_by_name(name) + local id = font_id(name) + return id >= 0 and get_font_by_id(id) +end + +-- get_score_font_id(name) -- Look up a font identifier in the +-- ``score_fonts`` table. Returns the id of the font if found, -1 +-- otherwise. +local function get_score_font_id(name) + local sfnt = score_fonts[name] + if sfnt then + return font_id(sfnt) + end + return -1 +end + +local resource_dummy = { unicodes = { } } + +-- get_font_resources(number) -- Retrieve the resource table +-- associated with a font id. Always returns a Lua table value whose +-- ``unicodes`` field is indexable. +local function get_font_resources(id) + local fnt = get_font_by_id(id) + if fnt then + return fnt.resources or resource_dummy + end + return resource_dummy +end + +-- get_score_font_resources(string) -- Retrieve the resource table +-- belonging to a font in the ``score_font`` table. Always returns +-- a table whose ``unicodes`` field is indexable. +local function get_score_font_resources(name) + return get_font_resources(get_score_font_id(name)) +end + +local function get_score_font_unicode_pairs(name) + local unicodes = get_score_font_resources(name).unicodes + if not font_indexed[name] then + -- The unicodes table may be lazy-loaded, so iterating it may not + -- return everything. Attempting to retrieve the code point of a + -- glyph that has not already been loaded will trigger the __index + -- method in the metatable (implemented by the fontloader) to load + -- the table until the glyph is found. When iterating the + -- unicodes, we want the whole table to be filled, so we try to + -- access a non-existing glyph in order to force load the entire + -- table. + local ignored = unicodes['_this_is_hopefully_a_nonexistent_glyph_'] + font_indexed[name] = true + end + return pairs(unicodes) +end + +local function check_font_version() + local gregoriofont = get_font_by_name('gre@font@music') + if gregoriofont then + local fontversion = gregoriofont.shared.rawdata.metadata.version + if fontversion ~= internalversion then + local fontname = gregoriofont.shared.rawdata.metadata.fontname + local fontfile = gregoriofont.shared.rawdata.metadata.origname + err("\nUncoherent file versions!\ngregoriotex.tex is version %s\nwhile %s.ttf is version %s\nplease update file\n%s", internalversion, fontname, fontversion, fontfile) + end + end +end + +local function map_font(name, prefix) + log("Mapping font %s", name) + local glyph, unicode + for glyph, unicode in get_score_font_unicode_pairs(name) do + if unicode >= 0 and not string.match(glyph, '%.') then + log("Setting \\Gre%s%s to \\char%d", prefix, glyph, unicode) + tex.sprint(catcode_at_letter, string.format( + [[\xdef\Gre%s%s{\char%d}]], prefix, glyph, unicode)) + end + end +end + +local function init_variant_font(font_name, for_score, gre_factor) + if font_name ~= '*' then + local font_table = for_score and score_fonts or symbol_fonts + if font_table[font_name] == nil then + local font_csname = variant_prefix..string.gsub(tostring(next_variant), '[0-9]', number_to_letter) + font_table[font_name] = font_csname + log("Registering variant font %s as %s.", font_name, font_csname) + if for_score then + tex.print(catcode_at_letter, string.format( + [[\global\font\%s = {name:%s} at 10 sp\relax ]], + font_csname, font_name)) + -- loaded_font_sizes will only be given a value if the font is for_score + loaded_font_sizes[font_name] = {size = '10', gre_factor = gre_factor} + if font_factors[font_name] == nil then + font_factors[font_name] = '100000' + end + else + -- is there a nice way to make this string readable? + tex.print(catcode_at_letter, string.format( + [[\gdef\%sSymReload#1{{\edef\localsize{#1}\ifx\localsize\%sSymSize\relax\relax\else\global\font\%s = {name:%s} at \localsize pt\relax\xdef\%sSymSize{\localsize}\fi}}\xdef\%sSymSize{0}\%sSymReload{\gre@symbolfontsize}]], + font_csname, font_csname, font_csname, font_name, font_csname, + font_csname, font_csname)) + end + next_variant = next_variant + 1 + end + end +end + +local function set_score_glyph(csname, font_csname, char) + log([[Setting \%s to \%s\char%d]], csname, font_csname, char) + tex.print(catcode_at_letter, string.format( + [[\edef\%s{{\noexpand\%s\char%d}}]], csname, font_csname, char)) +end + +local function set_common_score_glyph(csname, font_csname, char) + -- font_csname is ignored + log([[Setting \%s to \char%d]], csname, char) + tex.print(catcode_at_letter, string.format( + [[\edef\%s{{\char%d}}]], csname, char)) +end + +local function set_symbol_glyph(csname, font_csname, char) + tex.print(catcode_at_letter, string.format( + [[\def\%s{\%sSymReload{\gre@symbolfontsize}{\%s\char%d}\relax}]], + csname, font_csname, font_csname, char)) +end + +local function set_sized_symbol_glyph(csname, font_csname, char) + tex.print(catcode_at_letter, string.format( + [[\gdef\%s#1{\%sSymReload{#1}{\%s\char%d}\relax}]], + csname, font_csname, font_csname, char)) +end + +local function def_glyph(csname, font_name, glyph, font_table, setter) + local font_csname = font_table[font_name] + local char + if string.match(glyph, '^%d+$') then + char = tonumber(glyph) + else + local fid = font_id(font_csname) + if fid < 0 then + err('\nFont %s is not defined.', font_name) + end + char = get_font_resources(fid).unicodes[glyph] + if char == nil then + err('\nGlyph %s in font %s was not found.', glyph, font_name) + end + end + setter(csname, font_csname, char) +end + +local function change_single_score_glyph(glyph_name, font_name, replacement) + if font_name == '*' then def_glyph('GreCP'..glyph_name, 'greciliae', replacement, score_fonts, set_common_score_glyph) + else + def_glyph('GreCP'..glyph_name, font_name, replacement, score_fonts, + set_score_glyph) + end +end + +local function change_score_glyph(glyph_name, font_name, replacement) + if string.match(glyph_name, '%*') then + glyph_name = '^'..glyph_name:gsub('%*', '.*')..'$' + if not string.match(replacement, '^%.') then + err('If a wildcard is supplied for glyph name, replacement must start with a dot.') + end + local other_font + if font_name == '*' then + other_font = get_score_font_resources('greciliae').unicodes + else + other_font = get_score_font_resources(font_name).unicodes + end + local name, char + for name, char in get_score_font_unicode_pairs('greciliae') do + if not string.match(name, '%.') and char >= 0 and string.match(name, glyph_name) then + local matched_replacement = name..replacement + if other_font[matched_replacement] ~= nil and other_font[matched_replacement] >= 0 then + change_single_score_glyph(name, font_name, matched_replacement) + end + end + end + else + if string.match(replacement, '^%.') then + replacement = glyph_name..replacement + end + change_single_score_glyph(glyph_name, font_name, replacement) + end +end + +local function reset_score_glyph(glyph_name) + if string.match(glyph_name, '%*') then + glyph_name = '^'..glyph_name:gsub('%*', '.*')..'$' + local name, char + for name, char in get_score_font_unicode_pairs('greciliae') do + if not string.match(name, '%.') and char >= 0 and string.match(name, glyph_name) then + set_common_score_glyph('GreCP'..name, nil, char) + end + end + else + local char = get_score_font_resources("greciliae").unicodes[glyph_name] + if char == nil then + err('\nGlyph %s was not found.', glyph_name) + end + set_common_score_glyph('GreCP'..glyph_name, nil, char) + end +end + +local function set_font_factor(font_name, font_factor) + font_factors[font_name] = font_factor +end + +local function scale_score_fonts(size, gre_factor) + for font_name, font_csname in pairs(score_fonts) do + if loaded_font_sizes[font_name] and font_factors[font_name] and loaded_font_sizes[font_name].size ~= gre_factor * font_factors[font_name] then + tex.print(catcode_at_letter, string.format( + [[\global\font\%s = {name:%s} at %s sp\relax ]], + font_csname, font_name, gre_factor * font_factors[font_name])) + loaded_font_sizes[font_name] = {size = size, gre_factor = gre_factor} + end + end +end + +local function def_symbol(csname, font_name, glyph, sized) + def_glyph(csname, font_name, glyph, symbol_fonts, + sized and set_sized_symbol_glyph or set_symbol_glyph) +end + +local function font_size() + tex.print(string.format('%.2f', (unsafe_get_font_by_id(font.current()).size / 65536.0))) +end + +local function adjust_line_height(inside_discretionary) + if score_heights then + local heights = score_heights[tex.getattribute(glyph_id_attr)] + if heights then + tex.sprint(catcode_at_letter, string.format( + [[\gre@calculate@additionalspaces{%d}{%d}{%d}{%d}]], + heights[1], heights[2], heights[3], heights[4])) + if inside_discretionary == 0 then + tex.sprint(catcode_at_letter, [[\gre@updateleftbox ]]) + end + end + end +end + +local function var_brace_note_pos(brace, start_end) + tex.print(string.format([[\luatexlatelua{gregoriotex.late_brace_note_pos('%s', %d, %d, \number\pdflastxpos)}]], cur_score_id, brace, start_end)) +end + +local function late_brace_note_pos(score_id, brace, start_end, pos) + if new_var_brace_positions[score_id] == nil then + new_var_brace_positions[score_id] = {} + end + if new_var_brace_positions[score_id][brace] == nil then + new_var_brace_positions[score_id][brace] = {} + end + new_var_brace_positions[score_id][brace][start_end] = pos +end + +local function var_brace_len(brace) + if var_brace_positions[cur_score_id] ~= nil then + if var_brace_positions[cur_score_id][brace] ~= nil then + local posend = var_brace_positions[cur_score_id][brace][2] + local posstart = var_brace_positions[cur_score_id][brace][1] + if posend > posstart then + tex.print(string.format('%dsp', posend - posstart)) + else + warn('Dynamically sized braces spanning multiple lines unsupported, using length 2mm.') + tex.print('2mm') + end + return + end + end + tex.print('2mm') +end + +local function save_pos(index, which) + tex.print(string.format([[\pdfsavepos\luatexlatelua{gregoriotex.late_save_pos('%s', %d, %d, \number\pdflastxpos, \number\pdflastypos)}]], cur_score_id, index, which)) +end + +local function late_save_pos(score_id, index, which, xpos, ypos) + if new_pos_saves[score_id] == nil then + new_pos_saves[score_id] = {} + end + if new_pos_saves[score_id][index] == nil then + new_pos_saves[score_id][index] = {} + end + new_pos_saves[score_id][index][(2 * which) - 1] = xpos + new_pos_saves[score_id][index][2 * which] = ypos +end + +-- this function is meant to be used from \ifcase; prints 0 for true and 1 for false +local function is_ypos_different(index) + if pos_saves[cur_score_id] ~= nil then + local saved_pos = pos_saves[cur_score_id][index] + if saved_pos == nil or saved_pos[2] == saved_pos[4] then + tex.sprint([[\number1\relax ]]) + else + tex.sprint([[\number0\relax ]]) + end + else + tex.sprint([[\number1\relax ]]) + end +end + +local function width_to_bp(width, value_if_star) + if width == '*' then + tex.print(value_if_star or '0') + else + tex.print(tex.sp(width) * 1.00375 / 65536) + end +end + +-- computes the hypotenuse given the width and height of the right triangle +local function hypotenuse(width, height) + log("width %s height %s", width, height) + local a = tex.sp(width) + local b = tex.sp(height) + tex.sprint(math.sqrt((a * a) + (b * b)) .. 'sp') +end + +-- computes the rotation angle opposite the height of a right triangle +local function rotation(width, height) + local a = tex.sp(width) + local b = tex.sp(height) + tex.sprint(math.deg(math.atan2(b, a))) +end + +local function scale_space(factor) + local skip = tex.getskip('gre@skip@temp@four') + skip.width = skip.width * factor + -- should skip.stretch and skip.shink also be scaled? +end + +local function set_header_capture(header, macro_name, flags) + if macro_name == '' then + capture_header_macro[header] = nil + log("no longer capturing header %s", header) + else + local macro = {} + macro.name = macro_name + flags:gsub("([^,]+)", function(flag) + if flag == "string" then macro.takes_string = true + elseif flag == "name" then macro.takes_header_name = true + else err("unknown header capture flag: %s", flag) + end + end) + capture_header_macro[header] = macro + log("capturing header %s using %s, string=%s, name=%s", header, macro.name, macro.takes_string, macro.takes_header_name) + end +end + +local function capture_header(header, value) + local macro = capture_header_macro[header] + if macro ~= nil then + tex.sprint(string.format([[\%s{]], macro.name)) + if macro.takes_header_name then + tex.sprint(-2, header) + tex.sprint('}{') + end + if macro.takes_string then + tex.sprint(-2, value) + else + tex.sprint(value) + end + tex.print('}') + end +end + +local function mode_part(part) + if part ~= '' then + if not unicode.utf8.match(part, '^%p') then + tex.sprint([[\thinspace]]) + end + tex.print(part) + end +end + +gregoriotex.number_to_letter = number_to_letter +gregoriotex.init = init +gregoriotex.include_score = include_score +gregoriotex.atScoreEnd = atScoreEnd +gregoriotex.atScoreBeginning = atScoreBeginning +gregoriotex.check_font_version = check_font_version +gregoriotex.get_gregorioversion = get_gregorioversion +gregoriotex.map_font = map_font +gregoriotex.init_variant_font = init_variant_font +gregoriotex.change_score_glyph = change_score_glyph +gregoriotex.reset_score_glyph = reset_score_glyph +gregoriotex.scale_score_fonts = scale_score_fonts +gregoriotex.set_font_factor = set_font_factor +gregoriotex.def_symbol = def_symbol +gregoriotex.font_size = font_size +gregoriotex.direct_gabc = direct_gabc +gregoriotex.adjust_line_height = adjust_line_height +gregoriotex.var_brace_len = var_brace_len +gregoriotex.var_brace_note_pos = var_brace_note_pos +gregoriotex.late_brace_note_pos = late_brace_note_pos +gregoriotex.mark_translation = mark_translation +gregoriotex.mark_abovelinestext = mark_abovelinestext +gregoriotex.width_to_bp = width_to_bp +gregoriotex.hypotenuse = hypotenuse +gregoriotex.rotation = rotation +gregoriotex.scale_space = scale_space +gregoriotex.set_header_capture = set_header_capture +gregoriotex.capture_header = capture_header +gregoriotex.save_pos = save_pos +gregoriotex.late_save_pos = late_save_pos +gregoriotex.is_ypos_different = is_ypos_different +gregoriotex.mode_part = mode_part +gregoriotex.set_debug_string = set_debug_string + +dofile(kpse.find_file('gregoriotex-nabc.lua', 'lua')) +dofile(kpse.find_file('gregoriotex-signs.lua', 'lua')) +dofile(kpse.find_file('gregoriotex-symbols.lua', 'lua')) diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex.tex b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex.tex new file mode 100644 index 00000000000..ca9bf25334e --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gregoriotex.tex @@ -0,0 +1,293 @@ +% GregorioTeX boostrap file for Plain TeX +% +% Copyright (C) 2015 The Gregorio Project (see CONTRIBUTORS.md) +% +% This file is part of Gregorio. +% +% Gregorio 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. +% +% Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +% this file contains definitions for lines, initial, fonts, etc. + + +% This file needs to be marked with the version number. For now I've done this with the following comment, but we should check to see if PlainTeX has something similar to the version declaration of LaTeX and use that if it does. +% [2016/03/10 v4.1.1 GregorioTeX system.]% PARSE_VERSION_DATE_LTX + + +\edef\greoldcatcode{\the\catcode`@} +\catcode`\@=11 + +\input ifluatex.sty% +\input luatexbase.sty% +\input luamplib.sty% +\input luaotfload.sty% +\input graphicx.tex % for \resizebox +\input xstring.sty% + +\def\gre@error#1{\begingroup% +\def\MessageBreak{^^J}% +\let\protect\string% +\errmessage{GregorioTeX error: #1}% +\endgroup}% + +\def\gre@warning#1{\begingroup% +\def\MessageBreak{^^J}% +\let\protect\string% +\message{GregorioTeX warning: #1}% +\endgroup}% + +\def\gre@bug#1{\begingroup% +\def\MessageBreak{^^J}% +\let\protect\string% +\errmessage{GregorioTeX bug: #1 !! This is a bug in Gregorio. Please report it at https://github.com/gregorio-project/gregorio/issues}% +\endgroup}% + +\def\gre@typeout#1{\begingroup% +\def\MessageBreak{^^J}% +\let\protect\string% +\message{#1}% +\endgroup}% + +\ifcsname gre@debug\endcsname% +\else% + \def\gre@debug{}% +\fi% + +\ifcsname f@size\endcsname% +\else% + \def\f@size{\directlua{gregoriotex.font_size()}}% +\fi% + +\newif\ifgre@allowdeprecated% +\gre@allowdeprecatedtrue% + +\long\def\gre@metapost#1{{% + \gre@localleftbox{}% + \gre@localrightbox{}% + \mplibcode + #1 + \endmplibcode% +}}% + +%% This is \strip@pt from LaTeX +\begingroup% + \catcode`P=12% + \catcode`T=12% + \lowercase{% + \def\x{\def\gre@rem@pt##1.##2PT{##1\ifnum##2>\z@.##2\fi}}}% + \expandafter\endgroup\x% +\def\gre@strip@pt{\expandafter\gre@rem@pt\the}% + +\long\def\gre@iflatex#1{}% +\input gregoriotex-main.tex + +%%%%%%%%% +%% PlainTeX specific definitions for fonts +%%%%%%%%% + +\def\GreBold#1{% + {\bf #1}% + \relax % +}% + +\def\GreItalic#1{% + {\it #1}% + %\relax +}% + +\def\GreSmallCaps#1{% + {\sc #1}% + \relax % +}% + +\def\GreTypewriter#1{% + {\tt #1}% + \relax % +}% + +% Note since underlining and coloring don’t exist in PlainTeX, but we need the following commands to maintain compatibility with LaTeX. +\def\GreUnderline#1{% + \gre@warning{Underlining cannot be done in PlainTeX}% + {#1}% + \relax % +}% + +\def\GreColored#1{% + \gre@warning{Text color cannot be changed in PlainTeX}% + {#1}% + \relax % +}% + +%%%%%%%%%%%%%%% +%% Line color +%%%%%%%%%%%%%%% + +% Colors don't work in PlainTeX, but we need these functions for interoperability with LaTeX. + +\def\gresetlinecolor#1{% + \gre@warning{Line color cannot be changed in PlainTeX}% + \relax% +} + + +\def\grecoloredlines#1#2#3{%OBSOLETE + \gre@obsolete{\protect\grecoloredlines}{\protect\gresetlinecolor}% +} + +\def\greredlines{%OBSOLETE + \gre@obsolete{\protect\greredlines}{\protect\gresetlinecolor{gregoriocolor}}% +} + +\let\redlines\greredlines%OBSOLETE + +\def\grenormallines{%OBSOLETE + \gre@obsolete{\protect\grenormallines}{\protect\gresetlinecolor{black}}% +} + +\let\normallines\grenormallines%OBSOLETE + +%%%%%%%%%%%%%%%%%%%% +%% Formatting environments +%%%%%%%%%%%%%%%%%%%% + +\font\gre@font@biginitial=pncr at 80pt\relax%%% DEPRECATED for removal in 5.0 +\font\gre@font@initial=pncr at 40pt\relax% + +\def\gre@style@initial{% + \begingroup% + \gre@font@initial% + \relax % +}% +\def\endgre@style@initial{\endgroup}% + +\def\gre@style@biginitial{%%% DEPRECATED for removal in 5.0 + \begingroup%%% DEPRECATED for removal in 5.0 + \gre@font@biginitial%%% DEPRECATED for removal in 5.0 + \relax %%% DEPRECATED for removal in 5.0 +}%%% DEPRECATED for removal in 5.0 +\def\endgre@style@biginitial{\endgroup}%%% DEPRECATED for removal in 5.0 + +\def\gre@style@translation{% + \begingroup% + \it% +}% +\def\endgre@style@translation{\endgroup}% + +\def\gre@style@abovelinestext{% + \begingroup% + \it% +}% +\def\endgre@style@abovelinestext{\endgroup}% + +\def\gre@style@normalstafflines{% + \begingroup% + \relax% +}% +\def\endgre@style@normalstafflines{\endgroup}% + +\def\gre@style@additionalstafflines{% + \begingroup% + \gre@style@normalstafflines% +}% +\def\endgre@style@additionalstafflines{% + \endgre@style@normalstafflines% + \endgroup% +}% + +\def\gre@style@lowchoralsign{% + \begingroup% + \relax% +}% +\def\endgre@style@lowchoralsign{\endgroup}% + +\def\gre@style@highchoralsign{% + \begingroup% + \relax% +}% +\def\endgre@style@highchoralsign{\endgroup}% + +\def\gre@style@firstsyllableinitial{% + \begingroup% + \relax% +}% +\def\endgre@style@firstsyllableinitial{\endgroup}% + +\def\gre@style@firstsyllable{% + \begingroup% + \relax% +}% +\def\endgre@style@firstsyllable{\endgroup}% + +\def\gre@style@firstword{% + \begingroup% + \relax% +}% +\def\endgre@style@firstword{\endgroup}% + +\def\gre@style@modeline{% + \begingroup% + \bf% + \sc% + \relax% +}% +\def\endgre@style@modeline{\endgroup}% + +\def\gre@style@modemodifier{% + \begingroup% + \bf% + \it% + \relax% +}% +\def\endgre@style@modemodifier{\endgroup}% + +\def\gre@style@modedifferentia{% + \begingroup% + \bf% + \relax% +}% +\def\endgre@style@modedifferentia{\endgroup}% + +\def\gre@style@commentary{% + \begingroup% + \it% + % footnotesize is LaTeX, but nothing here since changing font size is so hard + \relax% +}% +\def\endgre@style@commentary{\endgroup}% + +\def\gre@style@elision{% + \begingroup% + \it% + % small is LaTeX, but nothing here since changing font size is so hard + \relax% +}% +\def\endgre@style@elision{\endgroup}% + +\def\gre@style@annotation{% + \begingroup% + \relax% +}% +\def\endgre@style@annotation{\endgroup}% + +\def\gre@style@nabc{% + \begingroup% + \relax% we do nothing since colors are not implemented in PlainTeX +} +\def\endgre@style@nabc{\endgroup}% + +\def\gre@changestyle#1#2[#3]{% + \gdef\csname gre@style@#1\endcsname{\begingroup#2}% + \gdef\csname endgre@style@#1\endcsname{#3\endgroup}% +}% + +\catcode`\@=\greoldcatcode diff --git a/Master/texmf-dist/tex/luatex/gregoriotex/gsp-default.tex b/Master/texmf-dist/tex/luatex/gregoriotex/gsp-default.tex new file mode 100644 index 00000000000..2c2af57a84a --- /dev/null +++ b/Master/texmf-dist/tex/luatex/gregoriotex/gsp-default.tex @@ -0,0 +1,354 @@ +%GregorioTeX file. +% +% Copyright (C) 2010-2015 The Gregorio Project (see CONTRIBUTORS.md) +% +% This file is part of Gregorio. +% +% Gregorio 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. +% +% Gregorio 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 Gregorio. If not, see <http://www.gnu.org/licenses/>. + +% this file contains definitions of spaces and penalties + +%% First, the penalties + +% penalty to force a break on a new line +\xdef\grenewlinepenalty{-10001}% +% penalty to prevent a line break +\xdef\grenobreakpenalty{10001}% +% penalty at the end of a syllable which is the end of a word +\xdef\greendofwordpenalty{-100}% +% penalty at the end of a syllable which is not the end of a word +\xdef\greendofsyllablepenalty{-50}% +% penalty at the end of a syllable which is just a bar, with something printed +% under it +\xdef\greendafterbarpenalty{-200}% +% penalty right after a bar with nothing printed +\xdef\greendafterbaraltpenalty{-200}% +% penalty at the end of the score +\xdef\grefinalpenalty{0}% +% penalty at the end of a breakable neumatic element (typically at a space +% between elements) +\xdef\greendofelementpenalty{-50}% +% hyphenpenalty will be used in discretionaries, in Gregorio this is used for +% a bar with clef change for example. It also set \exhyphenpenalty. It should +% be close to \greendafterbarpenalty +\xdef\grehyphenpenalty{-200}% +% broken penalty is the vertical penalty inserted after a break on a clef change +% I'm not sure it should be set, but it might be useful... +\xdef\grebrokenpenalty{0}% + +%% These macro enable the tuning of linepenalty, tolerance, pretolerance +%% and emergencystretch +\def\grelooseness{-1}% +\def\gretolerance{9000}% +% Workaround for bug 842 (http://tracker.luatex.org/view.php?id=842) +% see http://tug.org/pipermail/luatex/2013-July/004516.html +% The idea is that we use discretionaries (explicit hyphens, though more than hyphens in our case) for clef changes, and we need to give them a special penalty, which is not taken into account if pretolerance is > -1 on LuaTeX < 0.80. For a more detailed explanation see http://tug.org/pipermail/luatex/2013-July/004516.html. +\ifnum\the\luatexversion < 78\relax % + \global\def\grepretolerance{-1}% +\else % + \global\def\grepretolerance{\pretolerance}% +\fi % +\def\greemergencystretch{\emergencystretch}% +% By default, we don't care if a line of score is alone on the page, +% if you think it is bad, you can modify the two following values. Assigning +% 10000 to them will prevent all orphaned lines (this will certainly improve +% some spacings a lot). +\def\grewidowpenalty{0}% +\def\greclubpenalty{0}% + + + +%%%%%%%%%%%%%%%%%%% +%% And finally, all the spacings: +%%%%%%%%%%%%%%%%%%% + +%This count tells gregoriotex what \gre@factor the below values correspond to. +%% All the following values correspond to a gre@factor of 17. At this size the scores should be approximately the size usually seen in a gradual. +%% If you’re creating your own space configuration file, you may set this to some other value, should you so desire. +\greconffactor=17% + +% the additional width of the additional lines (compared to the width of the glyph they're associated with) +\grecreatedim{additionallineswidth}{0.14584 cm}{scalable}% +% width of the additional lines, used only for the custos (maybe should depend on the width of the custos...) +% the width is the one for the custos at end of lines, the line for custos in the middle of a score is the same +% multiplied by 2. +\grecreatedim{additionalcustoslineswidth}{0.09114 cm}{scalable}% +% null space +\grecreatedim{zerowidthspace}{0 cm}{scalable}% +% space between glyphs in the same element +\grecreatedim{interglyphspace}{0.06927 cm plus 0.00363 cm minus 0.00363 cm}{scalable}% +% space between an alteration (flat or natural) and the next glyph +\grecreatedim{alterationspace}{0.07747 cm}{scalable}% +% space between a clef and a flat (for clefs with flat) +\grecreatedim{clefflatspace}{0.05469 cm plus 0.00638 cm minus 0.00638 cm}{scalable}% +% space before a choral sign +\grecreatedim{beforelowchoralsignspace}{0.04556 cm plus 0.00638 cm minus 0.00638 cm}{scalable}% +% when bolshifts are enabled, minimal space between a clef at the beginning of the line and a leading alteration glyph (should be larger than clefflatspace so that a flatted clef can be distinguished from a flat which is part of the first glyph on a line, but also smaller than spaceafterlineclef, the distance from the clef to the first notes) +\grecreatedim{beforealterationspace}{0.1 cm}{scalable}% +% half-space between elements +\grecreatedim{halfspace}{0.03463 cm plus 0.00091 cm minus 0.00182 cm}{scalable}% +% space between elements +\grecreatedim{interelementspace}{0.06927 cm plus 0.00182 cm minus 0.00363 cm}{scalable}% +% larger space between elements +\grecreatedim{largerspace}{0.10938 cm plus 0.01822 cm minus 0.00911 cm}{scalable}% +% space between elements in ancient notation +\grecreatedim{nabcinterelementspace}{0.06927 cm plus 0.00182 cm minus 0.00363 cm}{scalable}% +% larger space between elements in ancient notation +\grecreatedim{nabclargerspace}{0.10938 cm plus 0.01822 cm minus 0.00911 cm}{scalable}% +% space between elements which has the size of a note +\grecreatedim{glyphspace}{0.21877 cm plus 0.01822 cm minus 0.01822 cm}{scalable}% +% space before in-line custos +\grecreatedim{spacebeforeinlinecustos}{0 cm plus 0 cm minus 0 cm}{scalable}% +% space before end-of-line custos +\grecreatedim{spacebeforeeolcustos}{0.3 cm plus 0 cm minus 0 cm}{scalable}% +% space before punctum mora and augmentum duplex +\grecreatedim{spacebeforesigns}{0.050 cm plus 0.004 cm minus 0.004 cm}{scalable}% +% when a syllable is shifted left because of a preceding punctum mora, moraadjustmentbar is +% also added. Use it to make the syllable a bit further from the punctum mora if you want. +% This version is the general case. +\grecreatedim{moraadjustment}{0.050 cm}{scalable}% +% This version is for when punctum mora is before a bar. +\grecreatedim{moraadjustmentbar}{0 cm}{scalable}% +% space after punctum mora and augmentum duplex +\grecreatedim{spaceaftersigns}{0.08203 cm plus 0.0082 cm minus 0.0082 cm}{scalable}% +% space after a clef at the beginning of a line +\grecreatedim{spaceafterlineclef}{0.27345 cm plus 0.14584 cm minus 0.01367 cm}{scalable}% +% minimal space between notes of different words +\grecreatedim{interwordspacenotes}{0.27 cm plus 0.15 cm minus 0.05 cm}{scalable}% +% minimal space between notes of the same syllable. +\grecreatedim{intersyllablespacenotes}{0.24 cm}{scalable}% +% stretching added in the case where the text of two syllables of the same word are +% separated with an automatic hyphen +\grecreatedim{intersyllablespacestretchhyphen}{0cm plus 0.05cm}{scalable}% +% minimal space between letters of different words. Makes sense to have +% the same plus and minus as interwordspacenotes. +\grecreatedim{interwordspacetext}{0.38 cm plus 0.15 cm minus 0.05 cm}{scalable}% +% Versions of interword spaces for euouae blocks +\grecreatedim{interwordspacenotes@euouae}{0.19 cm plus 0.1 cm minus 0.05 cm}{scalable}% +\grecreatedim{interwordspacetext@euouae}{0.27 cm plus 0.1 cm minus 0.05 cm}{scalable}% +% versions of note spaces when the first note of the second syllable is an alteration +% those are used in euouae blocks +\grecreatedim{interwordspacenotes@alteration}{0.1 cm plus 0.07 cm minus 0.01 cm}{scalable}% +\grecreatedim{intersyllablespacenotes@alteration}{0.1 cm}{scalable}% +% space between notes of a bivirga or trivirga +\grecreatedim{bitrivirspace}{0.06927 cm plus 0.00182 cm minus 0.00546 cm}{scalable}% +% space between notes of a bistropha or tristrophae +\grecreatedim{bitristrospace}{0.06927 cm plus 0.00182 cm minus 0.00546 cm}{scalable}% +% +%%%%%%%%%%%%%%%%%%%% +% puncta inclinata % +%%%%%%%%%%%%%%%%%%%% +% +% space between two punctum inclinatum +\grecreatedim{punctuminclinatumshift}{-0.03918 cm plus 0.0009 cm minus 0.0009 cm}{scalable}% +% space before puncta inclinata +\grecreatedim{beforepunctainclinatashift}{0.05286 cm plus 0.00728 cm minus 0.00455 cm}{scalable}% +% space between a punctum inclinatum and a punctum inclinatum deminutus +\grecreatedim{punctuminclinatumanddebilisshift}{-0.02278 cm plus 0.0009 cm minus 0.0009 cm}{scalable}% +% space between two punctum inclinatum deminutus +\grecreatedim{punctuminclinatumdebilisshift}{-0.00728 cm plus 0.0009 cm minus 0.0009 cm}{scalable}% +% space between puncta inclinata, larger ambitus (range=3rd) +\grecreatedim{punctuminclinatumbigshift}{0.07565 cm plus 0.0009 cm minus 0.0009 cm}{scalable}% +% space between puncta inclinata, larger ambitus (range=4th or 5th) +\grecreatedim{punctuminclinatummaxshift}{0.17865 cm plus 0.0009 cm minus 0.0009 cm}{scalable}% +% space between two ascending punctum inclinatum +\grecreatedim{ascendingpunctuminclinatumshift}{-0.07918 cm plus 0.0009 cm minus 0.0009 cm}{scalable}% +% space between a punctum inclinatum and a punctum inclinatum deminutus, ascending +\grecreatedim{ascendingpunctuminclinatumanddebilisshift}{-0.06278 cm plus 0.0009 cm minus 0.0009 cm}{scalable}% +% space between ascending puncta inclinata, larger ambitus (range=3rd) +\grecreatedim{ascendingpunctuminclinatumbigshift}{-0.00435 cm plus 0.0009 cm minus 0.0009 cm}{scalable}% +% space between ascending puncta inclinata, larger ambitus (range=4th or 5th) +\grecreatedim{ascendingpunctuminclinatummaxshift}{0.09865 cm plus 0.0009 cm minus 0.0009 cm}{scalable}% +% space between a punctum inclinatum and a no-bar glyph one pitch below +\grecreatedim{descendinginclinatumtonobarshift}{-0.00073 cm plus 0.00363 cm minus 0.00363 cm}{scalable}% +% space between a punctum inclinatum and a no-bar glyph two pitches below +\grecreatedim{descendinginclinatumtonobarbigshift}{0.10927 cm plus 0.00363 cm minus 0.00363 cm}{scalable}% +% space between a punctum inclinatum and a no-bar glyph three or four pitches below +\grecreatedim{descendinginclinatumtonobarmaxshift}{0.23927 cm plus 0.00363 cm minus 0.00363 cm}{scalable}% +% space between a punctum inclinatum and a no-bar glyph one pitch above +\grecreatedim{ascendinginclinatumtonobarshift}{-0.02473 cm plus 0.00363 cm minus 0.00363 cm}{scalable}% +% space between a punctum inclinatum and a no-bar glyph two pitches above +\grecreatedim{ascendinginclinatumtonobarbigshift}{0.04427 cm plus 0.00363 cm minus 0.00363 cm}{scalable}% +% space between a punctum inclinatum and a no-bar glyph three or four pitches above +\grecreatedim{ascendinginclinatumtonobarmaxshift}{0.12927 cm plus 0.00363 cm minus 0.00363 cm}{scalable}% +% +%%%%%%%% +% bars % +%%%%%%%% +% +% bars inside syllables +% +\grecreatedim{bar@virgula}{0.1823 cm plus 0.22787 cm minus 0.00469 cm}{scalable}% +\grecreatedim{bar@minima}{0.1823 cm plus 0.22787 cm minus 0.00469 cm}{scalable}% +\grecreatedim{bar@minor}{0.1823 cm plus 0.22787 cm minus 0.00469 cm}{scalable}% +% dominican bars +\grecreatedim{bar@dominican}{0.1823 cm plus 0.22787 cm minus 0.00469 cm}{scalable}% +\grecreatedim{bar@maior}{0.1823 cm plus 0.22787 cm minus 0.00469 cm}{scalable}% +\grecreatedim{bar@finalis}{0.1823 cm plus 0.22787 cm minus 0.00469 cm}{scalable}% +% space added before the final divisio finalis (old bar spacing algorithm only) +\grecreatedim{bar@finalfinalis}{0.29169 cm plus 0.07292 cm minus 0.27345 cm}{scalable}% +% +% bars having their own syllable, with text associated (new bar spacing algorithm only) +% plus or minus here will trigger some problems +% +\grecreatedim{bar@virgula@standalone@text}{0.2323 cm}{scalable}% +\grecreatedim{bar@minima@standalone@text}{0.2323 cm}{scalable}% +\grecreatedim{bar@minor@standalone@text}{0.2323 cm}{scalable}% +\grecreatedim{bar@dominican@standalone@text}{0.2323 cm}{scalable}% +\grecreatedim{bar@maior@standalone@text}{0.2323 cm}{scalable}% +\grecreatedim{bar@finalis@standalone@text}{0.2323 cm}{scalable}% +% actual space before divisio finalis, not additional one +\grecreatedim{bar@finalfinalis@standalone@text}{0.29169 cm}{scalable}% +% +% bars having their own syllable, with no text associated (new bar spacing algorithm only) +% +\grecreatedim{bar@virgula@standalone@notext}{0.2323 cm}{scalable}% +\grecreatedim{bar@minima@standalone@notext}{0.2323 cm}{scalable}% +\grecreatedim{bar@minor@standalone@notext}{0.2323 cm}{scalable}% +\grecreatedim{bar@dominican@standalone@notext}{0.2323 cm}{scalable}% +\grecreatedim{bar@maior@standalone@notext}{0.2323 cm}{scalable}% +\grecreatedim{bar@finalis@standalone@notext}{0.2323 cm}{scalable}% +\grecreatedim{bar@finalfinalis@standalone@notext}{0.29169 cm}{scalable}% +% +% minimal space between letters of different syllable texts for text around bars +% (new bar spacing algorithm only) +\grecreatedim{interwordspacetext@bars}{0.15 cm}{scalable}% +% minimal space between letters of different syllable texts for text around bars, +% euouae context +\grecreatedim{interwordspacetext@bars@euouae}{0.15 cm}{scalable}% +\grecreatedim{interwordspacetext@bars@notext}{0.4 cm}{scalable}% +% minimal space between letters of different syllable texts for text around bars, +% euouae context +\grecreatedim{interwordspacetext@bars@notext@euouae}{0.3 cm}{scalable}% +% rubber length that will be added around bars in new bar spacing algorithm +\grecreatedim{bar@rubber}{0 cm plus 0.22787 cm minus 0.02 cm}{scalable}% +% additional space that will appear around bars that are preceded by a custos and followed by a key. +\grecreatedim{spacearoundclefbars}{0.03645 cm plus 0.00455 cm minus 0.0009 cm}{scalable}% +% space between the text of previous syllable and text associated with a bar (old bar spacing algorithm only) +\grecreatedim{textbartextspace}{0.24611 cm plus 0.13672 cm minus 0.04921 cm}{scalable}% +% minimal space between a note and a bar (old algorithm only) +\grecreatedim{notebarspace}{0.31903 cm plus 0.27345 cm minus 0.02824 cm}{scalable}% +% Maximum offset between a bar and its associated text when the text goes left of the bar (new bar spacing algorithm only) +\grecreatedim{maxbaroffsettextleft}{0.6 cm}{scalable}% +% Same as maxbaroffsettextleft when text goes right of the bar +\grecreatedim{maxbaroffsettextright}{0 cm}{scalable}% +% Maximum offset between a no-bar (i.e. something like `text()` in gabc) and its associated text when the text goes left of the no-bar (new bar spacing algorithm only) +\grecreatedim{maxbaroffsettextleft@nobar}{12 cm}{scalable}% +% Same as maxbaroffsettextleft@nobar when text goes right of the no-bar +\grecreatedim{maxbaroffsettextright@nobar}{12 cm}{scalable}% +% Space between the two bars of a divisio finalis +% Maximum offset between a bar and its associated text when the text goes left of the bar and the bar terminates a line (i.e. something line `text(::z)` in gabc) (new bar spacing algorithm only) +\grecreatedim{maxbaroffsettextleft@eol}{0.0 cm}{scalable}% +% Same as maxbaroffsettextleft@eol when text goes right of the bar +\grecreatedim{maxbaroffsettextright@eol}{0 cm}{scalable}% +\grecreatedim{divisiofinalissep}{0.1094 cm}{scalable}% +% +% +% maximal space between two syllables for which we consider a dash is not needed +\grecreatedim{maximumspacewithoutdash}{0 cm}{scalable}% +% an extensible space for the beginning of lines +\grecreatedim{afterclefnospace}{0 cm plus 0.27345 cm minus 0 cm}{scalable}% +% space between the initial and the beginning of the score +\grecreatedim{afterinitialshift}{0.2457 cm}{scalable}% +% space before the initial +\grecreatedim{beforeinitialshift}{0.2457 cm}{scalable}% +% when bolshifts are enabled, minimum space between beginning of line and first syllable text +\grecreatedim{minimalspaceatlinebeginning}{0.05 cm}{scalable}% +% space to force the initial width to. Ignored when 0. +\grecreatedim{manualinitialwidth}{0 cm}{scalable}% +% distance to move the initial up by +\grecreatedim{initialraise}{0 cm}{scalable}% +% Space between lines in the annotation +\grecreatedim{annotationseparation}{0.05cm}{scalable}% +% Amount to raise (positive) or lower (negative) the annotations from the default position +\grecreatedim{annotationraise}{0cm}{scalable}% +% Space between lines in the commentary +\grecreatedim{commentaryseparation}{0.05cm}{scalable}% +% Amount to raise (positive) or lower (negative) the commentary from the default position (base line of bottom commentary aligned with top line of staff) +\grecreatedim{commentaryraise}{0.2cm}{scalable}% +% space at the beginning of the lines if there is no clef +\grecreatedim{noclefspace}{0.1 cm}{scalable}% +% space around a clef change +\grecreatedim{clefchangespace}{0.01768 cm plus 0.00175 cm minus 0.01768 cm}{scalable}% +% When \gre@clivisalignment is 2, this distance is the maximum length of the consonants after vowels for which the clivis will be aligned on its center. +\grecreatedim{clivisalignmentmin}{0.3 cm}{scalable}% + +%%%%%%%%%%%%%%%%%% +% vertical spaces +%%%%%%%%%%%%%%%%%% + +% the amount to shift down: +% (a) low choral signs that are not lower than the note, regardless of whether +% it's on a line or in a space +% (b) high choral signs and low choral signs that are lower than the note which +% are in a space +\grecreatedim{choralsigndownshift}{0.00911 cm}{scalable}% +% the amount to shift up: +% (a) high choral signs and low choral signs that are lower than the note which +% are on a line +\grecreatedim{choralsignupshift}{0.04556 cm}{scalable}% +% the space for the translation +\grecreatedim{translationheight}{0.5 cm}{scalable}% +%the space above the lines +\grecreatedim{spaceabovelines}{0.45576 cm plus 0.36461 cm minus 0.09114 cm}{scalable}% +% this counter is the threshold above which we start accounting notes above +% lines for additional space above lines. For instance with a threshold of +% 2, notes with a pitch of k and l will not interfere with the space above +% lines +\grechangecount{additionaltopspacethreshold}{2}% +% same, for notes taken into account for alt text vertical position +\grechangecount{additionaltopspacealtthreshold}{0}% +%the space between the lines and the bottom of the text +\grecreatedim{spacelinestext}{0.60617 cm}{scalable}% +%the space beneath the text +\grecreatedim{spacebeneathtext}{0 cm}{scalable}% +% height of the text above the note line +\grecreatedim{abovelinestextraise}{-0.1 cm}{scalable}% +% height that is added at the top of the lines if there is text above the lines (it must be bigger than the text for it to be taken into consideration) +\grecreatedim{abovelinestextheight}{0.3 cm}{scalable}% +% an additional shift you can give to the brace above the bars if you don't like it +\grecreatedim{braceshift}{0 cm}{scalable}% +% a shift you can give to the accentus above the curly brace +\grecreatedim{curlybraceaccentusshift}{-0.05 cm}{scalable}% +% the amount to shift the over slur up +\grecreatedim{overslurshift}{0.05000 cm}{scalable}% +% the amount to shift the under slur up +\grecreatedim{underslurshift}{0.01000 cm}{scalable}% +% shift for a horizontal episema over a note in a low position in the space +\grecreatedim{overhepisemalowshift}{0.02287 cm}{scalable}% +% shift for a horizontal episema over a note in a high position in the space +\grecreatedim{overhepisemahighshift}{0.10066 cm}{scalable}% +% shift for a horizontal episema under a note in a low position in the space +\grecreatedim{underhepisemalowshift}{0.02763 cm}{scalable}% +% shift for a horizontal episema under a note in a high position in the space +\grecreatedim{underhepisemahighshift}{0.10981 cm}{scalable}% +% shift for a horizontal episema in the middle of a space +\grecreatedim{hepisemamiddleshift}{0.07206 cm}{scalable}% +% shift for a vertical episema in a low position in the space +\grecreatedim{vepisemalowshift}{-0.01262 cm}{scalable}% +% shift for a vertical episema in a high position in the space +\grecreatedim{vepisemahighshift}{0.06634 cm}{scalable}% +% shift for a punctum mora for a note on a line +\grecreatedim{linepunctummorashift}{-0.06314 cm}{scalable}% +% shift for a punctum mora for a note in a space +\grecreatedim{spacepunctummorashift}{-0.02013 cm}{scalable}% +% shift for a punctum mora for the second note (in a space) of a pes with ambitus one +\grecreatedim{spaceamonepespunctummorashift}{0.00183 cm}{scalable}% +% shift for a punctum mora for the second note in a porrectus, on a line +\grecreatedim{lineporrectuspunctummorashift}{0.04575 cm}{scalable}% +% shift for a punctum mora for the second note in a porrectus, in a space +\grecreatedim{spaceporrectuspunctummorashift}{0.00000 cm}{scalable}% +% shift for a rare sign +\grecreatedim{raresignshift}{0.18302 cm}{scalable}% +% |