diff --git a/.gregorio-version b/.gregorio-version
index d1e1eda10..a4948dcb4 100644
--- a/.gregorio-version
+++ b/.gregorio-version
@@ -1,4 +1,4 @@
-4.0.0-rc2
+4.0.0
*** Do not modify this file. ***
Use VersionManager.py to change the version.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 68ea40e8d..242e0c45f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,61 +3,18 @@ All notable changes to this project will be documented in this file.
As of v3.0.0 this project adheres to [Semantic Versioning](http://semver.org/). It follows [some conventions](http://keepachangelog.com/).
## [Unreleased][unreleased]
-### Fixed
-- Spacing was too large when alteration begins a syllable, see [#663](https://github.com/gregorio-project/gregorio/issues/663).
-
### Changed
-- `alterationspace` is now a fixed dimension, see [UPGRADE.md](UPGRADE.md) for details.
-
-## [4.0.0-rc2] - 2015-11-05
-### Fixed
-- The spacing of manual in-line custos (`(f+)` in gabc) is now consistent with the spacing of automatic in-line custos (`(z0)` in gabc). See [#642](https://github.com/gregorio-project/gregorio/issues/642).
-- Signs on the climacus praepunctis deminutus `(ghgf~)` neume are now positioned correctly. See [#650](https://github.com/gregorio-project/gregorio/issues/650)
-- When using first letter lyric centering and big initials, the initial is no longer incorrectly included in the first syllable. See [#648](https://github.com/gregorio-project/gregorio/issues/648). This is a fix for a bug in a new 4.0.0 feature, so this changelog entry should be removed when the change log is merged for the 4.0.0 release.
-- Mac installer has been made SIP compliant (i.e. it now works on El Capitan).
-- Mac installer can now detect installations of TeXLive done with MacPorts or the command-line tool provided by TUG.
-- Windows executable has file version information attached correctly so that the installer can properly recognize and replace the binary during an upgrade process.
+- Initial handling has been simplified. The initial style should now be specified from TeX by using the `\gresetinitiallines` command, rather than from a gabc header. Big initials and normal initials are now governed by a single `initial` style, meant to be changed between scores as appropriate. See [UPGRADE.md](UPGRADE.md) and GregorioRef for details (for the change request, see [#632](https://github.com/gregorio-project/gregorio/issues/632)). Deprecations for this change are listed in the Deprecation section, below.
### Added
-- The ability to force a hyphen after an empty first syllable, enabled by default since this was the behavior prior to 4.0. Version 4.0 has an improved spacing algorithm which will eliminate the hyphen if the notes for the first syllable are too close to the second. To switch to this behavior, use `\gresetemptyfirstsyllablehyphen{auto}`. See [UPGRADE.md](UPGRADE.md) and GregorioRef for details (for the change request, see [#653](https://github.com/gregorio-project/gregorio/issues/653)).
-- Shell scripts for configuring TeXShop and TeXworks on a Mac.
-
-### Removed
-- The TeXShop script for compiling gabc files. Supplanted by the new autocompile feature of the package.
-- Spaces associated with chironomic signs (which were removed in 4.0.0-beta)
+- Salicus flexus glyphs (See [#631](https://github.com/gregorio-project/gregorio/issues/631)).
### Deprecated
-- The meaningless `gabc-version` header in gabc (see [#664](https://github.com/gregorio-project/gregorio/issues/664)).
+- `initial-style` gabc header, supplanted by the `\gresetinitiallines` TeX command.
+- `biginitial` style, consolidated into the `initial` style.
-## [4.0.0-rc1] - 2015-10-08
-### Fixed
-- Deactivating the end of line shifts now prevents lyrics from stretching under the custos at the end of the line.
-- All of the keywords for `\grescaledim` now work as described in the documentation.
-
-### Changed
-- `\grecreatedim` and `\grechangedim` now take keywords for their third argument (`scalable` and `fixed`) instead of integers (`1` and `0`) to make the more in keeping with the overall user command conventions.
-- `\grescaledim` now accepts `scalable` as a keyword to turn on scalable (in keeping with the above change)
-- Alterations are partially ignored when aligning lines on the notes (i.e. `\gresetbolshifts{enabled}`). They are not allowed to get any closer to the clef than `beforealterationspace` and the lyrics are not allowed to get any closer to the left-hand margin than `minimalspaceatlinebeginning`, but other than that GregorioTeX will shift them left as much as possible to make the notes align `spaceafterlineclef` away from the clef. Note that for the default values of these distances, only the natural is small enough to acheive true alignment.
-- `gregoriotex.sty` and `gregoriosyms.sty` now check to make sure that they are not both loaded. If `gregoriotex` detects that `gregoriosyms` is loaded, then an error is raised. If `gregoriosyms` detects that `gregoriotex` is loaded, then the loading of `gregoriosyms` is silently aborted and compilation proceeds.
-- Liquescence on a bistropha or tristropha will only appear on the note(s) marked by `<` in gabc, rather than on all notes in the figure. This means that a figure like `(gsss<)` will only have a liquescent "tail" on the final note. If you would like all notes to be liquescent for some reason, you can use a figure like `(gs.
-AC_INIT([gregorio],[4.0.0-rc2],[gregorio-devel@gna.org])
-FILENAME_VERSION="4_0_0-rc2"
+AC_INIT([gregorio],[4.0.0],[gregorio-devel@gna.org])
+FILENAME_VERSION="4_0_0"
AC_SUBST(FILENAME_VERSION)
MK=""
AC_SUBST(MK)
diff --git a/doc/Command_Index_User.tex b/doc/Command_Index_User.tex
index 629e7aaee..fbe62c49e 100644
--- a/doc/Command_Index_User.tex
+++ b/doc/Command_Index_User.tex
@@ -165,20 +165,17 @@ \subsubsection{Including scores}
\gregorioscore[a]{TecumPrincipium} % gabc auto compiled.
\end{latexcode}
-\macroname{\textbackslash gabcsnippet}{[\optional{\#1}]\{\#2\}}{gregoriotex-main.tex}
-Converts the gabc notation specified in \texttt{\#2} to Gregorio\TeX\ and
-includes it directly in the document. The optional argument \texttt{[\#1]}
-may be used to specify a gabc \texttt{initial-style}, which defaults to
-\texttt{1}.
+\macroname{\textbackslash gabcsnippet}{\{\#1\}}{gregoriotex-main.tex}
+Converts the gabc notation specified in \texttt{\#1} to Gregorio\TeX\ and
+includes it directly in the document.
\begin{argtable}
- \#1 & number & Optional. The gabc \texttt{initial-style} value to use.\\
- \#2 & string & The gabc to insert into the document.\\
+ \#1 & string & The gabc to insert into the document.\\
\end{argtable}
\medskip For example:\par\medskip
\begin{latexcode}
- \gabcsnippet[0]{(c3) Al(eg~)le(gv.fhg)lu(efe___)ia(e.) (::)}
+ \gabcsnippet{(c3) Al(eg~)le(gv.fhg)lu(efe___)ia(e.) (::)}
\end{latexcode}
@@ -512,7 +509,7 @@ \subsubsection{Glyph Alteration}
For example:
\medskip \begin{latexcode}
- \gresimpledefbarglyph{A}{0.3em}
+ \gresimpledefbarredsymbol{A}{0.3em}
\end{latexcode}
Will define \texttt{\textbackslash Abar} to be a A with a bar shifted right
@@ -611,8 +608,7 @@ \subsubsection{Styling}
\begin{tabular}{lp{7cm plus .5cm}r}
Element Name & Description & Default\\
\hline
- \stylename{initial} & Normal Initials & 40 pt font\\
- \stylename{biginitial} & Big (2-Line) Initials & 80 pt font\\
+ \stylename{initial} & Score initial (the first letter of the score, when offset from the rest of the text) & 40 pt font\\
\stylename{translation} & Translation text (appears below lyrics) & {\it italics}\\
\stylename{abovelinestext} & Above line text (\texttt{} in gabc, appears above the staff) & normal\\
\stylename{normalstafflines} & Full length staff lines & none\\
@@ -698,6 +694,12 @@ \subsubsection{Text Elements}
\textbf{Nota Bene:} Usually the argument of this command should be an \verb=\includegraphics= command, but you may use what ever you want as the illuminated initial.
+\macroname{\textbackslash gresetinitiallines}{\#1}{gregoriotex-syllable.tex}
+Sets the number of lines the score initial requires.
+
+\begin{argtable}
+ \#1 & number & The number of lines required by the initial. If \texttt{0}, the score will have no separated initial.\\
+\end{argtable}
\subsubsection{Text Alignment}
Gregorio\TeX\ allows you to manipulate the global alignment behavior of some text elements using the following commands.
diff --git a/doc/Command_Index_gregorio.tex b/doc/Command_Index_gregorio.tex
index a3dc678a1..a71f9ae7b 100644
--- a/doc/Command_Index_gregorio.tex
+++ b/doc/Command_Index_gregorio.tex
@@ -54,13 +54,6 @@ \section{Gregorio Controls}
\#3 & integer & Set horizontal episema (0), horizontal episema under a note (1), line at top of staff (2), line at bottom of staff (3), choral sign (4).\\
\end{argtable}
-\macroname{\textbackslash GreAdjustSecondLine}{}{gregoriotex.tex}
-%didn't actually find this one in gregoriotex-write.c, classified it here based on it’s related function GreAdjustThirdLine
-Macro to call before first syllable, but after \verb=\GreSetInitialClef=.
-
-\macroname{\textbackslash GreAdjustThirdLine}{}{gregoriotex-main.tex}
-Macro to call during the second line.
-
\macroname{\textbackslash GreAugmentumDuplex}{\#1\#2\#3}{gregoriotex-signs.tex}
Macro for typesetting an augmentum duplex (a pair of punctum mora)
@@ -114,9 +107,6 @@ \section{Gregorio Controls}
& \texttt{1} & Call came from translation centering.
\end{argtable}
-\macroname{\textbackslash GreBeginNotes}{}{gregoriotex.tex}
-Macro to draw the staff lines. Comes after the initial but before the clef.
-
\macroname{\textbackslash GreBold}{\#1}{gregoriotex.sty and gregoriotex.tex}
Makes argument bold. Accesses \LaTeX\ \verb=\textbf= (\textit{gregoriotex.sty}) or Plain \TeX\ \verb=\bf= (\textit{gregoriotex.tex}) as appropriate. Corresponds to ``'' tags in gabc.
@@ -532,9 +522,6 @@ \section{Gregorio Controls}
\#1 & integer & Height number of the custos.\\
\end{argtable}
-\macroname{\textbackslash GreNoInitial}{}{gregoriotex-main.tex}
-Macro called when no initial is being set.
-
\macroname{\textbackslash GreOverBrace}{\#1\#2\#3\#4}{gregoriotex-signs.tex}
Macro to typeset a round brace above the lines.
@@ -625,6 +612,16 @@ \section{Gregorio Controls}
\#2 & string & Type of glyph the semicirculus is attached to. See \nameref{EpisemaSpecial} argument for description of options.\\
\end{argtable}
+\macroname{\textbackslash GreScoreOpening}{\#1\#2\#3\#4}{gregoriotex-syllable.tex}
+Opens the score.
+
+\begin{argtable}
+ \#1 & \TeX\ code & Macros rendering the things after the initial but before the notes.\\
+ \#2 & \TeX\ code & Macros rendering the things after starting notes but before the syllable.\\
+ \#3 & \TeX\ control sequence & Control sequence for the syllable.\\
+ \#4 & \TeX\ code & Macros rendering the first syllable; should emit the initial and populate \verb=\gre@opening@syllabletext=.\\
+\end{argtable}
+
\macroname{\textbackslash GreScoreReference}{\#1}{gregoriotex-main.tex}
Currently does nothing.
@@ -636,8 +633,17 @@ \section{Gregorio Controls}
\#2 & string & Type of glyph the semicirculus is attached to. See \nameref{EpisemaSpecial} argument for description of options.\\
\end{argtable}
-\macroname{\textbackslash GreSetBigInitial}{}{gregoriotex-main.tex}
-Macro which indicates that a 2-line initial is desired.
+\macroname{\textbackslash GreSetFirstSyllableText}{\#1\#2\#3\#4\#5\#6}{gregoriotex-syllable.tex}
+Sets the first syllable text.
+
+\begin{argtable}
+ \#1 & \TeX\ code & Initial.\\
+ \#2 & \TeX\ code & First letter after the initial.\\
+ \#3 & \TeX\ code & Everything else in the syllable.\\
+ \#4 & \TeX\ code & Three syllable parts when there is a separated initial.\\
+ \#5 & \TeX\ code & Three syllable parts where there is no separated initial.\\
+ \#6 & \TeX\ code & Extra macros to run if there is an initial.\\
+\end{argtable}
\macroname{\textbackslash GreSetFixedNextTextFormat}{\#1}{gregoriotex-syllable.tex}
Same as \verb=\GreSetFixedTextFormat= except for next syllable.
@@ -669,9 +675,6 @@ \section{Gregorio Controls}
& \texttt{5} & underline
\end{argtable}
-\macroname{\textbackslash GreSetInitial}{\#1}{gregoriotex-main.tex}
-Macro to set the initial in the score.
-
\begin{argtable}
\#1 & character & The initial letter of the score.\\
\end{argtable}
@@ -705,6 +708,9 @@ \section{Gregorio Controls}
\#3 & string & the end letters, they don't count for alignment\\
\end{argtable}
+\macroname{\textbackslash GreSetNoFirstSyllableText}{}{gregoriotex-syllable.tex}
+Macro that indicates there is no next in the first syllable.
+
\macroname{\textbackslash GreSetTextAboveLines}{\#1}{gregoriotex-main.tex}
Macro to place argument above the lines and empty
\verb=\gre@currenttextabovelines= when done.
diff --git a/doc/Command_Index_internal.tex b/doc/Command_Index_internal.tex
index 79edd33db..c4eec3102 100644
--- a/doc/Command_Index_internal.tex
+++ b/doc/Command_Index_internal.tex
@@ -259,15 +259,6 @@ \section{Gregorio\TeX{} Controls}
\#1 & string & Snippet of gabc code.\\
\end{argtable}
-\macroname{\textbackslash gre@gabcsnippet@option}{[\#1]\#2}{gregoriotex-main.tex}
-Macro that handles \verb=\gabcsnippet= calls when they have an optional
-argument.
-
-\begin{argtable}
- \#1 & int & Value of initial style to be passed to gregorio \\
- \#2 & string & Snippet of gabc code.\\
-\end{argtable}
-
\macroname{\textbackslash gre@writemode}{\#1}{gregoriotex-main.tex}
Macro that writes its argument with \verb=\greannotation=. The
argument typically is given to this macro by \verb=\GreMode= in the
@@ -369,6 +360,27 @@ \section{Gregorio\TeX{} Controls}
\#1 & integer & height of the custos character to be placed\\
\end{argtable}
+\macroname{\textbackslash gre@beginnotes}{}{gregoriotex-main.tex}
+Macro to draw the staff lines. Comes after the initial but before the clef.
+
+\macroname{\textbackslash gre@noinitial}{}{gregoriotex-main.tex}
+Macro called when no initial is being set.
+
+\macroname{\textbackslash gre@setbiginitial}{}{gregoriotex-main.tex}
+Macro which indicates that a 2-line initial is desired.
+
+\macroname{\textbackslash gre@setinitial}{\#1}{gregoriotex-main.tex}
+Macro to set the initial in the score.
+
+\macroname{\textbackslash gre@adjustsecondline}{}{gregoriotex.tex}
+Macro to call before first syllable, but after \verb=\GreSetInitialClef=.
+
+\macroname{\textbackslash gre@adjustthirdline}{}{gregoriotex-main.tex}
+Macro to call during the second line.
+
+\macroname{\textbackslash gre@adjustlineifnecessary}{}{gregoriotex-main.tex}
+Macro that calls \verb=\gre@adjustthirdline= if indicated by \verb=\ifgre@thirdlineadjustmentnecessary=.
+
\macroname{\textbackslash gre@addspaceabove}{}{gregoriotex-main.tex}
Macro to increase the space above the lines to account for above lines text.
@@ -458,6 +470,24 @@ \section{Gregorio\TeX{} Controls}
& \texttt{0} & otherwise\\
\end{argtable}
+\macroname{\textbackslash gre@setfirstsyllabletext}{\#1\#2\#3\#4\#5\#6}{gregoriotex-syllable.tex}
+Internal macro to set the first syllable text after all parts are known.
+
+\begin{argtable}
+ \#1 & \TeX\ code & First part of the syllable (before the vowel)\\
+ \#2 & \TeX\ code & Middle part of the syllable (the vowel)\\
+ \#3 & \TeX\ code & Last part of the syllable (after the vowel)\\
+ \#4 & \TeX\ code & First letter of the syllable\\
+ \#5 & \TeX\ code & Everything after the first letter of the syllable\\
+ \#6 & \TeX\ code & Macros to run after the text is emitted\\
+\end{argtable}
+
+\macroname{\textbackslash gre@opening@syllabletext}{}{gregoriotex-syllable.tex}
+Macro that stores the computed \TeX\ code for rendering the text of the first syllable.
+
+\macroname{\textbackslash gre@opening@initialstyle}{}{gregoriotex-syllable.tex}
+Macro used by \verb=GreSetInitialStyle= to store the initial style
+
\macroname{\textbackslash gre@exhyphencharsave}{}{gregoriotex-main.tex}
Macro for saving the ex hyphen character so that it can be restored at the end of the score.
@@ -518,6 +548,7 @@ \section{Gregorio\TeX{} Controls}
& \texttt{1} & stay at the end of the glyph; doesn’t make much sense to use this\\
& \texttt{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\\
& \texttt{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\\
+ & \texttt{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\\
\#3 & integer &the ambitus for a two note episema at the diagonal stroke of a porrectus, porrectus flexus, orculus resupinus, or torculus resupinus flexus\\
\#4 & \texttt{0} & an horizontal episema\\
& \texttt{1} & an horizontal episema under a note\\
@@ -941,9 +972,6 @@ \subsection{Fonts}
\macroname{\textbackslash gre@font@nabc}{}{gregoriotex-nabc.tex}
The font for ancient notation.
-\macroname{\textbackslash gre@font@biginitial}{}{gregoriotex.tex}
-The font for the default big initial format in Plain \TeX.
-
\macroname{\textbackslash gre@font@initial}{}{gregoriotex.tex}
The font for the default initial format in Plain \TeX.
@@ -1208,6 +1236,9 @@ \subsection{Flags}
\macroname{\textbackslash ifgre@showhyphenafterthissyllable}{}{gregoriotex-syllable.tex}
Boolean used by \verb=\GreSyllable= to decide if a hyphen should be shown after the syllable.
+\macroname{\textbackslash ifgre@thirdlineadjustmentnecessary}{}{gregoriotex-syllable.tex}
+Boolean which indicates that a third-line adjustment to staff line width is necessary.
+
\macroname{\textbackslash ifgre@scale@stafflinefactor}{}{gregoriotex-spaces.tex}
Boolean indicating whether the stafflinefactor should scale with changes of \texttt{grefactor}, or not.
diff --git a/doc/GregorioRef.tex b/doc/GregorioRef.tex
index 0fe245003..52454021b 100644
--- a/doc/GregorioRef.tex
+++ b/doc/GregorioRef.tex
@@ -133,7 +133,7 @@
\vspace{1cm}
- \large Version \textbf{4.0.0-rc2}, 5 November 2015 %% PARSE_VERSION_DATE
+ \large Version \textbf{4.0.0}, 8 December 2015 %% PARSE_VERSION_DATE
\vspace{1.5cm}
\end{center}
diff --git a/fonts/squarize.py b/fonts/squarize.py
index fba8f9164..2ef3eba23 100644
--- a/fonts/squarize.py
+++ b/fonts/squarize.py
@@ -79,7 +79,7 @@
5: 'Five',
}
-GREGORIO_VERSION = '4.0.0-rc2'
+GREGORIO_VERSION = '4.0.0'
# The unicode character at which we start our numbering:
# U+E000 is the start of the BMP Private Use Area
@@ -173,6 +173,7 @@ def main():
scandicus(font_width)
ancus(font_width)
salicus(font_width)
+ salicus_flexus(font_width)
torculus(font_width)
torculus_liquescens(font_width)
porrectus(font_width)
@@ -394,6 +395,7 @@ def get_width(widths, glyphName):
S_VIRGA_STRATA = 'VirgaStrata'
S_SALICUS = 'Salicus'
S_SALICUS_LONGQUEUE = 'SalicusLongqueue'
+S_SALICUS_FLEXUS = 'SalicusFlexus'
S_TORCULUS_LIQUESCENS = 'TorculusLiquescens'
S_TORCULUS_LIQUESCENS_QUILISMA = 'TorculusLiquescensQuilisma'
S_FLEXUS_ORISCUS_SCAPUS = 'FlexusOriscusScapus'
@@ -833,6 +835,11 @@ def write_salicus(widths, i, j, last_glyph, shape, lique=L_NOTHING):
glyph_name = '%s%s%s%s' % (shape, AMBITUS[i], AMBITUS[j], lique)
if copy_existing_glyph(glyph_name):
return
+ length = draw_salicus(widths, i, j, last_glyph)
+ set_width(length)
+ end_glyph(glyph_name)
+
+def draw_salicus(widths, i, j, last_glyph):
not_deminutus = last_glyph != 'rdeminutus'
if j == 1 and not_deminutus:
if last_glyph == 'rvsbase':
@@ -878,6 +885,10 @@ def write_salicus(widths, i, j, last_glyph, shape, lique=L_NOTHING):
last_glyph = 'Virga'
elif last_glyph == 'rvlbase':
last_glyph = 'VirgaLongqueue'
+ elif last_glyph == 'PunctumLineBLBR':
+ last_glyph = 'PunctumLineBR'
+ elif last_glyph == 'PunctumLineBL':
+ last_glyph = 'Punctum'
if not_deminutus:
paste_and_move(last_glyph, length, (i+j)*BASE_HEIGHT)
length = length + get_width(widths, last_glyph)
@@ -885,6 +896,58 @@ def write_salicus(widths, i, j, last_glyph, shape, lique=L_NOTHING):
length = length+get_width(widths, 'line2')
paste_and_move(last_glyph, (length-get_width(widths, last_glyph)),
(i+j)*BASE_HEIGHT)
+ return length
+
+def salicus_flexus(widths):
+ "Creates the salicus flexus."
+ message("salicus")
+ for i in range(1, MAX_INTERVAL+1):
+ for j in range(1, MAX_INTERVAL+1):
+ for k in range(1, MAX_INTERVAL+1):
+ write_salicus_flexus(widths, i, j, k, "PunctumLineTL")
+ for i in range(1, MAX_INTERVAL+1):
+ for j in range(1, MAX_INTERVAL+1):
+ for k in range(1, MAX_INTERVAL+1):
+ write_salicus_flexus(widths, i, j, k, "deminutus", L_DEMINUTUS)
+ for i in range(1, MAX_INTERVAL+1):
+ for j in range(1, MAX_INTERVAL+1):
+ for k in range(1, MAX_INTERVAL+1):
+ write_salicus_flexus(widths, i, j, k, "auctusa1", L_ASCENDENS)
+ for i in range(1, MAX_INTERVAL+1):
+ for j in range(1, MAX_INTERVAL+1):
+ for k in range(1, MAX_INTERVAL+1):
+ write_salicus_flexus(widths, i, j, k, "auctusd1", L_DESCENDENS)
+
+def write_salicus_flexus(widths, i, j, k, last_glyph, lique=L_NOTHING):
+ "Writes the salicus glyphs."
+ new_glyph()
+ glyph_name = '%s%s%s%s%s' % (S_SALICUS_FLEXUS, AMBITUS[i], AMBITUS[j],
+ AMBITUS[k], lique)
+ if copy_existing_glyph(glyph_name):
+ return
+ is_deminutus = last_glyph == 'deminutus'
+ if k == 1 and not is_deminutus:
+ penult_glyph = 'PunctumLineBL'
+ else:
+ penult_glyph = 'PunctumLineBLBR'
+ length = draw_salicus(widths, i, j, penult_glyph)
+ if k == 1 and not is_deminutus:
+ length = length-0.01
+ if last_glyph == 'PunctumLineTL':
+ last_glyph = 'Punctum'
+ elif last_glyph == 'auctusa1':
+ last_glyph = 'PunctumAscendens'
+ elif last_glyph == 'auctusd1':
+ last_glyph = 'PunctumDescendens'
+ if k != 1:
+ length = length - get_width(widths, 'line2')
+ write_line(k, length, (1+i+j-k)*BASE_HEIGHT)
+ if is_deminutus:
+ length = length - get_width(widths, last_glyph)
+ if k != 1:
+ length = length + get_width(widths, 'line2')
+ paste_and_move(last_glyph, length, (i+j-k)*BASE_HEIGHT)
+ length = length + get_width(widths, last_glyph)
set_width(length)
end_glyph(glyph_name)
diff --git a/macosx/Gregorio.pkgproj b/macosx/Gregorio.pkgproj
index 9e0b3eec1..1cf7d364f 100755
--- a/macosx/Gregorio.pkgproj
+++ b/macosx/Gregorio.pkgproj
@@ -564,7 +564,7 @@
OVERWRITE_PERMISSIONS
VERSION
- 4.0.0-rc2
+ 4.0.0
UUID
74692645-8112-42EB-8FFC-2CBE2CEDE9FB
diff --git a/src/Makefile.am b/src/Makefile.am
index e2424dcbe..1bc3209ac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,7 +23,7 @@ gregorio_LDADD = $(KPSE_LIBS)
bin_PROGRAMS = gregorio
gregorio_SOURCES = gregorio-utils.c characters.c characters.h \
- messages.c messages.h struct.c struct.h \
+ messages.c messages.h struct.c struct.h enum_generator.h \
unicode.c unicode.h sha1.c sha1.h support.c support.h \
config.h bool.h plugins.h utf8strings.h dump/dump.c \
gregoriotex/gregoriotex-write.c \
diff --git a/src/bool.h b/src/bool.h
index e32bade4d..d40d0b441 100644
--- a/src/bool.h
+++ b/src/bool.h
@@ -1,4 +1,7 @@
/*
+ * Gregorio is a program that translates gabc files to GregorioTeX
+ * This header provides a minimum of C11-like bool functionality.
+ *
* Copyright (C) 2015 The Gregorio Project (see CONTRIBUTORS.md)
*
* This file is part of Gregorio.
diff --git a/src/characters.c b/src/characters.c
index 23b6e9bc5..2f2bb9f04 100644
--- a/src/characters.c
+++ b/src/characters.c
@@ -1,4 +1,7 @@
/*
+ * Gregorio is a program that translates gabc files to GregorioTeX.
+ * This file contains functions that deal with lyrics and styles.
+ *
* Copyright (C) 2008-2015 The Gregorio Project (see CONTRIBUTORS.md)
*
* This file is part of Gregorio.
@@ -42,6 +45,7 @@
#include "unicode.h"
#include "characters.h"
#include "messages.h"
+#include "support.h"
#include "utf8strings.h"
#include "vowel/vowel.h"
@@ -84,11 +88,7 @@ static bool read_vowel_rules(char *const lang) {
char buf[PATH_MAX];
size_t capacity = 16, size = 0;
- if (!(filenames = malloc(capacity * sizeof(char *)))) {
- gregorio_messagef("read_patterns", VERBOSITY_FATAL, 0,
- _("unable to allocate memory"));
- return false;
- }
+ filenames = gregorio_malloc(capacity * sizeof(char *));
file = popen("kpsewhich " VOWEL_FILE, "r");
if (!file) {
@@ -100,15 +100,11 @@ static bool read_vowel_rules(char *const lang) {
while (!feof(file) && !ferror(file) && fgets(buf, PATH_MAX, file)) {
rtrim(buf);
if (strlen(buf) > 0) {
- filenames[size++] = strdup(buf);
+ filenames[size++] = gregorio_strdup(buf);
if (size >= capacity) {
capacity <<= 1;
- if (!(filenames = realloc(filenames,
- capacity * sizeof(char *)))) {
- gregorio_messagef("read_patterns", VERBOSITY_FATAL, 0,
- _("unable to allocate memory"));
- return false;
- }
+ filenames = gregorio_realloc(filenames,
+ capacity * sizeof(char *));
}
} else {
gregorio_messagef("read_patterns", VERBOSITY_WARNING, 0,
@@ -216,7 +212,7 @@ static void determine_center(gregorio_character *character, int *start,
if (count == 0) {
return;
}
- subject = (grewchar *)malloc((count + 1) * sizeof(grewchar));
+ subject = (grewchar *)gregorio_malloc((count + 1) * sizeof(grewchar));
for (count = 0, ch = character; ch; ch = ch->next_character) {
if (ch->is_character) {
subject[count ++] = ch->cos.character;
@@ -238,7 +234,7 @@ static bool go_to_end_initial(gregorio_character **param_character)
if (!current_character) {
return false;
}
- gregorio_go_to_first_character(¤t_character);
+ gregorio_go_to_first_character_c(¤t_character);
/* skip past any initial */
if (!current_character->is_character
&& current_character->cos.s.type == ST_T_BEGIN
@@ -268,7 +264,7 @@ static void style_push(det_style **current_style, unsigned char style)
if (!current_style) {
return;
}
- element = (det_style *) malloc(sizeof(det_style));
+ element = (det_style *) gregorio_malloc(sizeof(det_style));
element->style = style;
element->previous_style = NULL;
element->next_style = (*current_style);
@@ -330,14 +326,14 @@ static void free_styles(det_style **first_style)
* special-character. It places current_character to the character next to the
* end of the verbatim or special_char charachters.
*/
-static __inline void verb_or_sp(gregorio_character **ptr_character,
+static __inline void verb_or_sp(const gregorio_character **ptr_character,
const grestyle_style style, FILE *const f,
void (*const function) (FILE *, grewchar *))
{
int i, j;
grewchar *text;
- gregorio_character *current_character;
- gregorio_character *begin_character;
+ const gregorio_character *current_character;
+ const gregorio_character *begin_character;
i = 0;
j = 0;
@@ -359,7 +355,7 @@ static __inline void verb_or_sp(gregorio_character **ptr_character,
ptr_character = ¤t_character;
return;
}
- text = (grewchar *) malloc((i + 1) * sizeof(grewchar));
+ text = (grewchar *) gregorio_malloc((i + 1) * sizeof(grewchar));
current_character = begin_character;
while (j < i) {
if (current_character->is_character) {
@@ -392,9 +388,9 @@ static __inline void verb_or_sp(gregorio_character **ptr_character,
* complex styles. It would be a bit stupid to do such a thing, but users are
* usually very creative when it comes to inventing twisted things...
*/
-void gregorio_write_text(const bool skip_initial,
- gregorio_character *current_character,
- FILE *const f, void (*const printverb) (FILE *, grewchar *),
+void gregorio_write_text(const gregorio_write_text_phase phase,
+ const gregorio_character *current_character, FILE *const f,
+ void (*const printverb) (FILE *, grewchar *),
void (*const printchar) (FILE *, grewchar),
void (*const begin) (FILE *, grestyle_style),
void (*const end) (FILE *, grestyle_style),
@@ -417,7 +413,7 @@ void gregorio_write_text(const bool skip_initial,
printspchar);
break;
case ST_INITIAL:
- if (skip_initial) {
+ if (phase == WTP_FIRST_SYLLABLE) {
while (current_character) {
if (!current_character->is_character
&& current_character->cos.s.type == ST_T_END
@@ -445,9 +441,10 @@ void gregorio_write_text(const bool skip_initial,
}
}
-void gregorio_write_first_letter_alignment_text(const bool skip_initial,
- gregorio_character *current_character,
- FILE *const f, void (*const printverb) (FILE *, grewchar *),
+void gregorio_write_first_letter_alignment_text(
+ const gregorio_write_text_phase phase,
+ const gregorio_character *current_character, FILE *const f,
+ void (*const printverb) (FILE *, grewchar *),
void (*const printchar) (FILE *, grewchar),
void (*const begin) (FILE *, grestyle_style),
void (*const end) (FILE *, grestyle_style),
@@ -456,7 +453,7 @@ void gregorio_write_first_letter_alignment_text(const bool skip_initial,
/* stack of styles to close and reopen */
det_style *first_style = NULL;
det_style *last_style = NULL;
- bool first_letter_open = true;
+ int first_letter_open = (phase == WTP_FIRST_SYLLABLE)? 2 : 1;
if (!current_character) {
return;
@@ -465,7 +462,9 @@ void gregorio_write_first_letter_alignment_text(const bool skip_initial,
/* go to the first character */
gregorio_go_to_first_character(¤t_character);
- begin(f, ST_SYLLABLE_INITIAL);
+ if (phase != WTP_FIRST_SYLLABLE) {
+ begin(f, ST_SYLLABLE_INITIAL);
+ }
/* loop until there are no characters left */
for (; current_character;
@@ -474,7 +473,7 @@ void gregorio_write_first_letter_alignment_text(const bool skip_initial,
/* found a real character */
if (current_character->is_character) {
printchar(f, current_character->cos.character);
- close_first_letter = first_letter_open;
+ close_first_letter = first_letter_open != 0;
} else switch (current_character->cos.s.type) {
case ST_T_NOTHING:
assert(false);
@@ -484,29 +483,23 @@ void gregorio_write_first_letter_alignment_text(const bool skip_initial,
switch (current_character->cos.s.style) {
case ST_CENTER:
case ST_FORCED_CENTER:
- /* ignore */
- break;
case ST_INITIAL:
- if (skip_initial) {
- while (current_character) {
- if (!current_character->is_character
- && current_character->cos.s.type == ST_T_END
- && current_character->cos.s.style ==
- ST_INITIAL) {
- break;
- }
- current_character = current_character->next_character;
- }
- } /* else ignore */
+ case ST_FIRST_SYLLABLE_INITIAL:
+ /* ignore */
break;
case ST_VERBATIM:
verb_or_sp(¤t_character, ST_VERBATIM, f, printverb);
- close_first_letter = first_letter_open;
+ close_first_letter = first_letter_open != 0;
break;
case ST_SPECIAL_CHAR:
verb_or_sp(¤t_character, ST_SPECIAL_CHAR, f, printspchar);
- close_first_letter = first_letter_open;
+ close_first_letter = first_letter_open != 0;
break;
+ case ST_FIRST_WORD:
+ case ST_FIRST_SYLLABLE:
+ if (phase == WTP_FIRST_SYLLABLE) {
+ break;
+ } /* else fall through */
default:
/* push the style onto the stack */
style_push(&first_style, current_character->cos.s.style);
@@ -518,12 +511,18 @@ void gregorio_write_first_letter_alignment_text(const bool skip_initial,
case ST_CENTER:
case ST_FORCED_CENTER:
case ST_INITIAL:
+ case ST_FIRST_SYLLABLE_INITIAL:
/* ignore */
break;
case ST_VERBATIM:
case ST_SPECIAL_CHAR:
assert(false);
break;
+ case ST_FIRST_WORD:
+ case ST_FIRST_SYLLABLE:
+ if (phase == WTP_FIRST_SYLLABLE) {
+ break;
+ } /* else fall through */
default:
/* pop the style from the stack */
assert(first_style->style == current_character->cos.s.style);
@@ -533,12 +532,10 @@ void gregorio_write_first_letter_alignment_text(const bool skip_initial,
break;
}
- if (!current_character->next_character && first_letter_open) {
- close_first_letter = first_letter_open;
- }
-
- if (close_first_letter) {
- first_letter_open = false;
+ while (close_first_letter || (!current_character->next_character
+ && first_letter_open > 0)) {
+ close_first_letter = false;
+ --first_letter_open;
/* close all the styles in the stack */
if (first_style) {
@@ -571,12 +568,18 @@ void gregorio_write_first_letter_alignment_text(const bool skip_initial,
}
}
+ if (phase == WTP_FIRST_SYLLABLE) {
+ while ((--first_letter_open) >= 0) {
+ end(f, ST_SYLLABLE_INITIAL);
+ }
+ }
+
free_styles(&first_style);
}
/* the default behaviour is to write only the initial, that is to say things
* between the styles ST_INITIAL */
-void gregorio_write_initial(gregorio_character *current_character,
+void gregorio_write_initial(const gregorio_character *current_character,
FILE *const f, void (*const printverb) (FILE *, grewchar *),
void (*const printchar) (FILE *, grewchar),
void (*const begin) (FILE *, grestyle_style),
@@ -708,7 +711,7 @@ static void insert_style_before(unsigned char type,
unsigned char style, gregorio_character *current_character)
{
gregorio_character *element =
- (gregorio_character *) malloc(sizeof(gregorio_character));
+ (gregorio_character *) gregorio_malloc(sizeof(gregorio_character));
element->is_character = 0;
element->cos.s.type = type;
element->cos.s.style = style;
@@ -732,7 +735,7 @@ static void insert_style_after(unsigned char type, unsigned char style,
gregorio_character **current_character)
{
gregorio_character *element =
- (gregorio_character *) malloc(sizeof(gregorio_character));
+ (gregorio_character *) gregorio_malloc(sizeof(gregorio_character));
element->is_character = 0;
element->cos.s.type = type;
element->cos.s.style = style;
@@ -750,7 +753,7 @@ static void insert_char_after(grewchar c,
gregorio_character **current_character)
{
gregorio_character *element =
- (gregorio_character *) malloc(sizeof(gregorio_character));
+ (gregorio_character *) gregorio_malloc(sizeof(gregorio_character));
element->is_character = 1;
element->cos.character = c;
element->next_character = (*current_character)->next_character;
@@ -971,7 +974,7 @@ static __inline bool _suppress_char_and_end_c(
* in the middle of a verbatim block.
*/
-void gregorio_rebuild_characters(gregorio_character **param_character,
+void gregorio_rebuild_characters(gregorio_character **const param_character,
gregorio_center_determination center_is_determined, bool skip_initial)
{
/* the current_character */
@@ -987,9 +990,9 @@ void gregorio_rebuild_characters(gregorio_character **param_character,
if (!current_character->next_character) {
/* nothing else to rebuild, but the initial needs to be ST_CENTER */
insert_style_after(ST_T_END, ST_CENTER, ¤t_character);
- gregorio_go_to_first_character(¤t_character);
+ gregorio_go_to_first_character_c(¤t_character);
insert_style_before(ST_T_BEGIN, ST_CENTER, current_character);
- gregorio_go_to_first_character(¤t_character);
+ gregorio_go_to_first_character_c(¤t_character);
(*param_character) = current_character;
return;
}
@@ -997,7 +1000,7 @@ void gregorio_rebuild_characters(gregorio_character **param_character,
/* move to the character after the initial */
current_character = current_character->next_character;
} else {
- gregorio_go_to_first_character(¤t_character);
+ gregorio_go_to_first_character_c(¤t_character);
}
}
/* first we see if there is already a center determined */
@@ -1178,12 +1181,12 @@ void gregorio_rebuild_characters(gregorio_character **param_character,
if (skip_initial && go_to_end_initial(¤t_character)) {
current_character = current_character->next_character;
} else {
- gregorio_go_to_first_character(¤t_character);
+ gregorio_go_to_first_character_c(¤t_character);
}
insert_style_before(ST_T_BEGIN, ST_CENTER, current_character);
}
/* well.. you're quite brave if you reach this comment. */
- gregorio_go_to_first_character(¤t_character);
+ gregorio_go_to_first_character_c(¤t_character);
(*param_character) = current_character;
free_styles(&first_style);
}
@@ -1212,7 +1215,7 @@ void gregorio_rebuild_first_syllable(gregorio_character **param_character,
gregorio_character *first_character;
gregorio_character *start_of_special;
/* so, here we start: we go to the first_character */
- gregorio_go_to_first_character(¤t_character);
+ gregorio_go_to_first_character_c(¤t_character);
/* first we look at the styles, to see if there is a FORCED_CENTER
* somewhere and we also remove the CENTER styles if the syllable starts at
* CENTER */
@@ -1240,7 +1243,7 @@ void gregorio_rebuild_first_syllable(gregorio_character **param_character,
current_character = current_character->next_character;
}
current_character = *param_character;
- gregorio_go_to_first_character(¤t_character);
+ gregorio_go_to_first_character_c(¤t_character);
first_character = current_character;
/* now we are going to place the two INITIAL styles (begin and end) */
while (current_character) {
@@ -1316,7 +1319,7 @@ void gregorio_rebuild_first_syllable(gregorio_character **param_character,
current_character = current_character->next_character;
}
} else {
- gregorio_go_to_first_character(¤t_character);
+ gregorio_go_to_first_character_c(¤t_character);
}
if (current_character) {
bool marked_syllable_initial = false;
@@ -1363,7 +1366,7 @@ void gregorio_rebuild_first_syllable(gregorio_character **param_character,
}
current_character = *param_character;
- gregorio_go_to_first_character(¤t_character);
+ gregorio_go_to_first_character_c(¤t_character);
(*param_character) = current_character;
}
@@ -1398,6 +1401,6 @@ void gregorio_set_first_word(gregorio_character **const character)
/* else there are no more characters here */
if (*character) {
- gregorio_go_to_first_character(character);
+ gregorio_go_to_first_character_c(character);
}
}
diff --git a/src/characters.h b/src/characters.h
index 94bec9c2d..06486dadc 100644
--- a/src/characters.h
+++ b/src/characters.h
@@ -1,4 +1,7 @@
/*
+ * Gregorio is a program that translates gabc files to GregorioTeX
+ * This header prototypes the lyric handling data structures and entry points.
+ *
* Copyright (C) 2008-2015 The Gregorio Project (see CONTRIBUTORS.md)
*
* This file is part of Gregorio.
@@ -54,23 +57,28 @@ typedef struct det_style {
gregorio_character *gregorio_first_text(gregorio_score *score);
-void gregorio_write_text(bool skip_initial,
- gregorio_character *current_character,
- FILE *f, void (*printverb) (FILE *, grewchar *),
+typedef enum gregorio_write_text_phase {
+ WTP_NORMAL,
+ WTP_FIRST_SYLLABLE
+} gregorio_write_text_phase;
+
+void gregorio_write_text(gregorio_write_text_phase phase,
+ const gregorio_character *current_character, FILE *f,
+ void (*printverb) (FILE *, grewchar *),
void (*printchar) (FILE *, grewchar),
void (*begin) (FILE *, grestyle_style),
void (*end) (FILE *, grestyle_style),
void (*printspchar) (FILE *, grewchar *));
-void gregorio_write_first_letter_alignment_text(bool skip_initial,
- gregorio_character *current_character,
- FILE *f, void (*printverb) (FILE *, grewchar *),
+void gregorio_write_first_letter_alignment_text(gregorio_write_text_phase phase,
+ const gregorio_character *current_character, FILE *f,
+ void (*printverb) (FILE *, grewchar *),
void (*printchar) (FILE *, grewchar),
void (*begin) (FILE *, grestyle_style),
void (*end) (FILE *, grestyle_style),
void (*printspchar) (FILE *, grewchar *));
-void gregorio_write_initial(gregorio_character *current_character,
+void gregorio_write_initial(const gregorio_character *current_character,
FILE *f, void (*printverb) (FILE *, grewchar *),
void (*printchar) (FILE *, grewchar),
void (*begin) (FILE *, grestyle_style),
diff --git a/src/config.h b/src/config.h
index 04f8734cb..9519115cb 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,4 +1,7 @@
/*
+ * Gregorio is a program that translates gabc files to GregorioTeX
+ * This header wraps the generated config_.h to provide version macros.
+ *
* Gregorio configuration headers.
*
* Copyright (C) 2015 The Gregorio Project (see CONTRIBUTORS.md)
diff --git a/src/dump/dump.c b/src/dump/dump.c
index a92a9d32c..db3b4a994 100644
--- a/src/dump/dump.c
+++ b/src/dump/dump.c
@@ -1,4 +1,7 @@
/*
+ * Gregorio is a program that translates gabc files to GregorioTeX.
+ * This file provides functions to dump out Gregorio structures.
+ *
* Copyright (C) 2007-2015 The Gregorio Project (see CONTRIBUTORS.md)
*
* This file is part of Gregorio.
@@ -27,78 +30,15 @@
#include "plugins.h"
#include "support.h"
-static const char *unknown(int value) {
- static char buf[20];
- gregorio_snprintf(buf, 20, "?%d", value);
- return buf;
-}
-
-static const char *dump_translation_type_to_string(gregorio_tr_centering
- translation_type)
-{
- switch (translation_type) {
- case TR_NORMAL:
- return "TR_NORMAL";
- case TR_WITH_CENTER_BEGINNING:
- return "TR_WITH_CENTER_BEGINNING";
- case TR_WITH_CENTER_END:
- return "TR_WITH_CENTER_END";
- }
- return unknown(translation_type);
-}
-
-static const char *dump_nlba_to_string(gregorio_nlba no_linebreak_area)
-{
- switch (no_linebreak_area) {
- case NLBA_NORMAL:
- return "NLBA_NORMAL";
- case NLBA_BEGINNING:
- return "NLBA_BEGINNING";
- case NLBA_END:
- return "NLBA_END";
- }
- return unknown(no_linebreak_area);
-}
-
static const char *dump_style_to_string(grestyle_style style)
{
- switch (style) {
- case ST_NO_STYLE:
- return " ST_NO_STYLE";
- case ST_ITALIC:
- return " ST_ITALIC";
- case ST_CENTER:
- return " ST_CENTER";
- case ST_FORCED_CENTER:
- return " ST_FORCED_CENTER";
- case ST_INITIAL:
- return " ST_INITIAL";
- case ST_BOLD:
- return " ST_BOLD";
- case ST_TT:
- return " ST_TT";
- case ST_UNDERLINED:
- return " ST_UNDERLINED";
- case ST_COLORED:
- return " ST_COLORED";
- case ST_SMALL_CAPS:
- return " ST_SMALL_CAPS";
- case ST_SPECIAL_CHAR:
- return " ST_SPECIAL_CHAR";
- case ST_VERBATIM:
- return " ST_VERBATIM";
- case ST_FIRST_WORD:
- return " ST_FIRST_WORD";
- case ST_FIRST_SYLLABLE:
- return "ST_FIRST_SYLLABLE";
- case ST_FIRST_SYLLABLE_INITIAL:
- return "ST_FIRST_SYLLABLE_INITIAL";
- default:
- return unknown(style);
- }
+ static char buf[50];
+
+ gregorio_snprintf(buf, sizeof buf, "%16s", grestyle_style_to_string(style));
+ return buf;
}
-static void dump_write_characters(FILE *const f,
+void dump_write_characters(FILE *const f,
const gregorio_character * current_character)
{
while (current_character) {
@@ -144,372 +84,10 @@ static const char *dump_key_to_char(const int key)
return "no key defined";
}
-static const char *dump_syllable_position(gregorio_word_position pos)
-{
- switch (pos) {
- case WORD_BEGINNING:
- return "WORD_BEGINNING";
- case WORD_MIDDLE:
- return "WORD_MIDDLE";
- case WORD_END:
- return "WORD_END";
- case WORD_ONE_SYLLABLE:
- return "WORD_ONE_SYLLABLE";
- }
- return "unknown";
-}
-
-static const char *dump_type(gregorio_type type)
-{
- switch (type) {
- case GRE_NOTE:
- return "GRE_NOTE";
- case GRE_GLYPH:
- return "GRE_GLYPH";
- case GRE_ELEMENT:
- return "GRE_ELEMENT";
- case GRE_FLAT:
- return "GRE_FLAT";
- case GRE_SHARP:
- return "GRE_SHARP";
- case GRE_NATURAL:
- return "GRE_NATURAL";
- case GRE_C_KEY_CHANGE:
- return "GRE_C_KEY_CHANGE";
- case GRE_F_KEY_CHANGE:
- return "GRE_F_KEY_CHANGE";
- case GRE_END_OF_LINE:
- return "GRE_END_OF_LINE";
- case GRE_END_OF_PAR:
- return "GRE_END_OF_PAR";
- case GRE_CUSTOS:
- return "GRE_CUSTOS";
- case GRE_SPACE:
- return "GRE_SPACE";
- case GRE_BAR:
- return "GRE_BAR";
- case GRE_SYLLABLE:
- return "GRE_SYLLABLE";
- case GRE_TEXVERB_GLYPH:
- return "GRE_TEXVERB_GLYPH";
- case GRE_TEXVERB_ELEMENT:
- return "GRE_TEXVERB_ELEMENT";
- case GRE_NLBA:
- return "GRE_NLBA";
- case GRE_ALT:
- return "GRE_ALT";
- case GRE_MANUAL_CUSTOS:
- return "GRE_MANUAL_CUSTOS";
- default:
- return "unknown";
- }
-}
-
-static const char *dump_bar_type(gregorio_bar element_type)
-{
- switch (element_type) {
- case B_NO_BAR:
- return "B_NO_BAR";
- case B_VIRGULA:
- return "B_VIRGULA";
- case B_DIVISIO_MINIMA:
- return "B_DIVISIO_MINIMA";
- case B_DIVISIO_MINOR:
- return "B_DIVISIO_MINOR";
- case B_DIVISIO_MAIOR:
- return "B_DIVISIO_MAIOR";
- case B_DIVISIO_FINALIS:
- return "B_DIVISIO_FINALIS";
- case B_DIVISIO_MINOR_D1:
- return "B_DIVISIO_MINOR_D1";
- case B_DIVISIO_MINOR_D2:
- return "B_DIVISIO_MINOR_D2";
- case B_DIVISIO_MINOR_D3:
- return "B_DIVISIO_MINOR_D3";
- case B_DIVISIO_MINOR_D4:
- return "B_DIVISIO_MINOR_D4";
- case B_DIVISIO_MINOR_D5:
- return "B_DIVISIO_MINOR_D5";
- case B_DIVISIO_MINOR_D6:
- return "B_DIVISIO_MINOR_D6";
- }
- return "unknown";
-}
-
-static const char *dump_space_type(gregorio_space element_type)
-{
- switch (element_type) {
- case SP_DEFAULT:
- return "SP_DEFAULT";
- case SP_NO_SPACE:
- return "SP_NO_SPACE";
- case SP_ZERO_WIDTH:
- return "SP_ZERO_WIDTH";
- case SP_NEUMATIC_CUT:
- return "SP_NEUMATIC_CUT";
- case SP_LARGER_SPACE:
- return "SP_LARGER_SPACE";
- case SP_GLYPH_SPACE:
- return "SP_GLYPH_SPACE";
- case SP_GLYPH_SPACE_NB:
- return "SP_GLYPH_SPACE_NB";
- case SP_LARGER_SPACE_NB:
- return "SP_LARGER_SPACE_NB";
- case SP_NEUMATIC_CUT_NB:
- return "SP_NEUMATIC_CUT_NB";
- }
- return "unknown";
-}
-
-static const char *dump_liquescentia(gregorio_liquescentia liquescentia)
-{
- switch (liquescentia) {
- case L_NO_LIQUESCENTIA:
- return "L_NO_LIQUESCENTIA";
- case L_DEMINUTUS:
- return "L_DEMINUTUS";
- case L_AUCTUS_ASCENDENS:
- return "L_AUCTUS_ASCENDENS";
- case L_AUCTUS_DESCENDENS:
- return "L_AUCTUS_DESCENDENS";
- case L_AUCTA:
- return "L_AUCTA";
- case L_INITIO_DEBILIS:
- return "L_INITIO_DEBILIS";
- case L_DEMINUTUS_INITIO_DEBILIS:
- return "L_DEMINUTUS_INITIO_DEBILIS";
- case L_AUCTUS_ASCENDENS_INITIO_DEBILIS:
- return "L_AUCTUS_ASCENDENS_INITIO_DEBILIS";
- case L_AUCTUS_DESCENDENS_INITIO_DEBILIS:
- return "L_AUCTUS_DESCENDENS_INITIO_DEBILIS";
- case L_AUCTA_INITIO_DEBILIS:
- return "L_AUCTA_INITIO_DEBILIS";
- }
- return "unknown";
-}
-
-static const char *dump_glyph_type(gregorio_glyph_type glyph_type)
-{
- switch (glyph_type) {
- case G_PUNCTUM_INCLINATUM:
- return "G_PUNCTUM_INCLINATUM";
- case G_2_PUNCTA_INCLINATA_DESCENDENS:
- return "G_2_PUNCTA_INCLINATA_DESCENDENS";
- case G_3_PUNCTA_INCLINATA_DESCENDENS:
- return "G_3_PUNCTA_INCLINATA_DESCENDENS";
- case G_4_PUNCTA_INCLINATA_DESCENDENS:
- return "G_4_PUNCTA_INCLINATA_DESCENDENS";
- case G_5_PUNCTA_INCLINATA_DESCENDENS:
- return "G_5_PUNCTA_INCLINATA_DESCENDENS";
- case G_2_PUNCTA_INCLINATA_ASCENDENS:
- return "G_2_PUNCTA_INCLINATA_ASCENDENS";
- case G_3_PUNCTA_INCLINATA_ASCENDENS:
- return "G_3_PUNCTA_INCLINATA_ASCENDENS";
- case G_4_PUNCTA_INCLINATA_ASCENDENS:
- return "G_4_PUNCTA_INCLINATA_ASCENDENS";
- case G_5_PUNCTA_INCLINATA_ASCENDENS:
- return "G_5_PUNCTA_INCLINATA_ASCENDENS";
- case G_TRIGONUS:
- return "G_TRIGONUS";
- case G_PUNCTA_INCLINATA:
- return "G_PUNCTA_INCLINATA";
- case G_UNDETERMINED:
- return "G_UNDETERMINED";
- case G_VIRGA:
- return "G_VIRGA";
- case G_VIRGA_REVERSA:
- return "G_VIRGA_REVERSA";
- case G_STROPHA:
- return "G_STROPHA";
- case G_STROPHA_AUCTA:
- return "G_STROPHA_AUCTA";
- case G_PUNCTUM:
- return "G_PUNCTUM";
- case G_PODATUS:
- return "G_PODATUS";
- case G_PES_QUADRATUM:
- return "G_PES_QUADRATUM";
- case G_FLEXA:
- return "G_FLEXA";
- case G_TORCULUS:
- return "G_TORCULUS";
- case G_TORCULUS_RESUPINUS:
- return "G_TORCULUS_RESUPINUS";
- case G_TORCULUS_RESUPINUS_FLEXUS:
- return "G_TORCULUS_RESUPINUS_FLEXUS";
- case G_PORRECTUS:
- return "G_PORRECTUS";
- case G_PORRECTUS_FLEXUS:
- return "G_PORRECTUS_FLEXUS";
- case G_BIVIRGA:
- return "G_BIVIRGA";
- case G_TRIVIRGA:
- return "G_TRIVIRGA";
- case G_DISTROPHA:
- return "G_DISTROPHA";
- case G_DISTROPHA_AUCTA:
- return "G_DISTROPHA_AUCTA";
- case G_TRISTROPHA:
- return "G_TRISTROPHA";
- case G_ANCUS:
- return "G_ANCUS";
- case G_TRISTROPHA_AUCTA:
- return "G_TRISTROPHA_AUCTA";
- case G_PES_QUADRATUM_FIRST_PART:
- return "G_PES_QUADRATUM_FIRST_PART";
- case G_SCANDICUS:
- return "G_SCANDICUS";
- case G_SALICUS:
- return "G_SALICUS";
- case G_VIRGA_STRATA:
- return "G_VIRGA_STRATA";
- case G_TORCULUS_LIQUESCENS:
- return "G_TORCULUS_LIQUESCENS";
- default:
- return "unknown";
- }
-}
-
-static const char *dump_shape(gregorio_shape shape)
-{
- switch (shape) {
- case S_UNDETERMINED:
- return "S_UNDETERMINED";
- case S_PUNCTUM:
- return "S_PUNCTUM";
- case S_PUNCTUM_END_OF_GLYPH:
- return "S_PUNCTUM_END_OF_GLYPH";
- case S_PUNCTUM_INCLINATUM:
- return "S_PUNCTUM_INCLINATUM";
- case S_PUNCTUM_INCLINATUM_DEMINUTUS:
- return "S_PUNCTUM_INCLINATUM_DEMINUTUS";
- case S_PUNCTUM_INCLINATUM_AUCTUS:
- return "S_PUNCTUM_INCLINATUM_AUCTUS";
- case S_VIRGA:
- return "S_VIRGA";
- case S_VIRGA_REVERSA:
- return "S_VIRGA_REVERSA";
- case S_BIVIRGA:
- return "S_BIVIRGA";
- case S_TRIVIRGA:
- return "S_TRIVIRGA";
- case S_ORISCUS:
- return "S_ORISCUS";
- case S_ORISCUS_AUCTUS:
- return "S_ORISCUS_AUCTUS";
- case S_ORISCUS_DEMINUTUS:
- return "S_ORISCUS_DEMINUTUS";
- case S_ORISCUS_SCAPUS:
- return "S_ORISCUS_SCAPUS";
- case S_QUILISMA:
- return "S_QUILISMA";
- case S_STROPHA:
- return "S_STROPHA";
- case S_STROPHA_AUCTA:
- return "S_STROPHA_AUCTA";
- case S_DISTROPHA:
- return "S_DISTROPHA";
- case S_DISTROPHA_AUCTA:
- return "S_DISTROPHA_AUCTA";
- case S_TRISTROPHA:
- return "S_TRISTROPHA";
- case S_TRISTROPHA_AUCTA:
- return "S_TRISTROPHA_AUCTA";
- case S_QUADRATUM:
- return "S_QUADRATUM";
- case S_PUNCTUM_CAVUM:
- return "S_PUNCTUM_CAVUM";
- case S_LINEA_PUNCTUM:
- return "S_LINEA_PUNCTUM";
- case S_LINEA_PUNCTUM_CAVUM:
- return "S_LINEA_PUNCTUM_CAVUM";
- case S_LINEA:
- return "S_LINEA";
- case S_PUNCTUM_CAVUM_INCLINATUM:
- return "S_PUNCTUM_CAVUM_INCLINATUM";
- case S_PUNCTUM_CAVUM_INCLINATUM_AUCTUS:
- return "S_PUNCTUM_CAVUM_INCLINATUM_AUCTUS";
- default:
- return "unknown";
- }
-}
-
-static const char *dump_signs(gregorio_sign signs)
-{
- switch (signs) {
- case _NO_SIGN:
- return "_NO_SIGN";
- case _PUNCTUM_MORA:
- return "_PUNCTUM_MORA";
- case _AUCTUM_DUPLEX:
- return "_AUCTUM_DUPLEX";
- case _V_EPISEMA:
- return "_V_EPISEMA";
- case _V_EPISEMA_PUNCTUM_MORA:
- return "_V_EPISEMA_PUNCTUM_MORA";
- case _V_EPISEMA_AUCTUM_DUPLEX:
- return "_V_EPISEMA_AUCTUM_DUPLEX";
- default:
- return "unknown";
- }
-}
-
-/* a function dumping special signs */
-static const char *dump_special_sign(gregorio_sign special_sign)
-{
- switch (special_sign) {
- case _ACCENTUS:
- return "_ACCENTUS";
- case _ACCENTUS_REVERSUS:
- return "_ACCENTUS_REVERSUS";
- case _CIRCULUS:
- return "_CIRCULUS";
- case _SEMI_CIRCULUS:
- return "_SEMI_CIRCULUS";
- case _SEMI_CIRCULUS_REVERSUS:
- return "_SEMI_CIRCULUS_REVERSUS";
- case _V_EPISEMA:
- return "_V_EPISEMA";
- case _V_EPISEMA_BAR_H_EPISEMA:
- return "_V_EPISEMA_BAR_H_EPISEMA";
- case _BAR_H_EPISEMA:
- return "_BAR_H_EPISEMA";
- default:
- return "unknown";
- }
-}
-
-static const char *dump_h_episema_size(grehepisema_size size)
-{
- switch (size) {
- case H_NORMAL:
- return "H_NORMAL";
- case H_SMALL_LEFT:
- return "H_SMALL_LEFT";
- case H_SMALL_CENTRE:
- return "H_SMALL_CENTRE";
- case H_SMALL_RIGHT:
- return "H_SMALL_RIGHT";
- }
- return "unknown";
-}
-
static const char *dump_bool(bool value) {
return value? "true" : "false";
}
-static const char *dump_vposition(gregorio_vposition vpos) {
- switch (vpos) {
- case VPOS_AUTO:
- return "VPOS_AUTO";
- case VPOS_ABOVE:
- return "VPOS_ABOVE";
- case VPOS_BELOW:
- return "VPOS_BELOW";
- }
- return "unknown";
-}
-
static const char *dump_pitch(const char height) {
static char buf[20];
if (height >= LOWEST_PITCH && height <= HIGHEST_PITCH) {
@@ -564,6 +142,9 @@ void dump_write_score(FILE *f, gregorio_score *score)
if (score->arranger) {
fprintf(f, " arranger %s\n", score->arranger);
}
+ if (score->language) {
+ fprintf(f, " language %s\n", score->language);
+ }
if (score->si.author) {
fprintf(f, " author %s\n", score->si.author);
}
@@ -591,16 +172,9 @@ void dump_write_score(FILE *f, gregorio_score *score)
fprintf(f, " transcription_date %s\n",
score->si.transcription_date);
}
- if (score->gregoriotex_font) {
- fprintf(f, " gregoriotex_font %s\n",
- score->gregoriotex_font);
- }
if (score->mode) {
fprintf(f, " mode %d\n", score->mode);
}
- if (score->initial_style) {
- fprintf(f, " initial_style %d\n", score->initial_style);
- }
if (score->nabc_lines) {
fprintf (f, " nabc_lines %d\n", (int)score->nabc_lines);
}
@@ -646,20 +220,20 @@ void dump_write_score(FILE *f, gregorio_score *score)
gregorio_element *element;
if (syllable->type) {
fprintf(f, " type %d (%s)\n",
- syllable->type, dump_type(syllable->type));
+ syllable->type, gregorio_type_to_string(syllable->type));
}
if (syllable->position) {
fprintf(f, " position %d (%s)\n",
syllable->position,
- dump_syllable_position(syllable->position));
+ gregorio_word_position_to_string(syllable->position));
}
if (syllable->special_sign) {
fprintf(f, " special sign %s\n",
- dump_special_sign(syllable->special_sign));
+ gregorio_sign_to_string(syllable->special_sign));
}
if (syllable->no_linebreak_area != NLBA_NORMAL) {
fprintf(f, " no line break area %s\n",
- dump_nlba_to_string(syllable->no_linebreak_area));
+ gregorio_nlba_to_string(syllable->no_linebreak_area));
}
if (syllable->text) {
if (syllable->translation) {
@@ -671,7 +245,7 @@ void dump_write_score(FILE *f, gregorio_score *score)
&& syllable->translation_type != TR_WITH_CENTER_END)
|| syllable->translation_type == TR_WITH_CENTER_END) {
fprintf(f, "\n Translation type %s",
- dump_translation_type_to_string
+ gregorio_tr_centering_to_string
(syllable->translation_type));
if (syllable->translation_type == TR_WITH_CENTER_END) {
fprintf(f, "\n");
@@ -689,7 +263,7 @@ void dump_write_score(FILE *f, gregorio_score *score)
fprintf(f, "---------------------------------------------------------------------\n");
if (element->type) {
fprintf(f, " type %d (%s)\n",
- element->type, dump_type(element->type));
+ element->type, gregorio_type_to_string(element->type));
}
switch (element->type) {
case GRE_CUSTOS:
@@ -705,8 +279,8 @@ void dump_write_score(FILE *f, gregorio_score *score)
if (element->u.misc.unpitched.info.space) {
fprintf(f, " space %d (%s)\n",
element->u.misc.unpitched.info.space,
- dump_space_type(element->u.misc.unpitched.info.
- space));
+ gregorio_space_to_string(element->u.misc.unpitched.
+ info.space));
}
break;
case GRE_TEXVERB_ELEMENT:
@@ -716,7 +290,7 @@ void dump_write_score(FILE *f, gregorio_score *score)
case GRE_NLBA:
fprintf(f, " nlba %d (%s)\n",
element->u.misc.unpitched.info.nlba,
- dump_nlba_to_string(element->u.misc.unpitched.info.
+ gregorio_nlba_to_string(element->u.misc.unpitched.info.
nlba));
break;
case GRE_ALT:
@@ -727,12 +301,13 @@ void dump_write_score(FILE *f, gregorio_score *score)
if (element->u.misc.unpitched.info.bar) {
fprintf(f, " bar %d (%s)\n",
element->u.misc.unpitched.info.bar,
- dump_bar_type(element->u.misc.unpitched.info.bar));
+ gregorio_bar_to_string(element->u.misc.unpitched.
+ info.bar));
if (element->u.misc.unpitched.special_sign) {
fprintf(f, " special sign %d (%s)\n",
element->u.misc.unpitched.special_sign,
- dump_special_sign(element->u.misc.unpitched.
- special_sign));
+ gregorio_sign_to_string(element->
+ u.misc.unpitched.special_sign));
}
}
break;
@@ -760,7 +335,8 @@ void dump_write_score(FILE *f, gregorio_score *score)
if (element->u.misc.unpitched.info.sub_type) {
fprintf(f, " sub_type %d (%s)\n",
element->u.misc.unpitched.info.sub_type,
- dump_type(element->u.misc.unpitched.info.sub_type));
+ gregorio_type_to_string(element->u.misc.unpitched.
+ info.sub_type));
}
break;
case GRE_ELEMENT:
@@ -770,7 +346,8 @@ void dump_write_score(FILE *f, gregorio_score *score)
fprintf(f, "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
if (glyph->type) {
fprintf(f, " type %d (%s)\n",
- glyph->type, dump_type(glyph->type));
+ glyph->type, gregorio_type_to_string(glyph->
+ type));
}
switch (glyph->type) {
case GRE_TEXVERB_GLYPH:
@@ -781,20 +358,20 @@ void dump_write_score(FILE *f, gregorio_score *score)
case GRE_SPACE:
fprintf(f, " space %d (%s)\n",
glyph->u.misc.unpitched.info.space,
- dump_space_type(glyph->u.misc.unpitched.info.
- space));
+ gregorio_space_to_string(glyph->u.misc.
+ unpitched.info.space));
break;
case GRE_BAR:
fprintf(f, " glyph_type %d (%s)\n",
glyph->u.misc.unpitched.info.bar,
- dump_bar_type(glyph->u.misc.unpitched.info.
- bar));
+ gregorio_bar_to_string(glyph->u.misc.unpitched.
+ info.bar));
if (glyph->u.misc.unpitched.special_sign) {
fprintf(f, " special sign %d (%s)\n",
glyph->u.misc.unpitched.special_sign,
- dump_special_sign(glyph->u.misc.unpitched.
- special_sign));
+ gregorio_sign_to_string(glyph->
+ u.misc.unpitched.special_sign));
}
break;
@@ -808,12 +385,13 @@ void dump_write_score(FILE *f, gregorio_score *score)
case GRE_GLYPH:
fprintf(f, " glyph_type %d (%s)\n",
glyph->u.notes.glyph_type,
- dump_glyph_type(glyph->u.notes.glyph_type));
+ gregorio_glyph_type_to_string(glyph->u.notes.
+ glyph_type));
if (glyph->u.notes.liquescentia) {
fprintf(f, " liquescentia %d (%s)\n",
glyph->u.notes.liquescentia,
- dump_liquescentia(glyph->u.notes.
- liquescentia));
+ gregorio_liquescentia_to_string(
+ glyph->u.notes.liquescentia));
}
break;
@@ -827,7 +405,8 @@ void dump_write_score(FILE *f, gregorio_score *score)
fprintf(f, "- - - - - - - - - - - - - - - - - - - - - - - \n");
if (note->type) {
fprintf(f, " type %d (%s)\n",
- note->type, dump_type(note->type));
+ note->type,
+ gregorio_type_to_string(note->type));
}
switch (note->type) {
case GRE_NOTE:
@@ -838,13 +417,14 @@ void dump_write_score(FILE *f, gregorio_score *score)
if (note->u.note.shape) {
fprintf(f, " shape %d (%s)\n",
note->u.note.shape,
- dump_shape(note->u.note.shape));
+ gregorio_shape_to_string(
+ note->u.note.shape));
}
if (note->u.note.liquescentia) {
fprintf(f, " liquescentia %d (%s)\n",
note->u.note.liquescentia,
- dump_liquescentia(note->u.note.
- liquescentia));
+ gregorio_liquescentia_to_string(
+ note->u.note.liquescentia));
}
break;
@@ -862,7 +442,8 @@ void dump_write_score(FILE *f, gregorio_score *score)
}
if (note->signs) {
fprintf(f, " signs %d (%s)\n",
- note->signs, dump_signs(note->signs));
+ note->signs,
+ gregorio_sign_to_string(note->signs));
}
if (note->signs & _V_EPISEMA && note->v_episema_height) {
if (note->v_episema_height < note->u.note.pitch) {
@@ -876,18 +457,21 @@ void dump_write_score(FILE *f, gregorio_score *score)
|| note->signs == _V_EPISEMA_PUNCTUM_MORA)
&& note->mora_vposition) {
fprintf(f, " mora vposition %s\n",
- dump_vposition(note->mora_vposition));
+ gregorio_vposition_to_string(note->
+ mora_vposition));
}
if (note->special_sign) {
fprintf(f, " special sign %d (%s)\n",
note->special_sign,
- dump_special_sign(note->special_sign));
+ gregorio_sign_to_string(
+ note->special_sign));
}
if (note->h_episema_above == HEPISEMA_AUTO
&& note->h_episema_below == HEPISEMA_AUTO) {
fprintf(f, " auto hepisema size %d (%s)\n",
note->h_episema_above_size,
- dump_h_episema_size(note->h_episema_above_size));
+ grehepisema_size_to_string(note->
+ h_episema_above_size));
fprintf(f, " auto hepisema bridge %s\n",
dump_bool(note->h_episema_above_connect));
}
@@ -895,14 +479,16 @@ void dump_write_score(FILE *f, gregorio_score *score)
if (note->h_episema_above == HEPISEMA_FORCED) {
fprintf(f, " above hepisema size %d (%s)\n",
note->h_episema_above_size,
- dump_h_episema_size(note->h_episema_above_size));
+ grehepisema_size_to_string(note->
+ h_episema_above_size));
fprintf(f, " above hepisema bridge %s\n",
dump_bool(note->h_episema_above_connect));
}
if (note->h_episema_below == HEPISEMA_FORCED) {
fprintf(f, " below hepisema size %d (%s)\n",
note->h_episema_below_size,
- dump_h_episema_size(note->h_episema_below_size));
+ grehepisema_size_to_string(note->
+ h_episema_below_size));
fprintf(f, " below hepisema bridge %s\n",
dump_bool(note->h_episema_below_connect));
}
diff --git a/src/enum_generator.h b/src/enum_generator.h
new file mode 100644
index 000000000..e6c6ae104
--- /dev/null
+++ b/src/enum_generator.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2006-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 .
+ */
+
+/* These macros are used for generating enum code. This is based on the
+ * technique described in http://stackoverflow.com/a/202511
+ *
+ * Two of these macros are meant for use outside this set of macros:
+ *
+ * - ENUM declares the enum itself and a prototype for the function that
+ * returns the string value of the enum's numeric value. This is meant to be
+ * used from a header file.
+ * - ENUM_TO_STRING defines the function whose prototype was declared by ENUM.
+ * This is meant to be used from a code file.
+ *
+ * These two macros both take the following two arguments:
+ *
+ * - TYPE is the name to use for the enum.
+ * - DEF is the name of a macro that generates the bodies of the enum and the
+ * to-string function. DEF should take four arguments, in the following
+ * order (with suggested names):
+ * - A is a macro that generates an enum value with a specifiec numeric
+ * value. It takes two arguments, the name and the numeric value.
+ * - E is a macro that generates an enum value that has no specific numeric
+ * value. It takes one argument, the name.
+ * - X is a macro that generates the last enum value when it has a specific
+ * numeric value. It takes the same two arguments as A.
+ * - L is a macro that generates the last enum value when it has no specific
+ * numeric value. It takes the same argument as E.
+ *
+ * Note: If we were supporting C11, we could take empty macro arguments and
+ * would be able to get away with only two arguments to DEF.
+ */
+
+#ifndef ENUM_GENERATOR_H
+#define ENUM_GENERATOR_H
+
+/* for enum values */
+#define ENUM_VALUE(NAME,VALUE) NAME = VALUE,
+#define ENUM_ENTRY(NAME) NAME,
+#define ENUM_LAST_VALUE(NAME,VALUE) NAME = VALUE
+#define ENUM_LAST_ENTRY(NAME) NAME
+
+/* for enum case */
+#define ENUM_VALUE_CASE(NAME,VALUE) case NAME: return #NAME;
+#define ENUM_ENTRY_CASE(NAME) case NAME: return #NAME;
+
+/* enum declaration */
+#define ENUM(TYPE,DEF) \
+ typedef enum TYPE { \
+ DEF(ENUM_VALUE, ENUM_ENTRY, ENUM_LAST_VALUE, ENUM_LAST_ENTRY) \
+ } TYPE; \
+ const char *TYPE##_to_string(TYPE value)
+
+/* enum *_to_string function defintiion */
+#define ENUM_TO_STRING(TYPE,DEF) \
+ const char *TYPE##_to_string(TYPE value) \
+ { \
+ switch(value) { \
+ DEF(ENUM_VALUE_CASE, ENUM_ENTRY_CASE, ENUM_VALUE_CASE, ENUM_ENTRY_CASE) \
+ default: return gregorio_unknown(value); \
+ } \
+ }
+
+#endif
diff --git a/src/gabc/gabc-elements-determination.c b/src/gabc/gabc-elements-determination.c
index eefdc86e4..3991760f8 100644
--- a/src/gabc/gabc-elements-determination.c
+++ b/src/gabc/gabc-elements-determination.c
@@ -1,4 +1,7 @@
/*
+ * Gregorio is a program that translates gabc files to GregorioTeX.
+ * This file provides functions for determining elements from notes.
+ *
* Copyright (C) 2006-2015 The Gregorio Project (see CONTRIBUTORS.md)
*
* This file is part of Gregorio.
diff --git a/src/gabc/gabc-glyphs-determination.c b/src/gabc/gabc-glyphs-determination.c
index 016d03b09..f31790d38 100644
--- a/src/gabc/gabc-glyphs-determination.c
+++ b/src/gabc/gabc-glyphs-determination.c
@@ -1,4 +1,7 @@
/*
+ * Gregorio is a program that translates gabc files to GregorioTeX
+ * This file provides functions for determining glyphs from notes.
+ *
* Copyright (C) 2006-2015 The Gregorio Project (see CONTRIBUTORS.md)
*
* This file is part of Gregorio.
@@ -339,6 +342,14 @@ static char gregorio_add_note_to_a_glyph(gregorio_glyph_type current_glyph_type,
case G_VIRGA_STRATA:
if (current_pitch > last_pitch) {
next_glyph_type = G_SALICUS;
+ } else {
+ next_glyph_type = G_PUNCTUM;
+ *end_of_glyph = DET_END_OF_PREVIOUS;
+ }
+ break;
+ case G_SALICUS:
+ if (current_pitch < last_pitch) {
+ next_glyph_type = G_SALICUS_FLEXUS;
*end_of_glyph = DET_END_OF_CURRENT;
} else {
next_glyph_type = G_PUNCTUM;
diff --git a/src/gabc/gabc-notes-determination.l b/src/gabc/gabc-notes-determination.l
index 80c2310f2..f48875aea 100644
--- a/src/gabc/gabc-notes-determination.l
+++ b/src/gabc/gabc-notes-determination.l
@@ -1,5 +1,8 @@
%{
/*
+ * Gregorio is a program that translates gabc files to GregorioTeX
+ * This file implements the note parser.
+ *
* Copyright (C) 2006-2015 The Gregorio Project (see CONTRIBUTORS.md)
*
* This file is part of Gregorio.
@@ -211,7 +214,7 @@ static __inline void add_alteration(const gregorio_type type) {
"\\GreVarBraceSavePos{%d}{%d}{1}"
"\\GreOverBrace{\\GreVarBraceLength{%d}}{0pt}{0pt}{%d}",
overbrace_var, char_for_brace, overbrace_var, char_for_brace);
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
}
\[ub:[01]\{\] {
@@ -226,7 +229,7 @@ static __inline void add_alteration(const gregorio_type type) {
"\\GreVarBraceSavePos{%d}{%d}{1}"
"\\GreUnderBrace{\\GreVarBraceLength{%d}}{0pt}{0pt}{%d}",
underbrace_var, char_for_brace, underbrace_var, char_for_brace);
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
}
\[ocb:[01]\{\] {
@@ -242,7 +245,7 @@ static __inline void add_alteration(const gregorio_type type) {
"\\GreVarBraceSavePos{%d}{%d}{1}"
"\\GreOverCurlyBrace{\\GreVarBraceLength{%d}}{0pt}{0pt}{%d}{0}",
overbrace_var, char_for_brace, overbrace_var, char_for_brace);
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
}
\[ocba:[01]\{\] {
@@ -258,7 +261,7 @@ static __inline void add_alteration(const gregorio_type type) {
"\\GreVarBraceSavePos{%d}{%d}{1}"
"\\GreOverCurlyBrace{\\GreVarBraceLength{%d}}{0pt}{0pt}{%d}{1}",
overbrace_var, char_for_brace, overbrace_var, char_for_brace);
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
}
\[ob:[01]\}\] {
@@ -277,7 +280,7 @@ static __inline void add_alteration(const gregorio_type type) {
"\\GreVarBraceSavePos{%d}{%d}{2}", overbrace_var,
char_for_brace);
overbrace_var = 0;
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
}
\[ub:[01]\}\] {
@@ -291,7 +294,7 @@ static __inline void add_alteration(const gregorio_type type) {
"\\GreVarBraceSavePos{%d}{%d}{2}", underbrace_var,
char_for_brace);
underbrace_var = 0;
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
}
\[ocb:[01]\}\] {
@@ -310,7 +313,7 @@ static __inline void add_alteration(const gregorio_type type) {
"\\GreVarBraceSavePos{%d}{%d}{2}", overbrace_var,
char_for_brace);
overbrace_var = 0;
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
}
\[ocba:[01]\}\] {
@@ -329,33 +332,33 @@ static __inline void add_alteration(const gregorio_type type) {
"\\GreVarBraceSavePos{%d}{%d}{2}", overbrace_var,
char_for_brace);
overbrace_var = 0;
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
}
\[nm[1-9]\] {
if (notesmacros[gabc_notes_determination_text[3]-'0']) {
gregorio_add_texverb_to_note(¤t_note,
- strdup(notesmacros[gabc_notes_determination_text[3]-'0']));
+ gregorio_strdup(notesmacros[gabc_notes_determination_text[3]-'0']));
} else error();
}
\[gm[1-9]\] {
if (notesmacros[gabc_notes_determination_text[3]-'0']) {
gregorio_add_texverb_as_note(¤t_note,
- strdup(notesmacros[gabc_notes_determination_text[3]-'0']),
+ gregorio_strdup(notesmacros[gabc_notes_determination_text[3]-'0']),
GRE_TEXVERB_GLYPH, ¬es_lloc);
} else error();
}
\[em[1-9]\] {
if (notesmacros[gabc_notes_determination_text[3]-'0']) {
gregorio_add_texverb_as_note(¤t_note,
- strdup(notesmacros[gabc_notes_determination_text[3]-'0']),
+ gregorio_strdup(notesmacros[gabc_notes_determination_text[3]-'0']),
GRE_TEXVERB_ELEMENT, ¬es_lloc);
} else error();
}
\[altm[1-9]\] {
if (notesmacros[gabc_notes_determination_text[5]-'0']) {
gregorio_add_texverb_as_note(¤t_note,
- strdup(notesmacros[gabc_notes_determination_text[5]-'0']),
+ gregorio_strdup(notesmacros[gabc_notes_determination_text[5]-'0']),
GRE_TEXVERB_ELEMENT, ¬es_lloc);
} else error();
}
@@ -381,63 +384,65 @@ static __inline void add_alteration(const gregorio_type type) {
gregorio_snprintf(tempstr, sizeof tempstr,
"\\GreOverBrace{%s}{0pt}{0pt}{%d}",
gabc_notes_determination_text, char_for_brace);
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
[^\]]+ {
gregorio_snprintf(tempstr, sizeof tempstr,
"\\GreUnderBrace{%s}{0pt}{0pt}{%d}",
gabc_notes_determination_text, char_for_brace);
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
[^\]]+ {
gregorio_snprintf(tempstr, sizeof tempstr,
"\\GreOverCurlyBrace{%s}{0pt}{0pt}{%d}{0}",
gabc_notes_determination_text, char_for_brace);
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
[^\]]+ {
gregorio_snprintf(tempstr, sizeof tempstr,
"\\GreOverCurlyBrace{%s}{0pt}{0pt}{%d}{1}",
gabc_notes_determination_text, char_for_brace);
- gregorio_add_texverb_to_note(¤t_note, strdup(tempstr));
+ gregorio_add_texverb_to_note(¤t_note, gregorio_strdup(tempstr));
}
[^\]]+ {
gregorio_add_cs_to_note(¤t_note,
- strdup(gabc_notes_determination_text), false);
+ gregorio_strdup(gabc_notes_determination_text), false);
}
[^\]]+ {
gregorio_add_cs_to_note(¤t_note,
- strdup(gabc_notes_determination_text), true);
+ gregorio_strdup(gabc_notes_determination_text), true);
}
[^\]]+ {
gregorio_add_texverb_to_note(¤t_note,
- strdup(gabc_notes_determination_text));
+ gregorio_strdup(gabc_notes_determination_text));
}
[^\]]+ {
gregorio_add_texverb_as_note(¤t_note,
- strdup(gabc_notes_determination_text), GRE_TEXVERB_GLYPH,
- ¬es_lloc);
+ gregorio_strdup(gabc_notes_determination_text),
+ GRE_TEXVERB_GLYPH, ¬es_lloc);
}
[^\]]+ {
gregorio_add_texverb_as_note(¤t_note,
- strdup(gabc_notes_determination_text), GRE_TEXVERB_ELEMENT,
- ¬es_lloc);
+ gregorio_strdup(gabc_notes_determination_text),
+ GRE_TEXVERB_ELEMENT, ¬es_lloc);
}
[^\]]+ {
gregorio_add_texverb_as_note(¤t_note,
- strdup(gabc_notes_determination_text), GRE_ALT, ¬es_lloc);
+ gregorio_strdup(gabc_notes_determination_text), GRE_ALT,
+ ¬es_lloc);
}
\] {
BEGIN(INITIAL);
}
\{ {
- gregorio_add_texverb_as_note(¤t_note, strdup("\\hbox to 0pt{"),
- GRE_TEXVERB_ELEMENT, ¬es_lloc);
+ gregorio_add_texverb_as_note(¤t_note,
+ gregorio_strdup("\\hbox to 0pt{"), GRE_TEXVERB_ELEMENT,
+ ¬es_lloc);
}
\} {
gregorio_add_texverb_as_note(¤t_note,
- strdup("\\hss%\n}%\n\\GreNoBreak\\relax "), GRE_TEXVERB_ELEMENT,
- ¬es_lloc);
+ gregorio_strdup("\\hss%\n}%\n\\GreNoBreak\\relax "),
+ GRE_TEXVERB_ELEMENT, ¬es_lloc);
}
[a-m]\+ {
gregorio_add_manual_custos_as_note(¤t_note,
diff --git a/src/gabc/gabc-score-determination.h b/src/gabc/gabc-score-determination.h
index 0eb917943..3098ec177 100644
--- a/src/gabc/gabc-score-determination.h
+++ b/src/gabc/gabc-score-determination.h
@@ -1,4 +1,7 @@
/*
+ * Gregorio is a program that translates gabc files to GregorioTeX
+ * This header shares definitions between the score parser and lexer.
+ *
* Gregorio score determination in gabc input.
* Copyright (C) 2006-2015 The Gregorio Project (see CONTRIBUTORS.md)
*
diff --git a/src/gabc/gabc-score-determination.l b/src/gabc/gabc-score-determination.l
index 4d2a07992..36cbe385e 100644
--- a/src/gabc/gabc-score-determination.l
+++ b/src/gabc/gabc-score-determination.l
@@ -1,5 +1,8 @@
%{
/*
+ * Gregorio is a program that translates gabc files to GregorioTeX
+ * This file implements the score lexer.
+ *
* Gregorio score determination in gabc input.
* Copyright (C) 2006-2015 The Gregorio Project (see CONTRIBUTORS.md)
*
@@ -25,12 +28,15 @@
#include
#include "struct.h"
#include "messages.h"
+#include "bool.h"
+#include "support.h"
#include "gabc.h"
#include "gabc-score-determination.h"
#include "gabc-score-determination-y.h"
static unsigned char style_stack = 0;
+static bool eof_found = false;
#define YY_NO_INPUT
@@ -120,7 +126,8 @@ semicolon. */
return COLON;
}
[^;\n\r]*(;[^;\n\r]+)*([\n\r]+[^;]*(;[^;]+)*)? {
- gabc_score_determination_lval.text = strdup(gabc_score_determination_text);
+ gabc_score_determination_lval.text =
+ gregorio_strdup(gabc_score_determination_text);
return ATTRIBUTE;
}
;(;|[\n\r]+) {
@@ -231,7 +238,8 @@ semicolon. */
gabc_score_determination_text[0]);
}
[^\{\}\(\[\]<%]+ {
- gabc_score_determination_lval.text = strdup(gabc_score_determination_text);
+ gabc_score_determination_lval.text =
+ gregorio_strdup(gabc_score_determination_text);
return CHARACTERS;
}
{
@@ -325,7 +333,8 @@ semicolon. */
return SP_END;
}